@leashmarket/mcp 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.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * `LeashSigner` — the cryptographic primitive every standalone Leash
3
+ * surface (MCP, CLI, SDK) shares. It's just an ed25519 keypair, but
4
+ * we centralise loading + the few representations we need so the
5
+ * tool code can stay representation-agnostic.
6
+ *
7
+ * Three representations come out of one secret:
8
+ *
9
+ * - `umi.identity()` (Metaplex `Signer`) — used for the MPL Core
10
+ * `Execute` instruction during withdraws and the SPL `Approve`
11
+ * during delegate rotation.
12
+ *
13
+ * - `@solana/kit` `TransactionSigner` — used by `@leashmarket/buyer-kit`
14
+ * when paying x402 links (the underlying x402 SVM scheme is
15
+ * written against `@solana/kit`).
16
+ *
17
+ * - The bare `Uint8Array` secret + base58 `pubkey` — used for
18
+ * `X-Leash-Sig` HTTP signing in batch 4.
19
+ *
20
+ * Accepts either a base58 string OR the JSON-array shape that
21
+ * `solana-keygen` writes by default. Throws on malformed input
22
+ * because a misconfigured signer should fail loudly at boot, not
23
+ * silently on first tool call.
24
+ */
25
+ import { type KeyPairSigner } from '@solana/kit';
26
+ import { type PublicKey as UmiPublicKey, type Umi } from '@metaplex-foundation/umi';
27
+ import type { SvmNetwork } from '@leashmarket/mcp-core';
28
+ export type LeashSigner = {
29
+ /** Base58 ed25519 public key. */
30
+ pubkey: string;
31
+ /** 64-byte raw secret. Keep in memory only. */
32
+ secret: Uint8Array;
33
+ /**
34
+ * Build a Umi instance configured with `mplCore` + `mplToolbox` and
35
+ * this signer set as the identity. Memoised per Leash config so
36
+ * repeat calls within one MCP process reuse the same RPC client.
37
+ */
38
+ getUmi(rpcUrl: string): Umi;
39
+ /**
40
+ * Build a `@solana/kit` `KeyPairSigner` for buyer-kit. Memoised.
41
+ */
42
+ getKitSigner(): Promise<KeyPairSigner>;
43
+ /** Convenience: the executive's pubkey as a Umi PublicKey. */
44
+ umiPubkey: UmiPublicKey;
45
+ };
46
+ /**
47
+ * Build a `LeashSigner` from a raw secret string. Sets up the lazy
48
+ * Umi + kit-signer caches; nothing network-touching happens until a
49
+ * tool actually needs them.
50
+ */
51
+ export declare function loadSigner(secretRaw: string): LeashSigner;
52
+ /** Ergonomic helper for callers that have a network-friendly slug. */
53
+ export declare function defaultRpcFor(network: SvmNetwork): string;
54
+ //# sourceMappingURL=signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAgC,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/E,OAAO,EAIL,KAAK,SAAS,IAAI,YAAY,EAC9B,KAAK,GAAG,EACT,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG;IACxB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,MAAM,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;IAC5B;;OAEG;IACH,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IACvC,8DAA8D;IAC9D,SAAS,EAAE,YAAY,CAAC;CACzB,CAAC;AAmCF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,CAmCzD;AAED,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAIzD"}
package/dist/signer.js ADDED
@@ -0,0 +1,102 @@
1
+ /**
2
+ * `LeashSigner` — the cryptographic primitive every standalone Leash
3
+ * surface (MCP, CLI, SDK) shares. It's just an ed25519 keypair, but
4
+ * we centralise loading + the few representations we need so the
5
+ * tool code can stay representation-agnostic.
6
+ *
7
+ * Three representations come out of one secret:
8
+ *
9
+ * - `umi.identity()` (Metaplex `Signer`) — used for the MPL Core
10
+ * `Execute` instruction during withdraws and the SPL `Approve`
11
+ * during delegate rotation.
12
+ *
13
+ * - `@solana/kit` `TransactionSigner` — used by `@leashmarket/buyer-kit`
14
+ * when paying x402 links (the underlying x402 SVM scheme is
15
+ * written against `@solana/kit`).
16
+ *
17
+ * - The bare `Uint8Array` secret + base58 `pubkey` — used for
18
+ * `X-Leash-Sig` HTTP signing in batch 4.
19
+ *
20
+ * Accepts either a base58 string OR the JSON-array shape that
21
+ * `solana-keygen` writes by default. Throws on malformed input
22
+ * because a misconfigured signer should fail loudly at boot, not
23
+ * silently on first tool call.
24
+ */
25
+ import { createKeyPairSignerFromBytes } from '@solana/kit';
26
+ import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
27
+ import { keypairIdentity, publicKey as umiPublicKey, } from '@metaplex-foundation/umi';
28
+ import { mplCore } from '@metaplex-foundation/mpl-core';
29
+ import { mplToolbox } from '@metaplex-foundation/mpl-toolbox';
30
+ import { base58 } from '@metaplex-foundation/umi/serializers';
31
+ /** Decode the loose secret form into a 64-byte Uint8Array. */
32
+ function decodeSecretBytes(secret) {
33
+ const trimmed = secret.trim();
34
+ // solana-keygen JSON shape.
35
+ if (trimmed.startsWith('[')) {
36
+ const parsed = JSON.parse(trimmed);
37
+ if (!Array.isArray(parsed) || parsed.length !== 64) {
38
+ throw new Error('executive secret JSON must be a 64-element byte array');
39
+ }
40
+ const bytes = Uint8Array.from(parsed.map((n) => Number(n)));
41
+ if (bytes.some((b) => Number.isNaN(b) || b < 0 || b > 255)) {
42
+ throw new Error('executive secret JSON contains non-byte values');
43
+ }
44
+ return bytes;
45
+ }
46
+ // base58.
47
+ try {
48
+ const bytes = base58.serialize(trimmed);
49
+ if (bytes.length !== 64) {
50
+ throw new Error(`executive secret must decode to 64 bytes (got ${bytes.length}). Use solana-keygen output verbatim.`);
51
+ }
52
+ return bytes;
53
+ }
54
+ catch (err) {
55
+ throw new Error(`executive secret is not a valid base58 string: ${err instanceof Error ? err.message : 'unknown'}`);
56
+ }
57
+ }
58
+ /**
59
+ * Build a `LeashSigner` from a raw secret string. Sets up the lazy
60
+ * Umi + kit-signer caches; nothing network-touching happens until a
61
+ * tool actually needs them.
62
+ */
63
+ export function loadSigner(secretRaw) {
64
+ const secret = decodeSecretBytes(secretRaw);
65
+ // Derive pubkey via a temporary Umi so we don't carry an extra
66
+ // ed25519 lib just for this one call.
67
+ const probe = createUmi('https://invalid');
68
+ const umiKp = probe.eddsa.createKeypairFromSecretKey(secret);
69
+ const pubkeyStr = umiKp.publicKey.toString();
70
+ let umi = null;
71
+ let cachedRpcUrl = null;
72
+ let kitSigner = null;
73
+ const getUmi = (rpcUrl) => {
74
+ if (umi && cachedRpcUrl === rpcUrl)
75
+ return umi;
76
+ umi = createUmi(rpcUrl).use(mplCore()).use(mplToolbox());
77
+ const kp = umi.eddsa.createKeypairFromSecretKey(secret);
78
+ umi.use(keypairIdentity(kp));
79
+ cachedRpcUrl = rpcUrl;
80
+ return umi;
81
+ };
82
+ const getKitSigner = async () => {
83
+ if (kitSigner)
84
+ return kitSigner;
85
+ kitSigner = await createKeyPairSignerFromBytes(secret);
86
+ return kitSigner;
87
+ };
88
+ return {
89
+ pubkey: pubkeyStr,
90
+ secret,
91
+ getUmi,
92
+ getKitSigner,
93
+ umiPubkey: umiPublicKey(pubkeyStr),
94
+ };
95
+ }
96
+ /** Ergonomic helper for callers that have a network-friendly slug. */
97
+ export function defaultRpcFor(network) {
98
+ return network === 'solana-mainnet'
99
+ ? 'https://api.mainnet-beta.solana.com'
100
+ : 'https://api.devnet.solana.com';
101
+ }
102
+ //# sourceMappingURL=signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.js","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "publishConfig": {
3
+ "access": "public"
4
+ },
5
+ "name": "@leashmarket/mcp",
6
+ "version": "0.1.0",
7
+ "description": "Standalone Leash MCP server. STDIO transport. Drop into Cursor / Claude Desktop / Cline / Continue / ChatGPT-MCP.",
8
+ "private": false,
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "bin": {
13
+ "leash-mcp": "./dist/cli.js"
14
+ },
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "dependencies": {
26
+ "@metaplex-foundation/mpl-core": "^1.10.0",
27
+ "@metaplex-foundation/mpl-toolbox": "^0.10.0",
28
+ "@metaplex-foundation/umi": "^1.5.1",
29
+ "@metaplex-foundation/umi-bundle-defaults": "^1.5.1",
30
+ "@modelcontextprotocol/sdk": "^1.29.0",
31
+ "@solana/kit": "^5.5.0",
32
+ "zod": "^3.24.1",
33
+ "@leashmarket/mcp-core": "0.1.0",
34
+ "@leashmarket/registry-utils": "0.1.0",
35
+ "@leashmarket/core": "0.1.0",
36
+ "@leashmarket/buyer-kit": "0.1.0",
37
+ "@leashmarket/schemas": "0.1.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.10.2",
41
+ "tsx": "^4.20.0",
42
+ "typescript": "^5.7.2",
43
+ "vitest": "^2.1.8"
44
+ },
45
+ "scripts": {
46
+ "build": "tsc -p tsconfig.build.json && chmod +x ./dist/cli.js",
47
+ "typecheck": "tsc -p tsconfig.json",
48
+ "lint": "echo lint:mcp",
49
+ "test": "vitest run",
50
+ "dev": "node --import tsx ./src/cli.ts",
51
+ "dev:demo-balance": "node --import tsx ./scripts/demo-balance.ts",
52
+ "fix-delegation": "node --import tsx ./scripts/fix-delegation.ts",
53
+ "test:yc-demo-devnet": "node --import tsx ./scripts/test-yc-demo-devnet.ts"
54
+ }
55
+ }