clawchain-wallet 1.0.0
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/SKILL.md +243 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +89 -0
- package/dist/src/executor.d.ts +23 -0
- package/dist/src/executor.js +65 -0
- package/dist/src/tools.d.ts +41 -0
- package/dist/src/tools.js +528 -0
- package/dist/src/types.d.ts +40 -0
- package/dist/src/types.js +4 -0
- package/index.ts +103 -0
- package/openclaw.plugin.json +16 -0
- package/package.json +76 -0
- package/python/clawchain_cli.py +1193 -0
- package/python/requirements.txt +2 -0
- package/scripts/postinstall.js +243 -0
- package/src/executor.ts +88 -0
- package/src/tools.ts +623 -0
- package/src/types.ts +45 -0
- package/tsconfig.json +15 -0
package/src/tools.ts
ADDED
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClawChain Agent Tools 定义
|
|
3
|
+
*
|
|
4
|
+
* 使用 OpenClaw Plugin SDK 的类型和辅助函数
|
|
5
|
+
* 支持按 Agent 隔离钱包存储
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { Type } from "@sinclair/typebox";
|
|
10
|
+
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
|
11
|
+
import { jsonResult } from "openclaw/plugin-sdk";
|
|
12
|
+
import type { ExecutorOptions, CommandArgs } from "./executor.js";
|
|
13
|
+
import { executeCommand } from "./executor.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Plugin 工具上下文类型
|
|
17
|
+
* 匹配 OpenClaw 的 OpenClawPluginToolContext
|
|
18
|
+
*/
|
|
19
|
+
export interface ToolContext {
|
|
20
|
+
workspaceDir?: string;
|
|
21
|
+
agentId?: string;
|
|
22
|
+
agentDir?: string;
|
|
23
|
+
sessionKey?: string;
|
|
24
|
+
messageChannel?: string;
|
|
25
|
+
sandboxed?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Agent 工具类型定义
|
|
30
|
+
*/
|
|
31
|
+
export interface AgentToolDef {
|
|
32
|
+
name: string;
|
|
33
|
+
label: string;
|
|
34
|
+
description: string;
|
|
35
|
+
parameters: unknown;
|
|
36
|
+
execute: (toolCallId: string, args: Record<string, unknown>) => Promise<AgentToolResult<unknown>>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 工具工厂函数类型
|
|
41
|
+
* 匹配 OpenClaw 的 OpenClawPluginToolFactory
|
|
42
|
+
*/
|
|
43
|
+
export type ToolFactory = (ctx: ToolContext) => AgentToolDef | null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 根据上下文确定钱包存储目录
|
|
47
|
+
*
|
|
48
|
+
* 优先级:
|
|
49
|
+
* 1. 显式配置的 walletsDir
|
|
50
|
+
* 2. Agent 工作区目录下的 .wallets
|
|
51
|
+
* 3. 默认目录(由 Python CLI 决定,通常是 ~/.clawchain/wallets)
|
|
52
|
+
*/
|
|
53
|
+
function resolveWalletsDir(baseOptions: ExecutorOptions, ctx: ToolContext): string | undefined {
|
|
54
|
+
// 如果显式配置了 walletsDir,优先使用
|
|
55
|
+
if (baseOptions.walletsDir) {
|
|
56
|
+
return baseOptions.walletsDir;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 否则使用 agent 工作区目录
|
|
60
|
+
if (ctx.workspaceDir) {
|
|
61
|
+
return path.join(ctx.workspaceDir, ".wallets");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 都没有则返回 undefined,让 Python CLI 使用默认值
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 创建所有 ClawChain 工具工厂
|
|
70
|
+
*
|
|
71
|
+
* 每个工厂函数会根据当前 agent 上下文确定钱包存储目录
|
|
72
|
+
*/
|
|
73
|
+
export function createClawChainToolFactories(baseOptions: ExecutorOptions): ToolFactory[] {
|
|
74
|
+
return [
|
|
75
|
+
createWalletCreateToolFactory(baseOptions),
|
|
76
|
+
createWalletImportToolFactory(baseOptions),
|
|
77
|
+
createWalletListToolFactory(baseOptions),
|
|
78
|
+
createWalletInfoToolFactory(baseOptions),
|
|
79
|
+
createWalletDeleteToolFactory(baseOptions),
|
|
80
|
+
createWalletRenameToolFactory(baseOptions),
|
|
81
|
+
createWalletExportToolFactory(baseOptions),
|
|
82
|
+
createBalanceQueryToolFactory(baseOptions),
|
|
83
|
+
createTransferToolFactory(baseOptions),
|
|
84
|
+
createTxInfoToolFactory(baseOptions),
|
|
85
|
+
createTxHistoryToolFactory(baseOptions),
|
|
86
|
+
createChainInfoToolFactory(baseOptions),
|
|
87
|
+
createBlockInfoToolFactory(baseOptions),
|
|
88
|
+
createClaimAirdropToolFactory(baseOptions),
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ==================== 钱包创建工具 ====================
|
|
93
|
+
|
|
94
|
+
function createWalletCreateToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
95
|
+
return (ctx: ToolContext) => {
|
|
96
|
+
const options: ExecutorOptions = {
|
|
97
|
+
...baseOptions,
|
|
98
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
name: "clawchain_wallet_create",
|
|
103
|
+
label: "ClawChain Wallet Create",
|
|
104
|
+
description: `在 ClawChain 上创建新钱包。创建后会自动保存到本地,返回钱包地址和私钥。
|
|
105
|
+
|
|
106
|
+
【重要】钱包命名规则:
|
|
107
|
+
1. 强烈建议为每个钱包指定一个**唯一且有意义的名称**,方便后续管理和区分
|
|
108
|
+
2. 名称必须是之前未使用过的,否则会报错
|
|
109
|
+
3. 如果不指定名称,系统会自动生成名称(格式:wallet-01, wallet-02 等)
|
|
110
|
+
4. 创建前可以先调用 clawchain_wallet_list 查看已有钱包名称,避免重复
|
|
111
|
+
|
|
112
|
+
建议的命名方式:
|
|
113
|
+
- 按用途命名:'主钱包'、'储蓄钱包'、'交易钱包'、'测试钱包'
|
|
114
|
+
- 按编号命名:'钱包-1'、'钱包-2' 等`,
|
|
115
|
+
parameters: Type.Object({
|
|
116
|
+
name: Type.Optional(
|
|
117
|
+
Type.String({
|
|
118
|
+
description: "钱包名称(必须唯一)。强烈建议指定一个有意义且未使用过的名称。如不指定,系统会自动生成 wallet-XX 格式的名称",
|
|
119
|
+
})
|
|
120
|
+
),
|
|
121
|
+
}),
|
|
122
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
123
|
+
const params = args as { name?: string };
|
|
124
|
+
const cmdArgs: CommandArgs = {};
|
|
125
|
+
if (params.name) {
|
|
126
|
+
cmdArgs.name = params.name;
|
|
127
|
+
}
|
|
128
|
+
const result = executeCommand(options, "wallet-create", cmdArgs);
|
|
129
|
+
return jsonResult(result);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// ==================== 钱包导入工具 ====================
|
|
136
|
+
|
|
137
|
+
function createWalletImportToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
138
|
+
return (ctx: ToolContext) => {
|
|
139
|
+
const options: ExecutorOptions = {
|
|
140
|
+
...baseOptions,
|
|
141
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
name: "clawchain_wallet_import",
|
|
146
|
+
label: "ClawChain Wallet Import",
|
|
147
|
+
description: `通过私钥导入已有的钱包到 ClawChain。
|
|
148
|
+
导入后钱包会保存到本地,可以像新创建的钱包一样使用。
|
|
149
|
+
|
|
150
|
+
【重要】钱包命名规则:
|
|
151
|
+
1. 强烈建议为导入的钱包指定一个**唯一且有意义的名称**
|
|
152
|
+
2. 名称必须是之前未使用过的,否则会报错
|
|
153
|
+
3. 如果不指定名称,系统会自动生成名称(格式:wallet-01, wallet-02 等)
|
|
154
|
+
4. 导入前可以先调用 clawchain_wallet_list 查看已有钱包名称,避免重复`,
|
|
155
|
+
parameters: Type.Object({
|
|
156
|
+
private_key: Type.String({
|
|
157
|
+
description: "要导入的钱包私钥(支持带或不带 0x 前缀)",
|
|
158
|
+
}),
|
|
159
|
+
name: Type.Optional(
|
|
160
|
+
Type.String({
|
|
161
|
+
description: "钱包名称(必须唯一)。强烈建议指定一个有意义且未使用过的名称。如不指定,系统会自动生成 wallet-XX 格式的名称",
|
|
162
|
+
})
|
|
163
|
+
),
|
|
164
|
+
}),
|
|
165
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
166
|
+
const params = args as { private_key: string; name?: string };
|
|
167
|
+
const cmdArgs: CommandArgs = {
|
|
168
|
+
private_key: params.private_key,
|
|
169
|
+
};
|
|
170
|
+
if (params.name) {
|
|
171
|
+
cmdArgs.name = params.name;
|
|
172
|
+
}
|
|
173
|
+
const result = executeCommand(options, "wallet-import", cmdArgs);
|
|
174
|
+
return jsonResult(result);
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ==================== 钱包列表工具 ====================
|
|
181
|
+
|
|
182
|
+
function createWalletListToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
183
|
+
return (ctx: ToolContext) => {
|
|
184
|
+
const options: ExecutorOptions = {
|
|
185
|
+
...baseOptions,
|
|
186
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
name: "clawchain_wallet_list",
|
|
191
|
+
label: "ClawChain Wallet List",
|
|
192
|
+
description: `列出所有已创建或导入的 ClawChain 钱包。
|
|
193
|
+
可以选择是否显示每个钱包的 CLAW 余额。
|
|
194
|
+
返回钱包名称、地址、创建时间等信息。`,
|
|
195
|
+
parameters: Type.Object({
|
|
196
|
+
show_balance: Type.Optional(
|
|
197
|
+
Type.Boolean({
|
|
198
|
+
description: "是否显示每个钱包的 CLAW 余额(查询余额需要联网,可能稍慢)",
|
|
199
|
+
default: false,
|
|
200
|
+
})
|
|
201
|
+
),
|
|
202
|
+
}),
|
|
203
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
204
|
+
const params = args as { show_balance?: boolean };
|
|
205
|
+
const cmdArgs: CommandArgs = {
|
|
206
|
+
show_balance: params.show_balance ?? false,
|
|
207
|
+
};
|
|
208
|
+
const result = executeCommand(options, "wallet-list", cmdArgs);
|
|
209
|
+
return jsonResult(result);
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// ==================== 钱包详情工具 ====================
|
|
216
|
+
|
|
217
|
+
function createWalletInfoToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
218
|
+
return (ctx: ToolContext) => {
|
|
219
|
+
const options: ExecutorOptions = {
|
|
220
|
+
...baseOptions,
|
|
221
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
name: "clawchain_wallet_info",
|
|
226
|
+
label: "ClawChain Wallet Info",
|
|
227
|
+
description: `获取指定钱包的详细信息,包括地址、余额、创建时间等。
|
|
228
|
+
可以通过钱包名称或钱包 ID 来查询。
|
|
229
|
+
默认不显示私钥,需要显示私钥时设置 show_private_key 为 true。`,
|
|
230
|
+
parameters: Type.Object({
|
|
231
|
+
identifier: Type.String({
|
|
232
|
+
description: "钱包名称或钱包 ID",
|
|
233
|
+
}),
|
|
234
|
+
show_private_key: Type.Optional(
|
|
235
|
+
Type.Boolean({
|
|
236
|
+
description: "是否显示私钥(敏感信息,谨慎使用)",
|
|
237
|
+
default: false,
|
|
238
|
+
})
|
|
239
|
+
),
|
|
240
|
+
}),
|
|
241
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
242
|
+
const params = args as { identifier: string; show_private_key?: boolean };
|
|
243
|
+
const cmdArgs: CommandArgs = {
|
|
244
|
+
identifier: params.identifier,
|
|
245
|
+
show_private_key: params.show_private_key ?? false,
|
|
246
|
+
};
|
|
247
|
+
const result = executeCommand(options, "wallet-info", cmdArgs);
|
|
248
|
+
return jsonResult(result);
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ==================== 钱包删除工具 ====================
|
|
255
|
+
|
|
256
|
+
function createWalletDeleteToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
257
|
+
return (ctx: ToolContext) => {
|
|
258
|
+
const options: ExecutorOptions = {
|
|
259
|
+
...baseOptions,
|
|
260
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
name: "clawchain_wallet_delete",
|
|
265
|
+
label: "ClawChain Wallet Delete",
|
|
266
|
+
description: `删除指定的钱包。删除前会自动备份到 deleted 目录。
|
|
267
|
+
可以通过钱包名称或钱包 ID 来指定要删除的钱包。
|
|
268
|
+
注意:删除后钱包将无法直接使用,但私钥备份仍保留。`,
|
|
269
|
+
parameters: Type.Object({
|
|
270
|
+
identifier: Type.String({
|
|
271
|
+
description: "要删除的钱包名称或钱包 ID",
|
|
272
|
+
}),
|
|
273
|
+
}),
|
|
274
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
275
|
+
const params = args as { identifier: string };
|
|
276
|
+
const cmdArgs: CommandArgs = {
|
|
277
|
+
identifier: params.identifier,
|
|
278
|
+
};
|
|
279
|
+
const result = executeCommand(options, "wallet-delete", cmdArgs);
|
|
280
|
+
return jsonResult(result);
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ==================== 钱包重命名工具 ====================
|
|
287
|
+
|
|
288
|
+
function createWalletRenameToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
289
|
+
return (ctx: ToolContext) => {
|
|
290
|
+
const options: ExecutorOptions = {
|
|
291
|
+
...baseOptions,
|
|
292
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
name: "clawchain_wallet_rename",
|
|
297
|
+
label: "ClawChain Wallet Rename",
|
|
298
|
+
description: `重命名指定的钱包。
|
|
299
|
+
可以通过钱包名称或钱包 ID 来指定要重命名的钱包。`,
|
|
300
|
+
parameters: Type.Object({
|
|
301
|
+
identifier: Type.String({
|
|
302
|
+
description: "要重命名的钱包名称或钱包 ID",
|
|
303
|
+
}),
|
|
304
|
+
new_name: Type.String({
|
|
305
|
+
description: "新的钱包名称",
|
|
306
|
+
}),
|
|
307
|
+
}),
|
|
308
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
309
|
+
const params = args as { identifier: string; new_name: string };
|
|
310
|
+
const cmdArgs: CommandArgs = {
|
|
311
|
+
identifier: params.identifier,
|
|
312
|
+
new_name: params.new_name,
|
|
313
|
+
};
|
|
314
|
+
const result = executeCommand(options, "wallet-rename", cmdArgs);
|
|
315
|
+
return jsonResult(result);
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ==================== 钱包导出工具 ====================
|
|
322
|
+
|
|
323
|
+
function createWalletExportToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
324
|
+
return (ctx: ToolContext) => {
|
|
325
|
+
const options: ExecutorOptions = {
|
|
326
|
+
...baseOptions,
|
|
327
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
return {
|
|
331
|
+
name: "clawchain_wallet_export",
|
|
332
|
+
label: "ClawChain Wallet Export",
|
|
333
|
+
description: `导出钱包的私钥。用于备份或在其他地方导入钱包。
|
|
334
|
+
警告:私钥是敏感信息,请勿泄露给他人!`,
|
|
335
|
+
parameters: Type.Object({
|
|
336
|
+
identifier: Type.String({
|
|
337
|
+
description: "要导出的钱包名称或钱包 ID",
|
|
338
|
+
}),
|
|
339
|
+
}),
|
|
340
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
341
|
+
const params = args as { identifier: string };
|
|
342
|
+
const cmdArgs: CommandArgs = {
|
|
343
|
+
identifier: params.identifier,
|
|
344
|
+
};
|
|
345
|
+
const result = executeCommand(options, "wallet-export", cmdArgs);
|
|
346
|
+
return jsonResult(result);
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// ==================== 余额查询工具 ====================
|
|
353
|
+
|
|
354
|
+
function createBalanceQueryToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
355
|
+
return (ctx: ToolContext) => {
|
|
356
|
+
const options: ExecutorOptions = {
|
|
357
|
+
...baseOptions,
|
|
358
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
name: "clawchain_balance",
|
|
363
|
+
label: "ClawChain Balance",
|
|
364
|
+
description: `查询 ClawChain 上指定地址或钱包的 CLAW 余额。
|
|
365
|
+
可以输入钱包名称、钱包 ID 或直接输入地址(0x 开头)。
|
|
366
|
+
返回余额(CLAW 和 Wei 两种单位)。`,
|
|
367
|
+
parameters: Type.Object({
|
|
368
|
+
address: Type.String({
|
|
369
|
+
description: "钱包地址(0x 开头)、钱包名称或钱包 ID",
|
|
370
|
+
}),
|
|
371
|
+
}),
|
|
372
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
373
|
+
const params = args as { address: string };
|
|
374
|
+
const cmdArgs: CommandArgs = {
|
|
375
|
+
address: params.address,
|
|
376
|
+
};
|
|
377
|
+
const result = executeCommand(options, "balance", cmdArgs);
|
|
378
|
+
return jsonResult(result);
|
|
379
|
+
},
|
|
380
|
+
};
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ==================== 转账工具 ====================
|
|
385
|
+
|
|
386
|
+
function createTransferToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
387
|
+
return (ctx: ToolContext) => {
|
|
388
|
+
const options: ExecutorOptions = {
|
|
389
|
+
...baseOptions,
|
|
390
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
return {
|
|
394
|
+
name: "clawchain_transfer",
|
|
395
|
+
label: "ClawChain Transfer",
|
|
396
|
+
description: `在 ClawChain 上进行 CLAW 转账。
|
|
397
|
+
从指定钱包转账到目标地址或另一个钱包。
|
|
398
|
+
发送方必须是本地已有的钱包(通过名称或 ID 指定)。
|
|
399
|
+
接收方可以是地址、钱包名称或钱包 ID。`,
|
|
400
|
+
parameters: Type.Object({
|
|
401
|
+
from_wallet: Type.String({
|
|
402
|
+
description: "发送方钱包名称或钱包 ID(必须是本地钱包)",
|
|
403
|
+
}),
|
|
404
|
+
to: Type.String({
|
|
405
|
+
description: "接收方地址(0x 开头)、钱包名称或钱包 ID",
|
|
406
|
+
}),
|
|
407
|
+
amount: Type.Number({
|
|
408
|
+
description: "转账金额(单位:CLAW)",
|
|
409
|
+
}),
|
|
410
|
+
wait: Type.Optional(
|
|
411
|
+
Type.Boolean({
|
|
412
|
+
description: "是否等待交易确认(默认不等待,立即返回交易哈希)",
|
|
413
|
+
default: false,
|
|
414
|
+
})
|
|
415
|
+
),
|
|
416
|
+
}),
|
|
417
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
418
|
+
const params = args as { from_wallet: string; to: string; amount: number; wait?: boolean };
|
|
419
|
+
const cmdArgs: CommandArgs = {
|
|
420
|
+
from_wallet: params.from_wallet,
|
|
421
|
+
to: params.to,
|
|
422
|
+
amount: params.amount,
|
|
423
|
+
wait: params.wait ?? false,
|
|
424
|
+
};
|
|
425
|
+
const execOptions = { ...options, timeout: 180000 };
|
|
426
|
+
const result = executeCommand(execOptions, "transfer", cmdArgs);
|
|
427
|
+
return jsonResult(result);
|
|
428
|
+
},
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// ==================== 交易详情工具 ====================
|
|
434
|
+
|
|
435
|
+
function createTxInfoToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
436
|
+
return (ctx: ToolContext) => {
|
|
437
|
+
const options: ExecutorOptions = {
|
|
438
|
+
...baseOptions,
|
|
439
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
return {
|
|
443
|
+
name: "clawchain_tx_info",
|
|
444
|
+
label: "ClawChain Transaction Info",
|
|
445
|
+
description: `查询 ClawChain 上指定交易的详细信息。
|
|
446
|
+
输入交易哈希,返回发送方、接收方、金额、状态等信息。`,
|
|
447
|
+
parameters: Type.Object({
|
|
448
|
+
hash: Type.String({
|
|
449
|
+
description: "交易哈希(0x 开头)",
|
|
450
|
+
}),
|
|
451
|
+
}),
|
|
452
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
453
|
+
const params = args as { hash: string };
|
|
454
|
+
const cmdArgs: CommandArgs = {
|
|
455
|
+
hash: params.hash,
|
|
456
|
+
};
|
|
457
|
+
const result = executeCommand(options, "tx-info", cmdArgs);
|
|
458
|
+
return jsonResult(result);
|
|
459
|
+
},
|
|
460
|
+
};
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// ==================== 交易历史工具 ====================
|
|
465
|
+
|
|
466
|
+
function createTxHistoryToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
467
|
+
return (ctx: ToolContext) => {
|
|
468
|
+
const options: ExecutorOptions = {
|
|
469
|
+
...baseOptions,
|
|
470
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
return {
|
|
474
|
+
name: "clawchain_tx_history",
|
|
475
|
+
label: "ClawChain Transaction History",
|
|
476
|
+
description: `查询指定地址或钱包的交易历史。
|
|
477
|
+
扫描最近的区块,找出与该地址相关的所有交易。
|
|
478
|
+
注意:扫描大量区块可能需要较长时间。`,
|
|
479
|
+
parameters: Type.Object({
|
|
480
|
+
address: Type.String({
|
|
481
|
+
description: "钱包地址、钱包名称或钱包 ID",
|
|
482
|
+
}),
|
|
483
|
+
blocks: Type.Optional(
|
|
484
|
+
Type.Number({
|
|
485
|
+
description: "扫描的区块数量(默认 1000)",
|
|
486
|
+
default: 1000,
|
|
487
|
+
})
|
|
488
|
+
),
|
|
489
|
+
limit: Type.Optional(
|
|
490
|
+
Type.Number({
|
|
491
|
+
description: "返回的交易数量限制(默认 20)",
|
|
492
|
+
default: 20,
|
|
493
|
+
})
|
|
494
|
+
),
|
|
495
|
+
}),
|
|
496
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
497
|
+
const params = args as { address: string; blocks?: number; limit?: number };
|
|
498
|
+
const cmdArgs: CommandArgs = {
|
|
499
|
+
address: params.address,
|
|
500
|
+
blocks: params.blocks ?? 1000,
|
|
501
|
+
limit: params.limit ?? 20,
|
|
502
|
+
};
|
|
503
|
+
const execOptions = { ...options, timeout: 120000 };
|
|
504
|
+
const result = executeCommand(execOptions, "tx-history", cmdArgs);
|
|
505
|
+
return jsonResult(result);
|
|
506
|
+
},
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// ==================== 链信息工具 ====================
|
|
512
|
+
|
|
513
|
+
function createChainInfoToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
514
|
+
return (ctx: ToolContext) => {
|
|
515
|
+
const options: ExecutorOptions = {
|
|
516
|
+
...baseOptions,
|
|
517
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
return {
|
|
521
|
+
name: "clawchain_info",
|
|
522
|
+
label: "ClawChain Info",
|
|
523
|
+
description: `获取 ClawChain 的基本信息,包括:
|
|
524
|
+
- 链名称:ClawChain
|
|
525
|
+
- 代币符号:CLAW
|
|
526
|
+
- RPC 地址
|
|
527
|
+
- Chain ID
|
|
528
|
+
- 连接状态
|
|
529
|
+
- 最新区块号
|
|
530
|
+
- 当前 Gas 价格`,
|
|
531
|
+
parameters: Type.Object({}),
|
|
532
|
+
execute: async () => {
|
|
533
|
+
const result = executeCommand(options, "chain-info", {});
|
|
534
|
+
return jsonResult(result);
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// ==================== 区块信息工具 ====================
|
|
541
|
+
|
|
542
|
+
function createBlockInfoToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
543
|
+
return (ctx: ToolContext) => {
|
|
544
|
+
const options: ExecutorOptions = {
|
|
545
|
+
...baseOptions,
|
|
546
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
return {
|
|
550
|
+
name: "clawchain_block_info",
|
|
551
|
+
label: "ClawChain Block Info",
|
|
552
|
+
description: `查询 ClawChain 上指定区块的信息。
|
|
553
|
+
可以输入区块号或 "latest" 获取最新区块。
|
|
554
|
+
返回区块哈希、时间戳、交易数量等信息。`,
|
|
555
|
+
parameters: Type.Object({
|
|
556
|
+
number: Type.Optional(
|
|
557
|
+
Type.String({
|
|
558
|
+
description: "区块号或 'latest'(默认为 latest)",
|
|
559
|
+
default: "latest",
|
|
560
|
+
})
|
|
561
|
+
),
|
|
562
|
+
}),
|
|
563
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
564
|
+
const params = args as { number?: string };
|
|
565
|
+
const cmdArgs: CommandArgs = {
|
|
566
|
+
number: params.number || "latest",
|
|
567
|
+
};
|
|
568
|
+
const result = executeCommand(options, "block-info", cmdArgs);
|
|
569
|
+
return jsonResult(result);
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
// ==================== 领取空投工具 ====================
|
|
576
|
+
|
|
577
|
+
function createClaimAirdropToolFactory(baseOptions: ExecutorOptions): ToolFactory {
|
|
578
|
+
return (ctx: ToolContext) => {
|
|
579
|
+
const options: ExecutorOptions = {
|
|
580
|
+
...baseOptions,
|
|
581
|
+
walletsDir: resolveWalletsDir(baseOptions, ctx),
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
return {
|
|
585
|
+
name: "clawchain_claim_airdrop",
|
|
586
|
+
label: "ClawChain Claim Airdrop",
|
|
587
|
+
description: `通过 moltbook 发帖领取 CLAW 空投。
|
|
588
|
+
|
|
589
|
+
【重要】领取空投的完整流程(必须按顺序执行):
|
|
590
|
+
|
|
591
|
+
第一步:确保有 ClawChain 钱包
|
|
592
|
+
- 调用 clawchain_wallet_list 查看现有钱包
|
|
593
|
+
- 如果没有钱包,调用 clawchain_wallet_create 创建一个
|
|
594
|
+
- 记住钱包地址
|
|
595
|
+
|
|
596
|
+
第二步:发布帖子
|
|
597
|
+
- 在 moltbook 上发布一个帖子
|
|
598
|
+
- 帖子内容必须包含你的钱包地址
|
|
599
|
+
- 例如: "申请 CLAW 空投,我的钱包地址: 0x1234...abcd"
|
|
600
|
+
- 获取帖子的完整 URL
|
|
601
|
+
|
|
602
|
+
第三步:调用此工具领取空投
|
|
603
|
+
- 将帖子的 URL 传入此工具
|
|
604
|
+
|
|
605
|
+
【注意事项】
|
|
606
|
+
- 帖子内容必须包含有效的钱包地址
|
|
607
|
+
- URL 必须是 moltbook.com 的链接`,
|
|
608
|
+
parameters: Type.Object({
|
|
609
|
+
post_url: Type.String({
|
|
610
|
+
description: "moltbook 帖子或回复的完整 URL,例如: https://www.moltbook.com/post/xxx-xxx-xxx",
|
|
611
|
+
}),
|
|
612
|
+
}),
|
|
613
|
+
execute: async (_toolCallId: string, args: Record<string, unknown>) => {
|
|
614
|
+
const params = args as { post_url: string };
|
|
615
|
+
const cmdArgs: CommandArgs = {
|
|
616
|
+
post_url: params.post_url,
|
|
617
|
+
};
|
|
618
|
+
const result = executeCommand(options, "claim-airdrop", cmdArgs);
|
|
619
|
+
return jsonResult(result);
|
|
620
|
+
},
|
|
621
|
+
};
|
|
622
|
+
};
|
|
623
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ClawChain Plugin 类型定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface ClawChainConfig {
|
|
6
|
+
walletsDir?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CommandResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
error?: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface WalletInfo {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
address: string;
|
|
19
|
+
created_at: string;
|
|
20
|
+
imported?: boolean;
|
|
21
|
+
balance?: string;
|
|
22
|
+
balance_wei?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface TransactionInfo {
|
|
26
|
+
hash: string;
|
|
27
|
+
from: string;
|
|
28
|
+
to: string;
|
|
29
|
+
value: string;
|
|
30
|
+
gas?: number;
|
|
31
|
+
gas_price?: string;
|
|
32
|
+
nonce?: number;
|
|
33
|
+
block_number?: number;
|
|
34
|
+
status?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ChainInfo {
|
|
38
|
+
name: string;
|
|
39
|
+
token_symbol: string;
|
|
40
|
+
rpc_url: string;
|
|
41
|
+
chain_id: number;
|
|
42
|
+
connected: boolean;
|
|
43
|
+
latest_block?: number;
|
|
44
|
+
gas_price?: string;
|
|
45
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"rootDir": "."
|
|
12
|
+
},
|
|
13
|
+
"include": ["*.ts", "src/**/*.ts"],
|
|
14
|
+
"exclude": ["node_modules", "dist"]
|
|
15
|
+
}
|