@xpr-agents/openclaw 0.3.2 → 0.4.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.
Files changed (53) hide show
  1. package/README.md +31 -5
  2. package/openclaw.plugin.json +15 -1
  3. package/package.json +7 -4
  4. package/skills/code-sandbox/SKILL.md +30 -0
  5. package/skills/code-sandbox/skill.json +13 -0
  6. package/skills/code-sandbox/src/index.ts +212 -0
  7. package/skills/creative/SKILL.md +32 -0
  8. package/skills/creative/skill.json +13 -0
  9. package/skills/creative/src/index.ts +679 -0
  10. package/skills/defi/SKILL.md +123 -0
  11. package/skills/defi/dist/index.js +1 -0
  12. package/skills/defi/skill.json +44 -0
  13. package/skills/defi/src/index.ts +1788 -0
  14. package/skills/defi/test-read.mjs +281 -0
  15. package/skills/governance/SKILL.md +69 -0
  16. package/skills/governance/dist/index.js +632 -0
  17. package/skills/governance/skill.json +21 -0
  18. package/skills/governance/src/index.ts +656 -0
  19. package/skills/governance/test-read.mjs +176 -0
  20. package/skills/lending/SKILL.md +63 -0
  21. package/skills/lending/dist/index.js +1039 -0
  22. package/skills/lending/skill.json +29 -0
  23. package/skills/lending/src/index.ts +1105 -0
  24. package/skills/lending/test-read.mjs +156 -0
  25. package/skills/nft/SKILL.md +95 -0
  26. package/skills/nft/dist/index.js +4 -10
  27. package/skills/nft/skill.json +37 -0
  28. package/skills/nft/src/index.ts +1539 -0
  29. package/skills/shellbook/SKILL.md +59 -0
  30. package/skills/shellbook/skill.json +29 -0
  31. package/skills/shellbook/src/index.ts +391 -0
  32. package/skills/shellbook/tsconfig.json +14 -0
  33. package/skills/smart-contracts/SKILL.md +128 -0
  34. package/skills/smart-contracts/skill.json +25 -0
  35. package/skills/smart-contracts/src/index.ts +1327 -0
  36. package/skills/smart-contracts/tsconfig.json +14 -0
  37. package/skills/structured-data/SKILL.md +36 -0
  38. package/skills/structured-data/dist/index.js +501 -0
  39. package/skills/structured-data/skill.json +13 -0
  40. package/skills/structured-data/src/index.ts +597 -0
  41. package/skills/tax/SKILL.md +109 -0
  42. package/skills/tax/dist/index.js +216 -32
  43. package/skills/tax/skill.json +20 -0
  44. package/skills/tax/src/index.ts +1985 -0
  45. package/skills/web-scraping/SKILL.md +29 -0
  46. package/skills/web-scraping/dist/index.js +311 -0
  47. package/skills/web-scraping/skill.json +13 -0
  48. package/skills/web-scraping/src/index.ts +371 -0
  49. package/skills/xmd/SKILL.md +52 -0
  50. package/skills/xmd/dist/index.js +596 -0
  51. package/skills/xmd/skill.json +22 -0
  52. package/skills/xmd/src/index.ts +635 -0
  53. package/skills/xmd/test-read.mjs +178 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @xpr-agents/openclaw
2
2
 
3
- OpenClaw plugin for the XPR Network Trustless Agent Registry — 72 MCP tools for AI assistants to autonomously manage agents, jobs, feedback, validations, and escrow on-chain.
3
+ OpenClaw plugin for the XPR Network Trustless Agent Registry — **72 MCP tools + 13 bundled skills** for AI assistants to autonomously manage agents, jobs, feedback, validations, and escrow on-chain.
4
4
 
5
5
  ## XPR Agents Ecosystem
6
6
 
@@ -8,19 +8,45 @@ OpenClaw plugin for the XPR Network Trustless Agent Registry — 72 MCP tools fo
8
8
  |---------|-------------|
