nodpay 0.2.2 → 0.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/SKILL.md CHANGED
@@ -39,12 +39,19 @@ The wallet is a **Safe 2-of-3 multisig**. You hold 1 key, the user holds 2 (pass
39
39
  ### 1. Generate an agent key
40
40
 
41
41
  ```bash
42
- node -e "const w=require('ethers').Wallet.createRandom();console.log('Address:',w.address,'\nKey:',w.privateKey)"
42
+ npx nodpay keygen --env-file .env
43
43
  ```
44
44
 
45
- Store the private key as `NODPAY_AGENT_KEY` in your environment. The address is your public agent identity.
45
+ This outputs your agent's **public address** (stdout). The private key is written directly to `.env` it never appears in your output or context.
46
46
 
47
- **⚠️ Storing the env var may trigger a restart.** Complete all config/env changes and wait for the restart to finish BEFORE sending any message to the user. Do not send messages and update config in parallel — the restart will truncate your message.
47
+ If `NODPAY_AGENT_KEY` already exists in the file, it reuses the existing key and prints the address.
48
+
49
+ **After keygen**, trigger a gateway restart so the env var takes effect. Send your wallet link message to the user BEFORE restarting — the restart will interrupt your session.
50
+
51
+ Recommended sequence:
52
+ 1. Run `npx nodpay keygen --env-file .env` → note the address
53
+ 2. Send the wallet link to your user (step 2 below)
54
+ 3. Trigger gateway restart
48
55
 
49
56
  ### 2. Send the user a wallet link
50
57
 
package/bin/nodpay.mjs CHANGED
@@ -7,6 +7,10 @@ if (command === 'propose') {
7
7
  const scriptPath = new URL('../scripts/propose.mjs', import.meta.url).pathname;
8
8
  process.argv = [process.argv[0], scriptPath, ...process.argv.slice(3)];
9
9
  await import(scriptPath);
10
+ } else if (command === 'keygen') {
11
+ const scriptPath = new URL('../scripts/keygen.mjs', import.meta.url).pathname;
12
+ process.argv = [process.argv[0], scriptPath, ...process.argv.slice(3)];
13
+ await import(scriptPath);
10
14
  } else if (command === 'version' || command === '--version' || command === '-v') {
11
15
  const { readFileSync } = await import('fs');
12
16
  const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
@@ -15,9 +19,11 @@ if (command === 'propose') {
15
19
  console.log(`Usage: nodpay <command>
16
20
 
17
21
  Commands:
22
+ keygen Generate (or reuse) agent keypair
18
23
  propose Propose a transaction for human approval
19
24
 
20
- Example:
25
+ Examples:
26
+ nodpay keygen --env-file .env
21
27
  nodpay propose --safe 0x... --to 0x... --value-eth 0.01 --signer-type passkey
22
28
 
23
29
  Docs: https://nodpay.ai/skill.md`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodpay",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "NodPay CLI — propose on-chain payments from agent-human shared wallets",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate (or reuse) an agent keypair.
4
+ *
5
+ * - If NODPAY_AGENT_KEY already exists in --env-file, derives and prints the address.
6
+ * - Otherwise generates a new keypair, appends to --env-file, prints the address.
7
+ *
8
+ * The private key NEVER appears in stdout — only the public address.
9
+ *
10
+ * Usage:
11
+ * npx nodpay keygen --env-file .env
12
+ */
13
+
14
+ import { Wallet } from 'ethers';
15
+ import { readFileSync, appendFileSync, existsSync } from 'fs';
16
+ import { resolve } from 'path';
17
+
18
+ const args = process.argv.slice(2);
19
+ const envFileIdx = args.indexOf('--env-file');
20
+ const envFile = envFileIdx !== -1 ? resolve(args[envFileIdx + 1]) : null;
21
+
22
+ if (!envFile) {
23
+ console.error('Usage: npx nodpay keygen --env-file <path>');
24
+ process.exit(1);
25
+ }
26
+
27
+ const ENV_VAR = 'NODPAY_AGENT_KEY';
28
+
29
+ // Check if key already exists in the env file
30
+ function findExistingKey() {
31
+ if (!existsSync(envFile)) return null;
32
+ const lines = readFileSync(envFile, 'utf8').split('\n');
33
+ for (const line of lines) {
34
+ const trimmed = line.trim();
35
+ if (trimmed.startsWith('#') || !trimmed.includes('=')) continue;
36
+ const [name, ...rest] = trimmed.split('=');
37
+ if (name.trim() === ENV_VAR) {
38
+ const value = rest.join('=').trim().replace(/^["']|["']$/g, '');
39
+ if (value) return value;
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+
45
+ const existing = findExistingKey();
46
+
47
+ if (existing) {
48
+ try {
49
+ const wallet = new Wallet(existing);
50
+ console.log(wallet.address);
51
+ console.error(`${ENV_VAR} already configured in ${envFile}`);
52
+ } catch {
53
+ console.error(`${ENV_VAR} exists in ${envFile} but is invalid. Remove it and re-run.`);
54
+ process.exit(1);
55
+ }
56
+ } else {
57
+ const wallet = Wallet.createRandom();
58
+ appendFileSync(envFile, `\n${ENV_VAR}=${wallet.privateKey}\n`);
59
+ console.log(wallet.address);
60
+ console.error(`Generated new agent key → ${envFile}`);
61
+ }