adp-openclaw 0.0.4 → 0.0.5
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 +1 -1
- package/server.tar +0 -0
- package/src/channel.ts +11 -16
- package/src/config-schema.ts +1 -1
- package/src/monitor.ts +15 -12
- package/src/runtime.ts +0 -1
package/package.json
CHANGED
package/server.tar
ADDED
|
Binary file
|
package/src/channel.ts
CHANGED
|
@@ -12,7 +12,6 @@ export type AdpOpenclawChannelConfig = {
|
|
|
12
12
|
enabled?: boolean;
|
|
13
13
|
serverUrl?: string;
|
|
14
14
|
wsUrl?: string;
|
|
15
|
-
apiToken?: string;
|
|
16
15
|
clientToken?: string;
|
|
17
16
|
pollIntervalMs?: number;
|
|
18
17
|
};
|
|
@@ -23,13 +22,13 @@ export type ResolvedAdpOpenclawAccount = {
|
|
|
23
22
|
enabled: boolean;
|
|
24
23
|
configured: boolean;
|
|
25
24
|
serverUrl: string;
|
|
26
|
-
|
|
25
|
+
clientToken: string;
|
|
27
26
|
pollIntervalMs: number;
|
|
28
27
|
};
|
|
29
28
|
|
|
30
29
|
function resolveAdpOpenclawCredentials(channelCfg?: AdpOpenclawChannelConfig): {
|
|
31
30
|
serverUrl: string;
|
|
32
|
-
|
|
31
|
+
clientToken: string;
|
|
33
32
|
pollIntervalMs: number;
|
|
34
33
|
} | null {
|
|
35
34
|
// Get serverUrl: support both serverUrl and wsUrl
|
|
@@ -45,23 +44,20 @@ function resolveAdpOpenclawCredentials(channelCfg?: AdpOpenclawChannelConfig): {
|
|
|
45
44
|
serverUrl = process.env.ADP_OPENCLAW_SERVER_URL || "";
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
// Get
|
|
49
|
-
let
|
|
50
|
-
if (!
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
if (!apiToken) {
|
|
54
|
-
apiToken = process.env.ADP_OPENCLAW_API_TOKEN || "";
|
|
47
|
+
// Get clientToken from config or env
|
|
48
|
+
let clientToken = channelCfg?.clientToken?.trim();
|
|
49
|
+
if (!clientToken) {
|
|
50
|
+
clientToken = process.env.ADP_OPENCLAW_CLIENT_TOKEN || "";
|
|
55
51
|
}
|
|
56
52
|
|
|
57
53
|
// Both are required for configured status
|
|
58
|
-
if (!serverUrl || !
|
|
54
|
+
if (!serverUrl || !clientToken) {
|
|
59
55
|
return null;
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
const pollIntervalMs = channelCfg?.pollIntervalMs ?? 1000;
|
|
63
59
|
|
|
64
|
-
return { serverUrl,
|
|
60
|
+
return { serverUrl, clientToken, pollIntervalMs };
|
|
65
61
|
}
|
|
66
62
|
|
|
67
63
|
function resolveAccount(cfg: ClawdbotConfig, accountId?: string): ResolvedAdpOpenclawAccount {
|
|
@@ -75,7 +71,7 @@ function resolveAccount(cfg: ClawdbotConfig, accountId?: string): ResolvedAdpOpe
|
|
|
75
71
|
enabled,
|
|
76
72
|
configured: Boolean(creds),
|
|
77
73
|
serverUrl: creds?.serverUrl || "http://localhost:9876",
|
|
78
|
-
|
|
74
|
+
clientToken: creds?.clientToken || "",
|
|
79
75
|
pollIntervalMs: creds?.pollIntervalMs || 1000,
|
|
80
76
|
};
|
|
81
77
|
}
|
|
@@ -106,7 +102,6 @@ export const adpOpenclawPlugin: ChannelPlugin<ResolvedAdpOpenclawAccount> = {
|
|
|
106
102
|
enabled: { type: "boolean" },
|
|
107
103
|
serverUrl: { type: "string" },
|
|
108
104
|
wsUrl: { type: "string" },
|
|
109
|
-
apiToken: { type: "string" },
|
|
110
105
|
clientToken: { type: "string" },
|
|
111
106
|
pollIntervalMs: { type: "integer", minimum: 100 },
|
|
112
107
|
},
|
|
@@ -222,7 +217,7 @@ export const adpOpenclawPlugin: ChannelPlugin<ResolvedAdpOpenclawAccount> = {
|
|
|
222
217
|
const { monitorAdpOpenclaw } = await import("./monitor.js");
|
|
223
218
|
return monitorAdpOpenclaw({
|
|
224
219
|
serverUrl: account.serverUrl,
|
|
225
|
-
|
|
220
|
+
clientToken: account.clientToken,
|
|
226
221
|
pollIntervalMs: account.pollIntervalMs,
|
|
227
222
|
abortSignal: ctx.abortSignal,
|
|
228
223
|
log: ctx.log,
|
|
@@ -256,7 +251,7 @@ export const adpOpenclawPlugin: ChannelPlugin<ResolvedAdpOpenclawAccount> = {
|
|
|
256
251
|
method: "POST",
|
|
257
252
|
headers: {
|
|
258
253
|
"Content-Type": "application/json",
|
|
259
|
-
Authorization: `Bearer ${account.
|
|
254
|
+
Authorization: `Bearer ${account.clientToken}`,
|
|
260
255
|
},
|
|
261
256
|
body: JSON.stringify({
|
|
262
257
|
to: target,
|
package/src/config-schema.ts
CHANGED
package/src/monitor.ts
CHANGED
|
@@ -7,7 +7,7 @@ import crypto from "crypto";
|
|
|
7
7
|
|
|
8
8
|
export type MonitorParams = {
|
|
9
9
|
serverUrl: string;
|
|
10
|
-
|
|
10
|
+
clientToken: string;
|
|
11
11
|
pollIntervalMs: number; // Used as reconnect delay
|
|
12
12
|
abortSignal?: AbortSignal;
|
|
13
13
|
log?: PluginLogger;
|
|
@@ -63,9 +63,10 @@ type AuthResultPayload = {
|
|
|
63
63
|
message?: string;
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
// Generate HMAC-SHA256 signature for
|
|
67
|
-
function generateSignature(token: string, nonce: string): string {
|
|
68
|
-
|
|
66
|
+
// Generate HMAC-SHA256 signature for authentication (includes timestamp for anti-replay)
|
|
67
|
+
function generateSignature(token: string, nonce: string, timestamp: number): string {
|
|
68
|
+
// Use HMAC-SHA256 with token as the key, and "nonce:timestamp" as the message
|
|
69
|
+
return crypto.createHmac("sha256", token).update(`${nonce}:${timestamp}`).digest("hex");
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
// Generate random nonce
|
|
@@ -79,7 +80,7 @@ function generateRequestId(): string {
|
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
export async function monitorAdpOpenclaw(params: MonitorParams): Promise<void> {
|
|
82
|
-
const { serverUrl,
|
|
83
|
+
const { serverUrl, clientToken, pollIntervalMs, abortSignal, log, cfg } = params;
|
|
83
84
|
const runtime = getAdpOpenclawRuntime();
|
|
84
85
|
|
|
85
86
|
// Convert HTTP URL to WebSocket URL
|
|
@@ -91,7 +92,7 @@ export async function monitorAdpOpenclaw(params: MonitorParams): Promise<void> {
|
|
|
91
92
|
try {
|
|
92
93
|
await connectAndHandle({
|
|
93
94
|
wsUrl,
|
|
94
|
-
|
|
95
|
+
clientToken,
|
|
95
96
|
serverUrl,
|
|
96
97
|
abortSignal,
|
|
97
98
|
log,
|
|
@@ -115,7 +116,7 @@ export async function monitorAdpOpenclaw(params: MonitorParams): Promise<void> {
|
|
|
115
116
|
|
|
116
117
|
type ConnectParams = {
|
|
117
118
|
wsUrl: string;
|
|
118
|
-
|
|
119
|
+
clientToken: string;
|
|
119
120
|
serverUrl: string;
|
|
120
121
|
abortSignal?: AbortSignal;
|
|
121
122
|
log?: PluginLogger;
|
|
@@ -124,7 +125,7 @@ type ConnectParams = {
|
|
|
124
125
|
};
|
|
125
126
|
|
|
126
127
|
async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
127
|
-
const { wsUrl,
|
|
128
|
+
const { wsUrl, clientToken, serverUrl, abortSignal, log, runtime, cfg } = params;
|
|
128
129
|
|
|
129
130
|
// Dynamic import for WebSocket (works in both Node.js and browser)
|
|
130
131
|
const WebSocket = (await import("ws")).default;
|
|
@@ -144,19 +145,21 @@ async function connectAndHandle(params: ConnectParams): Promise<void> {
|
|
|
144
145
|
ws.on("open", () => {
|
|
145
146
|
log?.info(`[adp-openclaw] WebSocket connected, authenticating...`);
|
|
146
147
|
|
|
147
|
-
// Send authentication message with signature
|
|
148
|
+
// Send authentication message with signature (includes timestamp for anti-replay)
|
|
148
149
|
const nonce = generateNonce();
|
|
149
|
-
const
|
|
150
|
+
const timestamp = Date.now();
|
|
151
|
+
const signature = generateSignature(clientToken, nonce, timestamp);
|
|
150
152
|
|
|
151
153
|
const authMsg: WSMessage = {
|
|
152
154
|
type: MsgType.Auth,
|
|
153
155
|
requestId: generateRequestId(),
|
|
154
156
|
payload: {
|
|
155
|
-
token:
|
|
157
|
+
token: clientToken,
|
|
156
158
|
nonce,
|
|
157
159
|
signature,
|
|
160
|
+
timestamp, // Include timestamp in payload for server verification
|
|
158
161
|
},
|
|
159
|
-
timestamp
|
|
162
|
+
timestamp,
|
|
160
163
|
};
|
|
161
164
|
|
|
162
165
|
ws.send(JSON.stringify(authMsg));
|