@ironwallet/mcp-server 1.0.2 → 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.
- package/README.md +7 -3
- package/dist/api/rates.d.ts +62 -0
- package/dist/api/rates.js +198 -0
- package/dist/api/rates.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/consent/copy.d.ts +18 -0
- package/dist/consent/copy.js +27 -0
- package/dist/consent/copy.js.map +1 -0
- package/dist/consent/store.d.ts +23 -0
- package/dist/consent/store.js +63 -0
- package/dist/consent/store.js.map +1 -0
- package/dist/generated/env-config.js +3 -1
- package/dist/generated/env-config.js.map +1 -1
- package/dist/generated/env-profile.d.ts +4 -0
- package/dist/keystore/types.d.ts +8 -3
- package/dist/policy.d.ts +33 -3
- package/dist/policy.js +121 -32
- package/dist/policy.js.map +1 -1
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/definitions.js +38 -1
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/swap.js +5 -2
- package/dist/tools/swap.js.map +1 -1
- package/dist/tools/transfer.js +8 -1
- package/dist/tools/transfer.js.map +1 -1
- package/dist/tools/wallets.js +106 -15
- package/dist/tools/wallets.js.map +1 -1
- package/dist/web/manager.js +61 -0
- package/dist/web/manager.js.map +1 -1
- package/package.json +2 -2
- package/tools.json +61 -2
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ The mnemonic never appears in tool inputs/outputs, logs meant for the agent, or
|
|
|
63
63
|
| **Balances** | Native coins and tokens |
|
|
64
64
|
| **Transfers** | Fee estimate and send through IronWallet’s transfer relay |
|
|
65
65
|
| **Swaps** | Quotes and execution through IronWallet |
|
|
66
|
-
| **Policy** | Optional per-wallet limits (`readOnly`, `
|
|
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
|
|
|
@@ -73,8 +73,10 @@ The mnemonic never appears in tool inputs/outputs, logs meant for the agent, or
|
|
|
73
73
|
| Tool | Purpose | Moves funds? |
|
|
74
74
|
|------|---------|:------------:|
|
|
75
75
|
| `list_wallets` | Names, addresses, and `policy` | no |
|
|
76
|
+
| `accept_mcp_consent` | Record chat acceptance of the MCP disclaimer | no |
|
|
76
77
|
| `create_wallets` | New wallets; returns a browser `backup_url` | no |
|
|
77
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 |
|
|
78
80
|
| `get_deposit_qr` | PNG QR (try chat; else local `qr_url`) | no |
|
|
79
81
|
| `get_balance` | Native or token balance | no |
|
|
80
82
|
| `estimate_transfer` | Fee estimate, no broadcast | no |
|
|
@@ -125,7 +127,7 @@ Swaps are a separate flow from transfers.
|
|
|
125
127
|
**Operational notes**
|
|
126
128
|
|
|
127
129
|
- Quotes expire. Prefer `execute_swap` (fresh quote). If execute times out, **poll status** before retrying — do not blindly re-run execute.
|
|
128
|
-
- Wallet policy: `readOnly` blocks sends and swaps. `
|
|
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.
|
|
129
131
|
|
|
130
132
|
---
|
|
131
133
|
|
|
@@ -142,6 +144,8 @@ The user-facing backup is the **recovery phrase** in the wallet manager, not tho
|
|
|
142
144
|
| `IW_RELAY_API_KEY` | generated UUID | Override `x-api-key` |
|
|
143
145
|
| `IW_DEVICE_ID` | generated UUID | Override `X-Device-Id` (stable per keystore directory) |
|
|
144
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) |
|
|
145
149
|
| `IW_HTTP_TIMEOUT_MS` | `15000` | General HTTP timeout (1s–120s) |
|
|
146
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 |
|
|
147
151
|
| `IW_HTTP_RETRIES` | `2` | Retries for safe/idempotent calls; broadcasts are not auto-retried |
|
|
@@ -155,7 +159,7 @@ The user-facing backup is the **recovery phrase** in the wallet manager, not tho
|
|
|
155
159
|
## Security
|
|
156
160
|
|
|
157
161
|
- Seeds are encrypted at rest. They never appear in tool results, agent chat, or backend requests.
|
|
158
|
-
- The agent **can move funds without asking again**. Optional wallet policy (`readOnly`, `
|
|
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`.
|
|
159
163
|
- Anyone with the keystore **and** the wrapping secret controls the funds. A leaked seed cannot be revoked.
|
|
160
164
|
- Timeout is not always failure: poll status before retrying a send or swap.
|
|
161
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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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -38,6 +38,10 @@ export interface Config {
|
|
|
38
38
|
relayUrl: string;
|
|
39
39
|
/** Swap API host (`/swp/exchange/*`, `/swp/refs/*`). */
|
|
40
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;
|
|
41
45
|
/** Optional relay API key (x-api-key). Empty string means header is omitted. */
|
|
42
46
|
relayApiKey: string;
|
|
43
47
|
/** App version string sent as x-iwt-cli / X-App-Version. */
|
package/dist/config.js
CHANGED
|
@@ -150,6 +150,10 @@ export function getConfig() {
|
|
|
150
150
|
authUrl: envOr("IW_AUTH_URL", profile.authUrl),
|
|
151
151
|
relayUrl: envOr("IW_RELAY_URL", profile.relayUrl),
|
|
152
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 ?? ""),
|
|
153
157
|
relayApiKey: resolveRelayApiKey(),
|
|
154
158
|
appVersion: envOr("IW_APP_VERSION", `ironwallet-mcp/${packageVersion()}`),
|
|
155
159
|
deviceId,
|
package/dist/config.js.map
CHANGED
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
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 const CONSENT_VERSION = "v1";
|
|
6
|
+
export const CONSENT_TITLE = "Before connecting an AI agent to your wallet";
|
|
7
|
+
export const CONSENT_LEAD = "Connecting MCP lets the AI agent view balances, transfer assets, and swap on behalf of this wallet.";
|
|
8
|
+
export const CONSENT_BULLETS = [
|
|
9
|
+
"By default the agent can send funds and swap without extra confirmation on each operation.",
|
|
10
|
+
"Use a dedicated wallet with a small balance, not your main or savings wallet.",
|
|
11
|
+
"The recovery phrase stays encrypted on this device. Loss or compromise means permanent loss of access to the funds.",
|
|
12
|
+
"IronWallet is not responsible for the AI agent's actions, misconfiguration, or loss of funds from using this feature.",
|
|
13
|
+
"You can ask the agent to set limits in chat (read-only, a per-transaction USD limit, a transfer recipient allow-list).",
|
|
14
|
+
];
|
|
15
|
+
export const CONSENT_CHECKBOX = "I understand the risks and want to continue";
|
|
16
|
+
export 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.";
|
|
17
|
+
export function consentDocument() {
|
|
18
|
+
return {
|
|
19
|
+
version: CONSENT_VERSION,
|
|
20
|
+
title: CONSENT_TITLE,
|
|
21
|
+
lead: CONSENT_LEAD,
|
|
22
|
+
bullets: CONSENT_BULLETS,
|
|
23
|
+
checkbox: CONSENT_CHECKBOX,
|
|
24
|
+
instruction: CONSENT_CHAT_INSTRUCTION,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=copy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/consent/copy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAG,8CAA8C,CAAC;AAE5E,MAAM,CAAC,MAAM,YAAY,GACvB,qGAAqG,CAAC;AAExG,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,4FAA4F;IAC5F,+EAA+E;IAC/E,qHAAqH;IACrH,uHAAuH;IACvH,wHAAwH;CAChH,CAAC;AAEX,MAAM,CAAC,MAAM,gBAAgB,GAAG,6CAA6C,CAAC;AAE9E,MAAM,CAAC,MAAM,wBAAwB,GACnC,yLAAyL,CAAC;AAE5L,MAAM,UAAU,eAAe;IAQ7B,OAAO;QACL,OAAO,EAAE,eAAe;QACxB,KAAK,EAAE,aAAa;QACpB,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,eAAe;QACxB,QAAQ,EAAE,gBAAgB;QAC1B,WAAW,EAAE,wBAAwB;KACtC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable MCP consent next to the keystore. Written by accept_mcp_consent (chat)
|
|
3
|
+
* or the local manager. create / import stay blocked until the current version
|
|
4
|
+
* is accepted.
|
|
5
|
+
*/
|
|
6
|
+
import { consentDocument } from "./copy.js";
|
|
7
|
+
export declare const CONSENT_FILE = "mcp-consent.json";
|
|
8
|
+
export type ConsentChannel = "chat" | "manager";
|
|
9
|
+
export interface ConsentRecord {
|
|
10
|
+
version: string;
|
|
11
|
+
acceptedAt: string;
|
|
12
|
+
channel: ConsentChannel;
|
|
13
|
+
}
|
|
14
|
+
export declare function consentFilePath(dir?: string): string;
|
|
15
|
+
export declare function readConsent(dir?: string): ConsentRecord | undefined;
|
|
16
|
+
export declare function hasCurrentConsent(dir?: string): boolean;
|
|
17
|
+
export declare function recordConsent(channel: ConsentChannel, dir?: string): ConsentRecord;
|
|
18
|
+
/** Payload for agents when create/import is blocked. */
|
|
19
|
+
export declare function consentRequiredPayload(): {
|
|
20
|
+
needs_consent: true;
|
|
21
|
+
accept: "accept_mcp_consent";
|
|
22
|
+
consent: ReturnType<typeof consentDocument>;
|
|
23
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Durable MCP consent next to the keystore. Written by accept_mcp_consent (chat)
|
|
3
|
+
* or the local manager. create / import stay blocked until the current version
|
|
4
|
+
* is accepted.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
import { resolveKeystoreDir } from "../local-secrets.js";
|
|
9
|
+
import { restrictPrivateFile } from "../restrict-private-file.js";
|
|
10
|
+
import { CONSENT_VERSION, consentDocument } from "./copy.js";
|
|
11
|
+
export const CONSENT_FILE = "mcp-consent.json";
|
|
12
|
+
export function consentFilePath(dir = resolveKeystoreDir()) {
|
|
13
|
+
return join(dir, CONSENT_FILE);
|
|
14
|
+
}
|
|
15
|
+
export function readConsent(dir) {
|
|
16
|
+
const path = consentFilePath(dir);
|
|
17
|
+
if (!existsSync(path))
|
|
18
|
+
return undefined;
|
|
19
|
+
try {
|
|
20
|
+
const raw = JSON.parse(readFileSync(path, "utf8"));
|
|
21
|
+
if (typeof raw.version !== "string" || !raw.version.trim())
|
|
22
|
+
return undefined;
|
|
23
|
+
if (typeof raw.acceptedAt !== "string" || !raw.acceptedAt.trim())
|
|
24
|
+
return undefined;
|
|
25
|
+
if (raw.channel !== "chat" && raw.channel !== "manager")
|
|
26
|
+
return undefined;
|
|
27
|
+
return {
|
|
28
|
+
version: raw.version.trim(),
|
|
29
|
+
acceptedAt: raw.acceptedAt,
|
|
30
|
+
channel: raw.channel,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function hasCurrentConsent(dir) {
|
|
38
|
+
const record = readConsent(dir);
|
|
39
|
+
return record?.version === CONSENT_VERSION;
|
|
40
|
+
}
|
|
41
|
+
export function recordConsent(channel, dir) {
|
|
42
|
+
const root = dir ?? resolveKeystoreDir();
|
|
43
|
+
if (!existsSync(root))
|
|
44
|
+
mkdirSync(root, { recursive: true });
|
|
45
|
+
const record = {
|
|
46
|
+
version: CONSENT_VERSION,
|
|
47
|
+
acceptedAt: new Date().toISOString(),
|
|
48
|
+
channel,
|
|
49
|
+
};
|
|
50
|
+
const path = consentFilePath(root);
|
|
51
|
+
writeFileSync(path, `${JSON.stringify(record, null, 2)}\n`, { mode: 0o600 });
|
|
52
|
+
restrictPrivateFile(path);
|
|
53
|
+
return record;
|
|
54
|
+
}
|
|
55
|
+
/** Payload for agents when create/import is blocked. */
|
|
56
|
+
export function consentRequiredPayload() {
|
|
57
|
+
return {
|
|
58
|
+
needs_consent: true,
|
|
59
|
+
accept: "accept_mcp_consent",
|
|
60
|
+
consent: consentDocument(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/consent/store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,CAAC,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAU/C,MAAM,UAAU,eAAe,CAAC,MAAc,kBAAkB,EAAE;IAChE,OAAO,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAA2B,CAAC;QAC7E,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,SAAS,CAAC;QAC7E,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE;YAAE,OAAO,SAAS,CAAC;QACnF,IAAI,GAAG,CAAC,OAAO,KAAK,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC1E,OAAO;YACL,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE;YAC3B,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,MAAM,EAAE,OAAO,KAAK,eAAe,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAuB,EAAE,GAAY;IACjE,MAAM,IAAI,GAAG,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAkB;QAC5B,OAAO,EAAE,eAAe;QACxB,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,OAAO;KACR,CAAC;IACF,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACnC,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,sBAAsB;IAKpC,OAAO;QACL,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,oBAAoB;QAC5B,OAAO,EAAE,eAAe,EAAE;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -18,6 +18,8 @@ export const BAKED_ENV = {
|
|
|
18
18
|
"solanaRpcUrl": "https://api.mainnet-beta.solana.com",
|
|
19
19
|
"tonApiUrl": "https://toncenter.com/api/v2",
|
|
20
20
|
"xrpRpcUrl": "https://xrplcluster.com",
|
|
21
|
-
"bitcoinTestnet": false
|
|
21
|
+
"bitcoinTestnet": false,
|
|
22
|
+
"ratesApiUrl": "https://rates.iwio.app",
|
|
23
|
+
"staticResourcesUrl": "https://resources.iwio.app/Ironwallet"
|
|
22
24
|
};
|
|
23
25
|
//# sourceMappingURL=env-config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env-config.js","sourceRoot":"","sources":["../../src/generated/env-config.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,SAAS,GAAoB;IACxC,SAAS,EAAE,uBAAuB;IAClC,UAAU,EAAE,0BAA0B;IACtC,cAAc,EAAE,kBAAkB;IAClC,YAAY,EAAE;QACZ,UAAU,EAAE,qCAAqC;QACjD,KAAK,EAAE,gCAAgC;QACvC,SAAS,EAAE,wCAAwC;QACnD,MAAM,EAAE,iCAAiC;QACzC,UAAU,EAAE,yCAAyC;QACrD,UAAU,EAAE,qCAAqC;QACjD,WAAW,EAAE,8CAA8C;KAC5D;IACD,YAAY,EAAE,yBAAyB;IACvC,eAAe,EAAE,8BAA8B;IAC/C,gBAAgB,EAAE,+BAA+B;IACjD,YAAY,EAAE,0CAA0C;IACxD,cAAc,EAAE,qCAAqC;IACrD,WAAW,EAAE,8BAA8B;IAC3C,WAAW,EAAE,yBAAyB;IACtC,gBAAgB,EAAE,KAAK;
|
|
1
|
+
{"version":3,"file":"env-config.js","sourceRoot":"","sources":["../../src/generated/env-config.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,SAAS,GAAoB;IACxC,SAAS,EAAE,uBAAuB;IAClC,UAAU,EAAE,0BAA0B;IACtC,cAAc,EAAE,kBAAkB;IAClC,YAAY,EAAE;QACZ,UAAU,EAAE,qCAAqC;QACjD,KAAK,EAAE,gCAAgC;QACvC,SAAS,EAAE,wCAAwC;QACnD,MAAM,EAAE,iCAAiC;QACzC,UAAU,EAAE,yCAAyC;QACrD,UAAU,EAAE,qCAAqC;QACjD,WAAW,EAAE,8CAA8C;KAC5D;IACD,YAAY,EAAE,yBAAyB;IACvC,eAAe,EAAE,8BAA8B;IAC/C,gBAAgB,EAAE,+BAA+B;IACjD,YAAY,EAAE,0CAA0C;IACxD,cAAc,EAAE,qCAAqC;IACrD,WAAW,EAAE,8BAA8B;IAC3C,WAAW,EAAE,yBAAyB;IACtC,gBAAgB,EAAE,KAAK;IACvB,aAAa,EAAE,wBAAwB;IACvC,oBAAoB,EAAE,uCAAuC;CACrD,CAAC"}
|
|
@@ -3,6 +3,10 @@ export interface BakedEnvProfile {
|
|
|
3
3
|
authUrl: string;
|
|
4
4
|
relayUrl: string;
|
|
5
5
|
swapProxyUrl: string;
|
|
6
|
+
/** Rates API host (`/api/v1/rate/*`). Optional until configurations ships it. */
|
|
7
|
+
ratesApiUrl?: string;
|
|
8
|
+
/** Static resources base for asset catalogs (`/assets/main/blockchains/...`). */
|
|
9
|
+
staticResourcesUrl?: string;
|
|
6
10
|
evmRpcUrls: Record<string, string>;
|
|
7
11
|
tronApiUrl: string;
|
|
8
12
|
bitcoinApiUrl: string;
|
package/dist/keystore/types.d.ts
CHANGED
|
@@ -4,11 +4,16 @@ export interface WalletPolicy {
|
|
|
4
4
|
enabled: boolean;
|
|
5
5
|
/** If true, send_transfer and execute_swap are rejected. */
|
|
6
6
|
readOnly?: boolean;
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Max USD value per send_transfer or execute_swap (decimal string, e.g. "50").
|
|
9
|
+
* Converted at the moment of the operation via the rates backend; if the rate
|
|
10
|
+
* is unavailable the operation is rejected (fail closed).
|
|
11
|
+
*/
|
|
12
|
+
maxPerTxUsd?: string;
|
|
9
13
|
/**
|
|
10
14
|
* Allowed transfer destinations. Empty/undefined = no whitelist.
|
|
11
|
-
*
|
|
15
|
+
* Applies to send_transfer only; execute_swap is exempt because the bought
|
|
16
|
+
* asset is always paid out to the wallet's own keystore address.
|
|
12
17
|
*/
|
|
13
18
|
allowedRecipients?: string[];
|
|
14
19
|
}
|
package/dist/policy.d.ts
CHANGED
|
@@ -1,24 +1,54 @@
|
|
|
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 type { WalletEntry, WalletPolicy } from "./keystore/types.js";
|
|
7
8
|
import type { NetworkId } from "./config.js";
|
|
8
9
|
export interface PolicyCheck {
|
|
9
10
|
kind: "transfer" | "swap";
|
|
10
11
|
network: NetworkId;
|
|
11
|
-
/** Decimal string in asset units. Required to enforce `maxPerTx`. */
|
|
12
|
-
amount?: string;
|
|
13
12
|
/** Transfer destination. Ignored for swaps. */
|
|
14
13
|
toAddress?: string;
|
|
15
14
|
}
|
|
15
|
+
export interface UsdLimitCheck {
|
|
16
|
+
kind: "transfer" | "swap";
|
|
17
|
+
network: NetworkId;
|
|
18
|
+
/** Decimal string in asset units (final amount that will be signed). */
|
|
19
|
+
amount: string;
|
|
20
|
+
/** Asset symbol, used for catalog fallback matching and messages. */
|
|
21
|
+
symbol?: string;
|
|
22
|
+
/** Token contract. Omit for the native coin. */
|
|
23
|
+
tokenAddress?: string;
|
|
24
|
+
correlationId?: string;
|
|
25
|
+
}
|
|
16
26
|
/**
|
|
17
27
|
* Compare two non-negative decimal strings without floating point.
|
|
18
28
|
* Returns < 0 if a < b, 0 if equal, > 0 if a > b.
|
|
19
29
|
*/
|
|
20
30
|
export declare function compareDecimalAmount(a: string, b: string): number;
|
|
31
|
+
/** Render a float (e.g. a JSON rate) as a plain decimal string, no exponent. */
|
|
32
|
+
export declare function numberToDecimalString(n: number): string;
|
|
33
|
+
/** Multiply two non-negative decimal strings exactly (BigInt, no float). */
|
|
34
|
+
export declare function multiplyDecimalAmounts(a: string, b: string): string;
|
|
21
35
|
/** Always-present policy for `list_wallets` (`enabled: false` when unset). */
|
|
22
36
|
export declare function listWalletPolicy(policy: WalletPolicy | undefined): WalletPolicy;
|
|
23
37
|
/** Throws with a clear message if the operation violates the wallet policy. */
|
|
24
38
|
export declare function enforcePolicy(entry: WalletEntry, check: PolicyCheck): void;
|
|
39
|
+
/** Pure part of the USD check: amount × rate vs limit. Throws on violation. */
|
|
40
|
+
export declare function assertUsdWithinLimit(opts: {
|
|
41
|
+
wallet: string;
|
|
42
|
+
kind: "transfer" | "swap";
|
|
43
|
+
amount: string;
|
|
44
|
+
rate: number;
|
|
45
|
+
maxPerTxUsd: string;
|
|
46
|
+
assetLabel: string;
|
|
47
|
+
}): {
|
|
48
|
+
usdValue: string;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Enforce `maxPerTxUsd` right before signing. Fail closed: if the limit is set
|
|
52
|
+
* and the USD rate cannot be resolved, the operation is rejected.
|
|
53
|
+
*/
|
|
54
|
+
export declare function enforceUsdLimit(entry: WalletEntry, check: UsdLimitCheck): Promise<void>;
|