agentwallet-mcp 1.10.7 → 1.10.9

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 CHANGED
@@ -76,7 +76,7 @@ Local signing uses [viem](https://viem.sh) for EVM and `@solana/web3.js` for Sol
76
76
  - **31 MCP tools**: create wallets, send transactions, approve tokens, wrap ETH, transfer SPL tokens, pay and accept x402 payments, verify custody mode, and more
77
77
  - **EVM + Solana**: Ethereum, Base, Polygon, BSC, Arbitrum, Optimism, Avalanche, Zora, PulseChain, Solana, and any other EVM-compatible chain
78
78
  - **SOL + SPL tokens**: native SOL transfers and SPL token transfers (USDC, USDT, etc.) with automatic account creation
79
- - **Built-in guards**: daily spending limits, gas price protection, emergency pause, rate limiting, replay protection, and on-chain verification, all active by default
79
+ - **Built-in guards**: in hosted mode, daily spending limits, gas price protection, emergency pause and rate limiting are enforced server-side by default. In local mode your protection is the per-transaction caps you set (`AGENTWALLET_MAX_TX_NATIVE`, `AGENTWALLET_MAX_TX_TOKEN`, `AGENTWALLET_MAX_TX_SOL`, `AGENTWALLET_MAX_AUTOPAY`). x402 replay protection and on-chain verification apply either way
80
80
  - **x402 payments**: pay for x402-enabled APIs automatically, or accept x402 payments on your own endpoints (EVM and Solana)
81
81
  - **Self-custody option**: run local mode and the key never leaves your machine. In hosted mode, keys are encrypted at rest, decrypted only during signing, and zeroed from memory immediately after. Either way you can export and walk away.
82
82
  - **Permissionless**: No KYC. No KYT. No identity verification. No approval process. No compliance gatekeeping. Sign up, get an API key, and start transacting immediately.
@@ -274,7 +274,7 @@ On-chain verification ensures every payment is real. Replay protection prevents
274
274
  | KYC Required | Yes | **No** |
275
275
  | KYT / Transaction Monitoring | Yes | **No** |
276
276
  | Can Block Your Wallet | Yes | **No** |
277
- | Built-in Guards | Yes (requires setup) | **Yes (active by default)** |
277
+ | Built-in Guards | Yes (requires setup) | **Yes (hosted: active by default; local: env caps you set)** |
278
278
  | Free Operations / Month | 5,000 | **6,000** |
279
279
  | Cost Per Operation | $0.005 | **$0.00345** |
280
280
  | x402 Verification Cost | $0.001 | **$0.0005** |
@@ -295,17 +295,30 @@ You can also pre-purchase x402 verification credits with USDC using the `buy_ver
295
295
 
296
296
  ## Built-in Guards
297
297
 
298
- All guards are active by default, no configuration required.
298
+ Which guards apply depends on who holds the key.
299
+
300
+ **Hosted mode** (the server holds the key): every guard below is active by default, no configuration required.
299
301
 
300
302
  - **Encrypted at rest**: private keys encrypted before storage and never leave the server
301
303
  - **Memory zeroing**: keys wiped from memory immediately after every signing operation
302
- - **Daily spending limits**: set a per-wallet daily cap in USD, enforced automatically on every transaction
304
+ - **Daily spending limits**: set a per-wallet daily cap in USD, enforced by the server on every transaction
303
305
  - **Gas price protection**: transactions blocked when gas prices spike above safe thresholds
304
306
  - **Emergency pause**: instantly freeze any wallet or all wallets with one click
305
307
  - **Rate limiting**: API requests capped per minute to prevent abuse and brute force attacks
308
+
309
+ **Local mode** (you hold the key): there is no server in the signing path, so the server-side limits and pause above cannot see or stop a locally signed transaction, and nobody (including us) can freeze a local wallet. Your protection is the per-transaction caps enforced inside your own process before anything is signed. Set them before you fund the wallet; an unset cap means no limit.
310
+
311
+ - `AGENTWALLET_MAX_TX_NATIVE`: ceiling per transaction in native units (ETH, MATIC, and so on)
312
+ - `AGENTWALLET_MAX_TX_TOKEN`: ceiling per ERC-20 transfer, in human units of the token
313
+ - `AGENTWALLET_MAX_TX_SOL`: ceiling per SOL or SPL transfer
314
+ - `AGENTWALLET_MAX_AUTOPAY`: ceiling per x402 auto-payment (default `1`)
315
+
316
+ **Either mode**, for x402 paywalls you run through the hosted API:
317
+
306
318
  - **Replay protection**: every x402 payment verified on-chain with unique transaction tracking
307
319
  - **On-chain verification**: x402 payments verified directly on the blockchain with finalized commitment
308
- - Bug bounty program: $50,$500 for responsible disclosure ([details](https://hifriendbot.com/wallet))
320
+
321
+ Bug bounty program: $50 to $500 for responsible disclosure ([details](https://hifriendbot.com/wallet)).
309
322
 
310
323
  ## Links
311
324
 
package/build/index.js CHANGED
@@ -13,7 +13,7 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
13
13
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
14
14
  import { z } from 'zod';
15
15
  import { assertPublicUrl, safeFetch } from './ssrf-guard.js';
16
- import { deriveX402Payment, isWithinCap, lookupTrustedDecimals, assertDeclaredDecimals, } from './x402-payment.js';
16
+ import { deriveX402Payment, isWithinCap, lookupTrustedDecimals, assertDeclaredDecimals, nativeDecimals, SOLANA_CHAIN_IDS, } from './x402-payment.js';
17
17
  import { isLocalMode, getLocalAddress, localWalletRecord, localSend, localNativeBalance, localTokenBalance, localSignMessage, resolveRpcUrl, } from './local-wallet.js';
18
18
  import { isSolanaLocalMode, getSolanaAddress, solanaWalletRecord, localSolBalance, localSplBalance, localSolTransfer, localSplTransfer, resolveSolanaRpc, } from './local-solana.js';
19
19
  /** True when either chain family is running non-custodially. */
@@ -258,7 +258,7 @@ async function handleX402Payment(x402Data, originalPath, originalMethod, origina
258
258
  const assetForDecimals = accept.asset || accept.extra?.token || '';
259
259
  const trustedDecimals = assetForDecimals
260
260
  ? await resolveTrustedDecimals(chainId, assetForDecimals)
261
- : 18; // native asset: value is already in wei-equivalent base units
261
+ : nativeDecimals(chainId); // native asset: 18 on EVM (wei), 9 on Solana (lamports)
262
262
  const { tokenAddress, rawAmount, decimals } = deriveX402Payment(accept, maxAutopay, trustedDecimals);
263
263
  // Send payment using our wallet (with X-AGW-SKIP-X402 to prevent recursion)
264
264
  let txHash;
@@ -310,7 +310,6 @@ function jsonResponse(data) {
310
310
  return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
311
311
  }
312
312
  // ─── Solana Helpers ───────────────────────────────────────────────
313
- const SOLANA_CHAIN_IDS = new Set([900, 901, 902]);
314
313
  function isSolanaChain(chainId) {
315
314
  return SOLANA_CHAIN_IDS.has(chainId);
316
315
  }
@@ -424,7 +423,7 @@ function resolveChainId(network) {
424
423
  const AddressSchema = z.string().regex(/^(0x[a-fA-F0-9]{40}|[1-9A-HJ-NP-Za-km-z]{32,44})$/, 'Must be a 0x-prefixed 40-hex EVM address or a base58 Solana address');
425
424
  const server = new McpServer({
426
425
  name: 'agentwallet',
427
- version: '1.10.7',
426
+ version: '1.10.9',
428
427
  }, {
429
428
  instructions: `AgentWallet gives AI agents their own blockchain wallets. Private keys are encrypted server-side and never exposed — agents sign and broadcast transactions without ever touching raw keys.
430
429
 
@@ -1032,7 +1031,7 @@ server.tool('pay_x402', 'Handle an x402 payment flow. Fetches a URL, and if the
1032
1031
  const assetForDecimals = option.asset || option.extra?.token || '';
1033
1032
  const trustedDecimals = assetForDecimals
1034
1033
  ? await resolveTrustedDecimals(chainId, assetForDecimals)
1035
- : 18;
1034
+ : nativeDecimals(chainId); // 18 on EVM (wei), 9 on Solana (lamports)
1036
1035
  assertDeclaredDecimals(option.requiredDecimals, trustedDecimals);
1037
1036
  // Human-readable amount, computed with trusted decimals so what the agent
1038
1037
  // is told matches what will actually leave the wallet.
@@ -81,4 +81,15 @@ export declare function deriveX402Payment(accept: X402AcceptLike, maxAutopayHuma
81
81
  * @param trustedDecimals token decimals from a trusted source, NOT the 402 body
82
82
  * @param capHuman cap in human-readable units of the asset (e.g. "1")
83
83
  */
84
+ /**
85
+ * Chain IDs this server treats as Solana (mainnet, devnet, testnet).
86
+ */
87
+ export declare const SOLANA_CHAIN_IDS: ReadonlySet<number>;
88
+ /**
89
+ * Decimals of a chain's NATIVE asset. EVM natives are 18 (wei); native SOL is
90
+ * 9 (lamports). The x402 cap and the human-readable amount must use this when
91
+ * a requirement names no token, otherwise a native-SOL requirement is measured
92
+ * against a cap inflated by 10**9 (AW-002, reported 2026-09-22).
93
+ */
94
+ export declare function nativeDecimals(chainId: number): number;
84
95
  export declare function isWithinCap(rawAmountRequired: string, trustedDecimals: number, capHuman: string): boolean;
@@ -146,6 +146,19 @@ export function deriveX402Payment(accept, maxAutopayHuman, trustedDecimals) {
146
146
  * @param trustedDecimals token decimals from a trusted source, NOT the 402 body
147
147
  * @param capHuman cap in human-readable units of the asset (e.g. "1")
148
148
  */
149
+ /**
150
+ * Chain IDs this server treats as Solana (mainnet, devnet, testnet).
151
+ */
152
+ export const SOLANA_CHAIN_IDS = new Set([900, 901, 902]);
153
+ /**
154
+ * Decimals of a chain's NATIVE asset. EVM natives are 18 (wei); native SOL is
155
+ * 9 (lamports). The x402 cap and the human-readable amount must use this when
156
+ * a requirement names no token, otherwise a native-SOL requirement is measured
157
+ * against a cap inflated by 10**9 (AW-002, reported 2026-09-22).
158
+ */
159
+ export function nativeDecimals(chainId) {
160
+ return SOLANA_CHAIN_IDS.has(chainId) ? 9 : 18;
161
+ }
149
162
  export function isWithinCap(rawAmountRequired, trustedDecimals, capHuman) {
150
163
  if (!/^\d+$/.test(rawAmountRequired)) {
151
164
  throw new Error(`Invalid maxAmountRequired "${rawAmountRequired}" (expected an integer base-unit amount).`);
package/package.json CHANGED
@@ -1,69 +1,69 @@
1
- {
2
- "name": "agentwallet-mcp",
3
- "mcpName": "io.github.hifriendbot/agentwallet",
4
- "version": "1.10.7",
5
- "description": "MCP server for AgentWallet: self-custody local signing on EVM and Solana, or hosted wallets. Sign, broadcast, pay x402 invoices, and accept x402 payments.",
6
- "type": "module",
7
- "main": "build/index.js",
8
- "bin": {
9
- "agentwallet-mcp": "build/index.js"
10
- },
11
- "files": [
12
- "build",
13
- "README.md",
14
- "LICENSE"
15
- ],
16
- "scripts": {
17
- "build": "tsc",
18
- "start": "node build/index.js",
19
- "test": "node test/x402-payment.test.mjs && node test/token-cap.test.mjs && node test/spl-cap.test.mjs && node test/unknown-decimals-cap.test.mjs && node test/local-mode.test.mjs && node test/ssrf-guard.test.mjs",
20
- "prepublishOnly": "npm run build"
21
- },
22
- "keywords": [
23
- "mcp",
24
- "model-context-protocol",
25
- "wallet",
26
- "ai-agent",
27
- "blockchain",
28
- "evm",
29
- "ethereum",
30
- "base",
31
- "arbitrum",
32
- "optimism",
33
- "polygon",
34
- "avalanche",
35
- "bsc",
36
- "zora",
37
- "pulsechain",
38
- "solana",
39
- "spl-token",
40
- "erc20",
41
- "token-transfer",
42
- "transaction-signing",
43
- "x402",
44
- "http-402",
45
- "agent-payments",
46
- "agentwallet",
47
- "self-custody",
48
- "non-custodial",
49
- "local-signing"
50
- ],
51
- "author": "HiFriendbot (https://hifriendbot.com)",
52
- "license": "MIT",
53
- "homepage": "https://hifriendbot.com/wallet/",
54
- "engines": {
55
- "node": ">=18.0.0"
56
- },
57
- "dependencies": {
58
- "@modelcontextprotocol/sdk": "^1.11.4",
59
- "@solana/web3.js": "^1.98.4",
60
- "bs58": "^6.0.0",
61
- "undici": "^8.9.0",
62
- "viem": "^2.55.10",
63
- "zod": "^3.24.0"
64
- },
65
- "devDependencies": {
66
- "@types/node": "^20.0.0",
67
- "typescript": "^5.3.0"
68
- }
69
- }
1
+ {
2
+ "name": "agentwallet-mcp",
3
+ "mcpName": "io.github.hifriendbot/agentwallet",
4
+ "version": "1.10.9",
5
+ "description": "MCP server for AgentWallet: self-custody local signing on EVM and Solana, or hosted wallets. Sign, broadcast, pay x402 invoices, and accept x402 payments.",
6
+ "type": "module",
7
+ "main": "build/index.js",
8
+ "bin": {
9
+ "agentwallet-mcp": "build/index.js"
10
+ },
11
+ "files": [
12
+ "build",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "start": "node build/index.js",
19
+ "test": "node test/x402-payment.test.mjs && node test/token-cap.test.mjs && node test/spl-cap.test.mjs && node test/unknown-decimals-cap.test.mjs && node test/local-mode.test.mjs && node test/ssrf-guard.test.mjs",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "wallet",
26
+ "ai-agent",
27
+ "blockchain",
28
+ "evm",
29
+ "ethereum",
30
+ "base",
31
+ "arbitrum",
32
+ "optimism",
33
+ "polygon",
34
+ "avalanche",
35
+ "bsc",
36
+ "zora",
37
+ "pulsechain",
38
+ "solana",
39
+ "spl-token",
40
+ "erc20",
41
+ "token-transfer",
42
+ "transaction-signing",
43
+ "x402",
44
+ "http-402",
45
+ "agent-payments",
46
+ "agentwallet",
47
+ "self-custody",
48
+ "non-custodial",
49
+ "local-signing"
50
+ ],
51
+ "author": "HiFriendbot (https://hifriendbot.com)",
52
+ "license": "MIT",
53
+ "homepage": "https://hifriendbot.com/wallet/",
54
+ "engines": {
55
+ "node": ">=18.0.0"
56
+ },
57
+ "dependencies": {
58
+ "@modelcontextprotocol/sdk": "^1.11.4",
59
+ "@solana/web3.js": "^1.98.4",
60
+ "bs58": "^6.0.0",
61
+ "undici": "^8.9.0",
62
+ "viem": "^2.55.10",
63
+ "zod": "^3.24.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/node": "^20.0.0",
67
+ "typescript": "^5.3.0"
68
+ }
69
+ }