@highway1/cli 0.1.36 → 0.1.38

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@highway1/cli",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "CLI tool for Clawiverse network",
5
5
  "type": "module",
6
6
  "bin": {
@@ -7,6 +7,8 @@ import {
7
7
  createDHTOperations,
8
8
  createMessageRouter,
9
9
  sign,
10
+ verify,
11
+ extractPublicKey,
10
12
  } from '@highway1/core';
11
13
  import { getIdentity, getAgentCard, getBootstrapPeers } from '../config.js';
12
14
  import { success, error, spinner, printHeader, info } from '../ui.js';
@@ -66,46 +68,41 @@ export function registerJoinCommand(program: Command): void {
66
68
  }, { once: true });
67
69
  });
68
70
 
69
- // Phase 2: wait for relay reservation (up to 10s)
70
- const hasRelayAddr = () => node.getMultiaddrs().some(a => a.includes('/p2p-circuit'));
71
- if (!hasRelayAddr()) {
72
- info('Waiting for relay reservation...');
73
- await new Promise<void>((resolve) => {
74
- const timeout = setTimeout(() => {
75
- info(`Relay reservation timeout after 10s. Multiaddrs: ${node.getMultiaddrs().join(', ')}`);
76
- resolve();
77
- }, 10000);
78
-
79
- // Listen for relay:reservation event (fires when reservation succeeds)
80
- const onReservation = () => {
81
- info(`Relay reservation successful!`);
82
- clearTimeout(timeout);
83
- // Wait a bit for multiaddrs to update
84
- setTimeout(() => {
85
- info(`Relay addresses: ${node.getMultiaddrs().filter(a => a.includes('/p2p-circuit')).join(', ')}`);
86
- resolve();
87
- }, 500);
88
- };
89
-
90
- // Also listen for self:peer:update as fallback
91
- const onPeerUpdate = () => {
92
- if (hasRelayAddr()) {
93
- info(`Relay address acquired via peer update`);
94
- clearTimeout(timeout);
95
- resolve();
96
- }
97
- };
98
-
99
- node.libp2p.addEventListener('relay:reservation', onReservation, { once: true });
100
- node.libp2p.addEventListener('self:peer:update', onPeerUpdate);
101
-
102
- setTimeout(() => {
103
- node.libp2p.removeEventListener('relay:reservation', onReservation);
104
- node.libp2p.removeEventListener('self:peer:update', onPeerUpdate);
105
- }, 10000);
106
- });
107
- } else {
108
- info(`Relay address already present: ${node.getMultiaddrs().filter(a => a.includes('/p2p-circuit')).join(', ')}`);
71
+ // Phase 2: wait for relay reservation (up to 15s after connection)
72
+ // Check if we already have relay addresses (might be auto-added by libp2p)
73
+ const countRelayAddrs = () => node.getMultiaddrs().filter(a => a.includes('/p2p-circuit')).length;
74
+ const initialRelayCount = countRelayAddrs();
75
+
76
+ info(`Initial relay addresses: ${initialRelayCount}`);
77
+ info('Waiting for relay reservation...');
78
+
79
+ let reservationSucceeded = false;
80
+ await new Promise<void>((resolve) => {
81
+ const timeout = setTimeout(() => {
82
+ if (!reservationSucceeded) {
83
+ info(`Relay reservation timeout after 15s.`);
84
+ info(`Connected peers: ${node.libp2p.getPeers().map(p => p.toString()).join(', ')}`);
85
+ }
86
+ resolve();
87
+ }, 15000);
88
+
89
+ // Listen for relay:reservation event (fires when reservation succeeds)
90
+ const onReservation = (evt: any) => {
91
+ reservationSucceeded = true;
92
+ info(`✓ Relay reservation successful!`);
93
+ clearTimeout(timeout);
94
+ setTimeout(resolve, 500);
95
+ };
96
+
97
+ node.libp2p.addEventListener('relay:reservation', onReservation, { once: true });
98
+
99
+ setTimeout(() => {
100
+ node.libp2p.removeEventListener('relay:reservation', onReservation);
101
+ }, 15000);
102
+ });
103
+
104
+ if (!reservationSucceeded) {
105
+ info('⚠ Relay reservation did not complete - using fallback relay addresses');
109
106
  }
110
107
 
111
108
  connectSpin.succeed('Connected to network!');
@@ -153,10 +150,21 @@ export function registerJoinCommand(program: Command): void {
153
150
  }
154
151
  }, 30000); // ping every 30s
155
152
 
153
+ const verifyFn = async (signature: Uint8Array, data: Uint8Array): Promise<boolean> => {
154
+ try {
155
+ const decoded = JSON.parse(new TextDecoder().decode(data)) as { from?: string };
156
+ if (!decoded.from || typeof decoded.from !== 'string') return false;
157
+ const senderPublicKey = extractPublicKey(decoded.from);
158
+ return verify(signature, data, senderPublicKey);
159
+ } catch {
160
+ return false;
161
+ }
162
+ };
163
+
156
164
  // Register message handlers for incoming messages
157
165
  const router = createMessageRouter(
158
166
  node.libp2p,
159
- async () => true,
167
+ verifyFn,
160
168
  dht
161
169
  );
162
170
 
@@ -7,6 +7,8 @@ import {
7
7
  createMessageRouter,
8
8
  createDHTOperations,
9
9
  sign,
10
+ verify,
11
+ extractPublicKey,
10
12
  } from '@highway1/core';
11
13
  import { getIdentity, getBootstrapPeers } from '../config.js';
12
14
  import { success, error, spinner, printHeader, info } from '../ui.js';
@@ -70,10 +72,20 @@ export function registerSendCommand(program: Command): void {
70
72
  await identifyDone;
71
73
 
72
74
  const dht = createDHTOperations(node.libp2p);
75
+ const verifyFn = async (signature: Uint8Array, data: Uint8Array): Promise<boolean> => {
76
+ try {
77
+ const decoded = JSON.parse(new TextDecoder().decode(data)) as { from?: string };
78
+ if (!decoded.from || typeof decoded.from !== 'string') return false;
79
+ const senderPublicKey = extractPublicKey(decoded.from);
80
+ return verify(signature, data, senderPublicKey);
81
+ } catch {
82
+ return false;
83
+ }
84
+ };
73
85
 
74
86
  const router = createMessageRouter(
75
87
  node.libp2p,
76
- async () => true,
88
+ verifyFn,
77
89
  dht,
78
90
  bootstrapPeers
79
91
  );