@chest-gate/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +55 -0
  2. package/dist/chest_splitter_idl.json +482 -0
  3. package/dist/commands/app.d.ts +3 -0
  4. package/dist/commands/app.d.ts.map +1 -0
  5. package/dist/commands/app.js +42 -0
  6. package/dist/commands/app.js.map +1 -0
  7. package/dist/commands/deploy.d.ts +3 -0
  8. package/dist/commands/deploy.d.ts.map +1 -0
  9. package/dist/commands/deploy.js +285 -0
  10. package/dist/commands/deploy.js.map +1 -0
  11. package/dist/commands/gate.d.ts +3 -0
  12. package/dist/commands/gate.d.ts.map +1 -0
  13. package/dist/commands/gate.js +114 -0
  14. package/dist/commands/gate.js.map +1 -0
  15. package/dist/commands/init.d.ts +3 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +153 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/keypair.d.ts +3 -0
  20. package/dist/commands/keypair.d.ts.map +1 -0
  21. package/dist/commands/keypair.js +38 -0
  22. package/dist/commands/keypair.js.map +1 -0
  23. package/dist/commands/split.d.ts +3 -0
  24. package/dist/commands/split.d.ts.map +1 -0
  25. package/dist/commands/split.js +98 -0
  26. package/dist/commands/split.js.map +1 -0
  27. package/dist/commands/status.d.ts +3 -0
  28. package/dist/commands/status.d.ts.map +1 -0
  29. package/dist/commands/status.js +37 -0
  30. package/dist/commands/status.js.map +1 -0
  31. package/dist/config.d.ts +43 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +114 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +23 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/keypair.d.ts +9 -0
  40. package/dist/keypair.d.ts.map +1 -0
  41. package/dist/keypair.js +50 -0
  42. package/dist/keypair.js.map +1 -0
  43. package/dist/manifest.d.ts +69 -0
  44. package/dist/manifest.d.ts.map +1 -0
  45. package/dist/manifest.js +171 -0
  46. package/dist/manifest.js.map +1 -0
  47. package/dist/splitter-init.d.ts +32 -0
  48. package/dist/splitter-init.d.ts.map +1 -0
  49. package/dist/splitter-init.js +99 -0
  50. package/dist/splitter-init.js.map +1 -0
  51. package/package.json +58 -0
