clawpowers 1.1.2 → 1.1.3

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,553 @@
1
+ ---
2
+ name: agent-bounties
3
+ description: Agent-to-agent task bounties with mutual-stake escrow. Post tasks with rewards, accept and stake collateral, execute, verify, and release payment — all on-chain. Integrates MutualStakeEscrow from agentwallet-sdk and verification-before-completion for automated acceptance checks.
4
+ version: 1.0.0
5
+ requires:
6
+ tools: [bash, node, curl]
7
+ env: [AGENT_PRIVATE_KEY, AGENT_WALLET_ADDRESS]
8
+ runtime: true
9
+ metrics:
10
+ tracks: [bounties_posted, bounties_accepted, bounties_completed, bounties_disputed, escrow_value_usd]
11
+ improves: [task_specification_clarity, acceptance_criteria_precision, economic_efficiency]
12
+ ---
13
+
14
+ # Agent Bounties + Escrow
15
+
16
+ ## When to Use
17
+
18
+ Apply this skill when:
19
+
20
+ - **Hiring a specialist agent** — you need a task done that requires a different
21
+ skill set (security audit, code optimization, data enrichment)
22
+ - **Incentivizing quality** — you want the counterparty to have skin in the game
23
+ before accepting work
24
+ - **Coordinating across autonomous agents** — multi-agent pipelines where
25
+ intermediate results must be verified before proceeding
26
+ - **Preventing race conditions** — multiple agents competing for the same task;
27
+ first-accept-and-stake locks the work item
28
+ - **Building a verifiable service record** — bounty completion history feeds
29
+ the ERC-8004 reputation registry
30
+
31
+ **Skip when:**
32
+
33
+ - Task cost < $0.10 (gas overhead exceeds value — use a synchronous call instead)
34
+ - Acceptance criteria cannot be automated (purely subjective creative work)
35
+ - Both sides are the same agent process (no adversarial benefit from escrow)
36
+ - Deadline < 60 seconds from now (on-chain settlement lag)
37
+
38
+ ---
39
+
40
+ ## Core Methodology
41
+
42
+ ### Lifecycle Overview
43
+
44
+ ```
45
+ Agent A (Buyer) On-Chain Escrow Agent B (Seller)
46
+ ───────────────── ──────────────── ─────────────────
47
+ 1. postBounty() ──► StakeVaultFactory.createEscrow()
48
+ (define task, reward, vaultAddress returned
49
+ deadline, criteria)
50
+
51
+ 2. Broadcast bounty JSONL ──► ~/.clawpowers/state/bounties/
52
+
53
+ ◄── 3. discoverBounties()
54
+ (scan JSONL, pick task)
55
+
56
+ ──► 4. acceptBounty()
57
+ StakeVault.fund()
58
+ StakeVault.accept()
59
+ (stakes seller collateral)
60
+
61
+ ──► 5. execute()
62
+ (uses ClawPowers skills,
63
+ submits deliverables)
64
+
65
+ 6. verify() ◄── verification-before-completion ◄── 6. fulfill(proof)
66
+ (automated checks) skill runs acceptance tests
67
+
68
+ ╔══ PASS ══╗ ╔══ FAIL ══╗
69
+ ▼ ▼ ▼ ▼
70
+ 7a. StakeVault Auto-release 7b. Buyer disputes /
71
+ .verify() reward → B StakeVault.challenge()
72
+ stake returned Arbiter resolves
73
+ to A and B or deadline expires
74
+ → reclaimExpired()
75
+ ```
76
+
77
+ ### Phase 1: Post a Bounty
78
+
79
+ Agent A defines the task, reward, deadline, and machine-checkable acceptance criteria.
80
+
81
+ **Step 1a — Write the bounty to disk**
82
+
83
+ ```bash
84
+ BOUNTY_ID="bounty-$(date +%s)-$(head -c 4 /dev/urandom | xxd -p)"
85
+ BOUNTIES_DIR="$HOME/.clawpowers/state/bounties"
86
+ mkdir -p "$BOUNTIES_DIR"
87
+
88
+ cat >> "$BOUNTIES_DIR/open.jsonl" << EOF
89
+ {"id":"$BOUNTY_ID","posted_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)","status":"open","skill_required":"security-audit","title":"Audit authentication module for OWASP Top 10","description":"Run a complete security audit of ./src/auth/ against OWASP Top 10 checklist. Deliverable: JSON report at /tmp/audit-report.json","acceptance_criteria":{"type":"json_schema","path":"/tmp/audit-report.json","required_fields":["issues","severity_counts","owasp_coverage_pct"],"min_coverage":80},"reward_usdc":"0.50","buyer_stake_usdc":"0.25","seller_stake_usdc":"0.25","deadline_hours":2,"chain":"base","vault_address":null}
90
+ EOF
91
+
92
+ echo "Bounty posted: $BOUNTY_ID"
93
+ ```
94
+
95
+ **Step 1b — Deploy the escrow vault (JavaScript)**
96
+
97
+ ```javascript
98
+ import { walletFromEnv } from 'agentwallet-sdk';
99
+ import { MutualStakeEscrow } from 'agentwallet-sdk';
100
+ import { parseUnits } from 'viem';
101
+
102
+ const wallet = walletFromEnv();
103
+ const escrow = new MutualStakeEscrow(wallet);
104
+
105
+ // Post bounty: buyer funds payment + own stake
106
+ const { vaultAddress, txHash } = await escrow.createEscrow({
107
+ seller: '0xSELLER_AGENT_ADDRESS', // Agent B's wallet address
108
+ token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // USDC on base-sepolia
109
+ paymentAmount: parseUnits('0.50', 6), // reward for completing the task
110
+ buyerStake: parseUnits('0.25', 6), // buyer's skin-in-the-game
111
+ sellerStake: parseUnits('0.25', 6), // seller must match this to accept
112
+ deadline: Math.floor(Date.now() / 1000) + 7200, // 2 hours from now
113
+ challengeWindow: 300, // 5-minute dispute window
114
+ verifier: 'optimistic', // use optimistic verification
115
+ });
116
+
117
+ console.log(`Vault deployed: ${vaultAddress} (tx: ${txHash})`);
118
+
119
+ // Update the JSONL record with the vault address
120
+ // (use bash: sed -i or jq to patch the line matching bounty ID)
121
+ ```
122
+
123
+ **Step 1c — Broadcast (optional)**
124
+
125
+ For multi-agent systems, share the open.jsonl via a known shared path or
126
+ publish to the ERC-8004 identity registry's service endpoint.
127
+
128
+ ---
129
+
130
+ ### Phase 2: Accept & Stake
131
+
132
+ Agent B scans for open bounties, selects one, and commits stake to lock the work.
133
+
134
+ **Step 2a — Discover open bounties**
135
+
136
+ ```bash
137
+ # List open bounties sorted by reward descending
138
+ BOUNTIES="$HOME/.clawpowers/state/bounties/open.jsonl"
139
+
140
+ if [[ ! -f "$BOUNTIES" ]]; then
141
+ echo "No bounty file found at $BOUNTIES"
142
+ exit 0
143
+ fi
144
+
145
+ node -e "
146
+ const fs = require('fs');
147
+ const lines = fs.readFileSync('$BOUNTIES', 'utf8').trim().split('\n');
148
+ const open = lines
149
+ .map(l => { try { return JSON.parse(l); } catch { return null; } })
150
+ .filter(b => b && b.status === 'open')
151
+ .sort((a, b) => parseFloat(b.reward_usdc) - parseFloat(a.reward_usdc));
152
+
153
+ console.log(JSON.stringify(open, null, 2));
154
+ "
155
+ ```
156
+
157
+ **Step 2b — Fund and accept the vault (JavaScript)**
158
+
159
+ ```javascript
160
+ import { walletFromEnv } from 'agentwallet-sdk';
161
+ import { MutualStakeEscrow } from 'agentwallet-sdk';
162
+
163
+ // Agent B's wallet (must match the seller address in the vault)
164
+ const wallet = walletFromEnv();
165
+ const escrow = new MutualStakeEscrow(wallet);
166
+
167
+ const vaultAddress = '0xVAULT_ADDRESS_FROM_BOUNTY_JSONL';
168
+
169
+ // Fund — Agent B deposits their collateral stake into the vault
170
+ const { txHash: fundTx } = await escrow.fund(vaultAddress);
171
+ console.log(`Funded vault: ${fundTx}`);
172
+
173
+ // Accept — marks the vault as in-progress, locks both parties in
174
+ const { txHash: acceptTx } = await escrow.accept(vaultAddress);
175
+ console.log(`Accepted bounty: ${acceptTx}`);
176
+ ```
177
+
178
+ **Step 2c — Update bounty status**
179
+
180
+ ```bash
181
+ # Mark as accepted in the JSONL
182
+ python3 - << 'EOF'
183
+ import json, sys, os, time
184
+
185
+ bounty_id = os.environ['BOUNTY_ID']
186
+ path = os.path.expanduser('~/.clawpowers/state/bounties/open.jsonl')
187
+
188
+ lines = open(path).readlines()
189
+ updated = []
190
+ for line in lines:
191
+ b = json.loads(line)
192
+ if b['id'] == bounty_id:
193
+ b['status'] = 'accepted'
194
+ b['accepted_at'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
195
+ updated.append(json.dumps(b))
196
+
197
+ with open(path, 'w') as f:
198
+ f.write('\n'.join(updated) + '\n')
199
+
200
+ print(f'Bounty {bounty_id} marked accepted')
201
+ EOF
202
+ ```
203
+
204
+ ---
205
+
206
+ ### Phase 3: Execute
207
+
208
+ Agent B performs the work using ClawPowers skills.
209
+
210
+ ```bash
211
+ # Example: Agent B running a security audit as part of a bounty
212
+ echo "Executing bounty task: security audit"
213
+
214
+ # Load the bounty spec
215
+ BOUNTY=$(node -e "
216
+ const fs = require('fs');
217
+ const lines = fs.readFileSync(process.env.HOME + '/.clawpowers/state/bounties/open.jsonl', 'utf8').split('\n');
218
+ const b = lines.map(l => { try { return JSON.parse(l); } catch { return null; } })
219
+ .find(b => b && b.id === process.env.BOUNTY_ID);
220
+ console.log(JSON.stringify(b));
221
+ ")
222
+
223
+ # Delegate to the relevant ClawPowers skill
224
+ # (The agent reads the description and acceptance_criteria from the bounty)
225
+ echo "$BOUNTY" | node -e "
226
+ const b = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
227
+ console.log('Task:', b.description);
228
+ console.log('Criteria:', JSON.stringify(b.acceptance_criteria, null, 2));
229
+ "
230
+
231
+ # Run the actual work (example: security audit)
232
+ # → The agent follows skills/security-audit/SKILL.md using the task description
233
+ ```
234
+
235
+ ---
236
+
237
+ ### Phase 4: Verify with verification-before-completion
238
+
239
+ Before calling `fulfill()` on the vault, Agent B runs the acceptance criteria check.
240
+
241
+ ```bash
242
+ # Step 1: Check output against acceptance criteria
243
+ REPORT_PATH="/tmp/audit-report.json"
244
+ CRITERIA_TYPE="json_schema"
245
+
246
+ case "$CRITERIA_TYPE" in
247
+ json_schema)
248
+ node -e "
249
+ const fs = require('fs');
250
+ const criteria = JSON.parse(process.env.ACCEPTANCE_CRITERIA);
251
+ const report = JSON.parse(fs.readFileSync('$REPORT_PATH', 'utf8'));
252
+
253
+ // Check required fields
254
+ const missing = criteria.required_fields.filter(f => !(f in report));
255
+ if (missing.length > 0) {
256
+ console.error('FAIL: missing fields:', missing.join(', '));
257
+ process.exit(1);
258
+ }
259
+
260
+ // Check minimum coverage
261
+ if (report.owasp_coverage_pct < criteria.min_coverage) {
262
+ console.error('FAIL: coverage', report.owasp_coverage_pct, '< required', criteria.min_coverage);
263
+ process.exit(1);
264
+ }
265
+
266
+ console.log('PASS: all acceptance criteria met');
267
+ "
268
+ ;;
269
+ test_suite)
270
+ # Delegate to verification-before-completion skill
271
+ bash runtime/init.sh verify --criteria "$ACCEPTANCE_CRITERIA"
272
+ ;;
273
+ esac
274
+ ```
275
+
276
+ **Step 4b — Fulfill on-chain (JavaScript)**
277
+
278
+ ```javascript
279
+ import { walletFromEnv } from 'agentwallet-sdk';
280
+ import { MutualStakeEscrow } from 'agentwallet-sdk';
281
+ import { encodeHashVerifierData } from 'agentwallet-sdk';
282
+ import { keccak256, toHex } from 'viem';
283
+ import { readFileSync } from 'fs';
284
+
285
+ const wallet = walletFromEnv();
286
+ const escrow = new MutualStakeEscrow(wallet);
287
+
288
+ const vaultAddress = '0xVAULT_ADDRESS';
289
+ const deliverable = readFileSync('/tmp/audit-report.json', 'utf8');
290
+ const deliverableHash = keccak256(toHex(deliverable));
291
+
292
+ // Encode proof of work (hash of deliverable + metadata)
293
+ const proof = encodeHashVerifierData(deliverableHash);
294
+
295
+ const { txHash } = await escrow.fulfill(vaultAddress, proof);
296
+ console.log(`Fulfilled bounty: ${txHash}`);
297
+ ```
298
+
299
+ ---
300
+
301
+ ### Phase 5: Release
302
+
303
+ On successful verification, the vault auto-releases funds.
304
+
305
+ ```javascript
306
+ import { walletFromEnv } from 'agentwallet-sdk';
307
+ import { MutualStakeEscrow } from 'agentwallet-sdk';
308
+
309
+ const wallet = walletFromEnv(); // Agent A (buyer) calls verify
310
+ const escrow = new MutualStakeEscrow(wallet);
311
+
312
+ const vaultAddress = '0xVAULT_ADDRESS';
313
+
314
+ // For optimistic verification: buyer calls verify() after challenge window expires
315
+ const { txHash } = await escrow.verify(vaultAddress);
316
+ console.log(`Funds released: ${txHash}`);
317
+
318
+ // Result:
319
+ // → reward_usdc flows to Agent B
320
+ // → buyerStake returned to Agent A
321
+ // → sellerStake returned to Agent B
322
+ ```
323
+
324
+ ---
325
+
326
+ ### Phase 6: Dispute
327
+
328
+ If verification fails or the deadline expires without fulfillment:
329
+
330
+ ```javascript
331
+ import { walletFromEnv } from 'agentwallet-sdk';
332
+ import { MutualStakeEscrow } from 'agentwallet-sdk';
333
+ import { toHex } from 'viem';
334
+
335
+ const wallet = walletFromEnv(); // Agent A (buyer) raises dispute
336
+ const escrow = new MutualStakeEscrow(wallet);
337
+
338
+ const vaultAddress = '0xVAULT_ADDRESS';
339
+ const evidence = toHex('criteria_not_met:owasp_coverage_below_80pct');
340
+
341
+ // Challenge — triggers the dispute window
342
+ const { txHash: challengeTx } = await escrow.challenge(vaultAddress, evidence);
343
+ console.log(`Dispute opened: ${challengeTx}`);
344
+
345
+ // After arbiter resolution (or deadline expiry):
346
+ // → If buyer wins: reward + buyer stake returned to A; seller stake slashed
347
+ // → If seller wins: reward + seller stake released to B; buyer stake retained
348
+
349
+ // Reclaim expired bounty (no one accepted before deadline):
350
+ const { txHash: expiredTx } = await escrow.reclaimExpired(vaultAddress);
351
+ console.log(`Reclaimed expired bounty: ${expiredTx}`);
352
+ ```
353
+
354
+ ---
355
+
356
+ ## Bounty JSONL Format
357
+
358
+ All bounties are stored as JSONL (one JSON object per line) at:
359
+
360
+ ```
361
+ ~/.clawpowers/state/bounties/open.jsonl
362
+ ~/.clawpowers/state/bounties/completed.jsonl
363
+ ~/.clawpowers/state/bounties/disputed.jsonl
364
+ ```
365
+
366
+ **Schema:**
367
+
368
+ ```typescript
369
+ interface BountyRecord {
370
+ // Identity
371
+ id: string; // "bounty-{timestamp}-{randomHex4}"
372
+ posted_at: string; // ISO 8601 UTC
373
+ status: "open" | "accepted" | "in_progress" | "completed" | "disputed" | "expired";
374
+
375
+ // Task definition
376
+ skill_required: string; // ClawPowers skill name (e.g. "security-audit")
377
+ title: string; // One-line summary
378
+ description: string; // Full task description (what to do, what to produce)
379
+
380
+ // Machine-checkable acceptance criteria
381
+ acceptance_criteria: {
382
+ type: "json_schema" | "test_suite" | "hash_match" | "optimistic";
383
+ path?: string; // Output file path (for json_schema / hash_match)
384
+ required_fields?: string[]; // For json_schema
385
+ min_coverage?: number; // 0-100, for json_schema coverage checks
386
+ test_command?: string; // For test_suite — shell command, exit 0 = pass
387
+ expected_hash?: string; // For hash_match — keccak256 of expected output
388
+ };
389
+
390
+ // Economics
391
+ reward_usdc: string; // Decimal USDC (e.g. "0.50")
392
+ buyer_stake_usdc: string; // Buyer's collateral
393
+ seller_stake_usdc: string; // Required seller collateral to accept
394
+
395
+ // Timing
396
+ deadline_hours: number; // Hours from posted_at
397
+ deadline_ts?: number; // Unix timestamp (computed)
398
+
399
+ // On-chain
400
+ chain: string; // "base" | "base-sepolia" | etc.
401
+ vault_address: string | null; // Set after escrow deployed
402
+
403
+ // Participants
404
+ buyer_address?: string;
405
+ seller_address?: string; // Set after acceptance
406
+
407
+ // Lifecycle timestamps
408
+ accepted_at?: string;
409
+ completed_at?: string;
410
+ disputed_at?: string;
411
+ resolved_at?: string;
412
+
413
+ // Audit
414
+ fulfill_tx?: string;
415
+ verify_tx?: string;
416
+ dispute_tx?: string;
417
+ }
418
+ ```
419
+
420
+ **Example record:**
421
+
422
+ ```json
423
+ {"id":"bounty-1742680800-a3f1","posted_at":"2026-03-22T22:00:00Z","status":"completed","skill_required":"security-audit","title":"Audit auth module for OWASP Top 10","description":"Run complete security audit of ./src/auth/ against OWASP Top 10. Deliverable: /tmp/audit-report.json","acceptance_criteria":{"type":"json_schema","path":"/tmp/audit-report.json","required_fields":["issues","severity_counts","owasp_coverage_pct"],"min_coverage":80},"reward_usdc":"0.50","buyer_stake_usdc":"0.25","seller_stake_usdc":"0.25","deadline_hours":2,"chain":"base-sepolia","vault_address":"0xABCD1234...","buyer_address":"0xBUYER...","seller_address":"0xSELLER...","accepted_at":"2026-03-22T22:05:00Z","completed_at":"2026-03-22T22:47:00Z","fulfill_tx":"0xFULFILL...","verify_tx":"0xVERIFY..."}
424
+ ```
425
+
426
+ ---
427
+
428
+ ## ClawPowers Enhancement
429
+
430
+ When `~/.clawpowers/` runtime is initialized, bounties gain persistent tracking
431
+ and cross-session metrics:
432
+
433
+ ### Persistent Bounty Tracking
434
+
435
+ ```bash
436
+ # Record that a bounty was posted
437
+ bash runtime/persistence/store.sh set \
438
+ "bounty:$BOUNTY_ID:status" "open"
439
+
440
+ bash runtime/persistence/store.sh set \
441
+ "bounty:$BOUNTY_ID:vault" "$VAULT_ADDRESS"
442
+
443
+ # Query all open bounties
444
+ bash runtime/persistence/store.sh list "bounty:" | grep ":status" | \
445
+ while read key; do
446
+ val=$(bash runtime/persistence/store.sh get "$key")
447
+ [[ "$val" == "open" ]] && echo "${key%%:status}"
448
+ done
449
+ ```
450
+
451
+ ### Bounty Metrics
452
+
453
+ ```bash
454
+ # Record completion
455
+ bash runtime/metrics/collector.sh record \
456
+ --skill agent-bounties \
457
+ --outcome success \
458
+ --notes "bounty:$BOUNTY_ID reward:${REWARD_USDC} USDC completed in ${MINUTES}min"
459
+
460
+ # Aggregate ROI across all bounties
461
+ bash runtime/metrics/collector.sh report --skill agent-bounties
462
+ # Output:
463
+ # agent-bounties metrics:
464
+ # - bounties_completed: 14
465
+ # - bounties_disputed: 2 (12.5% dispute rate)
466
+ # - total_reward_earned: $4.20 USDC
467
+ # - avg_completion_time: 47 minutes
468
+ # - acceptance_rate: 94% (criteria well-defined)
469
+ ```
470
+
471
+ ### Integration with economic-code-optimization
472
+
473
+ ```markdown
474
+ When the `economic-code-optimization` skill runs and determines premium compute
475
+ would improve an outcome, it can automatically post a bounty for a specialist agent:
476
+
477
+ 1. economic-code-optimization detects: "This security scan needs deeper analysis"
478
+ 2. It calls: postBounty(skill="security-audit", reward="$0.25", criteria=automated)
479
+ 3. A security-specialist agent picks up the bounty
480
+ 4. economic-code-optimization receives the verified report
481
+ 5. The original task proceeds with the improved analysis
482
+
483
+ This creates a recursive market: agents hire agents, who hire agents,
484
+ until the task is optimally completed.
485
+ ```
486
+
487
+ ---
488
+
489
+ ## Anti-Patterns
490
+
491
+ | Anti-Pattern | Why It Fails | Correct Approach |
492
+ |---|---|---|
493
+ | **Reward < $0.10** | Gas cost ($0.02-0.05) erodes value; attracts no quality agents | Minimum $0.10 per bounty; batch small tasks |
494
+ | **Vague acceptance criteria** | Any output "passes" — seller delivers junk, buyer disputes | Write machine-checkable criteria FIRST; if you can't automate the check, redesign the task |
495
+ | **No deadline** | Vault locked indefinitely; buyer's stake frozen forever | Always set `deadline_hours`; 2-24h for most tasks |
496
+ | **Missing seller collateral** | Seller has no stake → abandons task after accepting | Set `seller_stake_usdc` ≥ 50% of reward |
497
+ | **Criteria requiring subjective judgment** | Optimistic verifier can't evaluate "is this beautiful code?" | Use test suites, hash checks, or schema validation instead |
498
+ | **Posting bounty before buyer stakes** | Vault not funded → no locked payment for seller to trust | Always deploy vault + fund it BEFORE broadcasting |
499
+ | **Challenge window = 0** | No time to dispute fraudulent fulfillment | Minimum 300s (5 min) challenge window |
500
+ | **Unclear deliverable location** | Seller doesn't know where to write the output | Specify exact file paths and formats in the description |
501
+ | **Too many open bounties** | Diminishes reputation if most expire | Post only bounties you're prepared to fund immediately |
502
+
503
+ ---
504
+
505
+ ## Integration with verification-before-completion
506
+
507
+ The `verification-before-completion` skill handles the automated acceptance check:
508
+
509
+ ```bash
510
+ # Before calling fulfill(), run verification
511
+ CRITERIA=$(node -e "
512
+ const b = JSON.parse(process.env.BOUNTY_JSON);
513
+ console.log(JSON.stringify(b.acceptance_criteria));
514
+ ")
515
+
516
+ # Delegate to verification skill
517
+ bash skills/verification-before-completion/verify.sh \
518
+ --criteria "$CRITERIA" \
519
+ --deliverable "$DELIVERABLE_PATH"
520
+
521
+ VERIFY_EXIT=$?
522
+
523
+ if [[ $VERIFY_EXIT -eq 0 ]]; then
524
+ echo "Verification passed — calling fulfill()"
525
+ # → proceed with fulfill() and collect reward
526
+ else
527
+ echo "Verification failed — do NOT call fulfill()"
528
+ echo "Fix the output and re-run verification"
529
+ # → fix work, retry, or release vault back to buyer
530
+ fi
531
+ ```
532
+
533
+ ---
534
+
535
+ ## Quick Reference
536
+
537
+ ```bash
538
+ # Initialize bounty state directory
539
+ mkdir -p ~/.clawpowers/state/bounties
540
+
541
+ # List open bounties
542
+ cat ~/.clawpowers/state/bounties/open.jsonl | \
543
+ node -e "
544
+ const lines = require('fs').readFileSync('/dev/stdin','utf8').split('\n');
545
+ lines.filter(Boolean).map(l => JSON.parse(l))
546
+ .filter(b => b.status === 'open')
547
+ .forEach(b => console.log(b.reward_usdc + ' USDC | ' + b.skill_required + ' | ' + b.title));
548
+ "
549
+
550
+ # Count completed vs disputed
551
+ grep '"status":"completed"' ~/.clawpowers/state/bounties/open.jsonl | wc -l
552
+ grep '"status":"disputed"' ~/.clawpowers/state/bounties/open.jsonl | wc -l
553
+ ```
@@ -266,6 +266,147 @@ print(json.dumps(prospects, indent=2))
266
266
  "
