nervepay 1.1.0 → 1.1.2
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/bin/nervepay-cli.js +144 -2
- package/package.json +1 -1
package/bin/nervepay-cli.js
CHANGED
|
@@ -39,14 +39,27 @@ program
|
|
|
39
39
|
try {
|
|
40
40
|
// Read OpenClaw config
|
|
41
41
|
const openclawConfig = JSON.parse(await readFile(OPENCLAW_CONFIG_PATH, 'utf-8'));
|
|
42
|
-
const gatewayConfig = openclawConfig.gateway?.remote;
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
// Support both local and remote gateway modes
|
|
44
|
+
let gatewayUrl, gatewayToken;
|
|
45
|
+
if (openclawConfig.gateway?.remote?.url) {
|
|
46
|
+
// Remote mode
|
|
47
|
+
gatewayUrl = openclawConfig.gateway.remote.url;
|
|
48
|
+
gatewayToken = openclawConfig.gateway.remote.token;
|
|
49
|
+
} else if (openclawConfig.gateway?.auth?.token) {
|
|
50
|
+
// Local mode - construct URL from port (default 18789)
|
|
51
|
+
const port = openclawConfig.gateway?.port || 18789;
|
|
52
|
+
gatewayUrl = `http://127.0.0.1:${port}`;
|
|
53
|
+
gatewayToken = openclawConfig.gateway.auth.token;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!gatewayUrl || !gatewayToken) {
|
|
45
57
|
console.error(chalk.red('❌ No OpenClaw gateway configured'));
|
|
46
58
|
console.error(chalk.yellow(' Run: openclaw configure'));
|
|
47
59
|
process.exit(1);
|
|
48
60
|
}
|
|
49
61
|
|
|
62
|
+
const gatewayConfig = { url: gatewayUrl, token: gatewayToken };
|
|
50
63
|
console.log(chalk.green('✓ Found OpenClaw gateway:'), gatewayConfig.url);
|
|
51
64
|
|
|
52
65
|
// Ask for agent details
|
|
@@ -192,6 +205,135 @@ program
|
|
|
192
205
|
}
|
|
193
206
|
});
|
|
194
207
|
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// PAIR COMMAND
|
|
210
|
+
// ============================================================================
|
|
211
|
+
|
|
212
|
+
program
|
|
213
|
+
.command('pair')
|
|
214
|
+
.description('Quick pair gateway using a dashboard pairing code')
|
|
215
|
+
.requiredOption('--code <code>', '6-character pairing code from NervePay dashboard')
|
|
216
|
+
.option('--api-url <url>', 'NervePay API URL', 'https://api.nervepay.xyz')
|
|
217
|
+
.action(async (options) => {
|
|
218
|
+
console.log(chalk.cyan('\n🔗 NervePay Quick Pair\n'));
|
|
219
|
+
console.log(chalk.gray(' Code:'), chalk.white(options.code));
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
// Step 1: Load existing credentials or read from env
|
|
223
|
+
let agentDid, privateKey, isNew = false;
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
const config = await loadConfig();
|
|
227
|
+
agentDid = config.agentDid;
|
|
228
|
+
privateKey = config.privateKey;
|
|
229
|
+
console.log(chalk.green('✓ Using existing agent identity'));
|
|
230
|
+
console.log(chalk.gray(' DID:'), agentDid);
|
|
231
|
+
} catch {
|
|
232
|
+
// No existing config — create a new pending identity
|
|
233
|
+
console.log(chalk.cyan(' No existing identity found, creating one...'));
|
|
234
|
+
const tempClient = new NervePayClient({ apiUrl: options.apiUrl });
|
|
235
|
+
const reg = await identity.registerPendingIdentity(tempClient, {
|
|
236
|
+
name: 'OpenClaw Gateway',
|
|
237
|
+
description: 'Gateway operator',
|
|
238
|
+
});
|
|
239
|
+
agentDid = reg.did;
|
|
240
|
+
privateKey = reg.private_key;
|
|
241
|
+
isNew = true;
|
|
242
|
+
console.log(chalk.green('✓ Agent identity created'));
|
|
243
|
+
console.log(chalk.gray(' DID:'), agentDid);
|
|
244
|
+
if (reg.claim_url) {
|
|
245
|
+
console.log(chalk.gray(' Claim URL:'), chalk.yellow(reg.claim_url));
|
|
246
|
+
}
|
|
247
|
+
if (reg.mnemonic) {
|
|
248
|
+
console.log(chalk.gray(' Mnemonic:'), chalk.yellow(reg.mnemonic));
|
|
249
|
+
console.log(chalk.red(' ⚠️ Save this mnemonic — you can recover your keys with it!'));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Step 2: Read gateway config
|
|
254
|
+
console.log(chalk.cyan('\n📡 Reading gateway config...'));
|
|
255
|
+
const openclawConfig = JSON.parse(await readFile(OPENCLAW_CONFIG_PATH, 'utf-8').catch(() => '{}'));
|
|
256
|
+
|
|
257
|
+
let gatewayUrl, gatewayToken;
|
|
258
|
+
if (openclawConfig.gateway?.remote?.url) {
|
|
259
|
+
gatewayUrl = openclawConfig.gateway.remote.url;
|
|
260
|
+
gatewayToken = openclawConfig.gateway.remote.token;
|
|
261
|
+
} else if (openclawConfig.gateway?.auth?.token || openclawConfig.auth?.token) {
|
|
262
|
+
const port = openclawConfig.gateway?.port || 18789;
|
|
263
|
+
gatewayUrl = `ws://127.0.0.1:${port}`;
|
|
264
|
+
gatewayToken = openclawConfig.gateway?.auth?.token || openclawConfig.auth?.token;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (!gatewayToken) {
|
|
268
|
+
gatewayToken = process.env.OPENCLAW_GATEWAY_TOKEN;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (!gatewayToken) {
|
|
272
|
+
console.error(chalk.red('\n❌ Could not find gateway token'));
|
|
273
|
+
console.error(chalk.yellow(' Checked: ~/.openclaw/openclaw.json, OPENCLAW_GATEWAY_TOKEN'));
|
|
274
|
+
console.error(chalk.yellow(' Fix: set OPENCLAW_GATEWAY_TOKEN env var'));
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
gatewayUrl = gatewayUrl || 'ws://127.0.0.1:18789';
|
|
279
|
+
console.log(chalk.green('✓ Gateway found'));
|
|
280
|
+
console.log(chalk.gray(' URL:'), gatewayUrl);
|
|
281
|
+
|
|
282
|
+
// Step 3: Complete pairing
|
|
283
|
+
console.log(chalk.cyan('\n🔐 Completing pairing...'));
|
|
284
|
+
const client = new NervePayClient({
|
|
285
|
+
apiUrl: options.apiUrl,
|
|
286
|
+
agentDid,
|
|
287
|
+
privateKey,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const result = await gateway.completePairing(client, {
|
|
291
|
+
pairing_code: options.code,
|
|
292
|
+
gateway_url: gatewayUrl,
|
|
293
|
+
gateway_token: gatewayToken,
|
|
294
|
+
gateway_name: 'OpenClaw Gateway',
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
console.log(chalk.green('\n✅ Pairing complete!'));
|
|
298
|
+
console.log(chalk.gray(' Gateway ID:'), result.gateway_id || 'created');
|
|
299
|
+
console.log(chalk.gray(' Agent DID: '), agentDid);
|
|
300
|
+
console.log(chalk.gray('\n Your gateway is now live in the NervePay dashboard.'));
|
|
301
|
+
console.log(chalk.gray(' Go to Mission Control to spawn agents and manage tasks.\n'));
|
|
302
|
+
|
|
303
|
+
// Save credentials if new
|
|
304
|
+
if (isNew) {
|
|
305
|
+
try {
|
|
306
|
+
const { mkdir } = await import('fs/promises');
|
|
307
|
+
await mkdir(join(homedir(), '.nervepay'), { recursive: true });
|
|
308
|
+
await writeFile(
|
|
309
|
+
NERVEPAY_CREDS_PATH,
|
|
310
|
+
JSON.stringify({ agent_did: agentDid, private_key: privateKey, created_at: new Date().toISOString() }, null, 2)
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
// Update OpenClaw config
|
|
314
|
+
if (!openclawConfig.plugins) openclawConfig.plugins = {};
|
|
315
|
+
if (!openclawConfig.plugins.entries) openclawConfig.plugins.entries = {};
|
|
316
|
+
if (!openclawConfig.plugins.entries.nervepay) {
|
|
317
|
+
openclawConfig.plugins.entries.nervepay = { enabled: true, config: {} };
|
|
318
|
+
}
|
|
319
|
+
openclawConfig.plugins.entries.nervepay.config = {
|
|
320
|
+
...openclawConfig.plugins.entries.nervepay.config,
|
|
321
|
+
apiUrl: options.apiUrl,
|
|
322
|
+
agentDid,
|
|
323
|
+
privateKey,
|
|
324
|
+
};
|
|
325
|
+
await writeFile(OPENCLAW_CONFIG_PATH, JSON.stringify(openclawConfig, null, 2));
|
|
326
|
+
console.log(chalk.green(' ✓ Credentials saved to ~/.nervepay/credentials.json'));
|
|
327
|
+
} catch {
|
|
328
|
+
// Non-fatal — credentials shown above
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error(chalk.red('\n❌ Pairing failed:'), error.message);
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
|
|
195
337
|
// ============================================================================
|
|
196
338
|
// WHOAMI COMMAND
|
|
197
339
|
// ============================================================================
|