@@ -0,0 +1,171 @@
1
+ /**
2
+ * app.md manifest, the authoring-side artifact for an App (an install-ready
3
+ * agent capability that wraps one or more paid Gates).
4
+ *
5
+ * Authors keep an `app.md` in their repo with YAML frontmatter declaring the
6
+ * App's identity, the upstream Gates it calls, and human-readable metadata.
7
+ * The markdown body becomes the listing description on chest.sh.
8
+ *
9
+ * The payout wallet is **deliberately not a manifest field**, it is resolved
10
+ * from the on-chain author record (npm/crates.io/Hugging Face pattern).
11
+ * Wallet rotation, multi-sig payouts, and impersonation prevention all live
12
+ * on the author record, not in every manifest.
13
+ *
14
+ * Hand-rolled validator (no zod dep). Returns either a typed manifest or
15
+ * a structured list of errors with field paths so the CLI can render them
16
+ * with line/column hints.
17
+ */
18
+ import { readFile } from "node:fs/promises";
19
+ import matter from "gray-matter";
20
+ export const CAPABILITY_TAGS = [
21
+ "INFERENCE",
22
+ "SEARCH",
23
+ "DATA",
24
+ "MEDIA",
25
+ "INFRA",
26
+ ];
27
+ const NAME_PATTERN = /^[a-z0-9-]+$/;
28
+ const AUTHOR_PATTERN = /^@[a-z0-9-]+$/;
29
+ const SLUG_PATTERN = /^@[a-z0-9-]+\/[a-z0-9-]+$/;
30
+ const SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:-[\w.-]+)?(?:\+[\w.-]+)?$/;
31
+ const HTTPS_PATTERN = /^https:\/\/[^\s]+$/;
32
+ /**
33
+ * Parse and validate an app.md manifest from disk. Returns either the
34
+ * typed manifest (`{ ok: true, manifest }`) or a list of errors.
35
+ */
36
+ export async function loadManifest(path) {
37
+ let raw;
38
+ try {
39
+ raw = await readFile(path, "utf-8");
40
+ }
41
+ catch (err) {
42
+ return {
43
+ ok: false,
44
+ errors: [{ path: "<file>", message: `Cannot read ${path}: ${err.message}` }],
45
+ };
46
+ }
47
+ return parseManifest(raw);
48
+ }
49
+ /**
50
+ * Parse and validate a manifest from a raw string. Exposed separately so
51
+ * tests don't need a real file on disk.
52
+ */
53
+ export function parseManifest(raw) {
54
+ let parsed;
55
+ try {
56
+ const result = matter(raw);
57
+ parsed = { data: result.data ?? {}, content: result.content ?? "" };
58
+ }
59
+ catch (err) {
60
+ return {
61
+ ok: false,
62
+ errors: [{ path: "<frontmatter>", message: `Invalid YAML: ${err.message}` }],
63
+ };
64
+ }
65
+ const errors = [];
66
+ const data = parsed.data;
67
+ // name
68
+ const name = data.name;
69
+ if (typeof name !== "string" || name.length === 0) {
70
+ errors.push({ path: "name", message: "required, must be a non-empty string" });
71
+ }
72
+ else if (name.length > 64) {
73
+ errors.push({ path: "name", message: "must be ≤ 64 chars" });
74
+ }
75
+ else if (!NAME_PATTERN.test(name)) {
76
+ errors.push({ path: "name", message: "must match [a-z0-9-]+ (kebab-case)" });
77
+ }
78
+ // author
79
+ const author = data.author;
80
+ if (typeof author !== "string" || author.length === 0) {
81
+ errors.push({ path: "author", message: "required, must be a non-empty string" });
82
+ }
83
+ else if (!AUTHOR_PATTERN.test(author)) {
84
+ errors.push({ path: "author", message: "must start with @ and match @[a-z0-9-]+" });
85
+ }
86
+ // version
87
+ const version = data.version;
88
+ if (typeof version !== "string" || version.length === 0) {
89
+ errors.push({ path: "version", message: "required, must be a non-empty string" });
90
+ }
91
+ else if (!SEMVER_PATTERN.test(version)) {
92
+ errors.push({ path: "version", message: `'${version}' is not valid semver` });
93
+ }
94
+ // description
95
+ const description = data.description;
96
+ if (typeof description !== "string" || description.length === 0) {
97
+ errors.push({ path: "description", message: "required, must be a non-empty string" });
98
+ }
99
+ else if (description.length > 280) {
100
+ errors.push({ path: "description", message: `${description.length} chars > 280 max` });
101
+ }
102
+ // capabilityTags
103
+ const tags = data.capabilityTags;
104
+ if (!Array.isArray(tags) || tags.length === 0) {
105
+ errors.push({ path: "capabilityTags", message: "required, must be a non-empty array" });
106
+ }
107
+ else {
108
+ tags.forEach((t, i) => {
109
+ if (typeof t !== "string" || !CAPABILITY_TAGS.includes(t)) {
110
+ errors.push({
111
+ path: `capabilityTags[${i}]`,
112
+ message: `'${String(t)}' is not one of ${CAPABILITY_TAGS.join(", ")}`,
113
+ });
114
+ }
115
+ });
116
+ }
117
+ // upstreamGates (optional)
118
+ const gates = data.upstreamGates;
119
+ if (gates !== undefined && gates !== null) {
120
+ if (!Array.isArray(gates)) {
121
+ errors.push({ path: "upstreamGates", message: "must be an array of @author/name slugs" });
122
+ }
123
+ else {
124
+ gates.forEach((g, i) => {
125
+ if (typeof g !== "string" || !SLUG_PATTERN.test(g)) {
126
+ errors.push({
127
+ path: `upstreamGates[${i}]`,
128
+ message: `'${String(g)}' must match @author/app-name`,
129
+ });
130
+ }
131
+ });
132
+ }
133
+ }
134
+ // homepage (optional)
135
+ if (data.homepage !== undefined && data.homepage !== null) {
136
+ if (typeof data.homepage !== "string" || !HTTPS_PATTERN.test(data.homepage)) {
137
+ errors.push({ path: "homepage", message: "must be an https:// URL" });
138
+ }
139
+ }
140
+ // repository (optional)
141
+ if (data.repository !== undefined && data.repository !== null) {
142
+ if (typeof data.repository !== "string" || !HTTPS_PATTERN.test(data.repository)) {
143
+ errors.push({ path: "repository", message: "must be an https:// URL" });
144
+ }
145
+ }
146
+ // license (optional, free-form string for v1, full SPDX list is too large
147
+ // to enforce here; the registry will warn on unknown identifiers later)
148
+ if (data.license !== undefined && data.license !== null) {
149
+ if (typeof data.license !== "string" || data.license.length === 0) {
150
+ errors.push({ path: "license", message: "must be a non-empty string (SPDX identifier)" });
151
+ }
152
+ }
153
+ if (errors.length > 0)
154
+ return { ok: false, errors };
155
+ return {
156
+ ok: true,
157
+ manifest: {
158
+ name: name,
159
+ author: author,
160
+ version: version,
161
+ description: description,
162
+ capabilityTags: tags,
163
+ upstreamGates: gates ? gates : undefined,
164
+ homepage: data.homepage ? data.homepage : undefined,
165
+ repository: data.repository ? data.repository : undefined,
166
+ license: data.license ? data.license : undefined,
167
+ body: parsed.content,
168
+ },
169
+ };
170
+ }
171
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import pkg from "@coral-xyz/anchor";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ export declare const CHEST_PROTOCOL_WALLET: pkg.web3.PublicKey;
4
+ export declare const RPC_URLS: Record<string, string>;
5
+ export interface SplitInitResult {
6
+ splitConfigPda: string;
7
+ vaultPda: string;
8
+ merchantTokenAccount: string;
9
+ protocolTokenAccount: string;
10
+ txSignature: string;
11
+ }
12
+ export declare function computeSlugHash(slug: string): Buffer;
13
+ /**
14
+ * Derive the split_config and vault PDAs for a given authority + slug + mint.
15
+ */
16
+ export declare function deriveSplitPdas(authority: PublicKey, slug: string, usdcMint: PublicKey): Promise<{
17
+ splitConfigPda: PublicKey;
18
+ vaultPda: PublicKey;
19
+ }>;
20
+ /**
21
+ * Initialize a split config on-chain for the given merchant + slug.
22
+ * Creates the SplitConfig PDA, vault PDA, and merchant/protocol ATAs if needed.
23
+ */
24
+ export declare function initializeSplit(opts: {
25
+ feePayerKeypair: Uint8Array;
26
+ merchantWallet: string;
27
+ usdcMintAddress: string;
28
+ slug: string;
29
+ referrerBps: number;
30
+ network: string;
31
+ }): Promise<SplitInitResult>;
32
+ //# sourceMappingURL=splitter-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splitter-init.d.ts","sourceRoot":"","sources":["../src/splitter-init.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,mBAAmB,CAAC;AAEpC,OAAO,EAAuB,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAgBhF,eAAO,MAAM,qBAAqB,oBAGjC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM3C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,GAClB,OAAO,CAAC;IAAE,cAAc,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAC,CAY7D;AAkCD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,eAAe,EAAE,UAAU,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuD3B"}
@@ -0,0 +1,99 @@
1
+ import pkg from "@coral-xyz/anchor";
2
+ const { AnchorProvider, Program, Wallet, setProvider } = pkg;
3
+ import { Connection, Keypair, PublicKey, SystemProgram } from "@solana/web3.js";
4
+ import { TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, getAssociatedTokenAddress, createAssociatedTokenAccountInstruction, getAccount, } from "@solana/spl-token";
5
+ import { createHash } from "crypto";
6
+ import idl from "./chest_splitter_idl.json" with { type: "json" };
7
+ const PROGRAM_ID = new PublicKey("9a6zrqau5xVEdxNqBUfL2G18WuryQbWeJScPAUHZvmmX");
8
+ // Chest treasury wallet, receives protocol fee (1.5%).
9
+ // Override with CHEST_PROTOCOL_WALLET env var for production.
10
+ // Default is the Chest devnet treasury (our Solana CLI keypair).
11
+ export const CHEST_PROTOCOL_WALLET = new PublicKey(process.env.CHEST_PROTOCOL_WALLET ||
12
+ "HndLQmUiUzi6mn1BHUrMWuNKzagvPfPQSkXFm6tC7wev");
13
+ export const RPC_URLS = {
14
+ "solana-devnet": "https://api.devnet.solana.com",
15
+ "solana-mainnet": "https://api.mainnet-beta.solana.com",
16
+ devnet: "https://api.devnet.solana.com",
17
+ mainnet: "https://api.mainnet-beta.solana.com",
18
+ localnet: "http://localhost:8899",
19
+ };
20
+ export function computeSlugHash(slug) {
21
+ return createHash("sha256").update(slug).digest().slice(0, 8);
22
+ }
23
+ /**
24
+ * Derive the split_config and vault PDAs for a given authority + slug + mint.
25
+ */
26
+ export async function deriveSplitPdas(authority, slug, usdcMint) {
27
+ const slugHash = computeSlugHash(slug);
28
+ const [splitConfigPda] = PublicKey.findProgramAddressSync([Buffer.from("split"), authority.toBuffer(), slugHash], PROGRAM_ID);
29
+ // Vault is now ATA(split_config_pda, mint), allowOwnerOffCurve = true for PDA owner
30
+ const vaultPda = await getAssociatedTokenAddress(usdcMint, splitConfigPda, true);
31
+ return { splitConfigPda, vaultPda };
32
+ }
33
+ /**
34
+ * Ensure an ATA exists for a wallet; create it if missing.
35
+ * Returns the ATA address.
36
+ */
37
+ async function ensureAta(connection, payer, mint, owner) {
38
+ const ata = await getAssociatedTokenAddress(mint, owner);
39
+ try {
40
+ await getAccount(connection, ata);
41
+ return ata;
42
+ }
43
+ catch {
44
+ // ATA doesn't exist, create it
45
+ const ix = createAssociatedTokenAccountInstruction(payer.publicKey, ata, owner, mint);
46
+ const { sendAndConfirmTransaction, Transaction } = await import("@solana/web3.js");
47
+ const tx = new Transaction().add(ix);
48
+ await sendAndConfirmTransaction(connection, tx, [payer]);
49
+ return ata;
50
+ }
51
+ }
52
+ /**
53
+ * Initialize a split config on-chain for the given merchant + slug.
54
+ * Creates the SplitConfig PDA, vault PDA, and merchant/protocol ATAs if needed.
55
+ */
56
+ export async function initializeSplit(opts) {
57
+ const rpcUrl = RPC_URLS[opts.network] ?? opts.network;
58
+ const connection = new Connection(rpcUrl, "confirmed");
59
+ const authority = Keypair.fromSecretKey(opts.feePayerKeypair);
60
+ const wallet = new Wallet(authority);
61
+ const provider = new AnchorProvider(connection, wallet, {
62
+ commitment: "confirmed",
63
+ });
64
+ setProvider(provider);
65
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
+ const program = new Program(idl, provider);
67
+ const merchantWallet = new PublicKey(opts.merchantWallet);
68
+ const usdcMint = new PublicKey(opts.usdcMintAddress);
69
+ const slugHash = computeSlugHash(opts.slug);
70
+ const slugHashArray = Array.from(slugHash);
71
+ const { splitConfigPda, vaultPda } = await deriveSplitPdas(authority.publicKey, opts.slug, usdcMint);
72
+ // Ensure merchant and protocol ATAs exist before initializing
73
+ const [merchantAta, protocolAta] = await Promise.all([
74
+ ensureAta(connection, authority, usdcMint, merchantWallet),
75
+ ensureAta(connection, authority, usdcMint, CHEST_PROTOCOL_WALLET),
76
+ ]);
77
+ const txSignature = await program.methods
78
+ .initializeSplit(slugHashArray, opts.referrerBps)
79
+ .accounts({
80
+ authority: authority.publicKey,
81
+ merchantWallet,
82
+ protocolWallet: CHEST_PROTOCOL_WALLET,
83
+ usdcMint,
84
+ splitConfig: splitConfigPda,
85
+ vault: vaultPda,
86
+ tokenProgram: TOKEN_PROGRAM_ID,
87
+ associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
88
+ systemProgram: SystemProgram.programId,
89
+ })
90
+ .rpc();
91
+ return {
92
+ splitConfigPda: splitConfigPda.toBase58(),
93
+ vaultPda: vaultPda.toBase58(),
94
+ merchantTokenAccount: merchantAta.toBase58(),
95
+ protocolTokenAccount: protocolAta.toBase58(),
96
+ txSignature,
97
+ };
98
+ }
99
+ //# sourceMappingURL=splitter-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splitter-init.js","sourceRoot":"","sources":["../src/splitter-init.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@chest-gate/cli",
3
+ "version": "0.1.0",
4
+ "description": "Chest Gate CLI. One command to monetise any API with x402 on Solana.",
5
+ "keywords": [
6
+ "x402",
7
+ "solana",
8
+ "cli",
9
+ "chest-gate",
10
+ "monetization",
11
+ "usdc",
12
+ "agent"
13
+ ],
14
+ "homepage": "https://chest.sh",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/chesthq/packages.git",
18
+ "directory": "cli"
19
+ },
20
+ "license": "MIT",
21
+ "type": "module",
22
+ "bin": {
23
+ "chest-gate": "./dist/index.js"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md"
28
+ ],
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc",
34
+ "dev": "tsc --watch",
35
+ "prepublishOnly": "npm run build"
36
+ },
37
+ "dependencies": {
38
+ "@chest-gate/proxy": "^0.1.0",
39
+ "@coral-xyz/anchor": "^0.32.1",
40
+ "@solana/kit": "^5.5.0",
41
+ "@solana/spl-token": "^0.4.14",
42
+ "@solana/web3.js": "^1.98.4",
43
+ "bip39": "^3.1.0",
44
+ "chalk": "^5.4.0",
45
+ "commander": "^13.0.0",
46
+ "ed25519-hd-key": "^1.3.0",
47
+ "gray-matter": "^4.0.3",
48
+ "inquirer": "^12.0.0",
49
+ "yaml": "^2.7.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^22.0.0",
53
+ "typescript": "^5.8.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=20"
57
+ }
58
+ }