@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/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @ironwallet/mcp-server
2
2
 
3
- Local [MCP](https://modelcontextprotocol.io) server for **Ironwallet** (`ironwallet-mcp` bin).
3
+ Local [MCP](https://modelcontextprotocol.io) server for **IronWallet** (`ironwallet-mcp` bin).
4
4
 
5
- The Ironwallet MCP server gives AI agents secure access to a **non-custodial** wallet. Seed phrases stay encrypted on the host and never leave this machine — they never pass through the agent. Agents can retrieve balances, sign locally, transfer tokens, and swap across 10+ networks.
5
+ The IronWallet MCP server gives AI agents secure access to a **non-custodial** wallet. Seed phrases stay encrypted on the host and never leave this machine — they never pass through the agent. Agents can retrieve balances, sign locally, transfer tokens, and swap across 10+ networks.
6
6
 
7
- Seed-compatible with the [Ironwallet](https://ironwallet.io) app.
7
+ Seed-compatible with the [IronWallet](https://ironwallet.io) app.
8
8
 
9
9
  There is no per-transaction confirmation UI.
10
10
 
@@ -47,7 +47,7 @@ The plugin install on [ironwallet.io/ai](https://ironwallet.io/ai) wires this up
47
47
  MCP client → ironwallet-mcp (stdio)
48
48
  ├── encrypted keystore on disk
49
49
  ├── signs on this machine
50
- └── HTTPS to Ironwallet backends
50
+ └── HTTPS to IronWallet backends
51
51
  ```
52
52
 
53
53
  The mnemonic never appears in tool inputs/outputs, logs meant for the agent, or requests to backends / the LLM / the MCP client’s cloud.
@@ -61,19 +61,22 @@ The mnemonic never appears in tool inputs/outputs, logs meant for the agent, or
61
61
  | **Networks** | Ethereum, BSC, Polygon, Base, Arbitrum, Optimism, Avalanche, Tron, Bitcoin, Litecoin, Dogecoin, Solana, XRP, TON |
62
62
  | **Wallets** | Create, import, list, deposit QR, and back up (local browser for secrets) |
63
63
  | **Balances** | Native coins and tokens |
64
- | **Transfers** | Fee estimate and send through Ironwallet’s transfer relay |
65
- | **Swaps** | Quotes and execution through Ironwallet **Swap Proxy** |
66
- | **Policy** | Optional per-wallet limits (`readOnly`, `maxPerTx`, transfer recipient allow-list). Applies to `send_transfer` and `execute_swap`. |
64
+ | **Transfers** | Fee estimate and send through IronWallet’s transfer relay |
65
+ | **Swaps** | Quotes and execution through IronWallet |
66
+ | **Policy** | Optional per-wallet limits (`readOnly`, `maxPerTxUsd`, transfer recipient allow-list) set via `set_wallet_policy`. Applies to `send_transfer` and `execute_swap`. |
67
67
 
68
68
  ---
69
69
 
70
70
  ## Tools
71
71
 
72
+ <!-- tools-table -->
72
73
  | Tool | Purpose | Moves funds? |
73
74
  |------|---------|:------------:|
74
75
  | `list_wallets` | Names, addresses, and `policy` | no |
76
+ | `accept_mcp_consent` | Record chat acceptance of the MCP disclaimer | no |
75
77
  | `create_wallets` | New wallets; returns a browser `backup_url` | no |
76
78
  | `open_wallet_manager` | Local browser UI to import / create / back up | no |
79
+ | `set_wallet_policy` | Replace per-wallet limits (`readOnly`, `maxPerTxUsd`, allow-list) | no |
77
80
  | `get_deposit_qr` | PNG QR (try chat; else local `qr_url`) | no |
78
81
  | `get_balance` | Native or token balance | no |
79
82
  | `estimate_transfer` | Fee estimate, no broadcast | no |
@@ -84,6 +87,7 @@ The mnemonic never appears in tool inputs/outputs, logs meant for the agent, or
84
87
  | `estimate_swap` | Quote (may expire) | no |
85
88
  | `execute_swap` | Fresh quote → sign → swap | **yes** |
86
89
  | `get_swap_status` | Poll a swap | no |
90
+ <!-- /tools-table -->
87
91
 
88
92
  No tool accepts or returns a seed. Import and backup only in the local browser (`open_wallet_manager` / `backup_url`).
89
93
 
@@ -107,7 +111,7 @@ The browser page binds to `127.0.0.1` under an unguessable path and shuts down a
107
111
 
108
112
  ### Swaps
109
113
 
110
- Swaps use **Swap Proxy**, not the transfer relay.
114
+ Swaps are a separate flow from transfers.
111
115
 
112
116
  1. `list_swap_networks`
113
117
  2. `list_swap_assets` (`direction=from`, then `direction=to` with the chosen sell asset)
@@ -123,13 +127,13 @@ Swaps use **Swap Proxy**, not the transfer relay.
123
127
  **Operational notes**
124
128
 
125
129
  - Quotes expire. Prefer `execute_swap` (fresh quote). If execute times out, **poll status** before retrying — do not blindly re-run execute.
126
- - Wallet policy: `readOnly` blocks sends and swaps. `maxPerTx` applies to the transfer amount or the corrected swap sell amount. A transfer recipient allow-list also blocks swaps (the swap router is not a whitelisted destination).
130
+ - Wallet policy: `readOnly` blocks sends and swaps. `maxPerTxUsd` values the transfer amount (or the corrected swap sell amount) in USD at operation time via IronWallet backend rates; when no rate is available the operation is rejected (fail closed). The recipient allow-list applies to `send_transfer`. `set_wallet_policy` replaces the whole policy — read `list_wallets.policy` first.
127
131
 
128
132
  ---
129
133
 
130
134
  ## Configuration
131
135
 
132
- Nothing to paste into MCP config for normal use. On first launch the server writes a relay API key, keystore wrapping secret, and device id under `~/.ironwallet-mcp/` (`keystore-passphrase`, `relay-api-key`, `device-id`, mode `0600`). Set the env vars only to override.
136
+ Nothing to paste into MCP config for normal use. On first launch the server writes a relay API key, keystore wrapping secret, and device id under `~/.ironwallet-mcp/` (`keystore-passphrase`, `relay-api-key`, `device-id`; owner-only POSIX `0600` or NTFS ACL on Windows). Set the env vars only to override.
133
137
 
134
138
  The user-facing backup is the **recovery phrase** in the wallet manager, not those files.
135
139
 
@@ -140,6 +144,8 @@ The user-facing backup is the **recovery phrase** in the wallet manager, not tho
140
144
  | `IW_RELAY_API_KEY` | generated UUID | Override `x-api-key` |
141
145
  | `IW_DEVICE_ID` | generated UUID | Override `X-Device-Id` (stable per keystore directory) |
142
146
  | `IW_KEYSTORE_DIR` | `~/.ironwallet-mcp` | Keystore directory |
147
+ | `IW_RATES_API_URL` | baked profile | Rates backend for `maxPerTxUsd` valuation. Unset in the profile → USD limits reject (fail closed) |
148
+ | `IW_STATIC_RESOURCES_URL` | baked profile | Static asset catalogs (token → rates id) |
143
149
  | `IW_HTTP_TIMEOUT_MS` | `15000` | General HTTP timeout (1s–120s) |
144
150
  | `IW_HTTP_FORWARD_TIMEOUT_MS` | `60000` | Longer timeout for broadcast-style calls. A client timeout does not always mean the operation failed — check status |
145
151
  | `IW_HTTP_RETRIES` | `2` | Retries for safe/idempotent calls; broadcasts are not auto-retried |
@@ -153,7 +159,7 @@ The user-facing backup is the **recovery phrase** in the wallet manager, not tho
153
159
  ## Security
154
160
 
155
161
  - Seeds are encrypted at rest. They never appear in tool results, agent chat, or backend requests.
156
- - The agent **can move funds without asking again**. Optional wallet policy (`readOnly`, `maxPerTx`, transfer recipient allow-list) is off by default and applies to both `send_transfer` and `execute_swap`.
162
+ - The agent **can move funds without asking again**. Optional wallet policy (`readOnly`, `maxPerTxUsd`, transfer recipient allow-list — set via `set_wallet_policy`) is off by default and applies to both `send_transfer` and `execute_swap`.
157
163
  - Anyone with the keystore **and** the wrapping secret controls the funds. A leaked seed cannot be revoked.
158
164
  - Timeout is not always failure: poll status before retrying a send or swap.
159
165
  - Desktop / stdio only. A phone or remote agent would need a design where signing stays on a trusted device.
@@ -0,0 +1,62 @@
1
+ /**
2
+ * USD rates for policy limits (`maxPerTxUsd`).
3
+ *
4
+ * Same backend the mobile app uses:
5
+ * GET {ratesApiUrl}/api/v1/rate/rates?Ids=<externalId,...>&Currencies=usd
6
+ * `Ids` are catalog `externalId`s (CoinGecko-style: "ethereum", "tether"), not
7
+ * symbols or contracts. Native coins map statically; tokens are resolved via the
8
+ * public static asset catalog
9
+ * GET {staticResourcesUrl}/assets/main/blockchains/<net>/assets.mainnet.json
10
+ * matched by contract address (symbol as fallback).
11
+ *
12
+ * Callers must fail closed: `undefined` means "no rate", never "skip the check".
13
+ */
14
+ import type { NetworkId } from "../networks.js";
15
+ /** Verified against the mobile app's asset catalogs (init_assets_data). */
16
+ export declare const NATIVE_EXTERNAL_ID: Record<NetworkId, string>;
17
+ export interface CatalogAsset {
18
+ symbol?: string;
19
+ address?: string;
20
+ externalId?: string;
21
+ }
22
+ export interface AssetCatalogDocument {
23
+ assets?: CatalogAsset[];
24
+ }
25
+ /** Hex (EVM) contracts compare case-insensitively; base58 chains compare exactly. */
26
+ export declare function sameTokenAddress(a: string, b: string): boolean;
27
+ /** Find a token's externalId in a static catalog document. Pure, for tests. */
28
+ export declare function findExternalIdInCatalog(doc: AssetCatalogDocument, query: {
29
+ symbol?: string;
30
+ tokenAddress?: string;
31
+ }): string | undefined;
32
+ /** Response shape of GET /api/v1/rate/rates (keys are externalIds). */
33
+ export type RatesResponse = Record<string, Record<string, {
34
+ value?: number;
35
+ dailyChange?: number;
36
+ isExpired?: boolean;
37
+ }> | null>;
38
+ /** Extract a positive USD rate from the backend response. Pure, for tests. */
39
+ export declare function parseUsdRate(response: RatesResponse, externalId: string): {
40
+ value: number;
41
+ isExpired: boolean;
42
+ } | undefined;
43
+ /** Test hook. */
44
+ export declare function clearRatesCaches(): void;
45
+ /**
46
+ * Resolve the rates id for an asset. Native coins come from the static map;
47
+ * tokens are looked up in the network's asset catalog by contract address.
48
+ */
49
+ export declare function resolveExternalId(asset: {
50
+ network: NetworkId;
51
+ symbol?: string;
52
+ tokenAddress?: string;
53
+ }, correlationId?: string): Promise<string | undefined>;
54
+ /**
55
+ * USD price for one asset unit, or `undefined` when the asset or its rate is
56
+ * unknown / the backend is unreachable. Cached for ~60s per externalId.
57
+ */
58
+ export declare function getUsdRate(asset: {
59
+ network: NetworkId;
60
+ symbol?: string;
61
+ tokenAddress?: string;
62
+ }, correlationId?: string): Promise<number | undefined>;
@@ -0,0 +1,198 @@
1
+ /**
2
+ * USD rates for policy limits (`maxPerTxUsd`).
3
+ *
4
+ * Same backend the mobile app uses:
5
+ * GET {ratesApiUrl}/api/v1/rate/rates?Ids=<externalId,...>&Currencies=usd
6
+ * `Ids` are catalog `externalId`s (CoinGecko-style: "ethereum", "tether"), not
7
+ * symbols or contracts. Native coins map statically; tokens are resolved via the
8
+ * public static asset catalog
9
+ * GET {staticResourcesUrl}/assets/main/blockchains/<net>/assets.mainnet.json
10
+ * matched by contract address (symbol as fallback).
11
+ *
12
+ * Callers must fail closed: `undefined` means "no rate", never "skip the check".
13
+ */
14
+ import { getConfig } from "../config.js";
15
+ import { logInfo, logWarn } from "../log.js";
16
+ import { httpJson } from "./http.js";
17
+ /** Verified against the mobile app's asset catalogs (init_assets_data). */
18
+ export const NATIVE_EXTERNAL_ID = {
19
+ ethereum: "ethereum",
20
+ bsc: "binancecoin",
21
+ polygon: "polygon-ecosystem-token",
22
+ base: "ethereum",
23
+ arbitrum: "ethereum",
24
+ optimism: "ethereum",
25
+ avalanche: "avalanche-2",
26
+ tron: "tron",
27
+ bitcoin: "bitcoin",
28
+ litecoin: "litecoin",
29
+ doge: "dogecoin",
30
+ solana: "solana",
31
+ ton: "the-open-network",
32
+ xrp: "ripple",
33
+ };
34
+ /** Networks with a token catalog on static resources (litecoin/doge are native-only). */
35
+ const CATALOG_NETWORKS = [
36
+ "ethereum",
37
+ "bsc",
38
+ "polygon",
39
+ "base",
40
+ "arbitrum",
41
+ "optimism",
42
+ "avalanche",
43
+ "tron",
44
+ "bitcoin",
45
+ "solana",
46
+ "ton",
47
+ "xrp",
48
+ ];
49
+ /** Hex (EVM) contracts compare case-insensitively; base58 chains compare exactly. */
50
+ export function sameTokenAddress(a, b) {
51
+ const ta = a.trim();
52
+ const tb = b.trim();
53
+ if (ta === tb)
54
+ return true;
55
+ if (ta.startsWith("0x") && tb.startsWith("0x")) {
56
+ return ta.toLowerCase() === tb.toLowerCase();
57
+ }
58
+ return false;
59
+ }
60
+ /** Find a token's externalId in a static catalog document. Pure, for tests. */
61
+ export function findExternalIdInCatalog(doc, query) {
62
+ const assets = doc.assets ?? [];
63
+ if (query.tokenAddress) {
64
+ const byAddress = assets.find((a) => a.address && sameTokenAddress(a.address, query.tokenAddress));
65
+ if (byAddress?.externalId)
66
+ return byAddress.externalId;
67
+ }
68
+ if (query.symbol) {
69
+ const want = query.symbol.trim().toLowerCase();
70
+ const bySymbol = assets.find((a) => !a.address && a.symbol?.trim().toLowerCase() === want);
71
+ if (bySymbol?.externalId)
72
+ return bySymbol.externalId;
73
+ }
74
+ return undefined;
75
+ }
76
+ /** Extract a positive USD rate from the backend response. Pure, for tests. */
77
+ export function parseUsdRate(response, externalId) {
78
+ const perCurrency = response[externalId];
79
+ if (!perCurrency)
80
+ return undefined;
81
+ const usdKey = Object.keys(perCurrency).find((k) => k.toLowerCase() === "usd");
82
+ if (!usdKey)
83
+ return undefined;
84
+ const rate = perCurrency[usdKey];
85
+ if (!rate || typeof rate.value !== "number" || !(rate.value > 0))
86
+ return undefined;
87
+ return { value: rate.value, isExpired: rate.isExpired === true };
88
+ }
89
+ const CATALOG_TTL_MS = 6 * 60 * 60 * 1000;
90
+ const RATE_TTL_MS = 60 * 1000;
91
+ /**
92
+ * Keep the policy check snappy: a send/swap should not hang for minutes when
93
+ * the rates backend is down — it will be rejected (fail closed) anyway.
94
+ */
95
+ const FETCH_OPTS = { timeoutMs: 10000, retries: 1 };
96
+ const catalogCache = new Map();
97
+ const rateCache = new Map();
98
+ /** Test hook. */
99
+ export function clearRatesCaches() {
100
+ catalogCache.clear();
101
+ rateCache.clear();
102
+ }
103
+ async function fetchCatalog(network, correlationId) {
104
+ const cached = catalogCache.get(network);
105
+ if (cached && Date.now() - cached.at < CATALOG_TTL_MS)
106
+ return cached.doc;
107
+ const cfg = getConfig();
108
+ if (!cfg.staticResourcesUrl) {
109
+ logWarn("rates.catalog.no_url", { correlationId, network });
110
+ return undefined;
111
+ }
112
+ const url = `${cfg.staticResourcesUrl}/assets/main/blockchains/${network}/assets.mainnet.json`;
113
+ try {
114
+ const doc = await httpJson(url, { method: "GET" }, { correlationId, label: "rates.catalog", ...FETCH_OPTS });
115
+ catalogCache.set(network, { at: Date.now(), doc });
116
+ logInfo("rates.catalog.ok", {
117
+ correlationId,
118
+ network,
119
+ assets: doc.assets?.length ?? 0,
120
+ });
121
+ return doc;
122
+ }
123
+ catch (e) {
124
+ logWarn("rates.catalog.fail", {
125
+ correlationId,
126
+ network,
127
+ error: e instanceof Error ? e.message : String(e),
128
+ });
129
+ return undefined;
130
+ }
131
+ }
132
+ /**
133
+ * Resolve the rates id for an asset. Native coins come from the static map;
134
+ * tokens are looked up in the network's asset catalog by contract address.
135
+ */
136
+ export async function resolveExternalId(asset, correlationId) {
137
+ if (!asset.tokenAddress)
138
+ return NATIVE_EXTERNAL_ID[asset.network];
139
+ if (!CATALOG_NETWORKS.includes(asset.network))
140
+ return undefined;
141
+ const doc = await fetchCatalog(asset.network, correlationId);
142
+ if (!doc)
143
+ return undefined;
144
+ return findExternalIdInCatalog(doc, {
145
+ symbol: asset.symbol,
146
+ tokenAddress: asset.tokenAddress,
147
+ });
148
+ }
149
+ /**
150
+ * USD price for one asset unit, or `undefined` when the asset or its rate is
151
+ * unknown / the backend is unreachable. Cached for ~60s per externalId.
152
+ */
153
+ export async function getUsdRate(asset, correlationId) {
154
+ const externalId = await resolveExternalId(asset, correlationId);
155
+ if (!externalId) {
156
+ logWarn("rates.usd.no_external_id", {
157
+ correlationId,
158
+ network: asset.network,
159
+ symbol: asset.symbol,
160
+ tokenAddress: asset.tokenAddress,
161
+ });
162
+ return undefined;
163
+ }
164
+ const cached = rateCache.get(externalId);
165
+ if (cached && Date.now() - cached.at < RATE_TTL_MS)
166
+ return cached.value;
167
+ const cfg = getConfig();
168
+ if (!cfg.ratesApiUrl) {
169
+ logWarn("rates.usd.no_url", { correlationId, externalId });
170
+ return undefined;
171
+ }
172
+ const url = `${cfg.ratesApiUrl}/api/v1/rate/rates` +
173
+ `?Ids=${encodeURIComponent(externalId)}&Currencies=usd`;
174
+ let response;
175
+ try {
176
+ response = await httpJson(url, { method: "GET" }, { correlationId, label: "rates.usd", ...FETCH_OPTS });
177
+ }
178
+ catch (e) {
179
+ logWarn("rates.usd.fetch_fail", {
180
+ correlationId,
181
+ externalId,
182
+ error: e instanceof Error ? e.message : String(e),
183
+ });
184
+ return undefined;
185
+ }
186
+ const rate = parseUsdRate(response ?? {}, externalId);
187
+ if (!rate) {
188
+ logWarn("rates.usd.missing", { correlationId, externalId });
189
+ return undefined;
190
+ }
191
+ if (rate.isExpired) {
192
+ logWarn("rates.usd.expired", { correlationId, externalId, value: rate.value });
193
+ }
194
+ rateCache.set(externalId, { at: Date.now(), value: rate.value });
195
+ logInfo("rates.usd.ok", { correlationId, externalId, value: rate.value });
196
+ return rate.value;
197
+ }
198
+ //# sourceMappingURL=rates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rates.js","sourceRoot":"","sources":["../../src/api/rates.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Swap Proxy (SWP) HTTP client — matches mobile SwapProxyApiClient:
2
+ * Swap HTTP client — matches the mobile client:
3
3
  * /swp/refs/* discovery
4
4
  * /swp/exchange/* estimate → create → execute → status
5
5
  *
package/dist/api/swap.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Swap Proxy (SWP) HTTP client — matches mobile SwapProxyApiClient:
2
+ * Swap HTTP client — matches the mobile client:
3
3
  * /swp/refs/* discovery
4
4
  * /swp/exchange/* estimate → create → execute → status
5
5
  *
package/dist/config.d.ts CHANGED
@@ -4,15 +4,11 @@
4
4
  * generated on first launch. There is no runtime IW_ENV switch — each build
5
5
  * embeds one profile via the repo-root `npm run bake`.
6
6
  */
7
+ import { type NetworkId } from "./networks.js";
7
8
  /** `package.json` version of this package (works from `src/` and compiled `dist/`). */
8
9
  export declare function packageVersion(): string;
9
- /** Canonical network identifiers used across the server. */
10
- export type NetworkId = "ethereum" | "bsc" | "polygon" | "base" | "arbitrum" | "optimism" | "avalanche" | "tron" | "bitcoin" | "litecoin" | "doge" | "solana" | "ton" | "xrp";
11
- /** Networks that share the secp256k1 EVM key and signing scheme. */
12
- export declare const EVM_NETWORKS: NetworkId[];
13
- /** Non-EVM chains, each with its own curve / address scheme / node API. */
14
- export declare const NON_EVM_NETWORKS: NetworkId[];
15
- export declare const ALL_NETWORKS: NetworkId[];
10
+ export type { NetworkId } from "./networks.js";
11
+ export { ALL_NETWORKS, EVM_NETWORKS, NON_EVM_NETWORKS } from "./networks.js";
16
12
  /**
17
13
  * Networks advertised during challenge login. Kept to the proven EVM+Tron set:
18
14
  * the backend authenticates against these public keys and the flow is verified
@@ -22,7 +18,7 @@ export declare const ALL_NETWORKS: NetworkId[];
22
18
  export declare const AUTH_NETWORKS: NetworkId[];
23
19
  /**
24
20
  * Networks whose transfer signing is implemented (send is allowed). All of these
25
- * go through the Ironwallet relay forward flow (estimate → sign → forward),
21
+ * go through the IronWallet relay forward flow (estimate → sign → forward),
26
22
  * including TON (IR-673 / mobile RelayV2).
27
23
  */
28
24
  export declare const SIGNABLE_NETWORKS: NetworkId[];
@@ -40,19 +36,25 @@ export declare function relaySegment(network: NetworkId): string;
40
36
  export interface Config {
41
37
  authUrl: string;
42
38
  relayUrl: string;
43
- /** Swap Proxy host (`/swp/exchange/*`, `/swp/refs/*`). */
39
+ /** Swap API host (`/swp/exchange/*`, `/swp/refs/*`). */
44
40
  swapProxyUrl: string;
41
+ /** Rates API host (`/api/v1/rate/rates`). Used only for USD policy limits. */
42
+ ratesApiUrl: string;
43
+ /** Static resources base with asset catalogs (`/assets/main/blockchains/...`). */
44
+ staticResourcesUrl: string;
45
45
  /** Optional relay API key (x-api-key). Empty string means header is omitted. */
46
46
  relayApiKey: string;
47
47
  /** App version string sent as x-iwt-cli / X-App-Version. */
48
48
  appVersion: string;
49
49
  /** Device id sent as X-Device-Id. UUID file under the keystore dir unless overridden. */
50
50
  deviceId: string;
51
+ /** Machine fingerprint sent as X-Device-Fingerprint. OS install id + platform, or device-id if that id is missing. */
52
+ deviceFingerprint: string;
51
53
  /** X-Device-Locale value, format: TimeZone=..;Language=..;Region=..; */
52
54
  deviceLocale: string;
53
55
  /**
54
- * JSON for `X-Device-Info`. Swap Proxy requires `systemName`
55
- * (e.g. `{"systemName":"iOS","systemVersion":"17.0","model":"iPhone"}`).
56
+ * JSON for `X-Device-Info`. The swap API keys routing off `systemName`
57
+ * (`Web` here — this is a desktop MCP, not a phone).
56
58
  */
57
59
  deviceInfo: string;
58
60
  /** Directory holding the encrypted keystore. */
@@ -88,8 +90,10 @@ export interface Config {
88
90
  /** When true, `send_transfer` and `execute_swap` are rejected immediately. */
89
91
  readOnly: boolean;
90
92
  }
93
+ /** Host-honest Web payload. Do not pretend to be iOS/Android. */
94
+ export declare function defaultDeviceInfo(): string;
91
95
  export declare function getConfig(): Config;
92
96
  /** Reject send/swap when `IW_READ_ONLY` is set. */
93
97
  export declare function assertServerWritable(action: "send" | "swap"): void;
94
- /** Common device-mimicking headers sent to auth, relay, and Swap Proxy. */
98
+ /** Device headers sent to auth, relay, and swap APIs. */
95
99
  export declare function commonHeaders(cfg: Config): Record<string, string>;
package/dist/config.js CHANGED
@@ -5,9 +5,12 @@
5
5
  * embeds one profile via the repo-root `npm run bake`.
6
6
  */
7
7
  import { readFileSync } from "node:fs";
8
+ import { arch, release, type as osType } from "node:os";
8
9
  import { dirname, join } from "node:path";
9
10
  import { fileURLToPath } from "node:url";
10
11
  import { BAKED_ENV } from "./generated/env-config.js";
12
+ import { ALL_NETWORKS, EVM_NETWORKS } from "./networks.js";
13
+ import { resolveDeviceFingerprint } from "./device-fingerprint.js";
11
14
  import { resolveDeviceId, resolveKeystoreDir, resolveKeystorePassphrase, resolveRelayApiKey, } from "./local-secrets.js";
12
15
  /** `package.json` version of this package (works from `src/` and compiled `dist/`). */
13
16
  export function packageVersion() {
@@ -20,27 +23,7 @@ export function packageVersion() {
20
23
  return "0.0.0";
21
24
  }
22
25
  }
23
- /** Networks that share the secp256k1 EVM key and signing scheme. */
24
- export const EVM_NETWORKS = [
25
- "ethereum",
26
- "bsc",
27
- "polygon",
28
- "base",
29
- "arbitrum",
30
- "optimism",
31
- "avalanche",
32
- ];
33
- /** Non-EVM chains, each with its own curve / address scheme / node API. */
34
- export const NON_EVM_NETWORKS = [
35
- "tron",
36
- "bitcoin",
37
- "litecoin",
38
- "doge",
39
- "solana",
40
- "ton",
41
- "xrp",
42
- ];
43
- export const ALL_NETWORKS = [...EVM_NETWORKS, ...NON_EVM_NETWORKS];
26
+ export { ALL_NETWORKS, EVM_NETWORKS, NON_EVM_NETWORKS } from "./networks.js";
44
27
  /**
45
28
  * Networks advertised during challenge login. Kept to the proven EVM+Tron set:
46
29
  * the backend authenticates against these public keys and the flow is verified
@@ -50,7 +33,7 @@ export const ALL_NETWORKS = [...EVM_NETWORKS, ...NON_EVM_NETWORKS];
50
33
  export const AUTH_NETWORKS = [...EVM_NETWORKS, "tron"];
51
34
  /**
52
35
  * Networks whose transfer signing is implemented (send is allowed). All of these
53
- * go through the Ironwallet relay forward flow (estimate → sign → forward),
36
+ * go through the IronWallet relay forward flow (estimate → sign → forward),
54
37
  * including TON (IR-673 / mobile RelayV2).
55
38
  */
56
39
  export const SIGNABLE_NETWORKS = [...ALL_NETWORKS];
@@ -106,6 +89,37 @@ function envBool(key, fallback) {
106
89
  return fallback;
107
90
  return !/^(0|false|off|no)$/i.test(v);
108
91
  }
92
+ /** Host-honest Web payload. Do not pretend to be iOS/Android. */
93
+ export function defaultDeviceInfo() {
94
+ return JSON.stringify({
95
+ systemName: "Web",
96
+ systemVersion: packageVersion(),
97
+ model: "ironwallet-mcp",
98
+ platform: process.platform,
99
+ arch: arch(),
100
+ os: osType(),
101
+ osRelease: release(),
102
+ });
103
+ }
104
+ function defaultDeviceLocale() {
105
+ let timeZone = "UTC";
106
+ let language = "en";
107
+ let region = "US";
108
+ try {
109
+ const opts = Intl.DateTimeFormat().resolvedOptions();
110
+ if (opts.timeZone)
111
+ timeZone = opts.timeZone;
112
+ const parts = (opts.locale ?? "").split(/[-_]/);
113
+ if (parts[0])
114
+ language = parts[0];
115
+ if (parts[1])
116
+ region = parts[1];
117
+ }
118
+ catch {
119
+ // keep UTC/en/US
120
+ }
121
+ return `TimeZone=${timeZone};Language=${language};Region=${region};`;
122
+ }
109
123
  /** Parse an integer env var, clamped to [min, max], falling back on invalid input. */
110
124
  function envInt(key, fallback, min, max) {
111
125
  const raw = process.env[key];
@@ -130,20 +144,22 @@ export function getConfig() {
130
144
  if (cached)
131
145
  return cached;
132
146
  resolveKeystorePassphrase();
147
+ const deviceId = resolveDeviceId();
133
148
  const profile = BAKED_ENV;
134
149
  cached = {
135
150
  authUrl: envOr("IW_AUTH_URL", profile.authUrl),
136
151
  relayUrl: envOr("IW_RELAY_URL", profile.relayUrl),
137
152
  swapProxyUrl: envOr("IW_SWAP_PROXY_URL", profile.swapProxyUrl),
153
+ // Hosts live only in the baked configurations profile (no fallbacks in
154
+ // code). Empty string means USD policy limits fail closed.
155
+ ratesApiUrl: envOr("IW_RATES_API_URL", profile.ratesApiUrl ?? ""),
156
+ staticResourcesUrl: envOr("IW_STATIC_RESOURCES_URL", profile.staticResourcesUrl ?? ""),
138
157
  relayApiKey: resolveRelayApiKey(),
139
158
  appVersion: envOr("IW_APP_VERSION", `ironwallet-mcp/${packageVersion()}`),
140
- deviceId: resolveDeviceId(),
141
- deviceLocale: envOr("IW_DEVICE_LOCALE", "TimeZone=UTC;Language=en;Region=US;"),
142
- deviceInfo: envOr("IW_DEVICE_INFO", JSON.stringify({
143
- systemName: "iOS",
144
- systemVersion: "17.0",
145
- model: "iPhone",
146
- })),
159
+ deviceId,
160
+ deviceFingerprint: resolveDeviceFingerprint(deviceId),
161
+ deviceLocale: envOr("IW_DEVICE_LOCALE", defaultDeviceLocale()),
162
+ deviceInfo: envOr("IW_DEVICE_INFO", defaultDeviceInfo()),
147
163
  keystoreDir: resolveKeystoreDir(),
148
164
  evmRpcUrls: resolveEvmRpcUrls(profile.evmRpcUrls),
149
165
  tronApiUrl: envOr("IW_TRON_API", profile.tronApiUrl),
@@ -171,15 +187,16 @@ export function assertServerWritable(action) {
171
187
  ? "Server is read-only (IW_READ_ONLY); swaps are disabled."
172
188
  : "Server is read-only (IW_READ_ONLY); sending is disabled.");
173
189
  }
174
- /** Common device-mimicking headers sent to auth, relay, and Swap Proxy. */
190
+ /** Device headers sent to auth, relay, and swap APIs. */
175
191
  export function commonHeaders(cfg) {
176
192
  const headers = {
177
193
  "x-iwt-cli": cfg.appVersion,
178
194
  "X-App-Version": cfg.appVersion,
179
195
  "X-Device-Id": cfg.deviceId,
196
+ "X-Device-Fingerprint": cfg.deviceFingerprint,
180
197
  // Backend validates the format: TimeZone=..;Language=..;Region=..;
181
198
  "X-Device-Locale": cfg.deviceLocale,
182
- // SWP validates UserData.XDeviceInfo — JSON with required `systemName`.
199
+ // Swap routing reads UserData.XDeviceInfo.systemName (`Web` for this client).
183
200
  "X-Device-Info": cfg.deviceInfo,
184
201
  "Content-Language": "en",
185
202
  };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Canonical MCP consent copy (English). Chat, create_wallets, and the local
3
+ * manager must show this text. Bump CONSENT_VERSION when the wording changes.
4
+ */
5
+ export declare const CONSENT_VERSION = "v1";
6
+ export declare const CONSENT_TITLE = "Before connecting an AI agent to your wallet";
7
+ export declare const CONSENT_LEAD = "Connecting MCP lets the AI agent view balances, transfer assets, and swap on behalf of this wallet.";
8
+ export declare const CONSENT_BULLETS: readonly ["By default the agent can send funds and swap without extra confirmation on each operation.", "Use a dedicated wallet with a small balance, not your main or savings wallet.", "The recovery phrase stays encrypted on this device. Loss or compromise means permanent loss of access to the funds.", "IronWallet is not responsible for the AI agent's actions, misconfiguration, or loss of funds from using this feature.", "You can ask the agent to set limits in chat (read-only, a per-transaction USD limit, a transfer recipient allow-list)."];
9
+ export declare const CONSENT_CHECKBOX = "I understand the risks and want to continue";
10
+ export declare const CONSENT_CHAT_INSTRUCTION = "Show this text in full in chat. Do not shorten it. After the user explicitly confirms, call accept_mcp_consent with accepted=true, or open the wallet manager so they can accept there.";
11
+ export declare function consentDocument(): {
12
+ version: string;
13
+ title: string;
14
+ lead: string;
15
+ bullets: readonly string[];
16
+ checkbox: string;
17
+ instruction: string;
18
+ };