@aifinpay/mcp 2.2.2 → 2.2.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 CHANGED
@@ -94,9 +94,14 @@ A quote or invoice is not a completed payment. Enable the owner-configured
94
94
  ## Local configuration
95
95
 
96
96
  ```bash
97
- npx @aifinpay/mcp init
97
+ AIFINPAY_WALLET_PASSPHRASE='<a long passphrase>' npx @aifinpay/mcp init
98
98
  ```
99
99
 
100
+ The keystore is encrypted at rest and the MCP server needs the same
101
+ `AIFINPAY_WALLET_PASSPHRASE` to load it. For a disposable test wallet only,
102
+ `npx @aifinpay/mcp init --plaintext` writes it unencrypted (mode 600); without
103
+ either, `init` refuses rather than create an unencrypted wallet you might fund.
104
+
100
105
  Select the wallet in this order: `SEED_HASH` → `./aifinpay/agents.json` →
101
106
  legacy `AIFINPAY_AGENT_SECRET` → `~/.aifinpay/agent.json`.
102
107
  SEED_HASH means a 32-byte hex seed, passed directly to SDK `fromSeed`.
@@ -68,7 +68,8 @@ const arg = (process.argv[2] || "").toLowerCase();
68
68
  if (arg === "--help" || arg === "-h" || arg === "help") {
69
69
  process.stdout.write(`aifinpay-mcp ${VERSION}
70
70
 
71
- npx @aifinpay/mcp init create a persistent wallet and print the config
71
+ npx @aifinpay/mcp init create a persistent wallet (encrypted: set AIFINPAY_WALLET_PASSPHRASE;
72
+ unencrypted test wallet: add --plaintext) and print the config
72
73
  npx @aifinpay/mcp start the MCP server (stdio)
73
74
 
74
75
  Run init once. It writes ${KEYSTORE} with mode 600 and the server picks
@@ -171,6 +172,20 @@ if (arg === "init") {
171
172
 
172
173
  let store = readKeystore();
173
174
  let freshlyCreated = false;
175
+ // A new wallet is encrypted at rest unless the owner asks otherwise, by name.
176
+ // It used to be written in plaintext whenever AIFINPAY_WALLET_PASSPHRASE was
177
+ // unset — which is the default — so the documented one-liner produced an
178
+ // unencrypted key for a wallet people then funded. Existing keystores are
179
+ // untouched; only creating a new plaintext one needs the flag.
180
+ if (!store && !PASSPHRASE && !process.argv.includes("--plaintext")) {
181
+ process.stderr.write(
182
+ `No wallet at ${KEYSTORE}, and none will be created unencrypted by default.\n\n` +
183
+ ` Encrypted (recommended): AIFINPAY_WALLET_PASSPHRASE='<a long passphrase>' npx @aifinpay/mcp init\n` +
184
+ ` Disposable test wallet: npx @aifinpay/mcp init --plaintext\n\n` +
185
+ `Keep the passphrase: an encrypted wallet cannot be recovered without it.\n`
186
+ );
187
+ process.exit(2);
188
+ }
174
189
  if (!store) {
175
190
  mkdirSync(HOME, { recursive: true, mode: 0o700 });
176
191
  const secretB58 = Agent.new().secretB58;
@@ -208,7 +223,7 @@ if (arg === "init") {
208
223
  process.stdout.write(
209
224
  PASSPHRASE
210
225
  ? `Created ${KEYSTORE} (mode 600, ENCRYPTED). Keep AIFINPAY_WALLET_PASSPHRASE — the wallet is unrecoverable without it.\n\n`
211
- : `Created ${KEYSTORE} (mode 600, plaintext). For at-rest encryption, set AIFINPAY_WALLET_PASSPHRASE before init.\n\n`
226
+ : `Created ${KEYSTORE} (mode 600, PLAINTEXT — --plaintext). Use it for testing only; for a funded wallet, re-create it with AIFINPAY_WALLET_PASSPHRASE set.\n\n`
212
227
  );
213
228
  } else {
214
229
  process.stdout.write(`Existing wallet found at ${KEYSTORE} — keeping it.\n\n`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifinpay/mcp",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "mcpName": "io.github.daochild/aifinpay",
5
5
  "description": "AiFinPay MCP: persistent agent wallets, discovery and owner-enabled verified native Polygon v1.4 payments with durable receipt recovery.",
6
6
  "type": "module",