@ch4r10teer41/clawpass 1.0.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.
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Clawpass OpenClaw plugin
3
+ *
4
+ * Exposes ERC-8004 identity, reputation, and validation as agent tools and CLI.
5
+ * Config: plugins.entries.clawpass.config
6
+ *
7
+ * @see https://docs.openclaw.ai/cli/plugins
8
+ * @see https://docs.openclaw.ai/plugins/manifest
9
+ * @see https://docs.openclaw.ai/plugins/agent-tools
10
+ */
11
+
12
+ import { ClawpassClient, toFixedPoint, calculateHash } from '@ch4r10teer41/clawpass';
13
+ import { ethers } from 'ethers';
14
+
15
+ type Api = {
16
+ config: Record<string, unknown>;
17
+ logger: { info: (msg: string) => void; warn: (msg: string) => void; error: (msg: string) => void };
18
+ registerTool: (tool: ToolDef, opts?: { optional?: boolean }) => void;
19
+ registerGatewayMethod?: (name: string, handler: (ctx: { respond: (ok: boolean, data: unknown) => void }) => void) => void;
20
+ registerCli?: (fn: (ctx: { program: { command: (name: string) => { description: (d: string) => { action: (fn: () => void) => void } } } }) => void, opts: { commands: string[] }) => void;
21
+ };
22
+
23
+ type ToolDef = {
24
+ name: string;
25
+ description: string;
26
+ parameters: Record<string, unknown>;
27
+ execute: (id: string, params: Record<string, unknown>) => Promise<{ content: Array<{ type: string; text: string }> }>;
28
+ };
29
+
30
+ function getPluginConfig(api: Api): Record<string, unknown> | null {
31
+ const entries = api.config?.plugins as Record<string, unknown> | undefined;
32
+ const pluginsEntries = entries?.entries as Record<string, unknown> | undefined;
33
+ const clawpassEntry = pluginsEntries?.clawpass as Record<string, unknown> | undefined;
34
+ return clawpassEntry?.config as Record<string, unknown> | null ?? null;
35
+ }
36
+
37
+ function createClient(api: Api): ClawpassClient | null {
38
+ const cfg = getPluginConfig(api);
39
+ if (!cfg?.rpcUrl || !cfg?.identityRegistryAddress || !cfg?.reputationRegistryAddress || !cfg?.validationRegistryAddress) {
40
+ return null;
41
+ }
42
+ const provider = new ethers.JsonRpcProvider(cfg.rpcUrl as string);
43
+ const signer = cfg.privateKey
44
+ ? new ethers.Wallet(cfg.privateKey as string, provider)
45
+ : provider;
46
+ return new ClawpassClient({
47
+ identityRegistryAddress: cfg.identityRegistryAddress as string,
48
+ reputationRegistryAddress: cfg.reputationRegistryAddress as string,
49
+ validationRegistryAddress: cfg.validationRegistryAddress as string,
50
+ providerOrSigner: signer,
51
+ });
52
+ }
53
+
54
+ let clientInstance: ClawpassClient | null = null;
55
+
56
+ function getClient(api: Api): ClawpassClient | null {
57
+ if (!clientInstance) {
58
+ clientInstance = createClient(api);
59
+ }
60
+ return clientInstance;
61
+ }
62
+
63
+ export default function register(api: Api): void {
64
+ api.logger?.info?.('Clawpass plugin registering');
65
+
66
+ // Optional agent tools (opt-in via tools.allow)
67
+ api.registerTool(
68
+ {
69
+ name: 'clawpass_get_agent_info',
70
+ description: 'Get ERC-8004 agent info: registration, owner, wallet. Requires agentId (number).',
71
+ parameters: {
72
+ type: 'object',
73
+ properties: { agentId: { type: 'number', description: 'ERC-8004 agent ID' } },
74
+ required: ['agentId'],
75
+ },
76
+ async execute(_id, params) {
77
+ const client = getClient(api);
78
+ if (!client) {
79
+ return { content: [{ type: 'text', text: 'Clawpass not configured. Set plugins.entries.clawpass.config (rpcUrl, identityRegistryAddress, reputationRegistryAddress, validationRegistryAddress).' }] };
80
+ }
81
+ try {
82
+ const agentId = BigInt(Number(params.agentId));
83
+ const info = await client.getAgentInfo(agentId);
84
+ return { content: [{ type: 'text', text: JSON.stringify({ agentId: String(agentId), owner: info.owner, wallet: info.wallet, name: info.registration.name, description: info.registration.description, services: info.registration.services }, null, 2) }] };
85
+ } catch (e) {
86
+ const msg = e instanceof Error ? e.message : String(e);
87
+ return { content: [{ type: 'text', text: `Error: ${msg}` }] };
88
+ }
89
+ },
90
+ },
91
+ { optional: true }
92
+ );
93
+
94
+ api.registerTool(
95
+ {
96
+ name: 'clawpass_get_reputation',
97
+ description: 'Get agent reputation from trusted clients. Requires agentId (number) and trustedClients (array of Ethereum addresses). Optional tag1, tag2.',
98
+ parameters: {
99
+ type: 'object',
100
+ properties: {
101
+ agentId: { type: 'number', description: 'ERC-8004 agent ID' },
102
+ trustedClients: { type: 'array', items: { type: 'string' }, description: 'Addresses of trusted reviewers' },
103
+ tag1: { type: 'string' },
104
+ tag2: { type: 'string' },
105
+ },
106
+ required: ['agentId', 'trustedClients'],
107
+ },
108
+ async execute(_id, params) {
109
+ const client = getClient(api);
110
+ if (!client) {
111
+ return { content: [{ type: 'text', text: 'Clawpass not configured.' }] };
112
+ }
113
+ try {
114
+ const agentId = BigInt(Number(params.agentId));
115
+ const trustedClients = (params.trustedClients as string[]) || [];
116
+ if (trustedClients.length === 0) {
117
+ return { content: [{ type: 'text', text: 'trustedClients must be a non-empty array (Sybil protection).' }] };
118
+ }
119
+ const rep = await client.getAgentReputation(agentId, trustedClients, params.tag1 as string, params.tag2 as string);
120
+ return { content: [{ type: 'text', text: JSON.stringify({ summary: { count: String(rep.summary.count), summaryValue: String(rep.summary.summaryValue), summaryValueDecimals: rep.summary.summaryValueDecimals }, feedbackCount: rep.feedback.length }, null, 2) }] };
121
+ } catch (e) {
122
+ const msg = e instanceof Error ? e.message : String(e);
123
+ return { content: [{ type: 'text', text: `Error: ${msg}` }] };
124
+ }
125
+ },
126
+ },
127
+ { optional: true }
128
+ );
129
+
130
+ api.registerTool(
131
+ {
132
+ name: 'clawpass_give_feedback',
133
+ description: 'Submit feedback for an agent (requires privateKey in plugin config). Params: agentId (number), value (number, e.g. 4.5), valueDecimals (0-18), optional tag1, tag2, endpoint.',
134
+ parameters: {
135
+ type: 'object',
136
+ properties: {
137
+ agentId: { type: 'number' },
138
+ value: { type: 'number', description: 'e.g. 4.5 for 4.5 stars' },
139
+ valueDecimals: { type: 'number', description: '0-18' },
140
+ tag1: { type: 'string' },
141
+ tag2: { type: 'string' },
142
+ endpoint: { type: 'string' },
143
+ },
144
+ required: ['agentId', 'value', 'valueDecimals'],
145
+ },
146
+ async execute(_id, params) {
147
+ const client = getClient(api);
148
+ if (!client) {
149
+ return { content: [{ type: 'text', text: 'Clawpass not configured.' }] };
150
+ }
151
+ try {
152
+ const value = toFixedPoint(Number(params.value), Number(params.valueDecimals) || 1);
153
+ await client.reputation.giveFeedback({
154
+ agentId: BigInt(Number(params.agentId)),
155
+ value,
156
+ valueDecimals: Number(params.valueDecimals) || 1,
157
+ tag1: params.tag1 as string,
158
+ tag2: params.tag2 as string,
159
+ endpoint: params.endpoint as string,
160
+ });
161
+ return { content: [{ type: 'text', text: 'Feedback submitted successfully.' }] };
162
+ } catch (e) {
163
+ const msg = e instanceof Error ? e.message : String(e);
164
+ return { content: [{ type: 'text', text: `Error: ${msg}` }] };
165
+ }
166
+ },
167
+ },
168
+ { optional: true }
169
+ );
170
+
171
+ api.registerTool(
172
+ {
173
+ name: 'clawpass_request_validation',
174
+ description: 'Request validation for an agent (requires privateKey). Params: validatorAddress (string), agentId (number), requestURI (string), requestData (string, will be hashed) or requestHash (string).',
175
+ parameters: {
176
+ type: 'object',
177
+ properties: {
178
+ validatorAddress: { type: 'string' },
179
+ agentId: { type: 'number' },
180
+ requestURI: { type: 'string' },
181
+ requestData: { type: 'string', description: 'Payload to hash if requestHash not provided' },
182
+ requestHash: { type: 'string' },
183
+ },
184
+ required: ['validatorAddress', 'agentId', 'requestURI'],
185
+ },
186
+ async execute(_id, params) {
187
+ const client = getClient(api);
188
+ if (!client) {
189
+ return { content: [{ type: 'text', text: 'Clawpass not configured.' }] };
190
+ }
191
+ try {
192
+ const requestHash = (params.requestHash as string) || (params.requestData ? calculateHash(String(params.requestData)) : '');
193
+ if (!requestHash) {
194
+ return { content: [{ type: 'text', text: 'Provide requestHash or requestData.' }] };
195
+ }
196
+ await client.validation.validationRequest({
197
+ validatorAddress: params.validatorAddress as string,
198
+ agentId: Number(params.agentId),
199
+ requestURI: params.requestURI as string,
200
+ requestHash,
201
+ });
202
+ return { content: [{ type: 'text', text: 'Validation requested successfully.' }] };
203
+ } catch (e) {
204
+ const msg = e instanceof Error ? e.message : String(e);
205
+ return { content: [{ type: 'text', text: `Error: ${msg}` }] };
206
+ }
207
+ },
208
+ },
209
+ { optional: true }
210
+ );
211
+
212
+ api.registerTool(
213
+ {
214
+ name: 'clawpass_validation_status',
215
+ description: 'Get validation status for a request. Requires requestHash (string).',
216
+ parameters: {
217
+ type: 'object',
218
+ properties: { requestHash: { type: 'string' } },
219
+ required: ['requestHash'],
220
+ },
221
+ async execute(_id, params) {
222
+ const client = getClient(api);
223
+ if (!client) {
224
+ return { content: [{ type: 'text', text: 'Clawpass not configured.' }] };
225
+ }
226
+ try {
227
+ const status = await client.validation.getValidationStatus(params.requestHash as string);
228
+ return { content: [{ type: 'text', text: JSON.stringify({ validatorAddress: status.validatorAddress, agentId: String(status.agentId), response: status.response, tag: status.tag, lastUpdate: String(status.lastUpdate) }, null, 2) }] };
229
+ } catch (e) {
230
+ const msg = e instanceof Error ? e.message : String(e);
231
+ return { content: [{ type: 'text', text: `Error: ${msg}` }] };
232
+ }
233
+ },
234
+ },
235
+ { optional: true }
236
+ );
237
+
238
+ if (api.registerGatewayMethod) {
239
+ api.registerGatewayMethod('clawpass.status', ({ respond }) => {
240
+ const client = getClient(api);
241
+ respond(!!client, { configured: !!client });
242
+ });
243
+ }
244
+
245
+ if (api.registerCli) {
246
+ api.registerCli(
247
+ ({ program }) => {
248
+ program
249
+ .command('clawpass')
250
+ .description('Clawpass ERC-8004 status')
251
+ .action(() => {
252
+ const client = getClient(api);
253
+ const cfg = getPluginConfig(api);
254
+ if (!cfg) {
255
+ console.log('Clawpass: not configured (plugins.entries.clawpass.config)');
256
+ return;
257
+ }
258
+ if (!client) {
259
+ console.log('Clawpass: invalid or incomplete config (rpcUrl + all three registry addresses required)');
260
+ return;
261
+ }
262
+ console.log('Clawpass: configured and ready');
263
+ });
264
+ },
265
+ { commands: ['clawpass'] }
266
+ );
267
+ }
268
+
269
+ api.logger?.info?.('Clawpass plugin registered (optional tools: clawpass_get_agent_info, clawpass_get_reputation, clawpass_give_feedback, clawpass_request_validation, clawpass_validation_status)');
270
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "id": "clawpass",
3
+ "name": "Clawpass",
4
+ "description": "ERC-8004 interface: agent identity, reputation, and validation on blockchain. Register agents, give/query feedback, request validation.",
5
+ "version": "1.0.0",
6
+ "kind": "tools",
7
+ "configSchema": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "rpcUrl": {
12
+ "type": "string",
13
+ "description": "EVM JSON-RPC URL (e.g. Alchemy, Infura)"
14
+ },
15
+ "identityRegistryAddress": {
16
+ "type": "string",
17
+ "description": "ERC-8004 Identity Registry contract address"
18
+ },
19
+ "reputationRegistryAddress": {
20
+ "type": "string",
21
+ "description": "ERC-8004 Reputation Registry contract address"
22
+ },
23
+ "validationRegistryAddress": {
24
+ "type": "string",
25
+ "description": "ERC-8004 Validation Registry contract address"
26
+ },
27
+ "privateKey": {
28
+ "type": "string",
29
+ "description": "Optional wallet private key for write operations (register, give feedback, validation request)"
30
+ },
31
+ "chainId": {
32
+ "type": "number",
33
+ "description": "Chain ID (e.g. 1 for mainnet)"
34
+ }
35
+ },
36
+ "required": ["rpcUrl", "identityRegistryAddress", "reputationRegistryAddress", "validationRegistryAddress"]
37
+ },
38
+ "uiHints": {
39
+ "rpcUrl": {
40
+ "label": "RPC URL",
41
+ "placeholder": "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY"
42
+ },
43
+ "identityRegistryAddress": {
44
+ "label": "Identity Registry Address",
45
+ "placeholder": "0x..."
46
+ },
47
+ "reputationRegistryAddress": {
48
+ "label": "Reputation Registry Address",
49
+ "placeholder": "0x..."
50
+ },
51
+ "validationRegistryAddress": {
52
+ "label": "Validation Registry Address",
53
+ "placeholder": "0x..."
54
+ },
55
+ "privateKey": {
56
+ "label": "Private Key (optional)",
57
+ "sensitive": true
58
+ },
59
+ "chainId": {
60
+ "label": "Chain ID",
61
+ "placeholder": "1"
62
+ }
63
+ }
64
+ }
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@ch4r10teer41/clawpass",
3
+ "version": "1.0.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/ch4r10t33r/clawpass.git"
7
+ },
8
+ "publishConfig": {
9
+ "registry": "https://registry.npmjs.org/",
10
+ "access": "public"
11
+ },
12
+ "description": "ERC-8004 interface module for AI agent identity, reputation, and validation on blockchain",
13
+ "main": "dist/index.js",
14
+ "module": "dist/index.mjs",
15
+ "types": "dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.mjs",
20
+ "require": "./dist/index.js"
21
+ }
22
+ },
23
+ "openclaw": {
24
+ "extensions": [
25
+ "./openclaw-plugin.ts"
26
+ ]
27
+ },
28
+ "scripts": {
29
+ "build": "tsup src/index.ts --format cjs,esm --dts",
30
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
31
+ "test": "jest",
32
+ "lint": "eslint src --ext .ts",
33
+ "format": "prettier --write \"src/**/*.ts\"",
34
+ "typecheck": "tsc --noEmit"
35
+ },
36
+ "keywords": [
37
+ "erc-8004",
38
+ "ethereum",
39
+ "ai-agents",
40
+ "identity",
41
+ "reputation",
42
+ "validation",
43
+ "blockchain",
44
+ "web3",
45
+ "moltbook",
46
+ "moltx",
47
+ "openclaw",
48
+ "openclaw-plugin"
49
+ ],
50
+ "author": "",
51
+ "license": "Apache-2.0",
52
+ "devDependencies": {
53
+ "@types/jest": "^29.5.12",
54
+ "@types/node": "^20.11.19",
55
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
56
+ "@typescript-eslint/parser": "^7.0.1",
57
+ "eslint": "^8.56.0",
58
+ "jest": "^29.7.0",
59
+ "prettier": "^3.2.5",
60
+ "ts-jest": "^29.1.2",
61
+ "tsup": "^8.0.2",
62
+ "typescript": "^5.3.3"
63
+ },
64
+ "dependencies": {
65
+ "ethers": "^6.11.1",
66
+ "zod": "^3.22.4"
67
+ },
68
+ "peerDependencies": {
69
+ "ethers": "^6.0.0"
70
+ }
71
+ }
package/setup.sh ADDED
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+
3
+ # Clawpass Setup Script
4
+ # This script helps you set up the Clawpass development environment
5
+
6
+ set -e
7
+
8
+ echo "๐Ÿ”ง Setting up Clawpass..."
9
+ echo ""
10
+
11
+ # Check Node.js version
12
+ echo "๐Ÿ“ฆ Checking Node.js version..."
13
+ NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
14
+ if [ "$NODE_VERSION" -lt 18 ]; then
15
+ echo "โŒ Error: Node.js 18 or higher is required"
16
+ echo " Current version: $(node -v)"
17
+ echo " Please upgrade Node.js: https://nodejs.org/"
18
+ exit 1
19
+ fi
20
+ echo "โœ… Node.js version: $(node -v)"
21
+ echo ""
22
+
23
+ # Install dependencies
24
+ echo "๐Ÿ“ฅ Installing dependencies..."
25
+ npm install
26
+ echo "โœ… Dependencies installed"
27
+ echo ""
28
+
29
+ # Build the project
30
+ echo "๐Ÿ”จ Building the project..."
31
+ npm run build
32
+ echo "โœ… Project built successfully"
33
+ echo ""
34
+
35
+ # Run tests
36
+ echo "๐Ÿงช Running tests..."
37
+ npm test
38
+ echo "โœ… Tests passed"
39
+ echo ""
40
+
41
+ # Run linter
42
+ echo "๐Ÿ” Running linter..."
43
+ npm run lint
44
+ echo "โœ… Linting passed"
45
+ echo ""
46
+
47
+ # Run type checker
48
+ echo "๐Ÿ“ Running type checker..."
49
+ npm run typecheck
50
+ echo "โœ… Type checking passed"
51
+ echo ""
52
+
53
+ echo "โœจ Setup complete!"
54
+ echo ""
55
+ echo "Next steps:"
56
+ echo " 1. Copy .env.example to .env and configure your settings"
57
+ echo " 2. Read QUICKSTART.md for usage examples"
58
+ echo " 3. Check out examples/ for integration patterns"
59
+ echo " 4. Run 'npm run dev' to start development mode"
60
+ echo ""
61
+ echo "Happy coding! ๐Ÿš€"