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 +10 -3
- package/bin/nodpay.mjs +7 -1
- package/package.json +1 -1
- package/scripts/keygen.mjs +61 -0
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
|
-
|
|
42
|
+
npx nodpay keygen --env-file .env
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
@@ -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
|
+
}
|