nervepay 1.2.1 → 1.2.6

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.
@@ -288,190 +288,431 @@ program
288
288
 
289
289
  program
290
290
  .command('pair')
291
- .description('Quick pair gateway using a dashboard pairing code')
292
- .requiredOption('--code <code>', '6-character pairing code from NervePay dashboard')
291
+ .description('Pair gateway via device node protocol (default) or pairing code (--code)')
292
+ .option('--code <code>', '6-character pairing code (legacy flow)')
293
293
  .option('--api-url <url>', 'NervePay API URL', 'https://api.nervepay.xyz')
294
294
  .option('--gateway-url <url>', 'Gateway URL (e.g. ws://127.0.0.1:18789)')
295
- .option('--gateway-token <token>', 'Gateway authentication token')
296
- .option('--name <name>', 'Agent name', 'OpenClaw Gateway')
295
+ .option('--gateway-token <token>', 'Gateway authentication token (only for --code flow)')
296
+ .option('--name <name>', 'Gateway display name', 'OpenClaw Gateway')
297
+ .option('--timeout <seconds>', 'Approval wait timeout in seconds', '300')
297
298
  .action(async (options) => {
298
- console.log(chalk.cyan('\nšŸ”— NervePay Quick Pair\n'));
299
- console.log(chalk.gray(' Code:'), chalk.white(options.code));
299
+ if (options.code) {
300
+ await legacyCodePairing(options);
301
+ } else {
302
+ await deviceNodePairing(options);
303
+ }
304
+ });
305
+
306
+ /**
307
+ * Device node pairing — connects to gateway via WebSocket, signs challenge
308
+ * with the agent's DID Ed25519 key, and receives a scoped device token.
309
+ */
310
+ async function deviceNodePairing(options) {
311
+ const { signRawBytes, deriveDeviceId, getPublicKeyFromPrivate } = await import('../dist/utils/crypto.js');
300
312
 
313
+ console.log(chalk.cyan('\nšŸ”— NervePay Device Node Pairing\n'));
314
+
315
+ try {
316
+ // 1. Load agent credentials (must exist — run setup first)
317
+ let config;
301
318
  try {
302
- // Step 1: Load existing credentials or create new identity
303
- let agentDid, privateKey, mnemonic, claimUrl, sessionId, isNew = false;
319
+ config = await loadConfig();
320
+ } catch {
321
+ console.error(chalk.red('āŒ No agent credentials found.'));
322
+ console.error(chalk.yellow(' Run:'), chalk.cyan('nervepay setup'), chalk.yellow('first'));
323
+ process.exit(1);
324
+ }
304
325
 
305
- try {
306
- const config = await loadConfig();
307
- agentDid = config.agentDid;
308
- privateKey = config.privateKey;
309
- console.log(chalk.green('āœ“ Using existing agent identity'));
310
- console.log(chalk.gray(' DID:'), agentDid);
311
- } catch {
312
- // No existing config — create a new pending identity
313
- console.log(chalk.cyan(' No existing identity found, creating one...\n'));
314
- const tempClient = new NervePayClient({ apiUrl: options.apiUrl });
315
- const reg = await identity.registerPendingIdentity(tempClient, {
316
- name: options.name,
317
- description: 'Gateway operator',
318
- });
319
- agentDid = reg.did;
320
- privateKey = reg.private_key;
321
- mnemonic = reg.mnemonic;
322
- claimUrl = reg.claim_url;
323
- sessionId = reg.session_id;
324
- isNew = true;
325
- console.log(chalk.green(' āœ“ Agent identity created'));
326
- console.log(chalk.gray(' DID:'), agentDid);
327
-
328
- // Show claim URL and offer to open browser
329
- if (claimUrl) {
330
- console.log(chalk.cyan('\n šŸ‘¤ Claim this agent to link it to your NervePay account:'));
331
- console.log(chalk.yellow(` ${claimUrl}`));
332
- console.log(chalk.gray(' (This links the agent to your dashboard for management)\n'));
326
+ const { agentDid, privateKey, apiUrl } = config;
327
+ console.log(chalk.green('āœ“ Agent identity loaded'));
328
+ console.log(chalk.gray(' DID:'), agentDid);
333
329
 
334
- try {
335
- const open = await import('open');
336
- await open.default(claimUrl);
337
- console.log(chalk.gray(' Opened in browser.'));
338
- } catch {
339
- console.log(chalk.gray(' Open the URL above in your browser.'));
330
+ // 2. Find gateway URL from config or --gateway-url flag
331
+ let gatewayUrl = options.gatewayUrl;
332
+ if (!gatewayUrl) {
333
+ const openclawConfig = await readOpenClawConfig();
334
+ const gw = extractGatewayConfig(openclawConfig);
335
+ gatewayUrl = gw.url;
336
+ }
337
+
338
+ if (!gatewayUrl) {
339
+ console.error(chalk.red('\nāŒ Could not find gateway URL'));
340
+ console.error(chalk.yellow(' Provide it via one of:'));
341
+ console.error(chalk.gray(' --gateway-url <url> (e.g. ws://127.0.0.1:18789)'));
342
+ console.error(chalk.gray(' ~/.openclaw/openclaw.json'));
343
+ process.exit(1);
344
+ }
345
+
346
+ // Normalize to ws:// URL
347
+ let wsUrl = gatewayUrl.replace(/\/$/, '');
348
+ if (wsUrl.startsWith('https://')) wsUrl = 'wss://' + wsUrl.slice('https://'.length);
349
+ else if (wsUrl.startsWith('http://')) wsUrl = 'ws://' + wsUrl.slice('http://'.length);
350
+ else if (!wsUrl.startsWith('ws://') && !wsUrl.startsWith('wss://')) wsUrl = 'ws://' + wsUrl;
351
+
352
+ console.log(chalk.gray(' Gateway:'), wsUrl);
353
+
354
+ // 3. Derive device ID from agent's public key
355
+ const publicKeyBase58 = await getPublicKeyFromPrivate(privateKey);
356
+ const deviceId = deriveDeviceId(publicKeyBase58);
357
+ console.log(chalk.gray(' Device ID:'), deviceId.slice(0, 16) + '...');
358
+
359
+ // 4. Connect to gateway via WebSocket
360
+ console.log(chalk.cyan('\nšŸ“” Connecting to gateway...'));
361
+ const WebSocket = (await import('ws')).default;
362
+
363
+ const ws = new WebSocket(wsUrl);
364
+ const timeoutMs = parseInt(options.timeout, 10) * 1000;
365
+
366
+ const result = await new Promise((resolve, reject) => {
367
+ let connectId = null;
368
+ let pairId = null;
369
+ let requestId = null;
370
+ const timer = setTimeout(() => {
371
+ ws.close();
372
+ reject(new Error(`Pairing approval timed out (waited ${options.timeout}s)`));
373
+ }, timeoutMs + 15000); // Extra buffer for handshake
374
+
375
+ ws.on('error', (err) => {
376
+ clearTimeout(timer);
377
+ reject(new Error(`WebSocket error: ${err.message}`));
378
+ });
379
+
380
+ ws.on('close', () => {
381
+ clearTimeout(timer);
382
+ if (!requestId) {
383
+ reject(new Error('Gateway closed connection before pairing completed'));
384
+ }
385
+ });
386
+
387
+ ws.on('message', async (data) => {
388
+ try {
389
+ const frame = JSON.parse(data.toString());
390
+
391
+ // Step 5: Receive connect.challenge → sign nonce
392
+ if (frame.event === 'connect.challenge') {
393
+ const nonce = frame.payload?.nonce || '';
394
+ console.log(chalk.green('āœ“ Challenge received'));
395
+
396
+ const nonceBytes = new TextEncoder().encode(nonce);
397
+ const signatureB64 = await signRawBytes(privateKey, nonceBytes);
398
+ const signedAt = Date.now();
399
+
400
+ // Encode public key as base64 for the gateway
401
+ const { decodeBase58 } = await import('../dist/utils/crypto.js');
402
+ const pubKeyBytes = decodeBase58(publicKeyBase58);
403
+ const pubKeyB64 = Buffer.from(pubKeyBytes).toString('base64');
404
+
405
+ // Step 6: Send connect request as operator with device identity
406
+ connectId = crypto.randomUUID();
407
+ const connectReq = {
408
+ type: 'request',
409
+ id: connectId,
410
+ method: 'connect',
411
+ params: {
412
+ role: 'operator',
413
+ scopes: ['operator.read', 'operator.write'],
414
+ client: {
415
+ id: `nervepay-cli-${crypto.randomUUID().slice(0, 8)}`,
416
+ version: '1.2.1',
417
+ platform: 'cli',
418
+ mode: 'pairing',
419
+ },
420
+ device: {
421
+ id: deviceId,
422
+ publicKey: pubKeyB64,
423
+ signature: signatureB64,
424
+ signedAt,
425
+ nonce,
426
+ },
427
+ },
428
+ };
429
+ ws.send(JSON.stringify(connectReq));
430
+ return;
340
431
  }
341
432
 
342
- // Poll for claim (30 seconds — quick pair shouldn't block too long)
343
- console.log(chalk.cyan(' ā³ Waiting for claim (30s timeout)...\n'));
344
- let claimed = false;
345
- for (let i = 0; i < 6; i++) {
346
- await new Promise((r) => setTimeout(r, 5000));
347
- try {
348
- const status = await fetch(`${options.apiUrl}/v1/agent-identity/register-pending/${sessionId}/status`);
349
- const data = await status.json();
350
- if (data.status === 'claimed') {
351
- claimed = true;
352
- console.log(chalk.green(' āœ“ Agent claimed successfully!\n'));
353
- break;
354
- } else if (data.status === 'expired') {
355
- break;
356
- }
357
- process.stdout.write(chalk.gray('.'));
358
- } catch {
359
- process.stdout.write(chalk.gray('.'));
433
+ // Connect response
434
+ if (frame.type === 'response' && frame.id === connectId) {
435
+ if (frame.ok) {
436
+ console.log(chalk.green('āœ“ Connected to gateway'));
437
+
438
+ // Step 7: Send node.pair.request
439
+ pairId = crypto.randomUUID();
440
+ const pairReq = {
441
+ type: 'request',
442
+ id: pairId,
443
+ method: 'node.pair.request',
444
+ params: {
445
+ displayName: `NervePay (${agentDid.split(':').pop().slice(0, 8)})`,
446
+ platform: 'cli',
447
+ },
448
+ };
449
+ ws.send(JSON.stringify(pairReq));
450
+ } else {
451
+ clearTimeout(timer);
452
+ ws.close();
453
+ reject(new Error(`Connect rejected: ${frame.error || 'Unknown error'}`));
360
454
  }
455
+ return;
361
456
  }
362
457
 
363
- if (!claimed) {
364
- console.log(chalk.yellow('\n āš ļø Not claimed yet — continuing with pairing.'));
365
- console.log(chalk.gray(' You can claim later at:'), chalk.yellow(claimUrl));
458
+ // Pair request response → extract requestId
459
+ if (frame.type === 'response' && frame.id === pairId) {
460
+ if (frame.ok) {
461
+ requestId = frame.payload?.requestId || '';
462
+ console.log(chalk.green('āœ“ Pairing request submitted'));
463
+ console.log(chalk.cyan('\nā³ Waiting for gateway owner approval...'));
464
+ console.log(chalk.gray(` Approve with: openclaw devices approve`));
465
+ console.log(chalk.gray(` Timeout: ${options.timeout}s\n`));
466
+ } else {
467
+ clearTimeout(timer);
468
+ ws.close();
469
+ reject(new Error(`Pair request rejected: ${frame.error || 'Unknown error'}`));
470
+ }
471
+ return;
366
472
  }
367
- }
368
473
 
369
- // Show mnemonic
370
- if (mnemonic) {
371
- console.log(chalk.cyan('\n šŸ” Recovery mnemonic:'));
372
- console.log(chalk.yellow(` ${mnemonic}`));
373
- console.log(chalk.red(' āš ļø Save this — you can recover your keys with it!\n'));
474
+ // Step 8: node.pair.resolved event
475
+ if (frame.event === 'node.pair.resolved') {
476
+ const rid = frame.payload?.requestId;
477
+ if (rid && rid !== requestId) return; // Not our request
478
+
479
+ const decision = frame.payload?.decision;
480
+ if (decision === 'approved') {
481
+ clearTimeout(timer);
482
+ const token = frame.payload?.token || '';
483
+ const nodeId = frame.payload?.nodeId || '';
484
+ ws.close();
485
+ resolve({ token, nodeId, requestId });
486
+ } else if (decision === 'rejected') {
487
+ clearTimeout(timer);
488
+ ws.close();
489
+ reject(new Error('Pairing request was rejected by the gateway owner'));
490
+ } else {
491
+ clearTimeout(timer);
492
+ ws.close();
493
+ reject(new Error(`Unexpected pairing decision: ${decision}`));
494
+ }
495
+ return;
496
+ }
497
+ } catch (err) {
498
+ // Ignore parse errors for non-JSON messages (ping, etc)
374
499
  }
500
+ });
501
+ });
502
+
503
+ // 9. Send device token to NervePay API
504
+ console.log(chalk.green('\nāœ“ Pairing approved! Saving to NervePay...'));
505
+
506
+ const client = new NervePayClient({
507
+ apiUrl: options.apiUrl || apiUrl,
508
+ agentDid,
509
+ privateKey,
510
+ });
511
+
512
+ const apiResult = await gateway.completeDevicePairing(client, {
513
+ device_token: result.token,
514
+ device_id: deviceId,
515
+ gateway_url: gatewayUrl,
516
+ gateway_name: options.name,
517
+ });
518
+
519
+ console.log(chalk.green('\nāœ… Device pairing complete!'));
520
+ console.log(chalk.gray(' Gateway ID:'), apiResult.gateway_id || 'created');
521
+ console.log(chalk.gray(' Device ID: '), deviceId.slice(0, 16) + '...');
522
+ console.log(chalk.gray(' Agent DID: '), agentDid);
523
+ console.log(chalk.gray('\n Your gateway is now live in the NervePay dashboard.'));
524
+ console.log(chalk.gray(' Go to Mission Control to spawn agents and manage tasks.\n'));
525
+ } catch (error) {
526
+ console.error(chalk.red('\nāŒ Device pairing failed:'), error.message);
527
+ process.exit(1);
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Legacy code-based pairing flow (--code flag provided).
533
+ */
534
+ async function legacyCodePairing(options) {
535
+ console.log(chalk.cyan('\nšŸ”— NervePay Code Pairing\n'));
536
+ console.log(chalk.gray(' Code:'), chalk.white(options.code));
537
+
538
+ try {
539
+ // Step 1: Load existing credentials or create new identity
540
+ let agentDid, privateKey, mnemonic, claimUrl, sessionId, isNew = false;
541
+
542
+ try {
543
+ const config = await loadConfig();
544
+ agentDid = config.agentDid;
545
+ privateKey = config.privateKey;
546
+ console.log(chalk.green('āœ“ Using existing agent identity'));
547
+ console.log(chalk.gray(' DID:'), agentDid);
548
+ } catch {
549
+ // No existing config — create a new pending identity
550
+ console.log(chalk.cyan(' No existing identity found, creating one...\n'));
551
+ const tempClient = new NervePayClient({ apiUrl: options.apiUrl });
552
+ const reg = await identity.registerPendingIdentity(tempClient, {
553
+ name: options.name,
554
+ description: 'Gateway operator',
555
+ });
556
+ agentDid = reg.did;
557
+ privateKey = reg.private_key;
558
+ mnemonic = reg.mnemonic;
559
+ claimUrl = reg.claim_url;
560
+ sessionId = reg.session_id;
561
+ isNew = true;
562
+ console.log(chalk.green(' āœ“ Agent identity created'));
563
+ console.log(chalk.gray(' DID:'), agentDid);
564
+
565
+ // Show claim URL and offer to open browser
566
+ if (claimUrl) {
567
+ console.log(chalk.cyan('\n šŸ‘¤ Claim this agent to link it to your NervePay account:'));
568
+ console.log(chalk.yellow(` ${claimUrl}`));
569
+ console.log(chalk.gray(' (This links the agent to your dashboard for management)\n'));
375
570
 
376
- // Save credentials immediately so they persist even if pairing fails
377
571
  try {
378
- const { mkdir } = await import('fs/promises');
379
- await mkdir(join(homedir(), '.nervepay'), { recursive: true });
380
- await writeFile(
381
- NERVEPAY_CREDS_PATH,
382
- JSON.stringify({
383
- agent_did: agentDid,
384
- private_key: privateKey,
385
- mnemonic: mnemonic || undefined,
386
- api_url: options.apiUrl,
387
- created_at: new Date().toISOString(),
388
- }, null, 2)
389
- );
390
- console.log(chalk.green(' āœ“ Credentials saved to ~/.nervepay/credentials.json'));
391
-
392
- // Update OpenClaw config if it exists
572
+ const open = await import('open');
573
+ await open.default(claimUrl);
574
+ console.log(chalk.gray(' Opened in browser.'));
575
+ } catch {
576
+ console.log(chalk.gray(' Open the URL above in your browser.'));
577
+ }
578
+
579
+ // Poll for claim (30 seconds — quick pair shouldn't block too long)
580
+ console.log(chalk.cyan(' ā³ Waiting for claim (30s timeout)...\n'));
581
+ let claimed = false;
582
+ for (let i = 0; i < 6; i++) {
583
+ await new Promise((r) => setTimeout(r, 5000));
393
584
  try {
394
- const ocConfigPath = await findOpenClawConfigPath();
395
- if (ocConfigPath) {
396
- const existingConfig = JSON.parse(await readFile(ocConfigPath, 'utf-8'));
397
- if (!existingConfig.plugins) existingConfig.plugins = {};
398
- if (!existingConfig.plugins.entries) existingConfig.plugins.entries = {};
399
- if (!existingConfig.plugins.entries.nervepay) {
400
- existingConfig.plugins.entries.nervepay = { enabled: true, config: {} };
401
- }
402
- existingConfig.plugins.entries.nervepay.config = {
403
- ...existingConfig.plugins.entries.nervepay.config,
404
- apiUrl: options.apiUrl,
405
- agentDid,
406
- privateKey,
407
- };
408
- await writeFile(ocConfigPath, JSON.stringify(existingConfig, null, 2));
409
- console.log(chalk.green(' āœ“ OpenClaw config updated'));
585
+ const status = await fetch(`${options.apiUrl}/v1/agent-identity/register-pending/${sessionId}/status`);
586
+ const data = await status.json();
587
+ if (data.status === 'claimed') {
588
+ claimed = true;
589
+ console.log(chalk.green(' āœ“ Agent claimed successfully!\n'));
590
+ break;
591
+ } else if (data.status === 'expired') {
592
+ break;
410
593
  }
594
+ process.stdout.write(chalk.gray('.'));
411
595
  } catch {
412
- // Non-fatal
596
+ process.stdout.write(chalk.gray('.'));
413
597
  }
414
- } catch (e) {
415
- console.log(chalk.yellow(' āš ļø Could not save credentials:'), e.message);
416
598
  }
417
- }
418
-
419
- // Step 2: Read gateway config (from flags, env, or config files)
420
- console.log(chalk.cyan('šŸ“” Reading gateway config...'));
421
-
422
- let gatewayUrl = options.gatewayUrl;
423
- let gatewayToken = options.gatewayToken;
424
599
 
425
- // Try OpenClaw config if flags not provided
426
- if (!gatewayUrl || !gatewayToken) {
427
- const openclawConfig = await readOpenClawConfig();
428
- const gw = extractGatewayConfig(openclawConfig);
429
- gatewayUrl = gatewayUrl || gw.url;
430
- gatewayToken = gatewayToken || gw.token;
600
+ if (!claimed) {
601
+ console.log(chalk.yellow('\n āš ļø Not claimed yet — continuing with pairing.'));
602
+ console.log(chalk.gray(' You can claim later at:'), chalk.yellow(claimUrl));
603
+ }
431
604
  }
432
605
 
433
- // Default URL if we have a token but no URL
434
- if (gatewayToken && !gatewayUrl) {
435
- gatewayUrl = 'http://127.0.0.1:18789';
606
+ // Show mnemonic
607
+ if (mnemonic) {
608
+ console.log(chalk.cyan('\n šŸ” Recovery mnemonic:'));
609
+ console.log(chalk.yellow(` ${mnemonic}`));
610
+ console.log(chalk.red(' āš ļø Save this — you can recover your keys with it!\n'));
436
611
  }
437
612
 
438
- if (!gatewayToken) {
439
- console.error(chalk.red('\nāŒ Could not find gateway token'));
440
- console.error(chalk.yellow(' Provide it via one of:'));
441
- console.error(chalk.gray(' --gateway-token <token>'));
442
- console.error(chalk.gray(' ~/.openclaw/openclaw.json (gateway.auth.token)'));
443
- console.error(chalk.gray(' OPENCLAW_GATEWAY_TOKEN env var'));
444
- process.exit(1);
613
+ // Save credentials immediately so they persist even if pairing fails
614
+ try {
615
+ const { mkdir } = await import('fs/promises');
616
+ await mkdir(join(homedir(), '.nervepay'), { recursive: true });
617
+ await writeFile(
618
+ NERVEPAY_CREDS_PATH,
619
+ JSON.stringify({
620
+ agent_did: agentDid,
621
+ private_key: privateKey,
622
+ mnemonic: mnemonic || undefined,
623
+ api_url: options.apiUrl,
624
+ created_at: new Date().toISOString(),
625
+ }, null, 2)
626
+ );
627
+ console.log(chalk.green(' āœ“ Credentials saved to ~/.nervepay/credentials.json'));
628
+
629
+ // Update OpenClaw config if it exists
630
+ try {
631
+ const ocConfigPath = await findOpenClawConfigPath();
632
+ if (ocConfigPath) {
633
+ const existingConfig = JSON.parse(await readFile(ocConfigPath, 'utf-8'));
634
+ if (!existingConfig.plugins) existingConfig.plugins = {};
635
+ if (!existingConfig.plugins.entries) existingConfig.plugins.entries = {};
636
+ if (!existingConfig.plugins.entries.nervepay) {
637
+ existingConfig.plugins.entries.nervepay = { enabled: true, config: {} };
638
+ }
639
+ existingConfig.plugins.entries.nervepay.config = {
640
+ ...existingConfig.plugins.entries.nervepay.config,
641
+ apiUrl: options.apiUrl,
642
+ agentDid,
643
+ privateKey,
644
+ };
645
+ await writeFile(ocConfigPath, JSON.stringify(existingConfig, null, 2));
646
+ console.log(chalk.green(' āœ“ OpenClaw config updated'));
647
+ }
648
+ } catch {
649
+ // Non-fatal
650
+ }
651
+ } catch (e) {
652
+ console.log(chalk.yellow(' āš ļø Could not save credentials:'), e.message);
445
653
  }
654
+ }
446
655
 
447
- console.log(chalk.green('āœ“ Gateway found'));
448
- console.log(chalk.gray(' URL:'), gatewayUrl);
656
+ // Step 2: Read gateway config (from flags, env, or config files)
657
+ console.log(chalk.cyan('šŸ“” Reading gateway config...'));
449
658
 
450
- // Step 3: Complete pairing
451
- console.log(chalk.cyan('\nšŸ” Completing pairing...'));
452
- const client = new NervePayClient({
453
- apiUrl: options.apiUrl,
454
- agentDid,
455
- privateKey,
456
- });
659
+ let gatewayUrl = options.gatewayUrl;
660
+ let gatewayToken = options.gatewayToken;
457
661
 
458
- const result = await gateway.completePairing(client, {
459
- pairing_code: options.code,
460
- gateway_url: gatewayUrl,
461
- gateway_token: gatewayToken,
462
- gateway_name: options.name,
463
- });
662
+ // Try OpenClaw config if flags not provided
663
+ if (!gatewayUrl || !gatewayToken) {
664
+ const openclawConfig = await readOpenClawConfig();
665
+ const gw = extractGatewayConfig(openclawConfig);
666
+ gatewayUrl = gatewayUrl || gw.url;
667
+ gatewayToken = gatewayToken || gw.token;
668
+ }
464
669
 
465
- console.log(chalk.green('\nāœ… Pairing complete!'));
466
- console.log(chalk.gray(' Gateway ID:'), result.gateway_id || 'created');
467
- console.log(chalk.gray(' Agent DID: '), agentDid);
468
- console.log(chalk.gray('\n Your gateway is now live in the NervePay dashboard.'));
469
- console.log(chalk.gray(' Go to Mission Control to spawn agents and manage tasks.\n'));
470
- } catch (error) {
471
- console.error(chalk.red('\nāŒ Pairing failed:'), error.message);
670
+ if (!gatewayToken) {
671
+ console.error(chalk.red('\nāŒ Could not find gateway token'));
672
+ console.error(chalk.yellow(' Provide it via one of:'));
673
+ console.error(chalk.gray(' --gateway-token <token>'));
674
+ console.error(chalk.gray(' ~/.openclaw/openclaw.json (gateway.auth.token)'));
675
+ console.error(chalk.gray(' OPENCLAW_GATEWAY_TOKEN env var'));
472
676
  process.exit(1);
473
677
  }
474
- });
678
+
679
+ if (!gatewayUrl) {
680
+ console.error(chalk.red('\nāŒ Could not find gateway URL'));
681
+ console.error(chalk.yellow(' Provide it via one of:'));
682
+ console.error(chalk.gray(' --gateway-url <url> (e.g. ws://your-server:18789)'));
683
+ console.error(chalk.gray(' ~/.openclaw/openclaw.json'));
684
+ console.error(chalk.gray(' OPENCLAW_GATEWAY_URL env var'));
685
+ process.exit(1);
686
+ }
687
+
688
+ console.log(chalk.green('āœ“ Gateway found'));
689
+ console.log(chalk.gray(' URL:'), gatewayUrl);
690
+
691
+ // Step 3: Complete pairing
692
+ console.log(chalk.cyan('\nšŸ” Completing pairing...'));
693
+ const client = new NervePayClient({
694
+ apiUrl: options.apiUrl,
695
+ agentDid,
696
+ privateKey,
697
+ });
698
+
699
+ const result = await gateway.completePairing(client, {
700
+ pairing_code: options.code,
701
+ gateway_url: gatewayUrl,
702
+ gateway_token: gatewayToken,
703
+ gateway_name: options.name,
704
+ });
705
+
706
+ console.log(chalk.green('\nāœ… Pairing complete!'));
707
+ console.log(chalk.gray(' Gateway ID:'), result.gateway_id || 'created');
708
+ console.log(chalk.gray(' Agent DID: '), agentDid);
709
+ console.log(chalk.gray('\n Your gateway is now live in the NervePay dashboard.'));
710
+ console.log(chalk.gray(' Go to Mission Control to spawn agents and manage tasks.\n'));
711
+ } catch (error) {
712
+ console.error(chalk.red('\nāŒ Pairing failed:'), error.message);
713
+ process.exit(1);
714
+ }
715
+ }
475
716
 
476
717
  // ============================================================================
477
718
  // WHOAMI COMMAND
@@ -29,6 +29,12 @@ export interface CompletePairingParams {
29
29
  gateway_token: string;
30
30
  gateway_name: string;
31
31
  }
32
+ export interface DevicePairingCompleteParams {
33
+ device_token: string;
34
+ device_id: string;
35
+ gateway_url: string;
36
+ gateway_name?: string;
37
+ }
32
38
  export interface Gateway {
33
39
  id: string;
34
40
  name: string;
@@ -56,6 +62,13 @@ export declare function completePairing(client: NervePayClient, params: Complete
56
62
  gateway_id: string;
57
63
  status: string;
58
64
  }>;
65
+ /**
66
+ * Complete device node pairing — sends the scoped device token to NervePay API
67
+ */
68
+ export declare function completeDevicePairing(client: NervePayClient, params: DevicePairingCompleteParams): Promise<{
69
+ gateway_id: string;
70
+ status: string;
71
+ }>;
59
72
  /**
60
73
  * List all gateways
61
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/tools/gateway.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../src/tools/gateway.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,12 @@ export async function getPairingRequestStatus(client, requestId) {
23
23
  export async function completePairing(client, params) {
24
24
  return client.post('/v1/integrations/openclaw/pairing/complete', params, true);
25
25
  }
26
+ /**
27
+ * Complete device node pairing — sends the scoped device token to NervePay API
28
+ */
29
+ export async function completeDevicePairing(client, params) {
30
+ return client.post('/v1/integrations/openclaw/device-pairing/complete', params, true);
31
+ }
26
32
  /**
27
33
  * List all gateways
28
34
  */
@@ -1 +1 @@
1
- {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/tools/gateway.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/tools/gateway.ts"],"names":[],"mappings":"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"}
@@ -21,6 +21,21 @@ export declare function verifySignature(publicKeyBase58: string, payload: Record
21
21
  * Generate SHA-256 hash of string
22
22
  */
23
23
  export declare function sha256Hash(data: string): string;
24
+ /**
25
+ * Sign raw bytes with Ed25519 private key (for gateway challenge signing).
26
+ * Returns base64-encoded signature.
27
+ */
28
+ export declare function signRawBytes(privateKeyBase58: string, data: Uint8Array): Promise<string>;
29
+ /**
30
+ * Derive a deterministic device ID from a public key (SHA-256 hex fingerprint).
31
+ * Matches the Rust `derive_device_id()` implementation.
32
+ */
33
+ export declare function deriveDeviceId(publicKeyBase58: string): string;
34
+ /**
35
+ * Extract the Ed25519 public key from a private key seed.
36
+ * Returns base58-encoded public key.
37
+ */
38
+ export declare function getPublicKeyFromPrivate(privateKeyBase58: string): Promise<string>;
24
39
  /**
25
40
  * Generate random UUID v4
26
41
  */
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA6BpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAwBtD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA6BpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAwBtD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
@@ -103,6 +103,36 @@ export function sha256Hash(data) {
103
103
  const bytes = new TextEncoder().encode(data);
104
104
  return bytesToHex(sha256(bytes));
105
105
  }
106
+ /**
107
+ * Sign raw bytes with Ed25519 private key (for gateway challenge signing).
108
+ * Returns base64-encoded signature.
109
+ */
110
+ export async function signRawBytes(privateKeyBase58, data) {
111
+ const keyStr = privateKeyBase58.replace(/^ed25519:/, '');
112
+ const privateKeyBytes = decodeBase58(keyStr);
113
+ const seed = privateKeyBytes.slice(0, 32);
114
+ const signature = await ed25519.sign(data, seed);
115
+ return Buffer.from(signature).toString('base64');
116
+ }
117
+ /**
118
+ * Derive a deterministic device ID from a public key (SHA-256 hex fingerprint).
119
+ * Matches the Rust `derive_device_id()` implementation.
120
+ */
121
+ export function deriveDeviceId(publicKeyBase58) {
122
+ const publicKeyBytes = decodeBase58(publicKeyBase58);
123
+ return bytesToHex(sha256(publicKeyBytes));
124
+ }
125
+ /**
126
+ * Extract the Ed25519 public key from a private key seed.
127
+ * Returns base58-encoded public key.
128
+ */
129
+ export async function getPublicKeyFromPrivate(privateKeyBase58) {
130
+ const keyStr = privateKeyBase58.replace(/^ed25519:/, '');
131
+ const privateKeyBytes = decodeBase58(keyStr);
132
+ const seed = privateKeyBytes.slice(0, 32);
133
+ const publicKey = await ed25519.getPublicKey(seed);
134
+ return encodeBase58(publicKey);
135
+ }
106
136
  /**
107
137
  * Generate random UUID v4
108
138
  */
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/utils/crypto.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nervepay",
3
- "version": "1.2.1",
3
+ "version": "1.2.6",
4
4
  "description": "NervePay plugin for OpenClaw - Self-sovereign identity, vault, and orchestration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -43,13 +43,15 @@
43
43
  "commander": "^13.1.0",
44
44
  "inquirer": "^12.4.0",
45
45
  "chalk": "^5.4.1",
46
- "open": "^10.1.0"
46
+ "open": "^10.1.0",
47
+ "ws": "^8.16.0"
47
48
  },
48
49
  "peerDependencies": {
49
50
  "openclaw": ">=1.0.0"
50
51
  },
51
52
  "devDependencies": {
52
53
  "@types/node": "^22.13.0",
54
+ "@types/ws": "^8.5.10",
53
55
  "typescript": "^5.7.3",
54
56
  "vitest": "^3.0.0"
55
57
  },