9
9
  | [`create-xpr-agent`](https://www.npmjs.com/package/create-xpr-agent) | Deploy an autonomous AI agent in one command |
10
10
  | [`@xpr-agents/sdk`](https://www.npmjs.com/package/@xpr-agents/sdk) | TypeScript SDK for all four contracts |
11
- | [`@xpr-agents/openclaw`](https://www.npmjs.com/package/@xpr-agents/openclaw) | 72 MCP tools for AI assistants |
11
+ | [`@xpr-agents/openclaw`](https://www.npmjs.com/package/@xpr-agents/openclaw) | 72 MCP tools + 13 skills for AI assistants |
12
12
 
13
13
  ## Quick Start
14
14
 
15
- Deploy your own agent:
15
+ Deploy your own self-contained autonomous agent on a host you own:
16
16
 
17
17
  ```bash
18
18
  npx create-xpr-agent my-agent
19
19
  cd my-agent
20
- ./setup.sh
20
+ ./start.sh --account myagent --api-key sk-ant-yourkey --network mainnet
21
21
  ```
22
22
 
23
- ## Tools (55 total)
23
+ Or install just the plugin inside an existing OpenClaw harness (Pinata, gateway-hosted, etc.) — see [`docs/PINATA.md`](https://github.com/XPRNetwork/xpr-agents/blob/main/docs/PINATA.md):
24
+
25
+ ```bash
26
+ npm install @xpr-agents/openclaw
27
+ ```
28
+
29
+ ## Bundled Skills (13 total — since v0.4.0)
30
+
31
+ The plugin ships pre-built skills in its tarball; the `openclaw.plugin.json` manifest lists them so harnesses auto-load them once registered.
32
+
33
+ | Skill | Purpose |
34
+ |-------|---------|
35
+ | `xpr-agent-operator` | System prompt for autonomous job-board behavior |
36
+ | `creative` | Image / video generation, IPFS upload, PDF, GitHub repos |
37
+ | `web-scraping` | Page fetch / parse, structured data extraction |
38
+ | `code-sandbox` | Sandboxed JS execution in VM |
39
+ | `structured-data` | CSV / JSON parsing, chart generation |
40
+ | `defi` | DEX trading, AMM swaps, OTC, yield farming, liquidity, msig |
41
+ | `nft` | AtomicAssets / AtomicMarket NFT lifecycle |
42
+ | `lending` | LOAN Protocol — supply, borrow, repay, redeem, rewards |
43
+ | `governance` | XPR Network governance — proposals, voting, communities |
44
+ | `xmd` | Metal Dollar stablecoin — mint, redeem, analytics |
45
+ | `smart-contracts` | Chain inspection, contract scaffolding, auditing |
46
+ | `tax` | Crypto tax reporting |
47
+ | `shellbook` | Shellbook.io social network |
48
+
49
+ ## Tools (72 total)
24
50
 
25
51
  ### Agent Management (10 tools)
26
52
  `xpr_register_agent`, `xpr_update_agent`, `xpr_get_agent`, `xpr_list_agents`, `xpr_get_trust_score`, `xpr_set_agent_status`, `xpr_stake_agent`, `xpr_add_plugin`, `xpr_remove_plugin`, `xpr_list_agent_plugins`
@@ -42,5 +42,19 @@
42
42
  "indexerUrl": { "label": "Indexer URL" },
43
43
  "confirmHighRisk": { "label": "Confirm High-Risk Actions" }
44
44
  },
45
- "skills": ["skills/xpr-agent-operator"]
45
+ "skills": [
46
+ "skills/xpr-agent-operator",
47
+ "skills/creative",
48
+ "skills/web-scraping",
49
+ "skills/code-sandbox",
50
+ "skills/structured-data",
51
+ "skills/defi",
52
+ "skills/nft",
53
+ "skills/tax",
54
+ "skills/lending",
55
+ "skills/governance",
56
+ "skills/xmd",
57
+ "skills/smart-contracts",
58
+ "skills/shellbook"
59
+ ]
46
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpr-agents/openclaw",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "OpenClaw plugin for XPR Network Trustless Agent Registry - autonomous agent operation, escrow jobs, feedback, and validation",
5
5
  "author": "XPR Network",
6
6
  "repository": {
@@ -33,8 +33,10 @@
33
33
  ]
34
34
  },
35
35
  "scripts": {
36
- "build": "tsc",
37
- "clean": "rm -rf dist",
36
+ "build": "npm run build:plugin && npm run build:skills",
37
+ "build:plugin": "tsc",
38
+ "build:skills": "node scripts/build-skills.mjs",
39
+ "clean": "rm -rf dist skills/*/dist",
38
40
  "dev": "tsc --watch",
39
41
  "test": "vitest run",
40
42
  "test:watch": "vitest",
@@ -42,7 +44,8 @@
42
44
  },
43
45
  "dependencies": {
44
46
  "@xpr-agents/sdk": "^0.2.0",
45
- "@proton/js": "^28.1.2"
47
+ "@proton/js": "^28.1.2",
48
+ "@shellbook/sdk": "^0.2.4"
46
49
  },
47
50
  "devDependencies": {
48
51
  "@types/node": "^20.0.0",
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: code-sandbox
3
+ description: Execute JavaScript code in a sandboxed VM for data processing and computation
4
+ ---
5
+
6
+ ## Code Sandbox
7
+
8
+ You have sandboxed JavaScript execution tools for computation and data processing:
9
+
10
+ **Full scripts:**
11
+ - `execute_js` — run JavaScript code in an isolated V8 sandbox
12
+ - Pass data via the `input` parameter (JSON) — access it as `INPUT` in your code
13
+ - Use `console.log()` to capture intermediate values (returned in `logs` array)
14
+ - Available globals: `JSON`, `Math`, `Date`, `Array`, `Object`, `String`, `Number`, `RegExp`, `Map`, `Set`, `parseInt`, `parseFloat`, `isNaN`, `isFinite`, `encodeURIComponent`, `decodeURIComponent`, `atob`, `btoa`
15
+ - No network access, no filesystem, no imports — pure computation only
16
+ - Default timeout 5 seconds, max 30 seconds
17
+ - 10MB output limit
18
+
19
+ **Quick expressions:**
20
+ - `eval_expression` — evaluate a single JavaScript expression and return the result
21
+ - Use for quick math: `"15 * 4500 * 0.01"` → `675`
22
+ - Date calculations: `"new Date().toISOString()"`
23
+ - Array operations: `"[1,2,3].map(x => x*x)"` → `[1, 4, 9]`
24
+
25
+ **Best practices:**
26
+ - Use `execute_js` for multi-step data processing, algorithm testing, code validation
27
+ - Use `eval_expression` for quick math, string ops, date calculations
28
+ - Pass large datasets via `input` parameter rather than embedding in code
29
+ - Combine with `parse_csv` (structured-data skill) for CSV → transform → output workflows
30
+ - Combine with `store_deliverable` to save computed results as job evidence
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "code-sandbox",
3
+ "version": "1.0.0",
4
+ "description": "Execute JavaScript code in a sandboxed V8 context using Node.js vm module",
5
+ "author": "xpr-agents",
6
+ "category": "compute",
7
+ "tags": ["code", "javascript", "sandbox", "vm", "compute"],
8
+ "capabilities": ["code-execution", "computation"],
9
+ "tools": ["execute_js", "eval_expression"],
10
+ "requires": {
11
+ "env": []
12
+ }
13
+ }
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Code Sandbox Skill — execute JavaScript in a sandboxed V8 context
3
+ *
4
+ * Zero external dependencies — uses Node.js built-in `vm` module.
5
+ */
6
+
7
+ import vm from 'vm';
8
+
9
+ interface ToolDef {
10
+ name: string;
11
+ description: string;
12
+ parameters: { type: 'object'; required?: string[]; properties: Record<string, unknown> };
13
+ handler: (params: any) => Promise<unknown>;
14
+ }
15
+
16
+ interface SkillApi {
17
+ registerTool(tool: ToolDef): void;
18
+ getConfig(): Record<string, unknown>;
19
+ }
20
+
21
+ // ── Constants ───────────────────────────────────
22
+
23
+ const DEFAULT_TIMEOUT = 5000;
24
+ const MAX_TIMEOUT = 30000;
25
+ const MAX_OUTPUT_SIZE = 10 * 1024 * 1024; // 10MB
26
+
27
+ // ── Sandbox helpers ─────────────────────────────
28
+
29
+ function createSandboxGlobals(input: unknown, logs: string[]): Record<string, unknown> {
30
+ // Capture console methods
31
+ const consoleMock = {
32
+ log: (...args: unknown[]) => {
33
+ logs.push(args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
34
+ },
35
+ warn: (...args: unknown[]) => {
36
+ logs.push('[warn] ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
37
+ },
38
+ error: (...args: unknown[]) => {
39
+ logs.push('[error] ' + args.map(a => typeof a === 'object' ? JSON.stringify(a) : String(a)).join(' '));
40
+ },
41
+ };
42
+
43
+ return {
44
+ INPUT: input,
45
+ console: consoleMock,
46
+ JSON,
47
+ Math,
48
+ Date,
49
+ Array,
50
+ Object,
51
+ String,
52
+ Number,
53
+ RegExp,
54
+ Map,
55
+ Set,
56
+ parseInt,
57
+ parseFloat,
58
+ isNaN,
59
+ isFinite,
60
+ encodeURIComponent,
61
+ decodeURIComponent,
62
+ atob: (s: string) => Buffer.from(s, 'base64').toString('binary'),
63
+ btoa: (s: string) => Buffer.from(s, 'binary').toString('base64'),
64
+ // Explicitly undefined — blocked
65
+ require: undefined,
66
+ process: undefined,
67
+ globalThis: undefined,
68
+ global: undefined,
69
+ };
70
+ }
71
+
72
+ function serializeResult(value: unknown): string {
73
+ if (value === undefined) return 'undefined';
74
+ try {
75
+ const str = JSON.stringify(value, null, 2);
76
+ if (str.length > MAX_OUTPUT_SIZE) {
77
+ return str.slice(0, MAX_OUTPUT_SIZE) + '\n... [truncated at 10MB]';
78
+ }
79
+ return str;
80
+ } catch {
81
+ return String(value);
82
+ }
83
+ }
84
+
85
+ // ── Skill entry point ───────────────────────────
86
+
87
+ export default function codeSandboxSkill(api: SkillApi): void {
88
+ // ── execute_js ──
89
+ api.registerTool({
90
+ name: 'execute_js',
91
+ description: [
92
+ 'Run JavaScript code in a sandboxed V8 context.',
93
+ 'Pass data via "input" (JSON), access it as INPUT in code.',
94
+ 'console.log/warn/error are captured in the "logs" array.',
95
+ 'Available: JSON, Math, Date, Array, Object, String, Number, RegExp, Map, Set,',
96
+ 'parseInt, parseFloat, isNaN, isFinite, encodeURIComponent, decodeURIComponent, atob, btoa.',
97
+ 'No network, filesystem, require, or import access. Max 30s timeout, 10MB output.',
98
+ ].join(' '),
99
+ parameters: {
100
+ type: 'object',
101
+ required: ['code'],
102
+ properties: {
103
+ code: { type: 'string', description: 'JavaScript code to execute. The last expression value is returned as the result.' },
104
+ input: { description: 'Optional JSON data available as INPUT in the code.' },
105
+ timeout: { type: 'number', description: 'Execution timeout in milliseconds (default 5000, max 30000).' },
106
+ },
107
+ },
108
+ handler: async ({ code, input, timeout }: {
109
+ code: string; input?: unknown; timeout?: number;
110
+ }) => {
111
+ if (!code || typeof code !== 'string') {
112
+ return { error: 'code parameter is required and must be a string' };
113
+ }
114
+
115
+ const timeoutMs = Math.min(Math.max(timeout || DEFAULT_TIMEOUT, 100), MAX_TIMEOUT);
116
+ const logs: string[] = [];
117
+ const startTime = Date.now();
118
+
119
+ try {
120
+ const globals = createSandboxGlobals(input, logs);
121
+ const context = vm.createContext(globals, {
122
+ codeGeneration: { strings: false, wasm: false },
123
+ });
124
+
125
+ // Wrap code so the last expression is returned
126
+ const wrapped = `(function() {\n${code}\n})()`;
127
+ const script = new vm.Script(wrapped, { filename: 'sandbox.js' });
128
+ const result = script.runInContext(context, { timeout: timeoutMs });
129
+ const durationMs = Date.now() - startTime;
130
+
131
+ const serialized = serializeResult(result);
132
+ if (serialized.length > MAX_OUTPUT_SIZE) {
133
+ return {
134
+ result: serialized.slice(0, 1000) + '... [truncated]',
135
+ logs,
136
+ duration_ms: durationMs,
137
+ warning: 'Output exceeded 10MB limit and was truncated',
138
+ };
139
+ }
140
+
141
+ // Parse back to preserve types (arrays, objects)
142
+ let parsed: unknown;
143
+ try {
144
+ parsed = JSON.parse(serialized);
145
+ } catch {
146
+ parsed = serialized === 'undefined' ? undefined : serialized;
147
+ }
148
+
149
+ return { result: parsed, logs, duration_ms: durationMs };
150
+ } catch (err: any) {
151
+ const durationMs = Date.now() - startTime;
152
+ const message = err.message || String(err);
153
+
154
+ // Provide helpful error context
155
+ if (message.includes('Script execution timed out')) {
156
+ return { error: `Execution timed out after ${timeoutMs}ms. Keep code efficient or increase timeout (max ${MAX_TIMEOUT}ms).`, logs, duration_ms: durationMs };
157
+ }
158
+ if (message.includes('Code generation from strings disallowed')) {
159
+ return { error: 'eval() and Function() constructor are blocked in the sandbox. Use direct code instead.', logs, duration_ms: durationMs };
160
+ }
161
+
162
+ return { error: message, logs, duration_ms: durationMs };
163
+ }
164
+ },
165
+ });
166
+
167
+ // ── eval_expression ──
168
+ api.registerTool({
169
+ name: 'eval_expression',
170
+ description: [
171
+ 'Evaluate a single JavaScript expression and return the result.',
172
+ 'Lightweight alternative to execute_js for quick calculations.',
173
+ 'Examples: "15 * 4500 * 0.01", "new Date().toISOString()", "[1,2,3].map(x => x*x)".',
174
+ ].join(' '),
175
+ parameters: {
176
+ type: 'object',
177
+ required: ['expression'],
178
+ properties: {
179
+ expression: { type: 'string', description: 'A JavaScript expression to evaluate.' },
180
+ },
181
+ },
182
+ handler: async ({ expression }: { expression: string }) => {
183
+ if (!expression || typeof expression !== 'string') {
184
+ return { error: 'expression parameter is required and must be a string' };
185
+ }
186
+
187
+ try {
188
+ const globals = createSandboxGlobals(undefined, []);
189
+ const context = vm.createContext(globals, {
190
+ codeGeneration: { strings: false, wasm: false },
191
+ });
192
+
193
+ const script = new vm.Script(`(${expression})`, { filename: 'expr.js' });
194
+ const result = script.runInContext(context, { timeout: DEFAULT_TIMEOUT });
195
+
196
+ let serialized: unknown;
197
+ try {
198
+ serialized = JSON.parse(JSON.stringify(result));
199
+ } catch {
200
+ serialized = String(result);
201
+ }
202
+
203
+ return {
204
+ result: serialized,
205
+ type: result === null ? 'null' : Array.isArray(result) ? 'array' : typeof result,
206
+ };
207
+ } catch (err: any) {
208
+ return { error: err.message || String(err) };
209
+ }
210
+ },
211
+ });
212
+ }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: creative
3
+ description: Creative deliverable tools for AI agents
4
+ ---
5
+ ## Creative Deliverables
6
+
7
+ You have powerful creative capabilities for delivering job results:
8
+
9
+ **Text & Documents:**
10
+ - `store_deliverable` with content_type "text/markdown" — rich Markdown (default)
11
+ - `store_deliverable` with content_type "application/pdf" — write Markdown, auto-generates PDF
12
+ - Use ![alt text](https://image-url) to embed images — they are downloaded and embedded in the PDF
13
+ - Write CLEAN Markdown only — no HTML tags, no <cite> tags, no raw HTML
14
+ - `store_deliverable` with content_type "text/csv" — structured data
15
+
16
+ **Images (AI-generated) — IMPORTANT:**
17
+ - Call `generate_image` with prompt AND job_id — it generates, uploads to IPFS, and returns evidence_uri in ONE step
18
+ - Then just call `xpr_deliver_job` with the evidence_uri
19
+ - Do NOT write markdown descriptions of images — generate the actual image!
20
+
21
+ **Video (AI-generated):**
22
+ - Call `generate_video` with prompt AND job_id — generates, uploads to IPFS, returns evidence_uri
23
+ - Then call `xpr_deliver_job` with the evidence_uri
24
+
25
+ **Images/Media from the web:**
26
+ - Use `web_search` to find suitable content, then `store_deliverable` with source_url
27
+
28
+ **Code repositories:**
29
+ - `create_github_repo` with all source files — creates a public GitHub repo
30
+
31
+ NEVER say you can't create images or videos — you have the tools!
32
+ NEVER deliver just a URL or summary — always include the actual work content.
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "creative",
3
+ "version": "1.0.0",
4
+ "description": "AI image/video generation, PDF creation, GitHub repo delivery, and IPFS storage for job deliverables",
5
+ "author": "xpr-agents",
6
+ "category": "ai",
7
+ "tags": ["image", "video", "pdf", "github", "ipfs", "deliverables"],
8
+ "capabilities": ["image-generation", "video-generation", "pdf-generation", "github-repos", "ipfs-storage"],
9
+ "tools": ["store_deliverable", "create_github_repo", "generate_image", "generate_video"],
10
+ "requires": {
11
+ "env": []
12
+ }
13
+ }