nodpay 0.2.3 → 0.2.4
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 +19 -1
- package/SKILL.md +3 -1
- package/package.json +1 -1
- package/scripts/propose.mjs +24 -3
package/README.md
CHANGED
|
@@ -28,11 +28,29 @@ NODPAY_AGENT_KEY=0x... npx nodpay propose \
|
|
|
28
28
|
3. Agent proposes transactions with `npx nodpay propose`
|
|
29
29
|
4. User approves/rejects on their phone
|
|
30
30
|
|
|
31
|
+
## Key generation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx nodpay keygen --env-file .env
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Outputs the agent's **public address only**. The private key is written directly to `.env` — it never appears in stdout, logs, or the agent's context window.
|
|
38
|
+
|
|
39
|
+
If a key already exists, it reuses it and prints the address.
|
|
40
|
+
|
|
41
|
+
### Security design
|
|
42
|
+
|
|
43
|
+
The agent (LLM) **never sees the private key**. `keygen` writes the secret directly to disk; the `propose` command reads it from the environment at runtime. This means:
|
|
44
|
+
|
|
45
|
+
- No private key in conversation history or context window
|
|
46
|
+
- No risk of leaking the key through prompt injection
|
|
47
|
+
- The agent only needs the public address (for wallet links)
|
|
48
|
+
|
|
31
49
|
## Env
|
|
32
50
|
|
|
33
51
|
| Variable | Required | Description |
|
|
34
52
|
|----------|----------|-------------|
|
|
35
|
-
| `NODPAY_AGENT_KEY` | ✅ | Agent's private key
|
|
53
|
+
| `NODPAY_AGENT_KEY` | ✅ | Agent's private key — use `npx nodpay keygen` to generate securely |
|
|
36
54
|
|
|
37
55
|
## Supported chains
|
|
38
56
|
|
package/SKILL.md
CHANGED
|
@@ -115,6 +115,7 @@ One agent key serves all wallets — multi-wallet is handled user-side (differen
|
|
|
115
115
|
```bash
|
|
116
116
|
NODPAY_AGENT_KEY=0x... \
|
|
117
117
|
npx nodpay propose \
|
|
118
|
+
--chain <CHAIN_NAME> \
|
|
118
119
|
--safe <WALLET_ADDRESS> \
|
|
119
120
|
--to <RECIPIENT> \
|
|
120
121
|
--value-eth <AMOUNT> \
|
|
@@ -159,6 +160,7 @@ Always check before proposing — this tells you the current nonce, pending ops,
|
|
|
159
160
|
|
|
160
161
|
| Flag | Required | Description |
|
|
161
162
|
|------|----------|-------------|
|
|
163
|
+
| `--chain` | ✅ | Chain name (e.g. `ethereum`, `base`, `sepolia`) |
|
|
162
164
|
| `--safe` | ✅ | Wallet (Safe) address |
|
|
163
165
|
| `--to` | ✅ | Recipient address |
|
|
164
166
|
| `--value-eth` | ✅ | Amount in ETH |
|
|
@@ -178,7 +180,7 @@ Only one env var is required:
|
|
|
178
180
|
|-----|-------------|
|
|
179
181
|
| `NODPAY_AGENT_KEY` | Agent signing key (required) |
|
|
180
182
|
|
|
181
|
-
Chain config (RPC, bundler
|
|
183
|
+
Chain config (RPC, bundler) is auto-resolved via `--chain` from [`@nodpay/core/networks`](https://www.npmjs.com/package/@nodpay/core). You can override with `RPC_URL`/`CHAIN_ID` env vars if needed, but `--chain` is the recommended way.
|
|
182
184
|
|
|
183
185
|
### Supported Chains
|
|
184
186
|
|
package/package.json
CHANGED
package/scripts/propose.mjs
CHANGED
|
@@ -37,10 +37,31 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
37
37
|
const PENDING_DIR = join(__dirname, '..', '.pending-txs');
|
|
38
38
|
mkdirSync(PENDING_DIR, { recursive: true });
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
// Resolve chain config: --chain flag auto-resolves from networks.json, env vars as fallback
|
|
41
|
+
import { createRequire } from 'module';
|
|
42
|
+
const require = createRequire(import.meta.url);
|
|
43
|
+
const NETWORKS = require('@nodpay/core/networks');
|
|
44
|
+
const allChains = { ...NETWORKS.mainnet, ...NETWORKS.testnet };
|
|
45
|
+
|
|
46
|
+
const chainArg = process.argv.includes('--chain')
|
|
47
|
+
? process.argv[process.argv.indexOf('--chain') + 1]
|
|
48
|
+
: null;
|
|
49
|
+
|
|
50
|
+
let RPC_URL, CHAIN_ID;
|
|
51
|
+
if (chainArg) {
|
|
52
|
+
const net = allChains[chainArg];
|
|
53
|
+
if (!net) {
|
|
54
|
+
console.error(`Error: Unknown chain "${chainArg}". Supported: ${Object.keys(allChains).join(', ')}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
RPC_URL = process.env.RPC_URL || net.rpcUrl;
|
|
58
|
+
CHAIN_ID = String(net.chainId);
|
|
59
|
+
} else {
|
|
60
|
+
RPC_URL = process.env.RPC_URL;
|
|
61
|
+
CHAIN_ID = process.env.CHAIN_ID;
|
|
62
|
+
}
|
|
42
63
|
if (!RPC_URL || !CHAIN_ID) {
|
|
43
|
-
console.error('Error:
|
|
64
|
+
console.error('Error: Specify --chain <name> or set RPC_URL + CHAIN_ID env vars.\nSupported chains: ' + Object.keys(allChains).join(', '));
|
|
44
65
|
process.exit(1);
|
|
45
66
|
}
|
|
46
67
|
const ENTRYPOINT_ADDRESS = ENTRYPOINT;
|