nodpay 0.2.9 → 0.2.11

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/SKILL.md CHANGED
@@ -14,6 +14,7 @@ You propose payments, your human approves with one tap. 2-of-3 multisig — you
14
14
  - **Your private key never leaves disk.** `keygen` writes to `.nodpay/.env` (chmod 600) — never in stdout, context, or logs.
15
15
  - **You can only propose.** Execution requires human co-sign (passkey). No single party can move funds.
16
16
  - **Wallet info is public key material.** Safe address, passkey X/Y, recovery signer — all safe to store.
17
+ - **Recovery key is user-held.** The 12-word phrase generates a third signer the user controls. If the agent key or passkey is lost, the user can still recover funds — the agent never has unilateral access.
17
18
  - **NodPay server is stateless.** It relays signed operations — no private keys, no custody, no accounts. If the server goes offline, funds stay safe on-chain.
18
19
  - **The web app is a convenience layer.** It helps users create wallets and approve transactions. All crypto operations happen client-side; nothing sensitive is stored server-side.
19
20
  - **Verify the agent address matches yours** before storing wallet info. Mismatch = wrong key binding.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodpay",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "NodPay CLI — propose on-chain payments from agent-human shared wallets",
5
5
  "type": "module",
6
6
  "bin": {
@@ -52,12 +52,17 @@ if (existing) {
52
52
  }
53
53
  } else {
54
54
  const wallet = Wallet.createRandom();
55
- // Ensure .nodpay/ directory exists with restricted permissions
55
+
56
+ // SECURITY: Private key is written directly to file — it never appears in
57
+ // stdout or process output. This is intentional: the calling agent (LLM)
58
+ // only sees the public address, so the key never enters the model's context
59
+ // window and cannot be leaked via prompt injection or conversation history.
56
60
  const dir = dirname(envFile);
57
- mkdirSync(dir, { recursive: true, mode: 0o700 });
58
- // Write key file with restricted permissions (owner read/write only)
61
+ mkdirSync(dir, { recursive: true, mode: 0o700 }); // directory: owner-only
59
62
  const content = existsSync(envFile) ? readFileSync(envFile, 'utf8') : '';
60
- writeFileSync(envFile, content + `${ENV_VAR}=${wallet.privateKey}\n`, { mode: 0o600 });
63
+ writeFileSync(envFile, content + `${ENV_VAR}=${wallet.privateKey}\n`, { mode: 0o600 }); // file: owner read/write only
64
+
65
+ // Only the public address reaches stdout — safe for LLM context
61
66
  console.log(wallet.address);
62
67
  console.error(`Generated new agent key → ${envFile}`);
63
68
  }
@@ -62,7 +62,9 @@ if (!RPC_URL || !CHAIN_ID) {
62
62
  }
63
63
  const ENTRYPOINT_ADDRESS = ENTRYPOINT;
64
64
 
65
- // Read agent key from .nodpay/.env
65
+ // SECURITY: Read agent key from .nodpay/.env file (chmod 600), not from
66
+ // process.env or CLI args. The key is loaded at runtime by the script itself,
67
+ // so it never passes through the LLM agent's context or conversation history.
66
68
  function loadAgentKey() {
67
69
  try {
68
70
  const envPath = join(process.cwd(), '.nodpay', '.env');