@namera-ai/cli 0.1.3 → 0.1.4

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 (143) hide show
  1. package/dist/commands/index.mjs +21 -0
  2. package/dist/commands/index.mjs.map +1 -0
  3. package/dist/commands/keystore/create.mjs +74 -0
  4. package/dist/commands/keystore/create.mjs.map +1 -0
  5. package/dist/commands/keystore/decrypt.mjs +71 -0
  6. package/dist/commands/keystore/decrypt.mjs.map +1 -0
  7. package/dist/commands/keystore/import.mjs +84 -0
  8. package/dist/commands/keystore/import.mjs.map +1 -0
  9. package/dist/commands/keystore/index.mjs +28 -0
  10. package/dist/commands/keystore/index.mjs.map +1 -0
  11. package/dist/commands/keystore/info.mjs +62 -0
  12. package/dist/commands/keystore/info.mjs.map +1 -0
  13. package/dist/commands/keystore/list.mjs +46 -0
  14. package/dist/commands/keystore/list.mjs.map +1 -0
  15. package/dist/commands/keystore/remove.mjs +51 -0
  16. package/dist/commands/keystore/remove.mjs.map +1 -0
  17. package/dist/commands/mcp/index.mjs +13 -0
  18. package/dist/commands/mcp/index.mjs.map +1 -0
  19. package/dist/commands/mcp/start.mjs +82 -0
  20. package/dist/commands/mcp/start.mjs.map +1 -0
  21. package/dist/commands/schema/index.mjs +53 -0
  22. package/dist/commands/schema/index.mjs.map +1 -0
  23. package/dist/commands/session-key/create/index.mjs +87 -0
  24. package/dist/commands/session-key/create/index.mjs.map +1 -0
  25. package/dist/commands/session-key/create/prompts/base.mjs +52 -0
  26. package/dist/commands/session-key/create/prompts/base.mjs.map +1 -0
  27. package/dist/commands/session-key/create/prompts/call.mjs +85 -0
  28. package/dist/commands/session-key/create/prompts/call.mjs.map +1 -0
  29. package/dist/commands/session-key/create/prompts/common.mjs +27 -0
  30. package/dist/commands/session-key/create/prompts/common.mjs.map +1 -0
  31. package/dist/commands/session-key/create/prompts/gas.mjs +19 -0
  32. package/dist/commands/session-key/create/prompts/gas.mjs.map +1 -0
  33. package/dist/commands/session-key/create/prompts/index.mjs +44 -0
  34. package/dist/commands/session-key/create/prompts/index.mjs.map +1 -0
  35. package/dist/commands/session-key/create/prompts/rate-limit.mjs +40 -0
  36. package/dist/commands/session-key/create/prompts/rate-limit.mjs.map +1 -0
  37. package/dist/commands/session-key/create/prompts/signature-caller.mjs +26 -0
  38. package/dist/commands/session-key/create/prompts/signature-caller.mjs.map +1 -0
  39. package/dist/commands/session-key/create/prompts/timestamp.mjs +32 -0
  40. package/dist/commands/session-key/create/prompts/timestamp.mjs.map +1 -0
  41. package/dist/commands/session-key/index.mjs +26 -0
  42. package/dist/commands/session-key/index.mjs.map +1 -0
  43. package/dist/commands/session-key/info.mjs +64 -0
  44. package/dist/commands/session-key/info.mjs.map +1 -0
  45. package/dist/commands/session-key/list.mjs +54 -0
  46. package/dist/commands/session-key/list.mjs.map +1 -0
  47. package/dist/commands/session-key/remove.mjs +51 -0
  48. package/dist/commands/session-key/remove.mjs.map +1 -0
  49. package/dist/commands/session-key/status.mjs +64 -0
  50. package/dist/commands/session-key/status.mjs.map +1 -0
  51. package/dist/commands/smart-account/create.mjs +94 -0
  52. package/dist/commands/smart-account/create.mjs.map +1 -0
  53. package/dist/commands/smart-account/import.mjs +45 -0
  54. package/dist/commands/smart-account/import.mjs.map +1 -0
  55. package/dist/commands/smart-account/index.mjs +30 -0
  56. package/dist/commands/smart-account/index.mjs.map +1 -0
  57. package/dist/commands/smart-account/info.mjs +66 -0
  58. package/dist/commands/smart-account/info.mjs.map +1 -0
  59. package/dist/commands/smart-account/list.mjs +48 -0
  60. package/dist/commands/smart-account/list.mjs.map +1 -0
  61. package/dist/commands/smart-account/remove.mjs +54 -0
  62. package/dist/commands/smart-account/remove.mjs.map +1 -0
  63. package/dist/commands/smart-account/status.mjs +63 -0
  64. package/dist/commands/smart-account/status.mjs.map +1 -0
  65. package/dist/dto/index.mjs +6 -0
  66. package/dist/dto/keystore.mjs +44 -0
  67. package/dist/dto/keystore.mjs.map +1 -0
  68. package/dist/dto/mcp.mjs +13 -0
  69. package/dist/dto/mcp.mjs.map +1 -0
  70. package/dist/dto/session-key.mjs +54 -0
  71. package/dist/dto/session-key.mjs.map +1 -0
  72. package/dist/dto/smart-account.mjs +45 -0
  73. package/dist/dto/smart-account.mjs.map +1 -0
  74. package/dist/flags/global.mjs +29 -0
  75. package/dist/flags/global.mjs.map +1 -0
  76. package/dist/flags/shared.mjs +11 -0
  77. package/dist/flags/shared.mjs.map +1 -0
  78. package/dist/helpers/humanize.mjs +153 -0
  79. package/dist/helpers/humanize.mjs.map +1 -0
  80. package/dist/helpers/paths.mjs +31 -0
  81. package/dist/helpers/paths.mjs.map +1 -0
  82. package/dist/helpers/policy.mjs +89 -0
  83. package/dist/helpers/policy.mjs.map +1 -0
  84. package/dist/helpers/pretty.mjs +71 -0
  85. package/dist/helpers/pretty.mjs.map +1 -0
  86. package/dist/index.mjs +15 -3264
  87. package/dist/index.mjs.map +1 -1
  88. package/dist/layers/config.mjs +124 -0
  89. package/dist/layers/config.mjs.map +1 -0
  90. package/dist/layers/index.mjs +11 -0
  91. package/dist/layers/keystore.mjs +225 -0
  92. package/dist/layers/keystore.mjs.map +1 -0
  93. package/dist/layers/mcp-context.mjs +8 -0
  94. package/dist/layers/mcp-context.mjs.map +1 -0
  95. package/dist/layers/mcp.mjs +31 -0
  96. package/dist/layers/mcp.mjs.map +1 -0
  97. package/dist/layers/output.mjs +21 -0
  98. package/dist/layers/output.mjs.map +1 -0
  99. package/dist/layers/prompt.mjs +78 -0
  100. package/dist/layers/prompt.mjs.map +1 -0
  101. package/dist/layers/session-key.mjs +218 -0
  102. package/dist/layers/session-key.mjs.map +1 -0
  103. package/dist/layers/smart-account.mjs +175 -0
  104. package/dist/layers/smart-account.mjs.map +1 -0
  105. package/dist/layers/web3.mjs +83 -0
  106. package/dist/layers/web3.mjs.map +1 -0
  107. package/dist/mcp/helpers/common.mjs +9 -0
  108. package/dist/mcp/helpers/common.mjs.map +1 -0
  109. package/dist/mcp/helpers/index.mjs +4 -0
  110. package/dist/mcp/helpers/session-key.mjs +129 -0
  111. package/dist/mcp/helpers/session-key.mjs.map +1 -0
  112. package/dist/mcp/index.mjs +43 -0
  113. package/dist/mcp/index.mjs.map +1 -0
  114. package/dist/mcp/mcp.mjs +15 -0
  115. package/dist/mcp/mcp.mjs.map +1 -0
  116. package/dist/mcp/tools/account/address.mjs +20 -0
  117. package/dist/mcp/tools/account/address.mjs.map +1 -0
  118. package/dist/mcp/tools/account/get-balance.mjs +54 -0
  119. package/dist/mcp/tools/account/get-balance.mjs.map +1 -0
  120. package/dist/mcp/tools/account/index.mjs +15 -0
  121. package/dist/mcp/tools/account/index.mjs.map +1 -0
  122. package/dist/mcp/tools/read/index.mjs +11 -0
  123. package/dist/mcp/tools/read/index.mjs.map +1 -0
  124. package/dist/mcp/tools/read/read-contract.mjs +49 -0
  125. package/dist/mcp/tools/read/read-contract.mjs.map +1 -0
  126. package/dist/mcp/tools/transaction/execute-transaction.mjs +38 -0
  127. package/dist/mcp/tools/transaction/execute-transaction.mjs.map +1 -0
  128. package/dist/mcp/tools/transaction/index.mjs +15 -0
  129. package/dist/mcp/tools/transaction/index.mjs.map +1 -0
  130. package/dist/mcp/tools/transaction/native-transfer.mjs +59 -0
  131. package/dist/mcp/tools/transaction/native-transfer.mjs.map +1 -0
  132. package/dist/schema/chain.mjs +124 -0
  133. package/dist/schema/chain.mjs.map +1 -0
  134. package/dist/schema/common.mjs +29 -0
  135. package/dist/schema/common.mjs.map +1 -0
  136. package/dist/schema/index.mjs +5 -0
  137. package/dist/schema/policy.mjs +114 -0
  138. package/dist/schema/policy.mjs.map +1 -0
  139. package/dist/schema/tx.mjs +19 -0
  140. package/dist/schema/tx.mjs.map +1 -0
  141. package/dist/types/index.mjs +11 -0
  142. package/dist/types/index.mjs.map +1 -0
  143. package/package.json +10 -11
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ import { chainIdToChainName, getChain } from "../../schema/chain.mjs";
3
+ import "../../schema/index.mjs";
4
+ import { McpContext } from "../../layers/mcp-context.mjs";
5
+ import { InsufficientPermissions } from "./common.mjs";
6
+ import { Web3Service } from "../../layers/web3.mjs";
7
+ import "../../layers/index.mjs";
8
+ import { Effect } from "effect";
9
+ import { createSessionKeyClient, deserializePermissionAccountParams } from "@namera-ai/sdk/session-key";
10
+ //#region src/mcp/helpers/session-key.ts
11
+ const toPolicyMap = (policies) => {
12
+ const map = {};
13
+ for (const p of policies) {
14
+ if (p.type === "timestamp") {
15
+ if (map.timestamp) return null;
16
+ map.timestamp = p;
17
+ }
18
+ if (p.type === "call") {
19
+ if (map.call) return null;
20
+ map.call = p;
21
+ }
22
+ if (p.type === "signature-caller") {
23
+ if (map.signatureCaller) return null;
24
+ map.signatureCaller = p;
25
+ }
26
+ if (p.type === "gas") {
27
+ if (map.gas) return null;
28
+ map.gas = p;
29
+ }
30
+ if (p.type === "rate-limit") {
31
+ if (map.rateLimit) return null;
32
+ map.rateLimit = p;
33
+ }
34
+ if (p.type === "sudo") {
35
+ if (map.sudo) return null;
36
+ map.sudo = p;
37
+ }
38
+ }
39
+ return map;
40
+ };
41
+ function evaluateTimestamp(policy, _chainIds, _operation) {
42
+ const now = Date.now();
43
+ if (policy.validAfter !== void 0 && now < policy.validAfter * 1e3) return false;
44
+ if (policy.validUntil !== void 0 && now >= policy.validUntil * 1e3) return false;
45
+ return true;
46
+ }
47
+ function evaluateSignature(policy, chainIds, operation) {
48
+ const callers = operation.allowedCallers;
49
+ if (!callers || callers.length === 0) return false;
50
+ if (!chainIds.includes(operation.chainId)) return false;
51
+ return callers.every((caller) => policy.allowedCallers.includes(caller));
52
+ }
53
+ function evaluateCall(policy, chainIds, operation) {
54
+ const permissions = policy.permissions ?? [];
55
+ if (permissions.length === 0) return false;
56
+ const { batches } = operation;
57
+ if (batches.length === 0) return false;
58
+ return batches.every((batch) => {
59
+ const { calls, chainId } = batch;
60
+ return calls.every((call) => {
61
+ const { to, value = 0n, data } = call;
62
+ if (!chainIds.includes(chainId)) return false;
63
+ return permissions.some((p) => {
64
+ if (p.target !== to) return false;
65
+ if (value > (p.valueLimit ?? 0n)) return false;
66
+ const isContractCall = data.length >= 10;
67
+ if ("functionName" in p) {
68
+ if (!isContractCall) return false;
69
+ if (!p.selector) return false;
70
+ if (data.slice(0, 10) !== p.selector) return false;
71
+ return true;
72
+ }
73
+ return true;
74
+ });
75
+ });
76
+ });
77
+ }
78
+ const evaluateSessionKey = (sessionKey, operation) => {
79
+ if (operation.intent === "read") return true;
80
+ const accountParams = deserializePermissionAccountParams(sessionKey.data.serializedAccounts[0]?.serializedAccount ?? "");
81
+ const chainIds = sessionKey.data.serializedAccounts.map((a) => getChain(a.chain).id);
82
+ const p = toPolicyMap((accountParams.permissionParams.policies ?? []).map((x) => x.policyParams));
83
+ if (!p) return false;
84
+ const hasSudo = Boolean(p.sudo);
85
+ if (hasSudo && (p.call || p.signatureCaller)) return false;
86
+ if (p.timestamp && !evaluateTimestamp(p.timestamp, chainIds, operation)) return false;
87
+ if (!hasSudo) {
88
+ if (operation.intent === "transaction") {
89
+ if (!p.call) return false;
90
+ if (!evaluateCall(p.call, chainIds, operation)) return false;
91
+ }
92
+ if (operation.intent === "sign") {
93
+ if (!p.signatureCaller) return false;
94
+ if (!evaluateSignature(p.signatureCaller, chainIds, operation)) return false;
95
+ }
96
+ }
97
+ return true;
98
+ };
99
+ const getSessionKeyClient = (params) => Effect.gen(function* () {
100
+ const { sessionKeys, smartAccount } = yield* McpContext;
101
+ const key = sessionKeys.filter((sk) => {
102
+ return evaluateSessionKey(sk, params.operation);
103
+ })[0];
104
+ if (!key) return yield* Effect.fail(new InsufficientPermissions());
105
+ const web3Service = yield* Web3Service;
106
+ let chainId;
107
+ if (params.operation.intent === "read") chainId = params.operation.chainId;
108
+ else if (params.operation.intent === "sign") chainId = params.operation.chainId;
109
+ else chainId = params.operation.batches[0]?.chainId ?? 1;
110
+ const chainName = chainIdToChainName(chainId);
111
+ const chain = getChain(chainName);
112
+ const publicClient = yield* web3Service.getPublicClient({ chain: chainName });
113
+ const bundlerTransport = yield* web3Service.getBundlerTransport({ chain: chainName });
114
+ const serializedAccount = key.data.serializedAccounts.find((a) => a.chain === chainName)?.serializedAccount ?? "";
115
+ return yield* Effect.promise(() => createSessionKeyClient({
116
+ type: "ecdsa",
117
+ bundlerTransport,
118
+ chain,
119
+ client: publicClient,
120
+ entrypointVersion: smartAccount.entryPointVersion,
121
+ kernelVersion: smartAccount.kernelVersion,
122
+ serializedAccount,
123
+ signer: key.signer
124
+ }));
125
+ });
126
+ //#endregion
127
+ export { evaluateCall, evaluateSignature, evaluateTimestamp, getSessionKeyClient };
128
+
129
+ //# sourceMappingURL=session-key.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-key.mjs","names":["McpContext.McpContext","Web3Service.Web3Service"],"sources":["../../../src/mcp/helpers/session-key.ts"],"sourcesContent":["/** biome-ignore-all lint/complexity/noExcessiveCognitiveComplexity: safe */\nimport type {\n CallPolicyParams,\n Policy,\n SignatureCallerPolicyParams,\n TimestampPolicyParams,\n} from \"@namera-ai/sdk/policy\";\nimport {\n createSessionKeyClient,\n deserializePermissionAccountParams,\n} from \"@namera-ai/sdk/session-key\";\nimport { Effect } from \"effect\";\n\nimport type { SessionKeyData } from \"@/dto\";\nimport { McpContext, Web3Service } from \"@/layers\";\nimport { getChain } from \"@/schema\";\n\nimport { chainIdToChainName } from \"../../schema/chain\";\nimport type { AnyOperation, PolicyMap } from \"../types\";\nimport { InsufficientPermissions } from \"./common\";\n\ntype PolicyParams = Policy[\"policyParams\"];\n\nconst toPolicyMap = (policies: PolicyParams[]): PolicyMap | null => {\n const map: PolicyMap = {};\n\n for (const p of policies) {\n if (p.type === \"timestamp\") {\n if (map.timestamp) return null; // Gracefully invalidate this key\n map.timestamp = p;\n }\n if (p.type === \"call\") {\n if (map.call) return null;\n map.call = p;\n }\n if (p.type === \"signature-caller\") {\n if (map.signatureCaller) return null;\n map.signatureCaller = p;\n }\n if (p.type === \"gas\") {\n if (map.gas) return null;\n map.gas = p;\n }\n if (p.type === \"rate-limit\") {\n if (map.rateLimit) return null;\n map.rateLimit = p;\n }\n if (p.type === \"sudo\") {\n if (map.sudo) return null;\n map.sudo = p;\n }\n }\n\n return map;\n};\n\nexport function evaluateTimestamp(\n policy: TimestampPolicyParams,\n _chainIds: number[],\n _operation: AnyOperation,\n): boolean {\n // validAfter: the time after which the signer becomes valid.\n // If not specified (or 0), the signer is immediately valid.\n //\n // validUntil: the time before which the signer is valid.\n // If not specified, the signer never expires.\n const now = Date.now(); // ms\n\n if (policy.validAfter !== undefined && now < policy.validAfter * 1000) {\n return false;\n }\n\n if (policy.validUntil !== undefined && now >= policy.validUntil * 1000) {\n return false;\n }\n\n return true;\n}\n\nexport function evaluateSignature(\n policy: SignatureCallerPolicyParams,\n chainIds: number[],\n operation: Extract<AnyOperation, { intent: \"sign\" }>,\n): boolean {\n const callers = operation.allowedCallers;\n\n if (!callers || callers.length === 0) return false;\n if (!chainIds.includes(operation.chainId)) return false;\n\n // every caller must be allowed\n return callers.every((caller) => policy.allowedCallers.includes(caller));\n}\n\nexport function evaluateCall(\n policy: CallPolicyParams,\n chainIds: number[],\n operation: Extract<AnyOperation, { intent: \"transaction\" }>,\n): boolean {\n const permissions = policy.permissions ?? [];\n if (permissions.length === 0) return false;\n\n const { batches } = operation;\n\n if (batches.length === 0) return false;\n\n return batches.every((batch) => {\n const { calls, chainId } = batch;\n\n return calls.every((call) => {\n const { to, value = 0n, data } = call;\n if (!chainIds.includes(chainId)) return false;\n\n return permissions.some((p) => {\n if (p.target !== to) return false;\n const valueLimit = p.valueLimit ?? 0n;\n if (value > valueLimit) return false;\n\n const isContractCall = data.length >= 10;\n\n if (\"functionName\" in p) {\n if (!isContractCall) return false;\n if (!p.selector) return false;\n\n const selector = data.slice(0, 10);\n if (selector !== p.selector) return false;\n\n // TODO: param rules\n return true;\n }\n\n // EOA\n return true;\n });\n });\n });\n}\n\nconst evaluateSessionKey = (\n sessionKey: SessionKeyData,\n operation: AnyOperation,\n) => {\n // Read is always allowed\n if (operation.intent === \"read\") return true;\n\n const accountParams = deserializePermissionAccountParams(\n sessionKey.data.serializedAccounts[0]?.serializedAccount ?? \"\",\n );\n\n const chainIds = sessionKey.data.serializedAccounts.map(\n (a) => getChain(a.chain).id,\n );\n\n const policies = (accountParams.permissionParams.policies ?? []).map(\n (x) => x.policyParams,\n );\n\n const p = toPolicyMap(policies);\n\n if (!p) return false;\n\n const hasSudo = Boolean(p.sudo);\n\n // A valid sudo key should not have call or signature policies attached\n if (hasSudo && (p.call || p.signatureCaller)) {\n return false;\n }\n\n if (p.timestamp && !evaluateTimestamp(p.timestamp, chainIds, operation))\n return false;\n\n // TODO: Do gas and rate limits\n\n if (!hasSudo) {\n if (operation.intent === \"transaction\") {\n if (!p.call) return false;\n if (!evaluateCall(p.call, chainIds, operation)) return false;\n }\n\n if (operation.intent === \"sign\") {\n if (!p.signatureCaller) return false;\n if (!evaluateSignature(p.signatureCaller, chainIds, operation))\n return false;\n }\n }\n\n return true;\n};\n\nexport type GetValidSessionKeysParams = {\n operation: AnyOperation;\n};\n\nexport const getValidSessionKeys = (params: GetValidSessionKeysParams) =>\n Effect.gen(function* () {\n const context = yield* McpContext.McpContext;\n const { sessionKeys } = context;\n\n const validKeys = sessionKeys.filter((sk) => {\n return evaluateSessionKey(sk, params.operation);\n });\n\n return validKeys;\n });\n\nexport const getSessionKeyClient = (params: GetValidSessionKeysParams) =>\n Effect.gen(function* () {\n const context = yield* McpContext.McpContext;\n const { sessionKeys, smartAccount } = context;\n\n const validKeys = sessionKeys.filter((sk) => {\n return evaluateSessionKey(sk, params.operation);\n });\n\n const key = validKeys[0];\n\n if (!key) return yield* Effect.fail(new InsufficientPermissions());\n\n const web3Service = yield* Web3Service.Web3Service;\n\n let chainId: number;\n\n if (params.operation.intent === \"read\") {\n chainId = params.operation.chainId;\n } else if (params.operation.intent === \"sign\") {\n chainId = params.operation.chainId;\n } else {\n chainId = params.operation.batches[0]?.chainId ?? 1;\n }\n\n const chainName = chainIdToChainName(chainId);\n const chain = getChain(chainName);\n const publicClient = yield* web3Service.getPublicClient({\n chain: chainName,\n });\n const bundlerTransport = yield* web3Service.getBundlerTransport({\n chain: chainName,\n });\n const serializedAccount =\n key.data.serializedAccounts.find((a) => a.chain === chainName)\n ?.serializedAccount ?? \"\";\n\n const accountClient = yield* Effect.promise(() =>\n createSessionKeyClient({\n type: \"ecdsa\",\n bundlerTransport,\n chain,\n client: publicClient,\n entrypointVersion: smartAccount.entryPointVersion,\n kernelVersion: smartAccount.kernelVersion,\n serializedAccount,\n signer: key.signer,\n }),\n );\n\n return accountClient;\n });\n"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ import { McpLive } from "./mcp.mjs";
3
+ import { NodeHttpServer, NodeStdio } from "@effect/platform-node";
4
+ import { Layer, Logger } from "effect";
5
+ import { createServer } from "node:http";
6
+ import { McpServer } from "effect/unstable/ai";
7
+ import { HttpRouter } from "effect/unstable/http";
8
+ //#region src/mcp/index.ts
9
+ const MCP_SERVER_NAME = "Namera MCP Server";
10
+ const MCP_SERVER_VERSION = "0.0.1";
11
+ const McpRouter = McpLive.pipe(Layer.provideMerge(McpServer.layerHttp({
12
+ name: MCP_SERVER_NAME,
13
+ path: "/mcp",
14
+ version: MCP_SERVER_VERSION
15
+ })), Layer.provideMerge(HttpRouter.cors({
16
+ allowedHeaders: [
17
+ "Content-Type",
18
+ "Authorization",
19
+ "mcp-session-id",
20
+ "mcp-protocol-version"
21
+ ],
22
+ allowedMethods: [
23
+ "GET",
24
+ "POST",
25
+ "PUT",
26
+ "DELETE",
27
+ "PATCH",
28
+ "OPTIONS"
29
+ ],
30
+ allowedOrigins: ["*"],
31
+ credentials: false,
32
+ exposedHeaders: ["mcp-session-id", "mcp-protocol-version"]
33
+ })));
34
+ const McpStdio = McpLive.pipe(Layer.provideMerge(McpServer.layerStdio({
35
+ name: MCP_SERVER_NAME,
36
+ version: MCP_SERVER_VERSION
37
+ })), Layer.provide(NodeStdio.layer), Layer.provide(Layer.succeed(Logger.LogToStderr)(true)));
38
+ const startMcpHttpServer = (port) => Layer.launch(HttpRouter.serve(McpRouter).pipe(Layer.provideMerge(NodeHttpServer.layer(createServer, { port }))));
39
+ const startMcpStdioServer = () => Layer.launch(McpStdio);
40
+ //#endregion
41
+ export { startMcpHttpServer, startMcpStdioServer };
42
+
43
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/mcp/index.ts"],"sourcesContent":["import { createServer } from \"node:http\";\n\nimport { NodeHttpServer, NodeStdio } from \"@effect/platform-node\";\nimport { Layer, Logger } from \"effect\";\nimport { McpServer } from \"effect/unstable/ai\";\nimport { HttpRouter } from \"effect/unstable/http\";\n\nimport { McpLive } from \"./mcp\";\n\nconst MCP_SERVER_NAME = \"Namera MCP Server\";\nconst MCP_SERVER_VERSION = \"0.0.1\";\n\nconst McpRouter = McpLive.pipe(\n Layer.provideMerge(\n McpServer.layerHttp({\n name: MCP_SERVER_NAME,\n path: \"/mcp\",\n version: MCP_SERVER_VERSION,\n }),\n ),\n Layer.provideMerge(\n HttpRouter.cors({\n allowedHeaders: [\n \"Content-Type\",\n \"Authorization\",\n \"mcp-session-id\",\n \"mcp-protocol-version\",\n ],\n allowedMethods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\", \"OPTIONS\"],\n allowedOrigins: [\"*\"],\n credentials: false,\n exposedHeaders: [\"mcp-session-id\", \"mcp-protocol-version\"],\n }),\n ),\n);\n\nconst McpStdio = McpLive.pipe(\n Layer.provideMerge(\n McpServer.layerStdio({\n name: MCP_SERVER_NAME,\n version: MCP_SERVER_VERSION,\n }),\n ),\n Layer.provide(NodeStdio.layer),\n Layer.provide(Layer.succeed(Logger.LogToStderr)(true)),\n);\n\nexport const startMcpHttpServer = (port: number) =>\n Layer.launch(\n HttpRouter.serve(McpRouter).pipe(\n Layer.provideMerge(NodeHttpServer.layer(createServer, { port })),\n ),\n );\n\nexport const startMcpStdioServer = () => Layer.launch(McpStdio);\n"],"mappings":";;;;;;;;AASA,MAAM,kBAAkB;AACxB,MAAM,qBAAqB;AAE3B,MAAM,YAAY,QAAQ,KACxB,MAAM,aACJ,UAAU,UAAU;CAClB,MAAM;CACN,MAAM;CACN,SAAS;CACV,CAAC,CACH,EACD,MAAM,aACJ,WAAW,KAAK;CACd,gBAAgB;EACd;EACA;EACA;EACA;EACD;CACD,gBAAgB;EAAC;EAAO;EAAQ;EAAO;EAAU;EAAS;EAAU;CACpE,gBAAgB,CAAC,IAAI;CACrB,aAAa;CACb,gBAAgB,CAAC,kBAAkB,uBAAuB;CAC3D,CAAC,CACH,CACF;AAED,MAAM,WAAW,QAAQ,KACvB,MAAM,aACJ,UAAU,WAAW;CACnB,MAAM;CACN,SAAS;CACV,CAAC,CACH,EACD,MAAM,QAAQ,UAAU,MAAM,EAC9B,MAAM,QAAQ,MAAM,QAAQ,OAAO,YAAY,CAAC,KAAK,CAAC,CACvD;AAED,MAAa,sBAAsB,SACjC,MAAM,OACJ,WAAW,MAAM,UAAU,CAAC,KAC1B,MAAM,aAAa,eAAe,MAAM,cAAc,EAAE,MAAM,CAAC,CAAC,CACjE,CACF;AAEH,MAAa,4BAA4B,MAAM,OAAO,SAAS"}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { AccountTools, AccountToolsHandlers } from "./tools/account/index.mjs";
3
+ import { ReadTools, ReadToolsHandlers } from "./tools/read/index.mjs";
4
+ import { TransactionTools, TransactionToolsHandlers } from "./tools/transaction/index.mjs";
5
+ import { Layer } from "effect";
6
+ import { McpServer } from "effect/unstable/ai";
7
+ //#region src/mcp/mcp.ts
8
+ const Account = Layer.effectDiscard(McpServer.registerToolkit(AccountTools)).pipe(Layer.provideMerge(AccountToolsHandlers));
9
+ const Transfer = Layer.effectDiscard(McpServer.registerToolkit(TransactionTools)).pipe(Layer.provideMerge(TransactionToolsHandlers));
10
+ const Read = Layer.effectDiscard(McpServer.registerToolkit(ReadTools)).pipe(Layer.provideMerge(ReadToolsHandlers));
11
+ const McpLive = Layer.mergeAll(Account, Transfer, Read);
12
+ //#endregion
13
+ export { McpLive };
14
+
15
+ //# sourceMappingURL=mcp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.mjs","names":[],"sources":["../../src/mcp/mcp.ts"],"sourcesContent":["import { Layer } from \"effect\";\nimport { McpServer } from \"effect/unstable/ai\";\n\nimport { AccountTools, AccountToolsHandlers } from \"./tools/account\";\nimport { ReadTools, ReadToolsHandlers } from \"./tools/read\";\nimport {\n TransactionTools,\n TransactionToolsHandlers,\n} from \"./tools/transaction\";\n\nconst Account = Layer.effectDiscard(\n McpServer.registerToolkit(AccountTools),\n).pipe(Layer.provideMerge(AccountToolsHandlers));\n\nconst Transfer = Layer.effectDiscard(\n McpServer.registerToolkit(TransactionTools),\n).pipe(Layer.provideMerge(TransactionToolsHandlers));\n\nconst Read = Layer.effectDiscard(McpServer.registerToolkit(ReadTools)).pipe(\n Layer.provideMerge(ReadToolsHandlers),\n);\n\nexport const McpLive = Layer.mergeAll(Account, Transfer, Read);\n"],"mappings":";;;;;;;AAUA,MAAM,UAAU,MAAM,cACpB,UAAU,gBAAgB,aAAa,CACxC,CAAC,KAAK,MAAM,aAAa,qBAAqB,CAAC;AAEhD,MAAM,WAAW,MAAM,cACrB,UAAU,gBAAgB,iBAAiB,CAC5C,CAAC,KAAK,MAAM,aAAa,yBAAyB,CAAC;AAEpD,MAAM,OAAO,MAAM,cAAc,UAAU,gBAAgB,UAAU,CAAC,CAAC,KACrE,MAAM,aAAa,kBAAkB,CACtC;AAED,MAAa,UAAU,MAAM,SAAS,SAAS,UAAU,KAAK"}
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { McpContext } from "../../../layers/mcp-context.mjs";
3
+ import { EmptyArgs } from "../../helpers/common.mjs";
4
+ import { Effect, Schema } from "effect";
5
+ import { Tool } from "effect/unstable/ai";
6
+ //#region src/mcp/tools/account/address.ts
7
+ const GetAddressTool = Tool.make("get_wallet_address", {
8
+ dependencies: [McpContext],
9
+ description: "Get the address of the wallet",
10
+ failure: Schema.Never,
11
+ parameters: EmptyArgs,
12
+ success: Schema.String
13
+ });
14
+ const getAddressToolHandler = () => Effect.gen(function* () {
15
+ return (yield* McpContext).smartAccount.smartAccountAddress;
16
+ });
17
+ //#endregion
18
+ export { GetAddressTool, getAddressToolHandler };
19
+
20
+ //# sourceMappingURL=address.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.mjs","names":[],"sources":["../../../../src/mcp/tools/account/address.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\";\nimport { Tool } from \"effect/unstable/ai\";\n\nimport { McpContext } from \"@/layers/mcp-context\";\nimport { EmptyArgs } from \"@/mcp/helpers/common\";\n\nexport const GetAddressTool = Tool.make(\"get_wallet_address\", {\n dependencies: [McpContext],\n description: \"Get the address of the wallet\",\n failure: Schema.Never,\n parameters: EmptyArgs,\n success: Schema.String,\n});\n\nexport const getAddressToolHandler = () =>\n Effect.gen(function* () {\n const context = yield* McpContext;\n\n return context.smartAccount.smartAccountAddress;\n });\n"],"mappings":";;;;;;AAMA,MAAa,iBAAiB,KAAK,KAAK,sBAAsB;CAC5D,cAAc,CAAC,WAAW;CAC1B,aAAa;CACb,SAAS,OAAO;CAChB,YAAY;CACZ,SAAS,OAAO;CACjB,CAAC;AAEF,MAAa,8BACX,OAAO,IAAI,aAAa;AAGtB,SAAO,OAFgB,YAER,aAAa;EAC5B"}
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ import { SupportedChain, getChain } from "../../../schema/chain.mjs";
3
+ import { EthereumAddress } from "../../../schema/common.mjs";
4
+ import "../../../schema/index.mjs";
5
+ import { McpContext } from "../../../layers/mcp-context.mjs";
6
+ import { InsufficientPermissions } from "../../helpers/common.mjs";
7
+ import { Web3Service } from "../../../layers/web3.mjs";
8
+ import { getSessionKeyClient } from "../../helpers/session-key.mjs";
9
+ import "../../helpers/index.mjs";
10
+ import { Effect, Schema } from "effect";
11
+ import { formatUnits } from "viem";
12
+ import { Tool } from "effect/unstable/ai";
13
+ import { getBalance } from "viem/actions";
14
+ //#region src/mcp/tools/account/get-balance.ts
15
+ const GetBalanceToolParams = Schema.Struct({
16
+ address: EthereumAddress.annotate({ description: "The address to get the balance for" }),
17
+ chain: SupportedChain.annotate({ description: "The chain to get the balance for" })
18
+ });
19
+ const GetBalanceToolResult = Schema.Struct({
20
+ nativeCurrency: Schema.Struct({
21
+ name: Schema.String.annotate({ description: "The name of the currency" }),
22
+ symbol: Schema.String.annotate({ description: "The symbol of the currency" }),
23
+ decimals: Schema.Number.annotate({ description: "The number of decimals the currency has" })
24
+ }).annotate({ description: "The native currency of the chain" }),
25
+ balance: Schema.Struct({
26
+ amount: Schema.String.annotate({ description: "Balance in atomic units" }),
27
+ formatted: Schema.String.annotate({ description: "Balance in native currency units" })
28
+ })
29
+ });
30
+ const GetBalanceTool = Tool.make("get_balance", {
31
+ dependencies: [McpContext, Web3Service],
32
+ description: "Get the address of the wallet",
33
+ failure: InsufficientPermissions,
34
+ parameters: GetBalanceToolParams,
35
+ success: GetBalanceToolResult
36
+ });
37
+ const getBalanceToolHandler = (params) => Effect.gen(function* () {
38
+ const sessionKeyClient = yield* getSessionKeyClient({ operation: {
39
+ intent: "read",
40
+ chainId: getChain(params.chain).id
41
+ } });
42
+ const res = yield* Effect.promise(() => getBalance(sessionKeyClient.client, { address: params.address }));
43
+ return {
44
+ nativeCurrency: sessionKeyClient.chain.nativeCurrency,
45
+ balance: {
46
+ amount: res.toString(),
47
+ formatted: formatUnits(res, sessionKeyClient.chain.nativeCurrency.decimals)
48
+ }
49
+ };
50
+ });
51
+ //#endregion
52
+ export { GetBalanceTool, getBalanceToolHandler };
53
+
54
+ //# sourceMappingURL=get-balance.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-balance.mjs","names":[],"sources":["../../../../src/mcp/tools/account/get-balance.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\";\nimport { Tool } from \"effect/unstable/ai\";\nimport { formatUnits } from \"viem\";\nimport { getBalance } from \"viem/actions\";\n\nimport { McpContext } from \"@/layers/mcp-context\";\nimport { Web3Service } from \"@/layers/web3\";\nimport { getSessionKeyClient, InsufficientPermissions } from \"@/mcp/helpers\";\nimport { EthereumAddress, getChain, SupportedChain } from \"@/schema\";\n\nexport const GetBalanceToolParams = Schema.Struct({\n address: EthereumAddress.annotate({\n description: \"The address to get the balance for\",\n }),\n chain: SupportedChain.annotate({\n description: \"The chain to get the balance for\",\n }),\n});\n\nexport const GetBalanceToolResult = Schema.Struct({\n nativeCurrency: Schema.Struct({\n name: Schema.String.annotate({\n description: \"The name of the currency\",\n }),\n symbol: Schema.String.annotate({\n description: \"The symbol of the currency\",\n }),\n decimals: Schema.Number.annotate({\n description: \"The number of decimals the currency has\",\n }),\n }).annotate({\n description: \"The native currency of the chain\",\n }),\n balance: Schema.Struct({\n amount: Schema.String.annotate({\n description: \"Balance in atomic units\",\n }),\n formatted: Schema.String.annotate({\n description: \"Balance in native currency units\",\n }),\n }),\n});\n\nexport type GetBalanceToolResult = typeof GetBalanceToolResult.Type;\nexport type GetBalanceToolParams = typeof GetBalanceToolParams.Type;\n\nexport const GetBalanceTool = Tool.make(\"get_balance\", {\n dependencies: [McpContext, Web3Service],\n description: \"Get the address of the wallet\",\n failure: InsufficientPermissions,\n parameters: GetBalanceToolParams,\n success: GetBalanceToolResult,\n});\n\nexport const getBalanceToolHandler = (params: GetBalanceToolParams) =>\n Effect.gen(function* () {\n const sessionKeyClient = yield* getSessionKeyClient({\n operation: {\n intent: \"read\",\n chainId: getChain(params.chain).id,\n },\n });\n\n const res = yield* Effect.promise(() =>\n getBalance(sessionKeyClient.client, {\n address: params.address,\n }),\n );\n\n const data = {\n nativeCurrency: sessionKeyClient.chain.nativeCurrency,\n balance: {\n amount: res.toString(),\n formatted: formatUnits(\n res,\n sessionKeyClient.chain.nativeCurrency.decimals,\n ),\n },\n };\n\n return data;\n });\n"],"mappings":";;;;;;;;;;;;;;AAUA,MAAa,uBAAuB,OAAO,OAAO;CAChD,SAAS,gBAAgB,SAAS,EAChC,aAAa,sCACd,CAAC;CACF,OAAO,eAAe,SAAS,EAC7B,aAAa,oCACd,CAAC;CACH,CAAC;AAEF,MAAa,uBAAuB,OAAO,OAAO;CAChD,gBAAgB,OAAO,OAAO;EAC5B,MAAM,OAAO,OAAO,SAAS,EAC3B,aAAa,4BACd,CAAC;EACF,QAAQ,OAAO,OAAO,SAAS,EAC7B,aAAa,8BACd,CAAC;EACF,UAAU,OAAO,OAAO,SAAS,EAC/B,aAAa,2CACd,CAAC;EACH,CAAC,CAAC,SAAS,EACV,aAAa,oCACd,CAAC;CACF,SAAS,OAAO,OAAO;EACrB,QAAQ,OAAO,OAAO,SAAS,EAC7B,aAAa,2BACd,CAAC;EACF,WAAW,OAAO,OAAO,SAAS,EAChC,aAAa,oCACd,CAAC;EACH,CAAC;CACH,CAAC;AAKF,MAAa,iBAAiB,KAAK,KAAK,eAAe;CACrD,cAAc,CAAC,YAAY,YAAY;CACvC,aAAa;CACb,SAAS;CACT,YAAY;CACZ,SAAS;CACV,CAAC;AAEF,MAAa,yBAAyB,WACpC,OAAO,IAAI,aAAa;CACtB,MAAM,mBAAmB,OAAO,oBAAoB,EAClD,WAAW;EACT,QAAQ;EACR,SAAS,SAAS,OAAO,MAAM,CAAC;EACjC,EACF,CAAC;CAEF,MAAM,MAAM,OAAO,OAAO,cACxB,WAAW,iBAAiB,QAAQ,EAClC,SAAS,OAAO,SACjB,CAAC,CACH;AAaD,QAAO;EAVL,gBAAgB,iBAAiB,MAAM;EACvC,SAAS;GACP,QAAQ,IAAI,UAAU;GACtB,WAAW,YACT,KACA,iBAAiB,MAAM,eAAe,SACvC;GACF;EAGI;EACP"}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { GetAddressTool, getAddressToolHandler } from "./address.mjs";
3
+ import { GetBalanceTool, getBalanceToolHandler } from "./get-balance.mjs";
4
+ import { Effect } from "effect";
5
+ import { Toolkit } from "effect/unstable/ai";
6
+ //#region src/mcp/tools/account/index.ts
7
+ const AccountTools = Toolkit.make(GetAddressTool, GetBalanceTool);
8
+ const AccountToolsHandlers = AccountTools.toLayer(Effect.succeed({
9
+ get_wallet_address: getAddressToolHandler,
10
+ get_balance: getBalanceToolHandler
11
+ }));
12
+ //#endregion
13
+ export { AccountTools, AccountToolsHandlers };
14
+
15
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/mcp/tools/account/index.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Toolkit } from \"effect/unstable/ai\";\n\nimport { GetAddressTool, getAddressToolHandler } from \"./address\";\nimport { GetBalanceTool, getBalanceToolHandler } from \"./get-balance\";\n\nexport const AccountTools = Toolkit.make(GetAddressTool, GetBalanceTool);\nexport const AccountToolsHandlers = AccountTools.toLayer(\n Effect.succeed({\n get_wallet_address: getAddressToolHandler,\n get_balance: getBalanceToolHandler,\n }),\n);\n"],"mappings":";;;;;;AAMA,MAAa,eAAe,QAAQ,KAAK,gBAAgB,eAAe;AACxE,MAAa,uBAAuB,aAAa,QAC/C,OAAO,QAAQ;CACb,oBAAoB;CACpB,aAAa;CACd,CAAC,CACH"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { ReadContractTool, readContractToolHandler } from "./read-contract.mjs";
3
+ import { Effect } from "effect";
4
+ import { Toolkit } from "effect/unstable/ai";
5
+ //#region src/mcp/tools/read/index.ts
6
+ const ReadTools = Toolkit.make(ReadContractTool);
7
+ const ReadToolsHandlers = ReadTools.toLayer(Effect.succeed({ read_contract: (params) => readContractToolHandler(params) }));
8
+ //#endregion
9
+ export { ReadTools, ReadToolsHandlers };
10
+
11
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/mcp/tools/read/index.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Toolkit } from \"effect/unstable/ai\";\n\nimport { ReadContractTool, readContractToolHandler } from \"./read-contract\";\n\nexport const ReadTools = Toolkit.make(ReadContractTool);\nexport const ReadToolsHandlers = ReadTools.toLayer(\n Effect.succeed({\n read_contract: (params) => readContractToolHandler(params),\n }),\n);\n"],"mappings":";;;;;AAKA,MAAa,YAAY,QAAQ,KAAK,iBAAiB;AACvD,MAAa,oBAAoB,UAAU,QACzC,OAAO,QAAQ,EACb,gBAAgB,WAAW,wBAAwB,OAAO,EAC3D,CAAC,CACH"}
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ import { SupportedChain, getChain } from "../../../schema/chain.mjs";
3
+ import { EthereumAddress } from "../../../schema/common.mjs";
4
+ import "../../../schema/index.mjs";
5
+ import { McpContext } from "../../../layers/mcp-context.mjs";
6
+ import { InsufficientPermissions } from "../../helpers/common.mjs";
7
+ import { Web3Service } from "../../../layers/web3.mjs";
8
+ import { getSessionKeyClient } from "../../helpers/session-key.mjs";
9
+ import "../../helpers/index.mjs";
10
+ import { Effect, Schema } from "effect";
11
+ import { Tool } from "effect/unstable/ai";
12
+ import { readContract } from "viem/actions";
13
+ //#region src/mcp/tools/read/read-contract.ts
14
+ const ReadContractToolParams = Schema.Struct({
15
+ chain: SupportedChain.annotate({ description: "The chain to use for the transfer" }),
16
+ contractAddress: EthereumAddress.annotate({ description: "The ethereum address of the contract to read" }),
17
+ abi: Schema.Array(Schema.Any).annotate({ description: "The ABI of the contract to read" }),
18
+ functionName: Schema.String.annotate({ description: "The name of the function to call on the contract" }),
19
+ args: Schema.Array(Schema.Any).annotate({ description: "The arguments to pass to the function" })
20
+ });
21
+ const ReadContractTool = Tool.make("read_contract", {
22
+ dependencies: [McpContext, Web3Service],
23
+ description: "Read data from a specified contract.",
24
+ failure: InsufficientPermissions,
25
+ parameters: ReadContractToolParams,
26
+ success: Schema.Any.annotate({ description: "The data returned by the contract" })
27
+ });
28
+ const readContractToolHandler = (params) => Effect.gen(function* () {
29
+ const client = yield* getSessionKeyClient({ operation: {
30
+ intent: "read",
31
+ chainId: getChain(params.chain).id
32
+ } });
33
+ readContract(client, {
34
+ address: params.contractAddress,
35
+ abi: params.abi,
36
+ functionName: params.functionName,
37
+ args: params.args
38
+ });
39
+ return yield* Effect.promise(() => readContract(client, {
40
+ address: params.contractAddress,
41
+ abi: params.abi,
42
+ functionName: params.functionName,
43
+ args: params.args
44
+ }));
45
+ });
46
+ //#endregion
47
+ export { ReadContractTool, readContractToolHandler };
48
+
49
+ //# sourceMappingURL=read-contract.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-contract.mjs","names":[],"sources":["../../../../src/mcp/tools/read/read-contract.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\";\nimport { Tool } from \"effect/unstable/ai\";\nimport { readContract } from \"viem/actions\";\n\nimport { McpContext } from \"@/layers/mcp-context\";\nimport { Web3Service } from \"@/layers/web3\";\nimport { getSessionKeyClient, InsufficientPermissions } from \"@/mcp/helpers\";\nimport { EthereumAddress, getChain, SupportedChain } from \"@/schema\";\n\nexport const ReadContractToolParams = Schema.Struct({\n chain: SupportedChain.annotate({\n description: \"The chain to use for the transfer\",\n }),\n contractAddress: EthereumAddress.annotate({\n description: \"The ethereum address of the contract to read\",\n }),\n abi: Schema.Array(Schema.Any).annotate({\n description: \"The ABI of the contract to read\",\n }),\n functionName: Schema.String.annotate({\n description: \"The name of the function to call on the contract\",\n }),\n args: Schema.Array(Schema.Any).annotate({\n description: \"The arguments to pass to the function\",\n }),\n});\n\nexport type ReadContractToolParams = typeof ReadContractToolParams.Type;\n\nexport const ReadContractTool = Tool.make(\"read_contract\", {\n dependencies: [McpContext, Web3Service],\n description: \"Read data from a specified contract.\",\n failure: InsufficientPermissions,\n parameters: ReadContractToolParams,\n success: Schema.Any.annotate({\n description: \"The data returned by the contract\",\n }),\n});\n\nexport const readContractToolHandler = (params: ReadContractToolParams) =>\n Effect.gen(function* () {\n const chain = getChain(params.chain);\n\n const client = yield* getSessionKeyClient({\n operation: {\n intent: \"read\",\n chainId: chain.id,\n },\n });\n\n readContract(client, {\n address: params.contractAddress,\n abi: params.abi,\n functionName: params.functionName,\n args: params.args,\n });\n\n const result = yield* Effect.promise(() =>\n readContract(client, {\n address: params.contractAddress,\n abi: params.abi,\n functionName: params.functionName,\n args: params.args,\n }),\n );\n\n return result;\n });\n"],"mappings":";;;;;;;;;;;;;AASA,MAAa,yBAAyB,OAAO,OAAO;CAClD,OAAO,eAAe,SAAS,EAC7B,aAAa,qCACd,CAAC;CACF,iBAAiB,gBAAgB,SAAS,EACxC,aAAa,gDACd,CAAC;CACF,KAAK,OAAO,MAAM,OAAO,IAAI,CAAC,SAAS,EACrC,aAAa,mCACd,CAAC;CACF,cAAc,OAAO,OAAO,SAAS,EACnC,aAAa,oDACd,CAAC;CACF,MAAM,OAAO,MAAM,OAAO,IAAI,CAAC,SAAS,EACtC,aAAa,yCACd,CAAC;CACH,CAAC;AAIF,MAAa,mBAAmB,KAAK,KAAK,iBAAiB;CACzD,cAAc,CAAC,YAAY,YAAY;CACvC,aAAa;CACb,SAAS;CACT,YAAY;CACZ,SAAS,OAAO,IAAI,SAAS,EAC3B,aAAa,qCACd,CAAC;CACH,CAAC;AAEF,MAAa,2BAA2B,WACtC,OAAO,IAAI,aAAa;CAGtB,MAAM,SAAS,OAAO,oBAAoB,EACxC,WAAW;EACT,QAAQ;EACR,SALU,SAAS,OAAO,MAKjB,CAAM;EAChB,EACF,CAAC;AAEF,cAAa,QAAQ;EACnB,SAAS,OAAO;EAChB,KAAK,OAAO;EACZ,cAAc,OAAO;EACrB,MAAM,OAAO;EACd,CAAC;AAWF,QAAO,OATe,OAAO,cAC3B,aAAa,QAAQ;EACnB,SAAS,OAAO;EAChB,KAAK,OAAO;EACZ,cAAc,OAAO;EACrB,MAAM,OAAO;EACd,CAAC,CACH;EAGD"}
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import { McpContext } from "../../../layers/mcp-context.mjs";
3
+ import { InsufficientPermissions } from "../../helpers/common.mjs";
4
+ import { Web3Service } from "../../../layers/web3.mjs";
5
+ import { getSessionKeyClient } from "../../helpers/session-key.mjs";
6
+ import "../../helpers/index.mjs";
7
+ import { Batch } from "../../../schema/tx.mjs";
8
+ import { Effect, Schema } from "effect";
9
+ import { Tool } from "effect/unstable/ai";
10
+ import { executeTransaction } from "@namera-ai/sdk/transaction";
11
+ //#region src/mcp/tools/transaction/execute-transaction.ts
12
+ const ExecuteTransactionToolParams = Batch;
13
+ const ExecuteTransactionTool = Tool.make("execute_transaction", {
14
+ dependencies: [McpContext, Web3Service],
15
+ description: "Send transactions.",
16
+ failure: InsufficientPermissions,
17
+ parameters: ExecuteTransactionToolParams,
18
+ success: Schema.String.annotate({ description: "The transaction hash for the executed transaction." })
19
+ });
20
+ const executeTransactionToolHandler = (params) => Effect.gen(function* () {
21
+ const batches = [{
22
+ chainId: params.chainId,
23
+ nonceKey: params.nonceKey,
24
+ calls: params.calls
25
+ }];
26
+ const client = yield* getSessionKeyClient({ operation: {
27
+ intent: "transaction",
28
+ batches
29
+ } });
30
+ return (yield* Effect.promise(() => executeTransaction({
31
+ clients: [client],
32
+ batches
33
+ })))[0]?.receipt.transactionHash;
34
+ });
35
+ //#endregion
36
+ export { ExecuteTransactionTool, executeTransactionToolHandler };
37
+
38
+ //# sourceMappingURL=execute-transaction.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-transaction.mjs","names":[],"sources":["../../../../src/mcp/tools/transaction/execute-transaction.ts"],"sourcesContent":["import { executeTransaction } from \"@namera-ai/sdk/transaction\";\nimport { Effect, Schema } from \"effect\";\nimport { Tool } from \"effect/unstable/ai\";\n\nimport { McpContext } from \"@/layers/mcp-context\";\nimport { Web3Service } from \"@/layers/web3\";\nimport { getSessionKeyClient, InsufficientPermissions } from \"@/mcp/helpers\";\nimport type { Hex } from \"@/schema\";\nimport { Batch } from \"@/schema/tx\";\n\nexport const ExecuteTransactionToolParams = Batch;\n\nexport type ExecuteTransactionToolParams =\n typeof ExecuteTransactionToolParams.Type;\n\nexport const ExecuteTransactionTool = Tool.make(\"execute_transaction\", {\n dependencies: [McpContext, Web3Service],\n description: \"Send transactions.\",\n failure: InsufficientPermissions,\n parameters: ExecuteTransactionToolParams,\n success: Schema.String.annotate({\n description: \"The transaction hash for the executed transaction.\",\n }),\n});\n\nexport const executeTransactionToolHandler = (\n params: ExecuteTransactionToolParams,\n) =>\n Effect.gen(function* () {\n const batches: Batch[] = [\n {\n chainId: params.chainId,\n nonceKey: params.nonceKey,\n calls: params.calls,\n },\n ];\n\n const client = yield* getSessionKeyClient({\n operation: {\n intent: \"transaction\",\n batches,\n },\n });\n\n const txHashes = yield* Effect.promise(() =>\n executeTransaction({\n clients: [client],\n batches,\n }),\n );\n\n return txHashes[0]?.receipt.transactionHash as Hex;\n });\n"],"mappings":";;;;;;;;;;;AAUA,MAAa,+BAA+B;AAK5C,MAAa,yBAAyB,KAAK,KAAK,uBAAuB;CACrE,cAAc,CAAC,YAAY,YAAY;CACvC,aAAa;CACb,SAAS;CACT,YAAY;CACZ,SAAS,OAAO,OAAO,SAAS,EAC9B,aAAa,sDACd,CAAC;CACH,CAAC;AAEF,MAAa,iCACX,WAEA,OAAO,IAAI,aAAa;CACtB,MAAM,UAAmB,CACvB;EACE,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,OAAO,OAAO;EACf,CACF;CAED,MAAM,SAAS,OAAO,oBAAoB,EACxC,WAAW;EACT,QAAQ;EACR;EACD,EACF,CAAC;AASF,SAAO,OAPiB,OAAO,cAC7B,mBAAmB;EACjB,SAAS,CAAC,OAAO;EACjB;EACD,CAAC,CACH,EAEe,IAAI,QAAQ;EAC5B"}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import { ExecuteTransactionTool, executeTransactionToolHandler } from "./execute-transaction.mjs";
3
+ import { NativeTransferTool, nativeTransferToolHandler } from "./native-transfer.mjs";
4
+ import { Effect } from "effect";
5
+ import { Toolkit } from "effect/unstable/ai";
6
+ //#region src/mcp/tools/transaction/index.ts
7
+ const TransactionTools = Toolkit.make(NativeTransferTool, ExecuteTransactionTool);
8
+ const TransactionToolsHandlers = TransactionTools.toLayer(Effect.succeed({
9
+ native_transfer: (params) => nativeTransferToolHandler(params),
10
+ execute_transaction: (params) => executeTransactionToolHandler(params)
11
+ }));
12
+ //#endregion
13
+ export { TransactionTools, TransactionToolsHandlers };
14
+
15
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/mcp/tools/transaction/index.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport { Toolkit } from \"effect/unstable/ai\";\n\nimport {\n ExecuteTransactionTool,\n executeTransactionToolHandler,\n} from \"./execute-transaction\";\nimport {\n NativeTransferTool,\n nativeTransferToolHandler,\n} from \"./native-transfer\";\n\nexport const TransactionTools = Toolkit.make(\n NativeTransferTool,\n ExecuteTransactionTool,\n);\nexport const TransactionToolsHandlers = TransactionTools.toLayer(\n Effect.succeed({\n native_transfer: (params) => nativeTransferToolHandler(params),\n execute_transaction: (params) => executeTransactionToolHandler(params),\n }),\n);\n"],"mappings":";;;;;;AAYA,MAAa,mBAAmB,QAAQ,KACtC,oBACA,uBACD;AACD,MAAa,2BAA2B,iBAAiB,QACvD,OAAO,QAAQ;CACb,kBAAkB,WAAW,0BAA0B,OAAO;CAC9D,sBAAsB,WAAW,8BAA8B,OAAO;CACvE,CAAC,CACH"}
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ import { SupportedChain, getChain } from "../../../schema/chain.mjs";
3
+ import { EthereumAddress } from "../../../schema/common.mjs";
4
+ import "../../../schema/index.mjs";
5
+ import { McpContext } from "../../../layers/mcp-context.mjs";
6
+ import { InsufficientPermissions } from "../../helpers/common.mjs";
7
+ import { Web3Service } from "../../../layers/web3.mjs";
8
+ import { getSessionKeyClient } from "../../helpers/session-key.mjs";
9
+ import "../../helpers/index.mjs";
10
+ import { Effect, Schema } from "effect";
11
+ import { parseUnits } from "viem";
12
+ import { Tool } from "effect/unstable/ai";
13
+ import { executeTransaction } from "@namera-ai/sdk/transaction";
14
+ //#region src/mcp/tools/transaction/native-transfer.ts
15
+ const NativeTransferToolParams = Schema.Struct({
16
+ chain: SupportedChain.annotate({ description: "The chain to use for the transfer" }),
17
+ address: EthereumAddress.annotate({ description: "The ethereum address to transfer to" }),
18
+ amount: Schema.String.annotate({ description: "The amount of native tokens to transfer" }),
19
+ unit: Schema.Literals([
20
+ "wei",
21
+ "gwei",
22
+ "ether"
23
+ ])
24
+ });
25
+ const NativeTransferTool = Tool.make("native_transfer", {
26
+ dependencies: [McpContext, Web3Service],
27
+ description: "Transfer Native Tokens to a specified address.",
28
+ failure: InsufficientPermissions,
29
+ parameters: NativeTransferToolParams,
30
+ success: Schema.String.annotate({ description: "The transaction hash of the transfer" })
31
+ });
32
+ const nativeTransferToolHandler = (params) => Effect.gen(function* () {
33
+ const decimals = () => {
34
+ if (params.unit === "wei") return 1;
35
+ if (params.unit === "gwei") return 9;
36
+ return 18;
37
+ };
38
+ const amount = parseUnits(params.amount.toString(), decimals());
39
+ const batches = [{
40
+ chainId: getChain(params.chain).id,
41
+ calls: [{
42
+ to: params.address,
43
+ value: amount,
44
+ data: "0x"
45
+ }]
46
+ }];
47
+ const client = yield* getSessionKeyClient({ operation: {
48
+ intent: "transaction",
49
+ batches
50
+ } });
51
+ return (yield* Effect.promise(() => executeTransaction({
52
+ clients: [client],
53
+ batches
54
+ })))[0]?.receipt.transactionHash;
55
+ });
56
+ //#endregion
57
+ export { NativeTransferTool, nativeTransferToolHandler };
58
+
59
+ //# sourceMappingURL=native-transfer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-transfer.mjs","names":[],"sources":["../../../../src/mcp/tools/transaction/native-transfer.ts"],"sourcesContent":["import { executeTransaction } from \"@namera-ai/sdk/transaction\";\nimport { Effect, Schema } from \"effect\";\nimport { Tool } from \"effect/unstable/ai\";\nimport { parseUnits } from \"viem\";\n\nimport { McpContext } from \"@/layers/mcp-context\";\nimport { Web3Service } from \"@/layers/web3\";\nimport { getSessionKeyClient, InsufficientPermissions } from \"@/mcp/helpers\";\nimport { EthereumAddress, getChain, type Hex, SupportedChain } from \"@/schema\";\nimport type { Batch } from \"@/schema/tx\";\n\nexport const NativeTransferToolParams = Schema.Struct({\n chain: SupportedChain.annotate({\n description: \"The chain to use for the transfer\",\n }),\n address: EthereumAddress.annotate({\n description: \"The ethereum address to transfer to\",\n }),\n amount: Schema.String.annotate({\n description: \"The amount of native tokens to transfer\",\n }),\n unit: Schema.Literals([\"wei\", \"gwei\", \"ether\"]),\n});\n\nexport type NativeTransferToolParams = typeof NativeTransferToolParams.Type;\n\nexport const NativeTransferTool = Tool.make(\"native_transfer\", {\n dependencies: [McpContext, Web3Service],\n description: \"Transfer Native Tokens to a specified address.\",\n failure: InsufficientPermissions,\n parameters: NativeTransferToolParams,\n success: Schema.String.annotate({\n description: \"The transaction hash of the transfer\",\n }),\n});\n\nexport const nativeTransferToolHandler = (params: NativeTransferToolParams) =>\n Effect.gen(function* () {\n const decimals = () => {\n if (params.unit === \"wei\") return 1;\n if (params.unit === \"gwei\") return 9;\n return 18;\n };\n\n const amount = parseUnits(params.amount.toString(), decimals());\n const chain = getChain(params.chain);\n\n const batches: Batch[] = [\n {\n chainId: chain.id,\n calls: [\n {\n to: params.address,\n value: amount,\n data: \"0x\",\n },\n ],\n },\n ];\n\n const client = yield* getSessionKeyClient({\n operation: {\n intent: \"transaction\",\n batches,\n },\n });\n\n const txHashes = yield* Effect.promise(() =>\n executeTransaction({\n clients: [client],\n batches,\n }),\n );\n\n return txHashes[0]?.receipt.transactionHash as Hex;\n });\n"],"mappings":";;;;;;;;;;;;;;AAWA,MAAa,2BAA2B,OAAO,OAAO;CACpD,OAAO,eAAe,SAAS,EAC7B,aAAa,qCACd,CAAC;CACF,SAAS,gBAAgB,SAAS,EAChC,aAAa,uCACd,CAAC;CACF,QAAQ,OAAO,OAAO,SAAS,EAC7B,aAAa,2CACd,CAAC;CACF,MAAM,OAAO,SAAS;EAAC;EAAO;EAAQ;EAAQ,CAAC;CAChD,CAAC;AAIF,MAAa,qBAAqB,KAAK,KAAK,mBAAmB;CAC7D,cAAc,CAAC,YAAY,YAAY;CACvC,aAAa;CACb,SAAS;CACT,YAAY;CACZ,SAAS,OAAO,OAAO,SAAS,EAC9B,aAAa,wCACd,CAAC;CACH,CAAC;AAEF,MAAa,6BAA6B,WACxC,OAAO,IAAI,aAAa;CACtB,MAAM,iBAAiB;AACrB,MAAI,OAAO,SAAS,MAAO,QAAO;AAClC,MAAI,OAAO,SAAS,OAAQ,QAAO;AACnC,SAAO;;CAGT,MAAM,SAAS,WAAW,OAAO,OAAO,UAAU,EAAE,UAAU,CAAC;CAG/D,MAAM,UAAmB,CACvB;EACE,SAJU,SAAS,OAAO,MAIjB,CAAM;EACf,OAAO,CACL;GACE,IAAI,OAAO;GACX,OAAO;GACP,MAAM;GACP,CACF;EACF,CACF;CAED,MAAM,SAAS,OAAO,oBAAoB,EACxC,WAAW;EACT,QAAQ;EACR;EACD,EACF,CAAC;AASF,SAAO,OAPiB,OAAO,cAC7B,mBAAmB;EACjB,SAAS,CAAC,OAAO;EACjB;EACD,CAAC,CACH,EAEe,IAAI,QAAQ;EAC5B"}