Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 168 additions & 33 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 14 additions & 4 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "module",
"main": "./bin/protokit-cli.js",
"bin": {
"proto-kit": "./bin/protokit-cli.js"
"protokit": "./bin/protokit-cli.js"
},
"publishConfig": {
"access": "public"
Expand All @@ -21,21 +21,31 @@
"author": "",
"license": "ISC",
"dependencies": {
"yargs": "17.7.2",
"@inquirer/figures": "^2.0.3",
"dotenv": "^17.2.3",
"inquirer": "^9.3.0",
"kleur": "^4.1.5",
"mina-fungible-token": "^1.1.0",
"reflect-metadata": "^0.1.13",
"spectaql": "3.0.5",
"ts-node": "^10.9.1",
"spectaql": "3.0.5"
"yargs": "17.7.2"
},
"peerDependencies": {
"@proto-kit/api": "*",
"@proto-kit/common": "*",
"@proto-kit/explorer": "*",
"@proto-kit/library": "*",
"@proto-kit/module": "*",
"@proto-kit/protocol": "*",
"@proto-kit/sdk": "*",
"@proto-kit/sequencer": "*",
"o1js": "^2.10.0"
"@proto-kit/stack": "*",
"o1js": "^2.10.0",
"tsyringe": "^4.10.0"
},
"devDependencies": {
"@types/inquirer": "^9.0.9",
"@types/node": "^20.19.24",
"@types/yargs": "17.0.32"
}
Expand Down
19 changes: 19 additions & 0 deletions packages/cli/src/commands/explorer/explorer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { CommandModule } from "yargs";

export const explorerCommand: CommandModule = {
command: "explorer <subcommand>",
describe: "Explorer commands",
builder: async (yargs) => {
const { explorerStartCommand } = await import("./explorerStart");

return yargs
.command(explorerStartCommand)
.demandCommand(
1,
"You must specify a subcommand. Use --help to see available options."
);
},
handler: () => {
console.log("Use a subcommand. See --help for available options.");
},
};
52 changes: 52 additions & 0 deletions packages/cli/src/commands/explorer/explorerStart.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { CommandModule } from "yargs";

interface ExplorerStartArgs {
port: number;
"indexer-url"?: string;
"dashboard-title"?: string;
"dashboard-slogan"?: string;
}

export const explorerStartCommand: CommandModule<{}, ExplorerStartArgs> = {
command: "start",
describe: "Start the explorer UI",
builder: (yarg) =>
yarg
.option("port", {
alias: "p",
type: "number",
default: 5003,
describe: "port to run the explorer on",
})
.option("indexer-url", {
type: "string",
describe: "GraphQL endpoint URL for the indexer",
})
.option("dashboard-title", {
type: "string",
default: "Protokit Explorer",
describe: "Title for the explorer dashboard",
})
.option("dashboard-slogan", {
type: "string",
default: "Explore your Protokit AppChain",
describe: "Slogan for the explorer dashboard",
}),
handler: async (args) => {
try {
const { default: explorerStart } = await import(
"../../scripts/explorer/start"
);
await explorerStart({
port: args.port,
indexerUrl: args["indexer-url"],
dashboardTitle: args["dashboard-title"],
dashboardSlogan: args["dashboard-slogan"],
});
process.exit(0);
} catch (error) {
console.error("Failed to start explorer:", error);
process.exit(1);
}
},
};
114 changes: 40 additions & 74 deletions packages/cli/src/commands/generateGqlDocs.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,44 @@
import {
BlockStorageNetworkStateModule,
InMemoryTransactionSender,
StateServiceQueryModule,
} from "@proto-kit/sdk";
import { Protocol } from "@proto-kit/protocol";
import {
AppChain,
Sequencer,
VanillaTaskWorkerModules,
} from "@proto-kit/sequencer";
import {
InMemorySequencerModules,
VanillaProtocolModules,
VanillaRuntimeModules,
} from "@proto-kit/library";
import {
GraphqlSequencerModule,
GraphqlServer,
VanillaGraphqlModules,
} from "@proto-kit/api";
import { Runtime } from "@proto-kit/module";
import { CommandModule } from "yargs";

import { generateGqlDocs } from "../utils";

export async function generateGqlDocsCommand(args: {
empty: boolean;
interface GenerateGqlDocsArgs {
port: number;
url: string;
}) {
if (args.empty) {
const { port } = args;
console.log(`Starting AppChain on port ${port}...`);

const appChain = AppChain.from({
Runtime: Runtime.from(VanillaRuntimeModules.with({})),
Protocol: Protocol.from(VanillaProtocolModules.with({})),
Sequencer: Sequencer.from(
InMemorySequencerModules.with({
GraphqlServer: GraphqlServer,
Graphql: GraphqlSequencerModule.from(VanillaGraphqlModules.with({})),
})
),
TransactionSender: InMemoryTransactionSender,
QueryTransportModule: StateServiceQueryModule,
NetworkStateTransportModule: BlockStorageNetworkStateModule,
});

appChain.configurePartial({
Runtime: VanillaRuntimeModules.defaultConfig(),
Protocol: VanillaProtocolModules.defaultConfig(),
Sequencer: {
Database: {},
TaskQueue: {},
LocalTaskWorkerModule: VanillaTaskWorkerModules.defaultConfig(),
Mempool: {},
BlockProducerModule: {},
SequencerStartupModule: {},
BlockTrigger: { blockInterval: 5000, produceEmptyBlocks: true },
FeeStrategy: {},
BaseLayer: {},
BatchProducerModule: {},
Graphql: VanillaGraphqlModules.defaultConfig(),
GraphqlServer: { port, host: "localhost", graphiql: true },
},
});

await appChain.start();
console.log("AppChain started successfully!");

const gqlUrl = `http://localhost:${port}/graphql`;
await generateGqlDocs(gqlUrl);
await appChain.close();
} else {
console.log(`Using existing GraphQL endpoint: ${args.url}`);
await generateGqlDocs(args.url);
}
empty: boolean;
}

export const generateGqlDocsCommand: CommandModule<{}, GenerateGqlDocsArgs> = {
command: "generate-gql-docs",
describe: "Generate GraphQL docs",
builder: (yarg) =>
yarg
.option("port", {
alias: "p",
type: "number",
default: 8080,
describe: "Port for the GraphQL server if creating an AppChain",
})
.option("url", {
alias: "u",
type: "string",
default: "http://localhost:8080/graphql",
describe: "GraphQL endpoint to use if not starting AppChain",
})
.option("empty", {
alias: "e",
type: "boolean",
default: false,
describe: "Start a new AppChain instead of using existing URL",
}),
handler: async (args) => {
try {
const { default: generateGqlDocs } = await import(
"../scripts/graphqlDocs/generateGqlDocs"
);
await generateGqlDocs(args);
process.exit(0);
} catch (error) {
console.error("Failed to start AppChain or generate docs:", error);
process.exit(1);
}
},
};
36 changes: 36 additions & 0 deletions packages/cli/src/commands/run/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { CommandModule } from "yargs";

interface DeployArgs {
"env-path"?: string;
env?: string[];
}

export const deployCommand: CommandModule<{}, DeployArgs> = {
command: "deploy",
describe:
"Deploy settlement contracts\n\nRequires: PROTOKIT_SETTLEMENT_CONTRACT_PRIVATE_KEY, PROTOKIT_DISPATCHER_CONTRACT_PRIVATE_KEY, PROTOKIT_MINA_BRIDGE_CONTRACT_PRIVATE_KEY",
builder: (yarg) =>
yarg
.option("env-path", { type: "string", describe: "path to .env file" })
.option("env", {
type: "string",
array: true,
describe: "environment variables as KEY=value",
}),
handler: async (args) => {
try {
const { default: deploy } = await import(
"../../scripts/settlement/deploy"
);
const { parseEnvArgs } = await import("../../utils/loadEnv");
await deploy({
envPath: args["env-path"],
envVars: parseEnvArgs(args.env ?? []),
});
process.exit(0);
} catch (error) {
console.error("Failed to deploy settlement:", error);
process.exit(1);
}
},
};
50 changes: 50 additions & 0 deletions packages/cli/src/commands/run/deposit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CommandModule } from "yargs";

interface DepositArgs {
tokenId: string;
fromKey: string;
toKey: string;
amount: number;
"env-path"?: string;
env?: string[];
}

export const depositCommand: CommandModule<{}, DepositArgs> = {
command: "deposit <tokenId> <fromKey> <toKey> <amount>",
describe:
"Deposit tokens to the bridge\n\nRequires: PROTOKIT_CUSTOM_TOKEN_PRIVATE_KEY (for custom tokens), PROTOKIT_CUSTOM_TOKEN_BRIDGE_PRIVATE_KEY, PROTOKIT_MINA_BRIDGE_CONTRACT_PRIVATE_KEY",
builder: (yarg) =>
yarg
.positional("tokenId", { type: "string", demandOption: true })
.positional("fromKey", { type: "string", demandOption: true })
.positional("toKey", { type: "string", demandOption: true })
.positional("amount", { type: "number", demandOption: true })
.option("env-path", { type: "string", describe: "path to .env file" })
.option("env", {
type: "string",
array: true,
describe: "environment variables as KEY=value",
}),
handler: async (args) => {
try {
const { default: deposit } = await import("../../scripts/bridge/deposit");
const { parseEnvArgs } = await import("../../utils/loadEnv");
await deposit(
{
envPath: args["env-path"],
envVars: parseEnvArgs(args.env ?? []),
},
{
tokenId: args.tokenId,
fromKey: args.fromKey,
toKey: args.toKey,
amount: args.amount,
}
);
process.exit(0);
} catch (error) {
console.error("Failed to deposit to bridge:", error);
process.exit(1);
}
},
};
38 changes: 38 additions & 0 deletions packages/cli/src/commands/run/faucet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { CommandModule } from "yargs";

interface FaucetArgs {
publicKey: string;
"env-path"?: string;
env?: string[];
}

export const faucetCommand: CommandModule<{}, FaucetArgs> = {
command: "faucet <publicKey>",
describe: "Send MINA to an account from the lightnet faucet",
builder: (yarg) =>
yarg
.positional("publicKey", {
type: "string",
describe: "public key to send MINA to",
demandOption: true,
})
.option("env-path", {
type: "string",
describe: "path to .env file",
})
.option("env", {
type: "string",
array: true,
describe: "environment variables as KEY=value",
}),
handler: async (args) => {
try {
const { default: faucet } = await import("../../scripts/lightnet/faucet");
await faucet(args.publicKey);
process.exit(0);
} catch (error) {
console.error("Failed to send funds from faucet:", error);
process.exit(1);
}
},
};
26 changes: 26 additions & 0 deletions packages/cli/src/commands/run/generateKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { CommandModule } from "yargs";

import type { GenerateKeysArgs } from "../../scripts/generateKeys";

export const generateKeysCommand: CommandModule<{}, GenerateKeysArgs> = {
command: "generate-keys [count]",
describe: "Generate private/public key pairs for development",
builder: (yarg) =>
yarg.positional("count", {
type: "number",
default: 1,
describe: "number of keys to generate",
}),
handler: async (args) => {
try {
const { default: generateKeys } = await import(
"../../scripts/generateKeys"
);
await generateKeys({ count: args.count });
process.exit(0);
} catch (error) {
console.error("Failed to generate keys:", error);
process.exit(1);
}
},
};
Loading