@fiber-pay/cli 0.1.1 → 0.2.1

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/README.md CHANGED
@@ -23,5 +23,5 @@ See [docs/l402-agent-guide.md](../../docs/l402-agent-guide.md) for L402 and agen
23
23
  ## Compatibility
24
24
 
25
25
  - Node.js `>=20`
26
- - Fiber target: `v0.7.1`
26
+ - Fiber target: `v0.8.0`
27
27
 
package/dist/cli.js CHANGED
@@ -147,8 +147,8 @@ function formatChannel(channel) {
147
147
  return {
148
148
  channelId: channel.channel_id,
149
149
  channelIdShort: truncateMiddle(channel.channel_id, 10, 8),
150
- peerId: channel.peer_id,
151
- peerIdShort: truncateMiddle(channel.peer_id, 10, 8),
150
+ peerId: channel.pubkey,
151
+ peerIdShort: truncateMiddle(channel.pubkey, 10, 8),
152
152
  state: channel.state.state_name,
153
153
  stateLabel: stateLabel(channel.state.state_name),
154
154
  stateFlags: channel.state.state_flags,
@@ -185,10 +185,10 @@ function extractInvoiceMetadata(invoice) {
185
185
  let description;
186
186
  let expirySeconds;
187
187
  for (const attr of invoice.data.attrs) {
188
- if ("Description" in attr) description = attr.Description;
189
- if ("ExpiryTime" in attr) {
188
+ if ("description" in attr) description = attr.description;
189
+ if ("expiry_time" in attr) {
190
190
  try {
191
- expirySeconds = Number(BigInt(attr.ExpiryTime));
191
+ expirySeconds = Number(BigInt(attr.expiry_time));
192
192
  } catch {
193
193
  }
194
194
  }
@@ -235,7 +235,7 @@ function printChannelDetailHuman(channel) {
235
235
  const capacity = local + remote;
236
236
  console.log("Channel");
237
237
  console.log(` ID: ${channel.channel_id}`);
238
- console.log(` Peer: ${channel.peer_id}`);
238
+ console.log(` Peer: ${channel.pubkey}`);
239
239
  console.log(
240
240
  ` State: ${stateLabel(channel.state.state_name)} (${channel.state.state_name})`
241
241
  );
@@ -308,7 +308,7 @@ function printChannelListHuman(channels) {
308
308
  );
309
309
  for (const channel of channels) {
310
310
  const id = truncateMiddle(channel.channel_id, 10, 8).padEnd(22, " ");
311
- const peer = truncateMiddle(channel.peer_id, 10, 8).padEnd(22, " ");
311
+ const peer = truncateMiddle(channel.pubkey, 10, 8).padEnd(22, " ");
312
312
  const state = channel.state.state_name.padEnd(24, " ");
313
313
  const local = `${shannonsToCkb(channel.local_balance)}`.padStart(8, " ");
314
314
  const remote = `${shannonsToCkb(channel.remote_balance)}`.padStart(8, " ");
@@ -323,12 +323,11 @@ function printPeerListHuman(peers) {
323
323
  }
324
324
  console.log(`Peers: ${peers.length}`);
325
325
  console.log("");
326
- console.log("PEER ID PUBKEY ADDRESS");
327
- console.log("--------------------------------------------------------------------------");
326
+ console.log("PUBKEY ADDRESS");
327
+ console.log("----------------------------------------------------------");
328
328
  for (const peer of peers) {
329
- const peerId = truncateMiddle(peer.peer_id, 10, 8).padEnd(22, " ");
330
329
  const pubkey = truncateMiddle(peer.pubkey, 10, 8).padEnd(22, " ");
331
- console.log(`${peerId} ${pubkey} ${peer.address}`);
330
+ console.log(`${pubkey} ${peer.address}`);
332
331
  }
333
332
  }
334
333
 
@@ -676,7 +675,7 @@ async function runAgentCallCommand(config, url, options) {
676
675
  // src/lib/agent-serve.ts
677
676
  import { execFileSync, spawn } from "child_process";
678
677
  import { createServer } from "http";
679
- import { createL402Middleware, FiberRpcClient as FiberRpcClient2 } from "@fiber-pay/sdk";
678
+ import { createL402Middleware, FiberRpcClient as FiberRpcClient2 } from "@fiber-pay/sdk/node";
680
679
  import express from "express";
681
680
  function getClientIp(req) {
682
681
  const forwarded = req.headers["x-forwarded-for"];
@@ -1232,7 +1231,7 @@ function createBinaryCommand(config) {
1232
1231
 
1233
1232
  // src/commands/channel.ts
1234
1233
  import { randomUUID } from "crypto";
1235
- import { ckbToShannons as ckbToShannons2 } from "@fiber-pay/sdk";
1234
+ import { ckbToShannons as ckbToShannons2, nodeIdToPeerId } from "@fiber-pay/sdk";
1236
1235
  import { Command as Command3 } from "commander";
1237
1236
 
1238
1237
  // src/lib/async.ts
@@ -1333,7 +1332,7 @@ async function executeRebalance(config, params) {
1333
1332
  }
1334
1333
  process.exit(1);
1335
1334
  }
1336
- const selfPubkey = (await rpc.nodeInfo()).node_id;
1335
+ const selfPubkey = (await rpc.nodeInfo()).pubkey;
1337
1336
  const amount = ckbToShannons(amountCkb);
1338
1337
  const isManual = manualHops.length > 0;
1339
1338
  let routeHopCount;
@@ -1468,7 +1467,7 @@ function registerChannelRebalanceCommand(parent, config) {
1468
1467
  }
1469
1468
  process.exit(1);
1470
1469
  }
1471
- if (fromChannel.peer_id === toChannel.peer_id) {
1470
+ if (fromChannel.pubkey === toChannel.pubkey) {
1472
1471
  const message = "Source and target channels point to the same peer; choose two different channel peers.";
1473
1472
  if (json) {
1474
1473
  printJsonError({
@@ -1479,7 +1478,7 @@ function registerChannelRebalanceCommand(parent, config) {
1479
1478
  details: {
1480
1479
  fromChannel: fromChannelId,
1481
1480
  toChannel: toChannelId,
1482
- peerId: fromChannel.peer_id
1481
+ peerId: fromChannel.pubkey
1483
1482
  }
1484
1483
  });
1485
1484
  } else {
@@ -1487,24 +1486,21 @@ function registerChannelRebalanceCommand(parent, config) {
1487
1486
  }
1488
1487
  process.exit(1);
1489
1488
  }
1490
- const peers = (await rpc.listPeers()).peers;
1491
- const pubkeyByPeerId = new Map(peers.map((peer) => [peer.peer_id, peer.pubkey]));
1492
- const fromPubkey = pubkeyByPeerId.get(fromChannel.peer_id);
1493
- const toPubkey = pubkeyByPeerId.get(toChannel.peer_id);
1489
+ const fromPubkey = fromChannel.pubkey;
1490
+ const toPubkey = toChannel.pubkey;
1494
1491
  if (!fromPubkey || !toPubkey) {
1495
- const message = "Unable to resolve selected channel peer_id to pubkey for guided rebalance route.";
1492
+ const message = "Unable to resolve selected channel pubkey for guided rebalance route.";
1496
1493
  if (json) {
1497
1494
  printJsonError({
1498
1495
  code: "CHANNEL_REBALANCE_INPUT_INVALID",
1499
1496
  message,
1500
1497
  recoverable: true,
1501
- suggestion: "Ensure both peers are connected (`peer list --json`) and retry guided mode, or use `payment rebalance --hops`.",
1498
+ suggestion: "Ensure channel details are up to date and retry guided mode, or use `payment rebalance --hops`.",
1502
1499
  details: {
1503
1500
  fromChannel: fromChannelId,
1504
1501
  toChannel: toChannelId,
1505
- fromPeerId: fromChannel.peer_id,
1506
- toPeerId: toChannel.peer_id,
1507
- resolvedPeers: peers.length
1502
+ fromPeerId: fromChannel.pubkey,
1503
+ toPeerId: toChannel.pubkey
1508
1504
  }
1509
1505
  });
1510
1506
  } else {
@@ -1526,13 +1522,42 @@ function registerChannelRebalanceCommand(parent, config) {
1526
1522
  }
1527
1523
 
1528
1524
  // src/commands/channel.ts
1525
+ function extractPeerIdFromMultiaddr(address) {
1526
+ const match = address.match(/\/p2p\/([^/]+)$/);
1527
+ return match?.[1];
1528
+ }
1529
+ async function resolvePeerPubkeyFromMultiaddr(rpc, address, timeoutMs) {
1530
+ const expectedPeerId = extractPeerIdFromMultiaddr(address);
1531
+ if (!expectedPeerId) {
1532
+ throw new Error("Invalid peer multiaddr: missing /p2p/<peerId> suffix");
1533
+ }
1534
+ const start = Date.now();
1535
+ while (Date.now() - start < timeoutMs) {
1536
+ const peers = await rpc.listPeers();
1537
+ for (const peer of peers.peers) {
1538
+ if (extractPeerIdFromMultiaddr(peer.address) === expectedPeerId) {
1539
+ return peer.pubkey;
1540
+ }
1541
+ try {
1542
+ if (await nodeIdToPeerId(peer.pubkey) === expectedPeerId) {
1543
+ return peer.pubkey;
1544
+ }
1545
+ } catch {
1546
+ }
1547
+ }
1548
+ await sleep(500);
1549
+ }
1550
+ throw new Error(
1551
+ `connect_peer accepted but peer pubkey not resolved within ${Math.floor(timeoutMs / 1e3)}s (${expectedPeerId})`
1552
+ );
1553
+ }
1529
1554
  function createChannelCommand(config) {
1530
1555
  const channel = new Command3("channel").description("Channel lifecycle and status commands");
1531
- channel.command("list").option("--state <state>").option("--peer <peerId>").option("--include-closed").option("--json").action(async (options) => {
1556
+ channel.command("list").option("--state <state>").option("--peer <pubkey>").option("--include-closed").option("--json").action(async (options) => {
1532
1557
  const rpc = await createReadyRpcClient(config);
1533
1558
  const stateFilter = parseChannelState(options.state);
1534
1559
  const response = await rpc.listChannels(
1535
- options.peer ? { peer_id: options.peer, include_closed: Boolean(options.includeClosed) } : { include_closed: Boolean(options.includeClosed) }
1560
+ options.peer ? { pubkey: options.peer, include_closed: Boolean(options.includeClosed) } : { include_closed: Boolean(options.includeClosed) }
1536
1561
  );
1537
1562
  const channels = stateFilter ? response.channels.filter((item) => item.state.state_name === stateFilter) : response.channels;
1538
1563
  if (options.json) {
@@ -1565,7 +1590,7 @@ function createChannelCommand(config) {
1565
1590
  printChannelDetailHuman(found);
1566
1591
  }
1567
1592
  });
1568
- channel.command("watch").option("--interval <seconds>", "Refresh interval", "5").option("--timeout <seconds>").option("--on-timeout <behavior>", "fail | success", "fail").option("--channel <channelId>").option("--peer <peerId>").option("--state <state>").option("--until <state>").option("--include-closed").option("--no-clear").option("--json").action(async (options) => {
1593
+ channel.command("watch").option("--interval <seconds>", "Refresh interval", "5").option("--timeout <seconds>").option("--on-timeout <behavior>", "fail | success", "fail").option("--channel <channelId>").option("--peer <pubkey>").option("--state <state>").option("--until <state>").option("--include-closed").option("--no-clear").option("--json").action(async (options) => {
1569
1594
  const intervalSeconds = parseInt(options.interval, 10);
1570
1595
  const timeoutSeconds = options.timeout ? parseInt(options.timeout, 10) : void 0;
1571
1596
  const onTimeout = String(options.onTimeout ?? "fail").trim().toLowerCase();
@@ -1594,7 +1619,7 @@ function createChannelCommand(config) {
1594
1619
  const previousStates = /* @__PURE__ */ new Map();
1595
1620
  while (true) {
1596
1621
  const response = await rpc.listChannels(
1597
- options.peer ? { peer_id: options.peer, include_closed: Boolean(options.includeClosed) } : { include_closed: Boolean(options.includeClosed) }
1622
+ options.peer ? { pubkey: options.peer, include_closed: Boolean(options.includeClosed) } : { include_closed: Boolean(options.includeClosed) }
1598
1623
  );
1599
1624
  let channels = response.channels;
1600
1625
  if (options.channel) {
@@ -1676,7 +1701,7 @@ function createChannelCommand(config) {
1676
1701
  await sleep(intervalSeconds * 1e3);
1677
1702
  }
1678
1703
  });
1679
- channel.command("open").requiredOption("--peer <peerIdOrMultiaddr>").requiredOption("--funding <ckb>").option("--private").option(
1704
+ channel.command("open").requiredOption("--peer <pubkeyOrMultiaddr>").requiredOption("--funding <ckb>").option("--private").option(
1680
1705
  "--idempotency-key <key>",
1681
1706
  "Reuse this key only when retrying the exact same open intent"
1682
1707
  ).option("--json").action(async (options) => {
@@ -1684,21 +1709,23 @@ function createChannelCommand(config) {
1684
1709
  const json = Boolean(options.json);
1685
1710
  const peerInput = options.peer;
1686
1711
  const fundingCkb = parseFloat(options.funding);
1687
- let peerId = peerInput;
1712
+ let peerPubkey = peerInput;
1688
1713
  if (peerInput.includes("/")) {
1689
1714
  await rpc.connectPeer({ address: peerInput });
1690
- const peerIdMatch = peerInput.match(/\/p2p\/([^/]+)/);
1691
- if (peerIdMatch) peerId = peerIdMatch[1];
1715
+ peerPubkey = await resolvePeerPubkeyFromMultiaddr(rpc, peerInput, 8e3);
1716
+ }
1717
+ if (!peerPubkey.startsWith("0x")) {
1718
+ throw new Error(`Invalid peer pubkey: ${peerPubkey}`);
1692
1719
  }
1693
- const idempotencyKey = typeof options.idempotencyKey === "string" && options.idempotencyKey.trim().length > 0 ? options.idempotencyKey.trim() : `open:${peerId}:${randomUUID()}`;
1720
+ const idempotencyKey = typeof options.idempotencyKey === "string" && options.idempotencyKey.trim().length > 0 ? options.idempotencyKey.trim() : `open:${peerPubkey}:${randomUUID()}`;
1694
1721
  const endpoint = resolveRpcEndpoint(config);
1695
1722
  if (endpoint.target === "runtime-proxy") {
1696
1723
  const created = await tryCreateRuntimeChannelJob(endpoint.url, {
1697
1724
  params: {
1698
1725
  action: "open",
1699
- peerId,
1726
+ peerId: peerPubkey,
1700
1727
  openChannelParams: {
1701
- peer_id: peerId,
1728
+ pubkey: peerPubkey,
1702
1729
  funding_amount: ckbToShannons2(fundingCkb),
1703
1730
  public: !options.private
1704
1731
  },
@@ -1713,7 +1740,7 @@ function createChannelCommand(config) {
1713
1740
  const payload2 = {
1714
1741
  jobId: created.id,
1715
1742
  jobState: created.state,
1716
- peer: peerId,
1743
+ peer: peerPubkey,
1717
1744
  fundingCkb,
1718
1745
  idempotencyKey
1719
1746
  };
@@ -1731,11 +1758,15 @@ function createChannelCommand(config) {
1731
1758
  }
1732
1759
  }
1733
1760
  const result = await rpc.openChannel({
1734
- peer_id: peerId,
1761
+ pubkey: peerPubkey,
1735
1762
  funding_amount: ckbToShannons2(fundingCkb),
1736
1763
  public: !options.private
1737
1764
  });
1738
- const payload = { temporaryChannelId: result.temporary_channel_id, peer: peerId, fundingCkb };
1765
+ const payload = {
1766
+ temporaryChannelId: result.temporary_channel_id,
1767
+ peer: peerPubkey,
1768
+ fundingCkb
1769
+ };
1739
1770
  if (json) {
1740
1771
  printJsonSuccess(payload);
1741
1772
  } else {
@@ -2790,7 +2821,7 @@ function printGraphNodeListHuman(nodes) {
2790
2821
  console.log("NODE ID ALIAS VERSION MIN FUNDING AGE");
2791
2822
  console.log("---------------------------------------------------------------------------------");
2792
2823
  for (const node of nodes) {
2793
- const nodeId = truncateMiddle(node.node_id, 10, 8).padEnd(22, " ");
2824
+ const nodeId = truncateMiddle(node.pubkey, 10, 8).padEnd(22, " ");
2794
2825
  const alias = (node.node_name || "(unnamed)").slice(0, 20).padEnd(20, " ");
2795
2826
  const version = (node.version || "?").slice(0, 10).padEnd(10, " ");
2796
2827
  const minFunding = shannonsToCkb3(node.auto_accept_min_ckb_funding_amount).toString().padStart(12, " ");
@@ -3768,7 +3799,7 @@ import { Command as Command8 } from "commander";
3768
3799
 
3769
3800
  // src/lib/l402-proxy.ts
3770
3801
  import { createServer as createServer2 } from "http";
3771
- import { createL402Middleware as createL402Middleware2, FiberRpcClient as FiberRpcClient3 } from "@fiber-pay/sdk";
3802
+ import { createL402Middleware as createL402Middleware2, FiberRpcClient as FiberRpcClient3 } from "@fiber-pay/sdk/node";
3772
3803
  import express2 from "express";
3773
3804
  import { createProxyMiddleware } from "http-proxy-middleware";
3774
3805
  async function runL402ProxyCommand(config, options) {
@@ -4220,7 +4251,7 @@ async function runNodeInfoCommand(config, options) {
4220
4251
  console.log("\u2705 Node info retrieved");
4221
4252
  console.log(` Version: ${nodeInfo.version}`);
4222
4253
  console.log(` Commit: ${nodeInfo.commit_hash}`);
4223
- console.log(` Node ID: ${nodeInfo.node_id}`);
4254
+ console.log(` Node Pubkey: ${nodeInfo.pubkey}`);
4224
4255
  if (nodeInfo.features.length > 0) {
4225
4256
  console.log(" Features:");
4226
4257
  for (const feature of nodeInfo.features) {
@@ -4272,11 +4303,7 @@ async function runNodeNetworkCommand(config, options) {
4272
4303
  ]);
4273
4304
  const graphNodesMap = /* @__PURE__ */ new Map();
4274
4305
  for (const node of graphNodes.nodes) {
4275
- graphNodesMap.set(node.node_id, node);
4276
- }
4277
- const peerIdToNodeIdMap = /* @__PURE__ */ new Map();
4278
- for (const peer of localPeers.peers) {
4279
- peerIdToNodeIdMap.set(peer.peer_id, peer.pubkey);
4306
+ graphNodesMap.set(node.pubkey, node);
4280
4307
  }
4281
4308
  const graphChannelsMap = /* @__PURE__ */ new Map();
4282
4309
  for (const channel of graphChannels.channels) {
@@ -4290,8 +4317,7 @@ async function runNodeNetworkCommand(config, options) {
4290
4317
  nodeInfo: graphNodesMap.get(peer.pubkey)
4291
4318
  }));
4292
4319
  const enrichedChannels = localChannels.channels.map((channel) => {
4293
- const nodeId = peerIdToNodeIdMap.get(channel.peer_id) || channel.peer_id;
4294
- const peerNodeInfo = graphNodesMap.get(nodeId);
4320
+ const peerNodeInfo = graphNodesMap.get(channel.pubkey);
4295
4321
  let graphChannelInfo;
4296
4322
  if (channel.channel_outpoint) {
4297
4323
  const outpointKey = `${channel.channel_outpoint.tx_hash}:${channel.channel_outpoint.index}`;
@@ -4310,7 +4336,7 @@ async function runNodeNetworkCommand(config, options) {
4310
4336
  }, 0n);
4311
4337
  const totalChannelCapacity = formatShannonsAsCkb(totalChannelCapacityShannons, 1);
4312
4338
  const networkData = {
4313
- localNodeId: nodeInfo.node_id,
4339
+ localNodeId: nodeInfo.pubkey,
4314
4340
  peers: enrichedPeers,
4315
4341
  channels: enrichedChannels,
4316
4342
  graphNodes: graphNodes.nodes,
@@ -4337,16 +4363,16 @@ function printNodeNetworkHuman(data) {
4337
4363
  console.log("");
4338
4364
  if (data.peers.length > 0) {
4339
4365
  console.log("Peers:");
4340
- console.log(" PEER_ID ALIAS ADDRESS VERSION");
4366
+ console.log(" PUBKEY ALIAS ADDRESS VERSION");
4341
4367
  console.log(
4342
4368
  " --------------------------------------------------------------------------------"
4343
4369
  );
4344
4370
  for (const peer of data.peers) {
4345
- const peerId = truncateMiddle(peer.peer_id, 10, 8).padEnd(22, " ");
4371
+ const pubkey = truncateMiddle(peer.pubkey, 10, 8).padEnd(22, " ");
4346
4372
  const alias = sanitizeForTerminal(peer.nodeInfo?.node_name || "(unnamed)").slice(0, 20).padEnd(20, " ");
4347
4373
  const address = truncateMiddle(sanitizeForTerminal(peer.address), 15, 8).padEnd(25, " ");
4348
4374
  const version = sanitizeForTerminal(peer.nodeInfo?.version || "?").slice(0, 8).padEnd(8, " ");
4349
- console.log(` ${peerId} ${alias} ${address} ${version}`);
4375
+ console.log(` ${pubkey} ${alias} ${address} ${version}`);
4350
4376
  }
4351
4377
  console.log("");
4352
4378
  }
@@ -5102,7 +5128,7 @@ import {
5102
5128
  buildMultiaddrFromNodeId,
5103
5129
  buildMultiaddrFromRpcUrl,
5104
5130
  ChannelState as ChannelState2,
5105
- nodeIdToPeerId,
5131
+ nodeIdToPeerId as nodeIdToPeerId2,
5106
5132
  scriptToAddress
5107
5133
  } from "@fiber-pay/sdk";
5108
5134
 
@@ -5296,21 +5322,21 @@ async function runNodeStatusCommand(config, options) {
5296
5322
  const nodeInfo = await rpc.nodeInfo();
5297
5323
  const channels = await rpc.listChannels({ include_closed: false });
5298
5324
  rpcResponsive = true;
5299
- nodeId = nodeInfo.node_id;
5325
+ nodeId = nodeInfo.pubkey;
5300
5326
  nodeName = nodeInfo.node_name;
5301
5327
  addresses = nodeInfo.addresses;
5302
5328
  chainHash = nodeInfo.chain_hash;
5303
5329
  version = nodeInfo.version;
5304
5330
  peersCount = parseInt(nodeInfo.peers_count, 16);
5305
5331
  try {
5306
- peerId = await nodeIdToPeerId(nodeInfo.node_id);
5332
+ peerId = await nodeIdToPeerId2(nodeInfo.pubkey);
5307
5333
  } catch (error) {
5308
5334
  peerIdError = error instanceof Error ? error.message : String(error);
5309
5335
  }
5310
5336
  const baseAddress = nodeInfo.addresses[0];
5311
5337
  if (baseAddress) {
5312
5338
  try {
5313
- multiaddr = await buildMultiaddrFromNodeId(baseAddress, nodeInfo.node_id);
5339
+ multiaddr = await buildMultiaddrFromNodeId(baseAddress, nodeInfo.pubkey);
5314
5340
  } catch (error) {
5315
5341
  multiaddrError = error instanceof Error ? error.message : String(error);
5316
5342
  }
@@ -5848,7 +5874,12 @@ async function runMigrationAndReport(opts) {
5848
5874
  }
5849
5875
  process.exit(0);
5850
5876
  }
5851
- if (!migrationCheck.needed) {
5877
+ const precheckUnsupported = migrationCheck.precheckUnsupported;
5878
+ if (precheckUnsupported && forceMigrateAttempt && !json) {
5879
+ console.log("\u26A0\uFE0F Migration pre-check is unavailable for this fnn-migrate version.");
5880
+ console.log(" --force-migrate is set, so migration will be attempted directly.");
5881
+ }
5882
+ if (!migrationCheck.needed && !(precheckUnsupported && forceMigrateAttempt)) {
5852
5883
  if (!json) console.log(" Store is compatible, no migration needed.");
5853
5884
  return normalizeMigrationCheck(migrationCheck);
5854
5885
  }
@@ -6292,21 +6323,37 @@ function getJobFailure(job) {
6292
6323
  }
6293
6324
 
6294
6325
  // src/commands/peer.ts
6326
+ import { nodeIdToPeerId as nodeIdToPeerId3 } from "@fiber-pay/sdk";
6295
6327
  import { Command as Command12 } from "commander";
6296
- function extractPeerIdFromMultiaddr(address) {
6328
+ function extractPeerIdFromMultiaddr2(address) {
6297
6329
  const match = address.match(/\/p2p\/([^/]+)$/);
6298
6330
  return match?.[1];
6299
6331
  }
6300
- async function waitForPeerConnected(rpc, peerId, timeoutMs) {
6332
+ async function findPeerByPeerId(rpc, expectedPeerId) {
6333
+ const peers = await rpc.listPeers();
6334
+ for (const peer of peers.peers) {
6335
+ if (extractPeerIdFromMultiaddr2(peer.address) === expectedPeerId) {
6336
+ return peer;
6337
+ }
6338
+ try {
6339
+ if (await nodeIdToPeerId3(peer.pubkey) === expectedPeerId) {
6340
+ return peer;
6341
+ }
6342
+ } catch {
6343
+ }
6344
+ }
6345
+ return void 0;
6346
+ }
6347
+ async function waitForPeerConnected(rpc, expectedPeerId, timeoutMs) {
6301
6348
  const start = Date.now();
6302
6349
  while (Date.now() - start < timeoutMs) {
6303
- const peers = await rpc.listPeers();
6304
- if (peers.peers.some((peer) => peer.peer_id === peerId)) {
6305
- return true;
6350
+ const match = await findPeerByPeerId(rpc, expectedPeerId);
6351
+ if (match) {
6352
+ return { pubkey: match.pubkey, address: match.address };
6306
6353
  }
6307
6354
  await new Promise((resolve2) => setTimeout(resolve2, 500));
6308
6355
  }
6309
- return false;
6356
+ return void 0;
6310
6357
  }
6311
6358
  function createPeerCommand(config) {
6312
6359
  const peer = new Command12("peer").description("Peer management");
@@ -6321,34 +6368,40 @@ function createPeerCommand(config) {
6321
6368
  });
6322
6369
  peer.command("connect").argument("<multiaddr>").option("--timeout <sec>", "Wait timeout for peer to appear in peer list", "8").option("--json").action(async (address, options) => {
6323
6370
  const rpc = await createReadyRpcClient(config);
6324
- const peerId = extractPeerIdFromMultiaddr(address);
6325
- if (!peerId) {
6371
+ const expectedPeerId = extractPeerIdFromMultiaddr2(address);
6372
+ if (!expectedPeerId) {
6326
6373
  throw new Error("Invalid multiaddr: missing /p2p/<peerId> suffix");
6327
6374
  }
6328
6375
  await rpc.connectPeer({ address });
6329
6376
  const timeoutMs = Math.max(1, Number.parseInt(String(options.timeout), 10) || 8) * 1e3;
6330
- const connected = await waitForPeerConnected(rpc, peerId, timeoutMs);
6377
+ const connected = await waitForPeerConnected(rpc, expectedPeerId, timeoutMs);
6331
6378
  if (!connected) {
6332
6379
  throw new Error(
6333
- `connect_peer accepted but peer not found in list within ${Math.floor(timeoutMs / 1e3)}s (${peerId})`
6380
+ `connect_peer accepted but peer not found in list within ${Math.floor(timeoutMs / 1e3)}s (${expectedPeerId})`
6334
6381
  );
6335
6382
  }
6336
6383
  if (options.json) {
6337
- printJsonSuccess({ address, peerId, message: "Connected" });
6384
+ printJsonSuccess({
6385
+ address,
6386
+ peerId: expectedPeerId,
6387
+ pubkey: connected.pubkey,
6388
+ message: "Connected"
6389
+ });
6338
6390
  } else {
6339
6391
  console.log("\u2705 Connected to peer");
6340
6392
  console.log(` Address: ${address}`);
6341
- console.log(` Peer ID: ${peerId}`);
6393
+ console.log(` Peer ID: ${expectedPeerId}`);
6394
+ console.log(` Peer Pubkey: ${connected.pubkey}`);
6342
6395
  }
6343
6396
  });
6344
- peer.command("disconnect").argument("<peerId>").option("--json").action(async (peerId, options) => {
6397
+ peer.command("disconnect").argument("<pubkey>").option("--json").action(async (pubkey, options) => {
6345
6398
  const rpc = await createReadyRpcClient(config);
6346
- await rpc.disconnectPeer({ peer_id: peerId });
6399
+ await rpc.disconnectPeer({ pubkey });
6347
6400
  if (options.json) {
6348
- printJsonSuccess({ peerId, message: "Disconnected" });
6401
+ printJsonSuccess({ pubkey, message: "Disconnected" });
6349
6402
  } else {
6350
6403
  console.log("\u2705 Disconnected peer");
6351
- console.log(` Peer ID: ${peerId}`);
6404
+ console.log(` Peer Pubkey: ${pubkey}`);
6352
6405
  }
6353
6406
  });
6354
6407
  return peer;
@@ -6847,8 +6900,8 @@ function createRuntimeCommand(config) {
6847
6900
  import { Command as Command14 } from "commander";
6848
6901
 
6849
6902
  // src/lib/build-info.ts
6850
- var CLI_VERSION = "0.1.1";
6851
- var CLI_COMMIT = "4b099d434842d019d12ba4df4031314860de25be";
6903
+ var CLI_VERSION = "0.2.1";
6904
+ var CLI_COMMIT = "7326728d24bfb81f431401c681e5dfadee5d27a6";
6852
6905
 
6853
6906
  // src/commands/version.ts
6854
6907
  function createVersionCommand() {