libp2p-mesh 2026.5.28 → 2026.5.30

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.
@@ -22,9 +22,13 @@ export function registerLibp2pMesh(api) {
22
22
  api.registerService({
23
23
  id: "libp2p-mesh",
24
24
  start: async () => {
25
- await mesh.start();
26
- // Load persisted peer identities so dedup checks work on restart
25
+ // Load persisted peer identities FIRST so dedup checks work when
26
+ // peers connect during mesh.start() (mDNS can fire peer:connect
27
+ // before this function's sequential code reaches onPeerConnect).
27
28
  await peerIdentityMap.load();
29
+ await mesh.start();
30
+ const instanceIdentity = mesh.getInstanceIdentity();
31
+ const localInstanceId = instanceIdentity?.id;
28
32
  // Register local identity so remote peers can route messages back to us
29
33
  const config = api.pluginConfig;
30
34
  const relayChannel = config?.relayChannel;
@@ -42,9 +46,13 @@ export function registerLibp2pMesh(api) {
42
46
  channel: relayChannel,
43
47
  accountId: relayAccountId,
44
48
  sessionKey,
49
+ instanceId: localInstanceId,
45
50
  });
46
51
  api.logger.info?.(`[libp2p-mesh] Local identity registered: agent=${api.name}, channel=${relayChannel}, account=${relayAccountId}`);
47
52
  // Announce identity to all currently-connected peers
53
+ // setLocalIdentity is called BEFORE this block, and localInstanceId
54
+ // is available from mesh.start(), so the identity message includes
55
+ // the instanceId.
48
56
  const identityMsg = JSON.stringify({
49
57
  id: crypto.randomUUID(),
50
58
  type: "identity",
@@ -53,6 +61,7 @@ export function registerLibp2pMesh(api) {
53
61
  agentId: api.name,
54
62
  channel: relayChannel,
55
63
  accountId: relayAccountId,
64
+ instanceId: localInstanceId,
56
65
  }),
57
66
  timestamp: Date.now(),
58
67
  });
@@ -70,12 +79,13 @@ export function registerLibp2pMesh(api) {
70
79
  mesh.onMessage((msg) => {
71
80
  handleP2PInbound(msg, buildInboundDeps());
72
81
  });
73
- // Dedup: skip identity send if peer is already known
82
+ // Always send our identity when a peer connects. Identity exchange is
83
+ // bidirectional: even if we already know this peer, they may not know
84
+ // our current identity (or theirs may be stale). The receiving side
85
+ // handles dedup via handleIdentityMessage (register only if new or
86
+ // updated). Removing the send-side dedup ensures both sides always
87
+ // have each other's current identity.
74
88
  mesh.onPeerConnect((peerId) => {
75
- if (peerIdentityMap.hasIdentity(peerId)) {
76
- api.logger.debug?.(`[libp2p-mesh] Peer ${peerId} already known, skipping identity send`);
77
- return;
78
- }
79
89
  api.logger.info?.(`[libp2p-mesh] Peer connected: ${peerId} — sending identity`);
80
90
  // Only send identity if relay config is set
81
91
  if (!relayChannel || !relayAccountId)
@@ -88,6 +98,7 @@ export function registerLibp2pMesh(api) {
88
98
  agentId: api.name,
89
99
  channel: relayChannel,
90
100
  accountId: relayAccountId,
101
+ instanceId: localInstanceId,
91
102
  }),
92
103
  timestamp: Date.now(),
93
104
  });
@@ -103,6 +114,7 @@ export function registerLibp2pMesh(api) {
103
114
  agentId: api.name,
104
115
  channel: relayChannel,
105
116
  accountId: relayAccountId,
117
+ instanceId: localInstanceId,
106
118
  }),
107
119
  timestamp: Date.now(),
108
120
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libp2p-mesh",
3
- "version": "2026.5.28",
3
+ "version": "2026.5.30",
4
4
  "description": "OpenClaw libp2p P2P mesh network plugin for cross-instance agent communication",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/plugin.ts CHANGED
@@ -30,10 +30,15 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
30
30
  api.registerService({
31
31
  id: "libp2p-mesh",
32
32
  start: async () => {
33
+ // Load persisted peer identities FIRST so dedup checks work when
34
+ // peers connect during mesh.start() (mDNS can fire peer:connect
35
+ // before this function's sequential code reaches onPeerConnect).
36
+ await peerIdentityMap.load();
37
+
33
38
  await mesh.start();
34
39
 
35
- // Load persisted peer identities so dedup checks work on restart
36
- await peerIdentityMap.load();
40
+ const instanceIdentity = mesh.getInstanceIdentity();
41
+ const localInstanceId = instanceIdentity?.id;
37
42
 
38
43
  // Register local identity so remote peers can route messages back to us
39
44
  const config = api.pluginConfig as MeshConfig | undefined;
@@ -52,12 +57,16 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
52
57
  channel: relayChannel,
53
58
  accountId: relayAccountId,
54
59
  sessionKey,
60
+ instanceId: localInstanceId,
55
61
  });
56
62
  api.logger.info?.(
57
63
  `[libp2p-mesh] Local identity registered: agent=${api.name}, channel=${relayChannel}, account=${relayAccountId}`,
58
64
  );
59
65
 
60
66
  // Announce identity to all currently-connected peers
67
+ // setLocalIdentity is called BEFORE this block, and localInstanceId
68
+ // is available from mesh.start(), so the identity message includes
69
+ // the instanceId.
61
70
  const identityMsg = JSON.stringify({
62
71
  id: crypto.randomUUID(),
63
72
  type: "identity",
@@ -66,6 +75,7 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
66
75
  agentId: api.name,
67
76
  channel: relayChannel,
68
77
  accountId: relayAccountId,
78
+ instanceId: localInstanceId,
69
79
  }),
70
80
  timestamp: Date.now(),
71
81
  });
@@ -84,12 +94,13 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
84
94
  handleP2PInbound(msg, buildInboundDeps());
85
95
  });
86
96
 
87
- // Dedup: skip identity send if peer is already known
97
+ // Always send our identity when a peer connects. Identity exchange is
98
+ // bidirectional: even if we already know this peer, they may not know
99
+ // our current identity (or theirs may be stale). The receiving side
100
+ // handles dedup via handleIdentityMessage (register only if new or
101
+ // updated). Removing the send-side dedup ensures both sides always
102
+ // have each other's current identity.
88
103
  mesh.onPeerConnect((peerId: string) => {
89
- if (peerIdentityMap.hasIdentity(peerId)) {
90
- api.logger.debug?.(`[libp2p-mesh] Peer ${peerId} already known, skipping identity send`);
91
- return;
92
- }
93
104
  api.logger.info?.(`[libp2p-mesh] Peer connected: ${peerId} — sending identity`);
94
105
  // Only send identity if relay config is set
95
106
  if (!relayChannel || !relayAccountId) return;
@@ -101,6 +112,7 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
101
112
  agentId: api.name,
102
113
  channel: relayChannel,
103
114
  accountId: relayAccountId,
115
+ instanceId: localInstanceId,
104
116
  }),
105
117
  timestamp: Date.now(),
106
118
  });
@@ -117,6 +129,7 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
117
129
  agentId: api.name,
118
130
  channel: relayChannel,
119
131
  accountId: relayAccountId,
132
+ instanceId: localInstanceId,
120
133
  }),
121
134
  timestamp: Date.now(),
122
135
  });