libp2p-mesh 2026.5.32 → 2026.6.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 +66 -79
- package/api.ts +19 -1
- package/dist/api.d.ts +3 -1
- package/dist/api.js +2 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +13 -0
- package/dist/src/agent-tools.d.ts +181 -80
- package/dist/src/agent-tools.js +155 -146
- package/dist/src/inbound-delivery.d.ts +11 -0
- package/dist/src/inbound-delivery.js +83 -0
- package/dist/src/inbound.d.ts +3 -10
- package/dist/src/inbound.js +4 -139
- package/dist/src/instance-peer-store.d.ts +11 -0
- package/dist/src/instance-peer-store.js +135 -0
- package/dist/src/instance-router.d.ts +14 -0
- package/dist/src/instance-router.js +326 -0
- package/dist/src/mesh.js +56 -29
- package/dist/src/plugin.js +30 -159
- package/dist/src/types.d.ts +99 -5
- package/index.ts +14 -1
- package/openclaw.plugin.json +12 -8
- package/package.json +2 -4
- package/src/agent-tools.ts +161 -152
- package/src/inbound-delivery.ts +117 -0
- package/src/inbound.ts +6 -149
- package/src/instance-peer-store.ts +186 -0
- package/src/instance-router.ts +426 -0
- package/src/mesh.ts +76 -34
- package/src/plugin.ts +31 -174
- package/src/types.ts +117 -5
- package/dist/src/identity-exchange.d.ts +0 -19
- package/dist/src/identity-exchange.js +0 -64
- package/dist/src/peer-identity.d.ts +0 -37
- package/dist/src/peer-identity.js +0 -130
- package/src/identity-exchange.ts +0 -111
- package/src/peer-identity.ts +0 -176
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# libp2p-mesh
|
|
2
2
|
|
|
3
3
|
P2P mesh network plugin for OpenClaw. Enables direct peer-to-peer communication between OpenClaw instances using libp2p — no central server required.
|
|
4
4
|
|
|
@@ -22,7 +22,7 @@ P2P mesh network plugin for OpenClaw. Enables direct peer-to-peer communication
|
|
|
22
22
|
### Method 1: Via OpenClaw CLI (Recommended)
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
openclaw install
|
|
25
|
+
openclaw install libp2p-mesh
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
### Method 2: Manual (npm)
|
|
@@ -31,7 +31,7 @@ openclaw install openclaw-libp2p-mesh
|
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
cd ~/.openclaw/npm
|
|
34
|
-
npm install
|
|
34
|
+
npm install libp2p-mesh
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
然后刷新插件注册表:
|
|
@@ -42,9 +42,7 @@ openclaw plugins registry --refresh
|
|
|
42
42
|
|
|
43
43
|
The published npm package includes compiled JavaScript under `dist/`, so OpenClaw and acpx can load it directly.
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
1. **Enable the plugin** in `~/.openclaw/openclaw.json`:
|
|
45
|
+
Then add to your `~/.openclaw/openclaw.json`:
|
|
48
46
|
|
|
49
47
|
```json
|
|
50
48
|
{
|
|
@@ -64,78 +62,6 @@ After installing the plugin, you must:
|
|
|
64
62
|
}
|
|
65
63
|
```
|
|
66
64
|
|
|
67
|
-
2. **Set `tools.profile` to `full`** — OpenClaw defaults to `"coding"` profile, which **filters out** P2P tools. Even if you add them to `tools.allow`, the coding profile will still block them. You must change to `"full"` first:
|
|
68
|
-
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"tools": {
|
|
72
|
-
"profile": "full",
|
|
73
|
-
"allow": [
|
|
74
|
-
"p2p_list_peers",
|
|
75
|
-
"p2p_send_message",
|
|
76
|
-
"p2p_broadcast"
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
> **Why `profile: "full"`?** The `"coding"` profile hardcodes a deny list that includes `p2p_list_peers`, `p2p_send_message`, and `p2p_broadcast`. With `profile: "coding"`, adding tools to `tools.allow` has no effect for these three — the profile filter runs first and removes them.
|
|
83
|
-
|
|
84
|
-
3. **Restart the gateway:**
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
openclaw gateway restart
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
4. **Verify tool registration:**
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
openclaw plugins inspect libp2p-mesh --runtime --json | jq '.plugin.toolNames, .tools'
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
Expected output:
|
|
97
|
-
```json
|
|
98
|
-
[
|
|
99
|
-
"p2p_send_message",
|
|
100
|
-
"p2p_broadcast",
|
|
101
|
-
"p2p_list_peers",
|
|
102
|
-
"p2p_get_instance_identity",
|
|
103
|
-
"p2p_get_network_info"
|
|
104
|
-
]
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### One-command setup (optional)
|
|
108
|
-
|
|
109
|
-
Instead of manually editing `openclaw.json`, run:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
npx openclaw-libp2p-mesh-configure-tools
|
|
113
|
-
# or, from the plugin directory:
|
|
114
|
-
npm run configure-tools
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
This patches `~/.openclaw/openclaw.json` with the correct `tools.profile` and `tools.allow` values. Use `--check` to preview without modifying:
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
npm run configure-tools:check
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Troubleshooting
|
|
124
|
-
|
|
125
|
-
### "plugin must declare contracts.tools before registering agent tools"
|
|
126
|
-
|
|
127
|
-
Make sure you are running **OpenClaw >= 2026.6.5** and the plugin is installed via `openclaw install` or `npm install` into `~/.openclaw/npm`. The manifest (`openclaw.plugin.json`) ships with `contracts.tools` pre-declared, so no manual manifest edits are needed.
|
|
128
|
-
|
|
129
|
-
### Tools still not available after setup
|
|
130
|
-
|
|
131
|
-
1. Confirm `tools.profile` is `"full"` (not `"coding"`):
|
|
132
|
-
```bash
|
|
133
|
-
cat ~/.openclaw/openclaw.json | jq '.tools'
|
|
134
|
-
```
|
|
135
|
-
2. Confirm all three P2P tools are in `tools.allow`.
|
|
136
|
-
3. Restart the gateway (not just reload).
|
|
137
|
-
4. Check `openclaw plugins inspect libp2p-mesh --runtime --json` for diagnostics.
|
|
138
|
-
|
|
139
65
|
## Configuration
|
|
140
66
|
|
|
141
67
|
Add a `libp2p-mesh` block to your `openclaw.json` under `plugins`:
|
|
@@ -214,7 +140,7 @@ If peers are on different networks, use a bootstrap node:
|
|
|
214
140
|
|
|
215
141
|
| Key | Type | Default | Description |
|
|
216
142
|
|-----|------|---------|-------------|
|
|
217
|
-
| `discovery` | `string` | `"mdns"` | Discovery mechanism: `"mdns"` (LAN), `"bootstrap"` (static list), `"dht"` (
|
|
143
|
+
| `discovery` | `string` | `"mdns"` | Discovery mechanism: `"mdns"` (LAN), `"bootstrap"` (static list), `"dht"` (Kademlia peer discovery and pubkey registry) |
|
|
218
144
|
| `listenAddrs` | `string[]` | `["/ip4/0.0.0.0/tcp/0"]` | libp2p listen multiaddrs |
|
|
219
145
|
| `bootstrapList` | `string[]` | `[]` | Static bootstrap peer multiaddrs (when `discovery=bootstrap`) |
|
|
220
146
|
| `enableWebSocket` | `boolean` | `false` | Enable WebSocket transport for browser/NAT compatibility |
|
|
@@ -230,6 +156,9 @@ If peers are on different networks, use a bootstrap node:
|
|
|
230
156
|
| `relayList` | `string[]` | `[]` | Multiaddrs of relays to reserve a slot on |
|
|
231
157
|
| `discoverRelays` | `number` | `0` | Auto-discover this many relays via content routing |
|
|
232
158
|
| `announceAddrs` | `string[]` | `[]` | Extra multiaddrs to announce on top of auto-detected ones |
|
|
159
|
+
| `inboundChannel` | `string` | `undefined` | OpenClaw channel used to display inbound P2P user messages, for example `"feishu"` |
|
|
160
|
+
| `inboundTarget` | `string` | `undefined` | OpenClaw channel target for inbound P2P messages, for example `user:ou_xxx` or `chat:oc_xxx` |
|
|
161
|
+
| `deliveryAckTimeoutMs` | `number` | `15000` | Timeout for waiting on remote channel delivery ACKs |
|
|
233
162
|
|
|
234
163
|
## NAT Traversal
|
|
235
164
|
|
|
@@ -342,6 +271,53 @@ Check the gateway logs on the receiving machine. You should see:
|
|
|
342
271
|
[libp2p-mesh] Direct message from <sender-peer-id>: Hello from A!
|
|
343
272
|
```
|
|
344
273
|
|
|
274
|
+
## Sending by OpenClaw Instance ID
|
|
275
|
+
|
|
276
|
+
When two gateways connect, `libp2p-mesh` exchanges instance route announcements and automatically writes:
|
|
277
|
+
|
|
278
|
+
```text
|
|
279
|
+
~/.openclaw/libp2p/instance-peer.json
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
When `OPENCLAW_STATE_DIR` is set, the file is written to:
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
$OPENCLAW_STATE_DIR/libp2p/instance-peer.json
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Users do not configure this file path. It is plugin-managed state.
|
|
289
|
+
|
|
290
|
+
For Feishu inbound display, configure the receiving instance:
|
|
291
|
+
|
|
292
|
+
```json
|
|
293
|
+
{
|
|
294
|
+
"plugins": {
|
|
295
|
+
"libp2p-mesh": {
|
|
296
|
+
"enabled": true,
|
|
297
|
+
"config": {
|
|
298
|
+
"discovery": "mdns",
|
|
299
|
+
"inboundChannel": "feishu",
|
|
300
|
+
"inboundTarget": "user:ou_xxx",
|
|
301
|
+
"deliveryAckTimeoutMs": 15000
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
"channels": {
|
|
306
|
+
"libp2p-mesh": { "enabled": true }
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
The OpenClaw agent should prefer:
|
|
312
|
+
|
|
313
|
+
```text
|
|
314
|
+
p2p_send_instance_message({ "instanceId": "<target-instance-id>", "message": "今晚出来吃饭" })
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
The sender reports success only after the remote OpenClaw instance forwards the message to its configured inbound channel and returns a delivery ACK.
|
|
318
|
+
|
|
319
|
+
Tools are not configured in `openclaw.json`; they are registered automatically by the plugin through `api.registerTool()`.
|
|
320
|
+
|
|
345
321
|
## Troubleshooting
|
|
346
322
|
|
|
347
323
|
### Peers do not discover each other
|
|
@@ -380,6 +356,17 @@ The peer may be unreachable. Check:
|
|
|
380
356
|
- Are both machines on the same network?
|
|
381
357
|
- Is there a firewall blocking the connection?
|
|
382
358
|
|
|
359
|
+
### Connected peers are not visible in logs
|
|
360
|
+
|
|
361
|
+
Peer connection and disconnection are logged at `info` level:
|
|
362
|
+
|
|
363
|
+
```text
|
|
364
|
+
[libp2p-mesh] Peer connected: 12D3KooW...
|
|
365
|
+
[libp2p-mesh] Instance mapping updated: bob@def.456 -> 12D3KooW...
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
If these lines are missing, confirm the gateway is running with normal info logs enabled and that both instances are on the same mDNS, bootstrap, or relay network.
|
|
369
|
+
|
|
383
370
|
## Architecture
|
|
384
371
|
|
|
385
372
|
```
|
package/api.ts
CHANGED
|
@@ -1,2 +1,20 @@
|
|
|
1
1
|
export { createMeshNetwork } from "./src/mesh.js";
|
|
2
|
-
export
|
|
2
|
+
export { createInstancePeerStore } from "./src/instance-peer-store.js";
|
|
3
|
+
export { createInstanceRouter } from "./src/instance-router.js";
|
|
4
|
+
export type {
|
|
5
|
+
DeliveryAckPayload,
|
|
6
|
+
InboundDeliveryAdapter,
|
|
7
|
+
InboundDeliveryRequest,
|
|
8
|
+
InboundDeliveryResult,
|
|
9
|
+
InstanceAnnouncePayload,
|
|
10
|
+
InstanceIdentity,
|
|
11
|
+
InstancePeerRecord,
|
|
12
|
+
InstancePeerStore,
|
|
13
|
+
InstancePeerTable,
|
|
14
|
+
InstanceRouter,
|
|
15
|
+
MeshConfig,
|
|
16
|
+
MeshNetwork,
|
|
17
|
+
P2PMessage,
|
|
18
|
+
P2PMessageType,
|
|
19
|
+
UserMessagePayload,
|
|
20
|
+
} from "./src/types.js";
|
package/dist/api.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { createMeshNetwork } from "./src/mesh.js";
|
|
2
|
-
export
|
|
2
|
+
export { createInstancePeerStore } from "./src/instance-peer-store.js";
|
|
3
|
+
export { createInstanceRouter } from "./src/instance-router.js";
|
|
4
|
+
export type { DeliveryAckPayload, InboundDeliveryAdapter, InboundDeliveryRequest, InboundDeliveryResult, InstanceAnnouncePayload, InstanceIdentity, InstancePeerRecord, InstancePeerStore, InstancePeerTable, InstanceRouter, MeshConfig, MeshNetwork, P2PMessage, P2PMessageType, UserMessagePayload, } from "./src/types.js";
|
package/dist/api.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
declare const _default:
|
|
1
|
+
import type { OpenClawPluginConfigSchema } from "openclaw/plugin-sdk/core";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
configSchema: OpenClawPluginConfigSchema;
|
|
7
|
+
register: NonNullable<import("openclaw/plugin-sdk/core").OpenClawPluginDefinition["register"]>;
|
|
8
|
+
} & Pick<import("openclaw/plugin-sdk/core").OpenClawPluginDefinition, "reload" | "kind" | "nodeHostCommands" | "securityAuditCollectors">;
|
|
3
9
|
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -109,6 +109,19 @@ function createLibp2pMeshConfigSchema() {
|
|
|
109
109
|
items: { type: "string" },
|
|
110
110
|
description: "Extra multiaddrs to announce to the network (useful when running behind a known port forward where AutoNAT cannot probe).",
|
|
111
111
|
},
|
|
112
|
+
inboundChannel: {
|
|
113
|
+
type: "string",
|
|
114
|
+
description: "OpenClaw channel used to display inbound P2P user messages, for example \"feishu\".",
|
|
115
|
+
},
|
|
116
|
+
inboundTarget: {
|
|
117
|
+
type: "string",
|
|
118
|
+
description: "OpenClaw channel target for inbound P2P user messages, for example user:ou_xxx or chat:oc_xxx.",
|
|
119
|
+
},
|
|
120
|
+
deliveryAckTimeoutMs: {
|
|
121
|
+
type: "number",
|
|
122
|
+
default: 15000,
|
|
123
|
+
description: "How long p2p_send_instance_message waits for a remote delivery ACK.",
|
|
124
|
+
},
|
|
112
125
|
},
|
|
113
126
|
},
|
|
114
127
|
};
|