267
267
  ```
268
268
 
269
+ ### Premium Enrichment (x402-Aware)
270
+
271
+ By default, the prospecting skill uses free public sources (GitHub, LinkedIn
272
+ search, Hunter.io free tier). When incomplete contact data is holding back
273
+ your campaign, x402-aware paid enrichment APIs can fill the gaps.
274
+
275
+ #### Three States
276
+
277
+ | State | Config | Behaviour |
278
+ |-------|--------|-----------|
279
+ | **disabled** | `payments.enabled: false` | Skip all paid enrichment, log a note, continue with free data |
280
+ | **dry-run** | `payments.mode: "dry_run"` | Log what _would_ be paid, show cost estimate, do NOT execute payment |
281
+ | **live** | `payments.mode: "live"` | Execute payment if within policy limits; queue for approval if over |
282
+
283
+ #### How It Works
284
+
285
+ After Phase 4 (Contact Enrichment), the skill checks how many contacts are
286
+ still missing key data (email, phone, LinkedIn URL) and offers to enrich them
287
+ via premium APIs that accept x402 micropayments.
288
+
289
+ ```bash
290
+ # After free enrichment — assess gaps
291
+ TOTAL_LEADS=15
292
+ INCOMPLETE=8 # missing email or key contact field
293
+
294
+ echo "Found $TOTAL_LEADS leads. $INCOMPLETE have incomplete data."
295
+ echo "Premium enrichment available for \$0.02/lead."
296
+ echo "Estimated cost: \$$(echo "$INCOMPLETE * 0.02" | bc) USDC"
297
+ ```
298
+
299
+ #### Payment Gate Flow
300
+
301
+ ```javascript
302
+ // runtime/payments/pipeline.js — called automatically when x402 enrichment is triggered
303
+ const { evaluatePayment } = require('../../runtime/payments/pipeline');
304
+
305
+ const result = await evaluatePayment({
306
+ skill: 'prospecting',
307
+ reason: 'premium contact enrichment',
308
+ amount_usd: incompleteCount * 0.02,
309
+ asset: 'USDC',
310
+ chain: 'base',
311
+ recipient: '0xENRICHMENT_API_RECIPIENT',
312
+ url: 'https://api.contactdb.example.com/enrich',
313
+ });
314
+
315
+ switch (result.action) {
316
+ case 'disabled':
317
+ console.log('[prospecting] Premium enrichment disabled — using free data only.');
318
+ break;
319
+
320
+ case 'dry_run':
321
+ console.log(
322
+ `[prospecting] DRY-RUN: would pay $${(incompleteCount * 0.02).toFixed(2)} USDC ` +
323
+ `to enrich ${incompleteCount} contacts via ${result.reason}. No payment made.`
324
+ );
325
+ break;
326
+
327
+ case 'queued':
328
+ console.log(
329
+ `[prospecting] Payment queued for owner approval: ` +
330
+ `$${(incompleteCount * 0.02).toFixed(2)} USDC for ${incompleteCount} enrichments.`
331
+ );
332
+ // → Enrichment pauses until owner approves pending tx
333
+ break;
334
+
335
+ case 'approved':
336
+ console.log(`[prospecting] Executing premium enrichment for ${incompleteCount} contacts...`);
337
+ await runPremiumEnrichment(incompleteContacts);
338
+ break;
339
+ }
340
+ ```
341
+
342
+ #### Enabling Premium Enrichment
343
+
344
+ ```bash
345
+ # ~/.clawpowers/config.json
346
+ {
347
+ "payments": {
348
+ "enabled": true,
349
+ "mode": "live",
350
+ "per_tx_limit": 0.50,
351
+ "daily_limit": 5.00,
352
+ "require_approval_above": 1.00
353
+ }
354
+ }
355
+ ```
356
+
357
+ ```bash
358
+ # .env additions for prospecting
359
+ AGENT_PRIVATE_KEY=0x...
360
+ AGENT_WALLET_ADDRESS=0x...
361
+ CHAIN_NAME=base
362
+ SPEND_LIMIT_PER_TX=0.50
363
+ SPEND_LIMIT_DAILY=5.00
364
+ ```
365
+
366
+ #### Supported Premium Enrichment Sources
367
+
368
+ | Source | Cost/lead | Data provided |
369
+ |--------|-----------|--------------|
370
+ | Apollo.io (paid tier) | ~$0.02 | Verified email, phone, LinkedIn |
371
+ | Clearbit Enrichment | ~$0.03 | Company firmographics, tech stack |
372
+ | Hunter.io Pro | ~$0.01 | Email verification, role signals |
373
+ | Proxycurl | ~$0.015 | LinkedIn profile scrape |
374
+ | Coresignal | ~$0.02 | Company employee headcount, tech |
375
+
376
+ All premium API calls go through the x402 client wrapper:
377
+
378
+ ```javascript
379
+ import { x402FromEnv } from 'agentwallet-sdk';
380
+
381
+ const wallet = walletFromEnv();
382
+ const client = x402FromEnv(wallet);
383
+
384
+ // Automatically pays any HTTP 402 responses from enrichment APIs
385
+ const response = await client.fetch(
386
+ `https://api.apollo.io/v1/people/enrich?email=${email}`,
387
+ { headers: { 'x-api-key': process.env.APOLLO_API_KEY } }
388
+ );
389
+ const enriched = await response.json();
390
+ ```
391
+
392
+ #### Dry-Run Output Example
393
+
394
+ When `payments.mode` is `"dry_run"`, the skill outputs a cost preview before
395
+ any action is taken:
396
+
397
+ ```
398
+ [prospecting] Enrichment summary:
399
+ Free sources: 7 / 15 contacts fully enriched
400
+ Incomplete: 8 / 15 contacts missing email or title
401
+
402
+ [prospecting] DRY-RUN: Premium enrichment would cost:
403
+ 8 contacts × $0.02/lead = $0.16 USDC
404
+ API: Apollo.io (paid), chain: base
405
+
406
+ To execute: set payments.mode = "live" in ~/.clawpowers/config.json
407
+ To approve this batch: clawpowers payments approve --skill prospecting
408
+ ```
409
+
269
410
  ## ClawPowers Enhancement
270
411
 
271
412
  When `~/.clawpowers/` runtime is initialized: