@ironwallet/mcp-server 1.0.1 → 1.0.3

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 (63) hide show
  1. package/README.md +17 -11
  2. package/dist/api/rates.d.ts +62 -0
  3. package/dist/api/rates.js +198 -0
  4. package/dist/api/rates.js.map +1 -0
  5. package/dist/api/swap.d.ts +1 -1
  6. package/dist/api/swap.js +1 -1
  7. package/dist/config.d.ts +16 -12
  8. package/dist/config.js +48 -31
  9. package/dist/config.js.map +1 -1
  10. package/dist/consent/copy.d.ts +18 -0
  11. package/dist/consent/copy.js +27 -0
  12. package/dist/consent/copy.js.map +1 -0
  13. package/dist/consent/store.d.ts +23 -0
  14. package/dist/consent/store.js +63 -0
  15. package/dist/consent/store.js.map +1 -0
  16. package/dist/device-fingerprint.d.ts +18 -0
  17. package/dist/device-fingerprint.js +81 -0
  18. package/dist/device-fingerprint.js.map +1 -0
  19. package/dist/generated/env-config.js +3 -1
  20. package/dist/generated/env-config.js.map +1 -1
  21. package/dist/generated/env-profile.d.ts +4 -0
  22. package/dist/keystore/store.js +3 -7
  23. package/dist/keystore/store.js.map +1 -1
  24. package/dist/keystore/types.d.ts +8 -3
  25. package/dist/local-secrets.d.ts +2 -2
  26. package/dist/local-secrets.js +5 -9
  27. package/dist/local-secrets.js.map +1 -1
  28. package/dist/networks.d.ts +5 -0
  29. package/dist/networks.js +21 -0
  30. package/dist/networks.js.map +1 -0
  31. package/dist/policy.d.ts +33 -3
  32. package/dist/policy.js +121 -32
  33. package/dist/policy.js.map +1 -1
  34. package/dist/restrict-private-file.d.ts +9 -0
  35. package/dist/restrict-private-file.js +53 -0
  36. package/dist/restrict-private-file.js.map +1 -0
  37. package/dist/server.js +3 -2
  38. package/dist/server.js.map +1 -1
  39. package/dist/tools/definitions.d.ts +40 -0
  40. package/dist/tools/definitions.js +256 -0
  41. package/dist/tools/definitions.js.map +1 -0
  42. package/dist/tools/helpers.d.ts +0 -3
  43. package/dist/tools/helpers.js +0 -3
  44. package/dist/tools/helpers.js.map +1 -1
  45. package/dist/tools/index.d.ts +1 -0
  46. package/dist/tools/index.js +1 -0
  47. package/dist/tools/index.js.map +1 -1
  48. package/dist/tools/swap.d.ts +1 -1
  49. package/dist/tools/swap.js +12 -76
  50. package/dist/tools/swap.js.map +1 -1
  51. package/dist/tools/transfer.d.ts +1 -1
  52. package/dist/tools/transfer.js +13 -54
  53. package/dist/tools/transfer.js.map +1 -1
  54. package/dist/tools/wallets.d.ts +1 -1
  55. package/dist/tools/wallets.js +110 -47
  56. package/dist/tools/wallets.js.map +1 -1
  57. package/dist/wallet/derive.d.ts +1 -1
  58. package/dist/wallet/derive.js +1 -1
  59. package/dist/web/manager.js +64 -3
  60. package/dist/web/manager.js.map +1 -1
  61. package/package.json +30 -5
  62. package/server.json +23 -0
  63. package/tools.json +632 -0
package/dist/policy.js CHANGED
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * Optional per-wallet spending policy. Disabled by default (sends autonomously).
3
3
  * When `policy.enabled` is set, both `send_transfer` and `execute_swap` check it
4
- * before signing.
4
+ * before signing. `maxPerTxUsd` converts the amount via the rates backend at the
5
+ * moment of the operation and fails closed when no rate is available.
5
6
  */
6
7
  import { normalizeAddress } from "./wallet/derive.js";
8
+ import { getUsdRate } from "./api/rates.js";
7
9
  import { logInfo, logWarn } from "./log.js";
8
10
  /**
9
11
  * Compare two non-negative decimal strings without floating point.
@@ -29,6 +31,38 @@ function parseNonNegativeDecimal(raw) {
29
31
  const [intPart, fracPart = ""] = t.split(".");
30
32
  return { int: BigInt(intPart), frac: fracPart };
31
33
  }
34
+ /** Render a float (e.g. a JSON rate) as a plain decimal string, no exponent. */
35
+ export function numberToDecimalString(n) {
36
+ if (!Number.isFinite(n) || n < 0) {
37
+ throw new Error(`Invalid rate ${n}.`);
38
+ }
39
+ const s = String(n);
40
+ if (!/[eE]/.test(s))
41
+ return s;
42
+ // ≥ 1e21 serializes exponentially even via toFixed; such floats are integral.
43
+ if (n >= 1e21)
44
+ return BigInt(n).toString();
45
+ // 1e-7 and friends: expand via toFixed and trim trailing zeros.
46
+ const fixed = n.toFixed(20);
47
+ return fixed.includes(".") ? fixed.replace(/0+$/, "").replace(/\.$/, "") : fixed;
48
+ }
49
+ /** Multiply two non-negative decimal strings exactly (BigInt, no float). */
50
+ export function multiplyDecimalAmounts(a, b) {
51
+ const pa = parseNonNegativeDecimal(a);
52
+ const pb = parseNonNegativeDecimal(b);
53
+ const scaleA = pa.frac.length;
54
+ const scaleB = pb.frac.length;
55
+ const rawA = BigInt(`${pa.int}${pa.frac}` || "0");
56
+ const rawB = BigInt(`${pb.int}${pb.frac}` || "0");
57
+ const product = rawA * rawB;
58
+ const scale = scaleA + scaleB;
59
+ if (scale === 0)
60
+ return product.toString();
61
+ const digits = product.toString().padStart(scale + 1, "0");
62
+ const intPart = digits.slice(0, -scale);
63
+ const fracPart = digits.slice(-scale).replace(/0+$/, "");
64
+ return fracPart ? `${intPart}.${fracPart}` : intPart;
65
+ }
32
66
  /** Always-present policy for `list_wallets` (`enabled: false` when unset). */
33
67
  export function listWalletPolicy(policy) {
34
68
  if (!policy || !policy.enabled)
@@ -47,9 +81,8 @@ export function enforcePolicy(entry, check) {
47
81
  kind: check.kind,
48
82
  network: check.network,
49
83
  toAddress: check.toAddress,
50
- amount: check.amount,
51
84
  readOnly: policy.readOnly,
52
- maxPerTx: policy.maxPerTx,
85
+ maxPerTxUsd: policy.maxPerTxUsd,
53
86
  allowedRecipients: policy.allowedRecipients?.length ?? 0,
54
87
  });
55
88
  if (policy.readOnly) {
@@ -62,39 +95,26 @@ export function enforcePolicy(entry, check) {
62
95
  ? `Wallet "${entry.name}" is read-only; swaps are disabled by policy.`
63
96
  : `Wallet "${entry.name}" is read-only; sending is disabled by policy.`);
64
97
  }
65
- if (check.amount !== undefined && policy.maxPerTx !== undefined && policy.maxPerTx !== "") {
66
- let cmp;
67
- try {
68
- cmp = compareDecimalAmount(check.amount, policy.maxPerTx);
69
- }
70
- catch {
71
- throw new Error(`Cannot enforce maxPerTx for wallet "${entry.name}": amounts must be non-negative decimals (got amount=${check.amount}, maxPerTx=${policy.maxPerTx}).`);
72
- }
73
- if (cmp > 0) {
74
- logWarn("policy.reject", {
75
- wallet: entry.name,
76
- kind: check.kind,
77
- reason: "max_per_tx",
78
- amount: check.amount,
79
- maxPerTx: policy.maxPerTx,
80
- });
81
- throw new Error(`Amount ${check.amount} exceeds per-transaction limit ${policy.maxPerTx} for wallet "${entry.name}".`);
82
- }
83
- }
84
- if (policy.allowedRecipients && policy.allowedRecipients.length > 0) {
85
- if (check.kind === "swap") {
86
- logWarn("policy.reject", {
87
- wallet: entry.name,
88
- kind: "swap",
89
- reason: "recipient_allow_list_blocks_swap",
90
- });
91
- throw new Error(`Wallet "${entry.name}" has a recipient allow-list; swaps are disabled by policy because the swap router is not a whitelisted transfer recipient.`);
92
- }
98
+ // The allow-list constrains transfer destinations only. Swaps are exempt:
99
+ // execute_swap has no recipient input — the bought asset is always paid out
100
+ // to this wallet's own keystore address on the buy network.
101
+ if (check.kind === "transfer" &&
102
+ policy.allowedRecipients &&
103
+ policy.allowedRecipients.length > 0) {
93
104
  if (!check.toAddress) {
94
105
  throw new Error(`Wallet "${entry.name}" has a recipient allow-list; a destination address is required.`);
95
106
  }
96
107
  const target = normalizeAddress(check.network, check.toAddress);
97
- const allowed = policy.allowedRecipients.some((a) => normalizeAddress(check.network, a) === target);
108
+ // Entries for other networks (or malformed ones) must not break the check:
109
+ // normalizeAddress throws on non-EVM strings for EVM networks.
110
+ const allowed = policy.allowedRecipients.some((a) => {
111
+ try {
112
+ return normalizeAddress(check.network, a) === target;
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ });
98
118
  if (!allowed) {
99
119
  logWarn("policy.reject", {
100
120
  wallet: entry.name,
@@ -111,4 +131,73 @@ export function enforcePolicy(entry, check) {
111
131
  network: check.network,
112
132
  });
113
133
  }
134
+ /** Pure part of the USD check: amount × rate vs limit. Throws on violation. */
135
+ export function assertUsdWithinLimit(opts) {
136
+ const usdValue = multiplyDecimalAmounts(opts.amount, numberToDecimalString(opts.rate));
137
+ if (compareDecimalAmount(usdValue, opts.maxPerTxUsd) > 0) {
138
+ throw new Error(`${opts.kind === "swap" ? "Swap sell" : "Transfer"} amount ${opts.amount} ${opts.assetLabel} ` +
139
+ `≈ $${usdValue} exceeds the ${opts.maxPerTxUsd} USD per-transaction limit for wallet "${opts.wallet}".`);
140
+ }
141
+ return { usdValue };
142
+ }
143
+ /**
144
+ * Enforce `maxPerTxUsd` right before signing. Fail closed: if the limit is set
145
+ * and the USD rate cannot be resolved, the operation is rejected.
146
+ */
147
+ export async function enforceUsdLimit(entry, check) {
148
+ const policy = entry.policy;
149
+ const limit = policy?.enabled ? policy.maxPerTxUsd : undefined;
150
+ if (!limit)
151
+ return;
152
+ const assetLabel = check.symbol ?? (check.tokenAddress ? "token" : check.network);
153
+ const rate = await getUsdRate({
154
+ network: check.network,
155
+ symbol: check.symbol,
156
+ tokenAddress: check.tokenAddress,
157
+ }, check.correlationId);
158
+ if (rate === undefined) {
159
+ logWarn("policy.reject", {
160
+ wallet: entry.name,
161
+ kind: check.kind,
162
+ reason: "usd_rate_unavailable",
163
+ network: check.network,
164
+ symbol: check.symbol,
165
+ tokenAddress: check.tokenAddress,
166
+ });
167
+ throw new Error(`Wallet "${entry.name}" has a ${limit} USD per-transaction limit, but no USD rate ` +
168
+ `is available for ${assetLabel} on ${check.network} right now. ` +
169
+ `The operation was rejected (fail closed). Retry later or adjust the policy.`);
170
+ }
171
+ let usdValue;
172
+ try {
173
+ ({ usdValue } = assertUsdWithinLimit({
174
+ wallet: entry.name,
175
+ kind: check.kind,
176
+ amount: check.amount,
177
+ rate,
178
+ maxPerTxUsd: limit,
179
+ assetLabel,
180
+ }));
181
+ }
182
+ catch (e) {
183
+ logWarn("policy.reject", {
184
+ wallet: entry.name,
185
+ kind: check.kind,
186
+ reason: "max_per_tx_usd",
187
+ amount: check.amount,
188
+ rate,
189
+ maxPerTxUsd: limit,
190
+ });
191
+ throw e;
192
+ }
193
+ logInfo("policy.usd.ok", {
194
+ wallet: entry.name,
195
+ kind: check.kind,
196
+ network: check.network,
197
+ amount: check.amount,
198
+ rate,
199
+ usdValue,
200
+ maxPerTxUsd: limit,
201
+ });
202
+ }
114
203
  //# sourceMappingURL=policy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Owner-only access for files under ~/.ironwallet-mcp/.
3
+ * POSIX: chmod 0600. Windows: NTFS ACL via icacls (chmod is a no-op there).
4
+ * Best-effort: a failed chmod/icacls must not block keystore or secret writes.
5
+ */
6
+ export declare function windowsIcaclsPath(systemRoot?: string | undefined): string;
7
+ export declare function windowsIcaclsArgs(filePath: string, username: string): string[];
8
+ export declare function resolveWindowsUsername(osUsername?: string | undefined, envUsername?: string | undefined): string;
9
+ export declare function restrictPrivateFile(filePath: string): void;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Owner-only access for files under ~/.ironwallet-mcp/.
3
+ * POSIX: chmod 0600. Windows: NTFS ACL via icacls (chmod is a no-op there).
4
+ * Best-effort: a failed chmod/icacls must not block keystore or secret writes.
5
+ */
6
+ import { execFileSync } from "node:child_process";
7
+ import { chmodSync } from "node:fs";
8
+ import { userInfo } from "node:os";
9
+ import { join } from "node:path";
10
+ export function windowsIcaclsPath(systemRoot = process.env.SystemRoot || process.env.WINDIR) {
11
+ return join(systemRoot || "C:\\Windows", "System32", "icacls.exe");
12
+ }
13
+ export function windowsIcaclsArgs(filePath, username) {
14
+ return [filePath, "/inheritance:r", "/grant:r", `${username}:F`];
15
+ }
16
+ export function resolveWindowsUsername(osUsername = safeOsUsername(), envUsername = process.env.USERNAME) {
17
+ const fromOs = osUsername?.trim();
18
+ if (fromOs)
19
+ return fromOs;
20
+ return envUsername?.trim() ?? "";
21
+ }
22
+ function safeOsUsername() {
23
+ try {
24
+ return userInfo().username;
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ }
30
+ export function restrictPrivateFile(filePath) {
31
+ if (process.platform === "win32") {
32
+ try {
33
+ const username = resolveWindowsUsername();
34
+ if (!username)
35
+ return;
36
+ execFileSync(windowsIcaclsPath(), windowsIcaclsArgs(filePath, username), {
37
+ windowsHide: true,
38
+ stdio: ["ignore", "pipe", "pipe"],
39
+ });
40
+ }
41
+ catch {
42
+ // missing icacls, AppLocker, Controlled Folder Access, bad account name
43
+ }
44
+ return;
45
+ }
46
+ try {
47
+ chmodSync(filePath, 0o600);
48
+ }
49
+ catch {
50
+ // best effort on filesystems without POSIX perms
51
+ }
52
+ }
53
+ //# sourceMappingURL=restrict-private-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restrict-private-file.js","sourceRoot":"","sources":["../src/restrict-private-file.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,iBAAiB,CAC/B,aAAiC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM;IAE7E,OAAO,IAAI,CAAC,UAAU,IAAI,aAAa,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,QAAgB;IAClE,OAAO,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,GAAG,QAAQ,IAAI,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,aAAiC,cAAc,EAAE,EACjD,cAAkC,OAAO,CAAC,GAAG,CAAC,QAAQ;IAEtD,MAAM,MAAM,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;IAClC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,OAAO,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,OAAO,QAAQ,EAAE,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,sBAAsB,EAAE,CAAC;YAC1C,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,YAAY,CAAC,iBAAiB,EAAE,EAAE,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;gBACvE,WAAW,EAAE,IAAI;gBACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;QAC1E,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;IACnD,CAAC;AACH,CAAC"}
package/dist/server.js CHANGED
@@ -11,12 +11,13 @@ import { logStartupBanner } from "./log.js";
11
11
  export async function serve() {
12
12
  const cfg = getConfig();
13
13
  const instructions = [
14
- "Non-custodial Ironwallet. Seed phrases stay encrypted on the host and never leave this machine. The agent can retrieve balances, sign locally, transfer tokens, and swap across 10+ networks. There is no extra confirmation UI. Prefer a dedicated wallet with limited balance.",
14
+ "Non-custodial IronWallet. Seed phrases stay encrypted on the host and never leave this machine. The agent can retrieve balances, sign locally, transfer tokens, and swap across 10+ networks. There is no extra confirmation UI. Prefer a dedicated wallet with limited balance.",
15
15
  "Never print, request, or invent recovery phrases or private keys. No tool accepts or returns a seed. Create/import/backup only via create_wallets backup_url or open_wallet_manager in the local browser.",
16
- "If there is no wallet yet, create_wallets or open_wallet_manager first.",
16
+ "Before create_wallets or import, the user must accept the MCP disclaimer (accept_mcp_consent after showing the full text in chat, or the local wallet manager). If create_wallets returns needs_consent, show consent in full and stop.",
17
17
  "Deposit QR: get_deposit_qr (pass network for one chain). Try to show the PNG in chat. If the host does not render it, open qr_url in the local browser and give the address. The wallet manager also has a QR button next to each address.",
18
18
  "Transfer: list_wallets / get_balance → estimate_transfer (optional) → send_transfer. On timeout poll get_operation_status; do not resubmit blindly. send_transfer may reduce the amount so the fee fits.",
19
19
  "Swap: list_swap_networks → list_swap_assets (copy network/symbol/address/decimals from the catalog; do not invent token addresses; omit address only for native coins) → estimate_swap or execute_swap. Quotes expire. maxMode: true sells as much as the service allows. After execute, poll get_swap_status; if execute times out, poll before retrying.",
20
+ "Limits: read list_wallets.policy before send/swap. Change it only when the user explicitly asks, via set_wallet_policy (full replace — read the current policy first). maxPerTxUsd is valued at operation time; if no USD rate is available the operation is rejected. The recipient allow-list applies to transfers.",
20
21
  ];
21
22
  if (cfg.readOnly) {
22
23
  instructions.push("This server is read-only (IW_READ_ONLY). send_transfer and execute_swap are disabled. Balances, estimates, and lists still work.");
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,YAAY,GAAG;QACnB,kRAAkR;QAClR,2MAA2M;QAC3M,yEAAyE;QACzE,4OAA4O;QAC5O,0MAA0M;QAC1M,4VAA4V;KAC7V,CAAC;IACF,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,YAAY,CAAC,IAAI,CACf,kIAAkI,CACnI,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,cAAc,EAAE;KAC1B,EACD;QACE,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;KACtC,CACF,CAAC;IAEF,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtB,0EAA0E;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oCAAoC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,CACzF,CAAC;IACF,gBAAgB,CAAC;QACf,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;QAC9C,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACvB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,MAAM,YAAY,GAAG;QACnB,kRAAkR;QAClR,2MAA2M;QAC3M,yOAAyO;QACzO,4OAA4O;QAC5O,0MAA0M;QAC1M,4VAA4V;QAC5V,uTAAuT;KACxT,CAAC;IACF,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,YAAY,CAAC,IAAI,CACf,kIAAkI,CACnI,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,cAAc,EAAE;KAC1B,EACD;QACE,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;KACtC,CACF,CAAC;IAEF,aAAa,CAAC,MAAM,CAAC,CAAC;IAEtB,0EAA0E;IAC1E,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oCAAoC,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,CACzF,CAAC;IACF,gBAAgB,CAAC;QACf,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,oBAAoB,EAAE,GAAG,CAAC,oBAAoB;QAC9C,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;KACvB,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * MCP tool catalog: Zod input schemas plus the short docs fields used in
3
+ * README / skill tables. Handlers stay in wallets.ts / transfer.ts / swap.ts.
4
+ * `tools.json` is generated from this file — do not edit that JSON by hand.
5
+ */
6
+ import { z, type ZodRawShape } from "zod";
7
+ export declare const networkEnum: z.ZodEnum<["ethereum" | "bsc" | "polygon" | "base" | "arbitrum" | "optimism" | "avalanche" | "tron" | "bitcoin" | "litecoin" | "doge" | "solana" | "ton" | "xrp", ...("ethereum" | "bsc" | "polygon" | "base" | "arbitrum" | "optimism" | "avalanche" | "tron" | "bitcoin" | "litecoin" | "doge" | "solana" | "ton" | "xrp")[]]>;
8
+ export declare const swapAssetInputSchema: z.ZodObject<{
9
+ network: z.ZodString;
10
+ symbol: z.ZodString;
11
+ address: z.ZodNullable<z.ZodOptional<z.ZodString>>;
12
+ decimals: z.ZodOptional<z.ZodNumber>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ symbol: string;
15
+ network: string;
16
+ address?: string | null | undefined;
17
+ decimals?: number | undefined;
18
+ }, {
19
+ symbol: string;
20
+ network: string;
21
+ address?: string | null | undefined;
22
+ decimals?: number | undefined;
23
+ }>;
24
+ export interface ToolDefinition {
25
+ name: string;
26
+ title: string;
27
+ description: string;
28
+ /** One-line purpose for markdown tool tables. */
29
+ purpose: string;
30
+ movesFunds: boolean;
31
+ inputSchema: ZodRawShape;
32
+ }
33
+ export declare const TOOL_DEFINITIONS: ToolDefinition[];
34
+ export declare function toolDefinition(name: string): ToolDefinition;
35
+ /** Fields passed to `server.registerTool` (docs-only keys stripped). */
36
+ export declare function mcpToolConfig(def: ToolDefinition): {
37
+ title: string;
38
+ description: string;
39
+ inputSchema: ZodRawShape;
40
+ };
@@ -0,0 +1,256 @@
1
+ /**
2
+ * MCP tool catalog: Zod input schemas plus the short docs fields used in
3
+ * README / skill tables. Handlers stay in wallets.ts / transfer.ts / swap.ts.
4
+ * `tools.json` is generated from this file — do not edit that JSON by hand.
5
+ */
6
+ import { z } from "zod";
7
+ import { ALL_NETWORKS } from "../networks.js";
8
+ export const networkEnum = z.enum([...ALL_NETWORKS]);
9
+ export const swapAssetInputSchema = z.object({
10
+ network: z.string().describe("Network id, e.g. ethereum, bsc, bitcoin."),
11
+ symbol: z.string().describe("Asset symbol, e.g. ETH, USDT."),
12
+ address: z
13
+ .string()
14
+ .optional()
15
+ .nullable()
16
+ .describe("Token contract address. Omit/null for the native coin."),
17
+ decimals: z
18
+ .number()
19
+ .int()
20
+ .optional()
21
+ .describe("Token decimals. If omitted, resolved via SWP catalog (paged). Prefer passing decimals (+ address for tokens) from list_swap_assets."),
22
+ });
23
+ export const TOOL_DEFINITIONS = [
24
+ {
25
+ name: "list_wallets",
26
+ title: "List wallets",
27
+ description: "List the wallets in the local keystore with their addresses per network. Each wallet includes policy ({ enabled: false } when unset). Never returns private keys or seed phrases.",
28
+ purpose: "Names, addresses, and `policy`",
29
+ movesFunds: false,
30
+ inputSchema: {},
31
+ },
32
+ {
33
+ name: "accept_mcp_consent",
34
+ title: "Accept MCP consent",
35
+ description: "Record that the user accepted the MCP risk disclaimer in chat. Call only after showing the full consent text (from a previous create_wallets needs_consent response, or the skill) and the user explicitly confirms. Does not create a wallet. accepted must be true.",
36
+ purpose: "Record chat acceptance of the MCP disclaimer",
37
+ movesFunds: false,
38
+ inputSchema: {
39
+ accepted: z
40
+ .boolean()
41
+ .describe("Must be true after the user confirmed they understand the risks."),
42
+ },
43
+ },
44
+ {
45
+ name: "create_wallets",
46
+ title: "Create wallets",
47
+ description: "Generate one or more brand-new wallets (BIP-39). Requires a current MCP consent (accept_mcp_consent in chat, or the local wallet manager). Returns names and addresses only. Seed phrases are NOT returned to the agent. The response includes a local browser URL where the user can view and back up the recovery phrases. If consent is missing, returns needs_consent and the full disclaimer instead of creating wallets.",
48
+ purpose: "New wallets; returns a browser `backup_url`",
49
+ movesFunds: false,
50
+ inputSchema: {
51
+ count: z.number().int().min(1).max(50).describe("How many wallets to create."),
52
+ name_prefix: z
53
+ .string()
54
+ .optional()
55
+ .describe("Optional name prefix, e.g. 'agent-hot'. Defaults to 'wallet'."),
56
+ },
57
+ },
58
+ {
59
+ name: "open_wallet_manager",
60
+ title: "Open wallet manager (browser)",
61
+ description: "Open a local browser form to add/import/create wallets or back them up (reveal the recovery phrase). Returns a localhost URL for the user to open. Seed phrases are entered and shown ONLY in the browser and never pass through the agent. Use this whenever the user asks to add, import, create, or back up a wallet.",
62
+ purpose: "Local browser UI to import / create / back up",
63
+ movesFunds: false,
64
+ inputSchema: {},
65
+ },
66
+ {
67
+ name: "set_wallet_policy",
68
+ title: "Set wallet policy",
69
+ description: "Replace the spending policy of a wallet (chat intent is the authorization; no extra confirmation). FULL REPLACE, not a patch: read list_wallets first and pass every field you want to keep. enabled=false removes all limits. readOnly blocks send_transfer and execute_swap. maxPerTxUsd caps each send/swap by USD value at the moment of the operation (rate from the IronWallet backend; if the rate is unavailable the operation is rejected — fail closed). allowedRecipients applies to send_transfer destinations. Use only when the user explicitly asks to change limits.",
70
+ purpose: "Replace per-wallet limits (`readOnly`, `maxPerTxUsd`, allow-list)",
71
+ movesFunds: false,
72
+ inputSchema: {
73
+ wallet: z.string().optional().describe("Wallet name. Optional if only one exists."),
74
+ enabled: z
75
+ .boolean()
76
+ .describe("false removes all limits; true enforces the fields below."),
77
+ readOnly: z
78
+ .boolean()
79
+ .optional()
80
+ .describe("Block send_transfer and execute_swap for this wallet."),
81
+ maxPerTxUsd: z
82
+ .string()
83
+ .optional()
84
+ .describe("Max USD value per send/swap as a decimal string, e.g. \"50\". Checked at operation time; rejected if no rate is available."),
85
+ allowedRecipients: z
86
+ .array(z.string())
87
+ .optional()
88
+ .describe("Transfer destination allow-list."),
89
+ },
90
+ },
91
+ {
92
+ name: "get_deposit_qr",
93
+ title: "Deposit QR",
94
+ description: "PNG QR to receive funds (generated on the fly; IW mark, address under the code). Pass network for one chain; omit it for one QR per unique address. Does not move funds. Never returns keys or seed phrases. Show the attached image in chat when the host renders it. Each item also has qr_url — open that local URL if the user cannot see the QR, and always write the address in the reply.",
95
+ purpose: "PNG QR (try chat; else local `qr_url`)",
96
+ movesFunds: false,
97
+ inputSchema: {
98
+ wallet: z.string().optional().describe("Wallet name. Optional if only one exists."),
99
+ network: networkEnum
100
+ .optional()
101
+ .describe("Network to deposit on. Omit to return one QR per unique address."),
102
+ },
103
+ },
104
+ {
105
+ name: "get_balance",
106
+ title: "Get balance",
107
+ description: "Get the balance for a wallet on a network. Optionally pass a token contract address; omit for the native coin.",
108
+ purpose: "Native or token balance",
109
+ movesFunds: false,
110
+ inputSchema: {
111
+ wallet: z.string().optional().describe("Wallet name. Optional if only one exists."),
112
+ network: networkEnum,
113
+ tokenAddress: z
114
+ .string()
115
+ .optional()
116
+ .describe("Token contract address. Omit for the native coin."),
117
+ },
118
+ },
119
+ {
120
+ name: "estimate_transfer",
121
+ title: "Estimate transfer",
122
+ description: "Estimate fees for a transfer without sending. Returns fees and the number of transactions that would be signed.",
123
+ purpose: "Fee estimate, no broadcast",
124
+ movesFunds: false,
125
+ inputSchema: {
126
+ wallet: z.string().optional(),
127
+ network: networkEnum,
128
+ to: z.string().describe("Recipient address."),
129
+ amount: z.string().describe("Amount in asset units (decimal string)."),
130
+ tokenAddress: z
131
+ .string()
132
+ .optional()
133
+ .describe("Token contract address. Omit for the native coin."),
134
+ memo: z.string().optional(),
135
+ },
136
+ },
137
+ {
138
+ name: "send_transfer",
139
+ title: "Send transfer",
140
+ description: "Send a transfer: sign locally with the wallet's key and broadcast via the IronWallet forward relay (estimate -> sign -> forward) for EVM, Tron, Bitcoin, Litecoin, Doge, Solana, XRP and TON. Irreversible once broadcast — no second confirmation. Returns the transaction hash (and operation id where applicable).",
141
+ purpose: "Sign locally and send",
142
+ movesFunds: true,
143
+ inputSchema: {
144
+ wallet: z.string().optional(),
145
+ network: networkEnum,
146
+ to: z.string().describe("Recipient address."),
147
+ amount: z.string().describe("Amount in asset units (decimal string)."),
148
+ tokenAddress: z
149
+ .string()
150
+ .optional()
151
+ .describe("Token contract address. Omit for the native coin."),
152
+ memo: z.string().optional(),
153
+ },
154
+ },
155
+ {
156
+ name: "get_operation_status",
157
+ title: "Get operation status",
158
+ description: "Poll the state of a forward operation by its operation id.",
159
+ purpose: "Poll a transfer",
160
+ movesFunds: false,
161
+ inputSchema: {
162
+ wallet: z.string().optional(),
163
+ network: networkEnum,
164
+ operationId: z.string(),
165
+ },
166
+ },
167
+ {
168
+ name: "list_swap_networks",
169
+ title: "List swap networks",
170
+ description: "List networks available for swaps. Use before listing swap assets.",
171
+ purpose: "Networks available for swap",
172
+ movesFunds: false,
173
+ inputSchema: {
174
+ wallet: z.string().optional(),
175
+ },
176
+ },
177
+ {
178
+ name: "list_swap_assets",
179
+ title: "List swap assets",
180
+ description: "List tradable assets. direction=from lists sell assets; direction=to requires fromNetwork/fromSymbol (and fromAddress for tokens) and lists buy assets. Enriches with wallet address and balance when possible.",
181
+ purpose: "Sell / buy catalog",
182
+ movesFunds: false,
183
+ inputSchema: {
184
+ wallet: z.string().optional(),
185
+ direction: z.enum(["from", "to"]),
186
+ fromNetwork: z.string().optional(),
187
+ fromSymbol: z.string().optional(),
188
+ fromAddress: z.string().optional().nullable(),
189
+ search: z.string().optional(),
190
+ networks: z.array(z.string()).optional(),
191
+ page: z.number().int().positive().optional(),
192
+ pageSize: z.number().int().positive().max(100).optional(),
193
+ },
194
+ },
195
+ {
196
+ name: "estimate_swap",
197
+ title: "Estimate swap",
198
+ description: "Get a swap quote (amounts, fees, operationId). Quote can expire — prefer execute_swap for sending (it re-estimates). Amount is a decimal string; set maxMode=true to sell the full balance (backend corrects amount).",
199
+ purpose: "Quote (may expire)",
200
+ movesFunds: false,
201
+ inputSchema: {
202
+ wallet: z.string().optional(),
203
+ from: swapAssetInputSchema,
204
+ to: swapAssetInputSchema,
205
+ amount: z
206
+ .string()
207
+ .optional()
208
+ .describe("Sell amount as decimal string. Required unless maxMode."),
209
+ maxMode: z.boolean().optional(),
210
+ },
211
+ },
212
+ {
213
+ name: "execute_swap",
214
+ title: "Execute swap",
215
+ description: "Execute a swap: fresh estimate → create → local sign → execute. Does NOT use the transfer relay. Irreversible once submitted — no second confirmation. Returns operationId and txHash; poll with get_swap_status.",
216
+ purpose: "Fresh quote → sign → swap",
217
+ movesFunds: true,
218
+ inputSchema: {
219
+ wallet: z.string().optional(),
220
+ from: swapAssetInputSchema,
221
+ to: swapAssetInputSchema,
222
+ amount: z
223
+ .string()
224
+ .optional()
225
+ .describe("Sell amount as decimal string. Required unless maxMode."),
226
+ maxMode: z.boolean().optional(),
227
+ },
228
+ },
229
+ {
230
+ name: "get_swap_status",
231
+ title: "Get swap status",
232
+ description: "Poll swap order/operation status by operationId.",
233
+ purpose: "Poll a swap",
234
+ movesFunds: false,
235
+ inputSchema: {
236
+ wallet: z.string().optional(),
237
+ operationId: z.string(),
238
+ },
239
+ },
240
+ ];
241
+ const BY_NAME = new Map(TOOL_DEFINITIONS.map((t) => [t.name, t]));
242
+ export function toolDefinition(name) {
243
+ const def = BY_NAME.get(name);
244
+ if (!def)
245
+ throw new Error(`Unknown tool "${name}".`);
246
+ return def;
247
+ }
248
+ /** Fields passed to `server.registerTool` (docs-only keys stripped). */
249
+ export function mcpToolConfig(def) {
250
+ return {
251
+ title: def.title,
252
+ description: def.description,
253
+ inputSchema: def.inputSchema,
254
+ };
255
+ }
256
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,7 @@
1
1
  /**
2
2
  * Shared MCP tool helpers: response shaping, logging wrapper, wallet session.
3
3
  */
4
- import { z } from "zod";
5
- import { type NetworkId } from "../config.js";
6
4
  import type { WalletEntry } from "../keystore/types.js";
7
- export declare const networkEnum: z.ZodEnum<[NetworkId, ...NetworkId[]]>;
8
5
  export type ImageContent = {
9
6
  type: "image";
10
7
  data: string;