ape-claw 0.1.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 (114) hide show
  1. package/.cursor/skills/ape-claw/SKILL.md +322 -0
  2. package/LICENSE +21 -0
  3. package/README.md +826 -0
  4. package/allowlists/opensea-slug-overrides.json +13 -0
  5. package/allowlists/recommended.apechain.json +322 -0
  6. package/config/clawbots.example.json +3 -0
  7. package/config/policy.example.json +27 -0
  8. package/data/starter-pack-bundle.json +1 -0
  9. package/data/starter-pack.json +495 -0
  10. package/docs/ACP_BOUNTIES.md +108 -0
  11. package/docs/APECLAW_V2_ALPHA.md +206 -0
  12. package/docs/AUTONOMY_AND_SUBSTRATE.md +69 -0
  13. package/docs/CLAWBOTS_AND_INVITES.md +102 -0
  14. package/docs/CLI_GUIDE.md +124 -0
  15. package/docs/CONTRIBUTING.md +130 -0
  16. package/docs/DASHBOARD_GUIDE.md +108 -0
  17. package/docs/GLOBAL_BACKEND.md +145 -0
  18. package/docs/ONCHAIN_V2_GUIDE.md +140 -0
  19. package/docs/PRODUCT_OVERVIEW.md +127 -0
  20. package/docs/README.md +40 -0
  21. package/docs/SKILLCARDS_AND_IMPORTER.md +147 -0
  22. package/docs/STARTER_PACK.md +297 -0
  23. package/docs/SUPPORTED_NETWORKS.md +58 -0
  24. package/docs/TELEMETRY_AND_EVENTS.md +103 -0
  25. package/docs/THE_POD_RUNNER.md +198 -0
  26. package/docs/V1_WORKFLOWS.md +108 -0
  27. package/docs/V2_ONCHAIN_SKILLS.md +157 -0
  28. package/docs/WEB4_PLAN_STATUS.md +95 -0
  29. package/docs/WEB4_SWARM_MODEL.md +104 -0
  30. package/docs/archive/AUTONOMY_AND_SUBSTRATE.md +66 -0
  31. package/docs/archive/WEB4_PLAN_STATUS.md +93 -0
  32. package/docs/archive/WEB4_SWARM_MODEL.md +98 -0
  33. package/docs/developer/01-architecture.md +345 -0
  34. package/docs/developer/02-contracts.md +1034 -0
  35. package/docs/developer/03-writing-modules.md +513 -0
  36. package/docs/developer/04-skillcard-spec.md +336 -0
  37. package/docs/developer/05-backend-api.md +1079 -0
  38. package/docs/developer/06-telemetry.md +798 -0
  39. package/docs/developer/07-testing.md +546 -0
  40. package/docs/developer/08-contributing.md +211 -0
  41. package/docs/operator/01-quickstart.md +49 -0
  42. package/docs/operator/02-dashboard.md +174 -0
  43. package/docs/operator/03-cli-reference.md +818 -0
  44. package/docs/operator/04-skills-library.md +169 -0
  45. package/docs/operator/05-pod-operations.md +314 -0
  46. package/docs/operator/06-deployment.md +299 -0
  47. package/docs/operator/07-safety-and-policy.md +311 -0
  48. package/docs/operator/08-troubleshooting.md +457 -0
  49. package/docs/operator/09-env-reference.md +238 -0
  50. package/docs/social/STARTER_PACK_THREAD.md +209 -0
  51. package/package.json +77 -0
  52. package/skillcards/import-sources.json +93 -0
  53. package/skillcards/seed/acp-bounty-poll.v1.json +38 -0
  54. package/skillcards/seed/acp-bounty-post.v1.json +55 -0
  55. package/skillcards/seed/acp-browse.v1.json +41 -0
  56. package/skillcards/seed/acp-fulfill-and-route.v1.json +56 -0
  57. package/skillcards/seed/apeclaw-bridge-relay.v1.json +46 -0
  58. package/skillcards/seed/apeclaw-nft-autobuy.v1.json +60 -0
  59. package/skillcards/seed/apeclaw-receipt-recorder.v1.json +64 -0
  60. package/skillcards/seed/humanizer.v1.json +74 -0
  61. package/skillcards/seed/otherside-navigator.v1.json +116 -0
  62. package/skillcards/seed/stonkbrokers-launcher.v1.json +280 -0
  63. package/skillcards/seed/walkie-p2p.v1.json +66 -0
  64. package/src/cli/index.mjs +8 -0
  65. package/src/cli.mjs +1929 -0
  66. package/src/lib/bridge-relay.mjs +294 -0
  67. package/src/lib/clawbots.mjs +94 -0
  68. package/src/lib/io.mjs +36 -0
  69. package/src/lib/market.mjs +233 -0
  70. package/src/lib/nft-opensea.mjs +159 -0
  71. package/src/lib/paths.mjs +17 -0
  72. package/src/lib/pod-init.mjs +40 -0
  73. package/src/lib/policy.mjs +112 -0
  74. package/src/lib/rpc.mjs +49 -0
  75. package/src/lib/telemetry.mjs +92 -0
  76. package/src/lib/v2-onchain-abi.mjs +294 -0
  77. package/src/lib/v2-skillcard.mjs +27 -0
  78. package/src/server/index.mjs +169 -0
  79. package/src/server/logger.mjs +21 -0
  80. package/src/server/middleware/auth.mjs +90 -0
  81. package/src/server/middleware/body-limit.mjs +35 -0
  82. package/src/server/middleware/cors.mjs +33 -0
  83. package/src/server/middleware/rate-limit.mjs +44 -0
  84. package/src/server/routes/chat.mjs +178 -0
  85. package/src/server/routes/clawbots.mjs +182 -0
  86. package/src/server/routes/events.mjs +95 -0
  87. package/src/server/routes/health.mjs +72 -0
  88. package/src/server/routes/pod.mjs +64 -0
  89. package/src/server/routes/quotes.mjs +161 -0
  90. package/src/server/routes/skills.mjs +239 -0
  91. package/src/server/routes/static.mjs +161 -0
  92. package/src/server/routes/v2.mjs +48 -0
  93. package/src/server/sse.mjs +73 -0
  94. package/src/server/storage/file-backend.mjs +295 -0
  95. package/src/server/storage/index.mjs +37 -0
  96. package/src/server/storage/sqlite-backend.mjs +380 -0
  97. package/src/telemetry-server.mjs +1604 -0
  98. package/ui/css/dashboard.css +792 -0
  99. package/ui/css/skills.css +689 -0
  100. package/ui/docs.html +840 -0
  101. package/ui/favicon-180.png +0 -0
  102. package/ui/favicon-192.png +0 -0
  103. package/ui/favicon-32.png +0 -0
  104. package/ui/favicon-lobster.png +0 -0
  105. package/ui/favicon.svg +10 -0
  106. package/ui/index.html +2957 -0
  107. package/ui/js/dashboard.js +1766 -0
  108. package/ui/js/skills.js +1621 -0
  109. package/ui/pod.html +909 -0
  110. package/ui/shared/motion.css +286 -0
  111. package/ui/shared/motion.js +170 -0
  112. package/ui/shared/sidebar-nav.css +379 -0
  113. package/ui/shared/sidebar-nav.js +137 -0
  114. package/ui/skills.html +2879 -0
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "ApeClaw NFT Autobuy",
3
+ "slug": "apeclaw-nft-autobuy",
4
+ "description": "Plan and (optionally) execute multi-collection NFT buys on ApeChain within strict policy gates. Designed for agents that collect NFTs while you sleep.",
5
+ "version": "1.0.0",
6
+ "inputs_schema": {
7
+ "type": "object",
8
+ "required": ["count", "minPrice", "maxPrice", "currency", "execute", "autonomous"],
9
+ "properties": {
10
+ "count": { "type": "integer", "minimum": 1, "maximum": 25 },
11
+ "scan": { "type": "integer", "minimum": 1, "maximum": 500 },
12
+ "minPrice": { "type": "number", "minimum": 0 },
13
+ "maxPrice": { "type": "number", "exclusiveMinimum": 0 },
14
+ "budget": { "type": ["number", "null"], "minimum": 0 },
15
+ "currency": { "type": "string", "enum": ["APE"] },
16
+ "execute": { "type": "boolean" },
17
+ "autonomous": { "type": "boolean" }
18
+ }
19
+ },
20
+ "outputs_schema": {
21
+ "type": "object",
22
+ "required": ["ok", "planned", "selectedCount"],
23
+ "properties": {
24
+ "ok": { "type": "boolean" },
25
+ "selectedCount": { "type": "integer" },
26
+ "planned": {
27
+ "type": "array",
28
+ "items": {
29
+ "type": "object",
30
+ "required": ["quoteId", "collection", "tokenId", "priceApe"],
31
+ "properties": {
32
+ "quoteId": { "type": "string" },
33
+ "collection": { "type": "string" },
34
+ "tokenId": { "type": "string" },
35
+ "priceApe": { "type": "number" }
36
+ }
37
+ }
38
+ }
39
+ }
40
+ },
41
+ "bindings": [
42
+ {
43
+ "type": "cli",
44
+ "command": "ape-claw nft autobuy --count <count> --minPrice <minPrice> --maxPrice <maxPrice> [--scan <scan>] [--budget <budget>] [--execute] [--autonomous] --json"
45
+ }
46
+ ],
47
+ "constraints": {
48
+ "notes": [
49
+ "ApeClaw enforces allowlists, currency allowlist, spend caps, confirm phrases, simulation requirements, and replay protection at the CLI layer."
50
+ ]
51
+ },
52
+ "required_permissions": ["onchain_execute", "market_data"],
53
+ "examples": [],
54
+ "eval_packs": [],
55
+ "provenance": {
56
+ "publisher": "apeclaw",
57
+ "signed": false
58
+ }
59
+ }
60
+
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "ApeClaw Receipt Recorder",
3
+ "slug": "apeclaw-receipt-recorder",
4
+ "description": "Record an append-only onchain receipt (ReceiptRegistry) for an action traceId. Designed to anchor auditability onchain without trusting a backend.",
5
+ "version": "1.0.0",
6
+ "inputs_schema": {
7
+ "type": "object",
8
+ "required": ["rpc", "privateKey", "receipts", "traceId"],
9
+ "properties": {
10
+ "rpc": { "type": "string", "description": "RPC URL for the target chain (ApeChain or local dev)." },
11
+ "privateKey": { "type": "string", "description": "EVM private key used to sign the receipt transaction." },
12
+ "receipts": { "type": "string", "description": "ReceiptRegistry contract address." },
13
+ "traceId": { "type": "string", "description": "Unique traceId for this action (hashed onchain)." },
14
+ "subject": { "type": "string", "default": "agent:unknown", "description": "Subject identifier (hashed onchain), e.g. agentId or account." },
15
+ "payload": { "type": ["object", "null"], "default": {}, "description": "Receipt payload (content-addressed via stable JSON hash)." },
16
+ "uri": { "type": "string", "default": "", "description": "Optional offchain URI (IPFS/Arweave/http/file) for additional evidence." }
17
+ }
18
+ },
19
+ "outputs_schema": {
20
+ "type": "object",
21
+ "required": ["ok", "txHash", "traceIdHash", "contentHash", "subjectHash"],
22
+ "properties": {
23
+ "ok": { "type": "boolean" },
24
+ "txHash": { "type": "string" },
25
+ "traceIdHash": { "type": "string" },
26
+ "contentHash": { "type": "string" },
27
+ "subjectHash": { "type": "string" },
28
+ "uri": { "type": "string" }
29
+ }
30
+ },
31
+ "bindings": [
32
+ {
33
+ "type": "cli",
34
+ "command": "ape-claw v2 receipt record --rpc <rpc> --privateKey <privateKey> --receipts <receipts> --traceId <traceId> [--subject <subject>] [--payload '<payloadJson>'] [--uri <uri>] --json"
35
+ }
36
+ ],
37
+ "constraints": {
38
+ "riskTier": 2,
39
+ "notes": [
40
+ "This skill writes an immutable receipt onchain. It should be used for audit anchors, not for storing secrets.",
41
+ "Prefer putting large evidence blobs in offchain storage and referencing via --uri."
42
+ ]
43
+ },
44
+ "required_permissions": ["onchain_execute"],
45
+ "examples": [
46
+ {
47
+ "title": "Record a receipt (local dev)",
48
+ "value": {
49
+ "rpc": "http://127.0.0.1:8545",
50
+ "privateKey": "0x...",
51
+ "receipts": "0xReceiptRegistry...",
52
+ "traceId": "nft_buy_1700000000_abc123",
53
+ "subject": "agent:the-clawllector",
54
+ "payload": { "kind": "nft.buy.confirmed", "collection": "gs-on-ape", "priceApe": 75 }
55
+ }
56
+ }
57
+ ],
58
+ "eval_packs": [],
59
+ "provenance": {
60
+ "publisher": "apeclaw",
61
+ "signed": false
62
+ }
63
+ }
64
+
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "Humanizer — Remove AI Writing Patterns",
3
+ "slug": "humanizer",
4
+ "description": "Remove signs of AI-generated writing from text. Detects and fixes 24 patterns including inflated symbolism, promotional language, em dash overuse, AI vocabulary, rule of three, and sycophantic tone. Based on Wikipedia's AI writing guide.",
5
+ "version": "2.1.1",
6
+ "inputs_schema": {
7
+ "type": "object",
8
+ "properties": {
9
+ "text": { "type": "string", "description": "The text to humanize." },
10
+ "tone": {
11
+ "type": "string",
12
+ "enum": ["formal", "casual", "technical", "conversational"],
13
+ "description": "Target writing tone."
14
+ }
15
+ }
16
+ },
17
+ "outputs_schema": {
18
+ "type": "object",
19
+ "properties": {
20
+ "humanized_text": { "type": "string", "description": "The rewritten text with AI patterns removed." },
21
+ "patterns_found": { "type": "array", "description": "List of AI patterns detected and fixed." }
22
+ }
23
+ },
24
+ "bindings": [
25
+ {
26
+ "type": "external",
27
+ "url": "https://github.com/blader/humanizer"
28
+ },
29
+ {
30
+ "type": "external",
31
+ "url": "https://raw.githubusercontent.com/blader/humanizer/main/SKILL.md"
32
+ },
33
+ {
34
+ "type": "openclaw_skill_md",
35
+ "source": "github",
36
+ "path": "SKILL.md",
37
+ "repo": {
38
+ "owner": "blader",
39
+ "repo": "humanizer",
40
+ "ref": "main",
41
+ "path": "SKILL.md"
42
+ }
43
+ }
44
+ ],
45
+ "constraints": {
46
+ "riskTier": 1,
47
+ "safety": [
48
+ "Read-only analysis and rewriting — no side effects",
49
+ "Preserves meaning while removing AI patterns",
50
+ "Does not add opinions the author didn't intend"
51
+ ]
52
+ },
53
+ "required_permissions": ["file_read", "file_write"],
54
+ "examples": [
55
+ {
56
+ "title": "Humanize promotional text",
57
+ "input": { "text": "This groundbreaking initiative serves as a testament to our commitment to fostering innovation in the evolving landscape." },
58
+ "output": { "humanized_text": "We started this project because the old system wasn't working. Here's what we changed and why." }
59
+ },
60
+ {
61
+ "title": "Fix AI vocabulary",
62
+ "input": { "text": "Furthermore, this multifaceted approach leverages cutting-edge technology to deliver comprehensive solutions." },
63
+ "output": { "humanized_text": "The approach uses three specific techniques: [concrete details]." }
64
+ }
65
+ ],
66
+ "eval_packs": [],
67
+ "provenance": {
68
+ "publisher": "apeclaw",
69
+ "signed": false,
70
+ "source": "github",
71
+ "sourceUrl": "https://github.com/blader/humanizer",
72
+ "license": "MIT"
73
+ }
74
+ }
@@ -0,0 +1,116 @@
1
+ {
2
+ "name": "Otherside Navigator (THE POD Loop)",
3
+ "slug": "otherside-navigator",
4
+ "description": "A strict opt-in autonomous loop for Clawbots to enter and navigate Otherside (otherside.xyz) using a rolling screenshot buffer + VLM vision (Claude CLI or stub), structured state parsing, action planning, and an execution layer. Includes both stub execution (default) and an optional macOS CGEvent executor for real movement when explicitly enabled.",
5
+ "version": "1.0.0",
6
+ "inputs_schema": {
7
+ "type": "object",
8
+ "required": ["enabled", "screenshotDir", "vlmBackend", "stuckSeconds", "maxRuntimeSeconds", "dryRun"],
9
+ "properties": {
10
+ "enabled": { "type": "boolean", "default": false, "description": "Must be true to run. Disabled by default for safety." },
11
+ "screenshotDir": { "type": "string", "default": "~/pod/screens", "description": "Rolling screenshot buffer directory (newest file = current frame)." },
12
+ "outDir": { "type": "string", "default": "~/pod", "description": "Output directory for state/journal/executions (persistent workspace)." },
13
+ "journalDir": { "type": "string", "default": "~/pod/journal", "description": "Default journal path (derived from outDir/journal in the runner)." },
14
+ "relationshipsPath": { "type": "string", "default": "~/pod/state/relationships.json", "description": "Planned: relationships/contacts state for social navigation." },
15
+ "browser": { "type": "string", "enum": ["chrome"], "default": "chrome", "description": "Planned: browser target for recovery automation." },
16
+ "stuckSeconds": { "type": "integer", "minimum": 10, "maximum": 600, "default": 60 },
17
+ "vlmBackend": { "type": "string", "enum": ["claude_cli", "stub"], "default": "stub" },
18
+ "claudeModel": { "type": "string", "default": "sonnet" },
19
+ "executor": { "type": "string", "enum": ["macos_stub", "macos_cgevent"], "default": "macos_stub", "description": "Execution backend. macos_cgevent sends real input events and requires explicit opt-in + macOS Accessibility permission." },
20
+ "allowSystemInput": { "type": "boolean", "default": false, "description": "Strict opt-in. Must be true for real input injection (macos_cgevent)." },
21
+ "focusApp": { "type": "string", "default": "Google Chrome", "description": "App to focus before sending input events (macos_cgevent)." },
22
+ "captureScreenshots": { "type": "boolean", "default": false, "description": "Optional: auto-capture screenshots using macOS screencapture into screenshotDir." },
23
+ "captureIntervalSeconds": { "type": "number", "default": 2.0, "description": "Screenshot capture interval (seconds) when captureScreenshots is enabled." },
24
+ "captureMaxFiles": { "type": "integer", "default": 120, "description": "Rolling buffer size when captureScreenshots is enabled." },
25
+ "execute": { "type": "boolean", "default": false, "description": "Strict opt-in. If true, allow the runner to execute planned actions (still requires allowSystemInput for macos_cgevent)." },
26
+ "fastPrompt": {
27
+ "type": "string",
28
+ "default": "What gets sent to Claude (the FAST_PROMPT):\n\nAnalyze this game screenshot briefly.\n\n1) PLAYERS: List any player names visible (floating text above characters)\n2) DIRECTION: which way is the waypoint/objective marker? (left/right/forward/none)\n3) STATE: gameplay / settings_menu / loading / launcher_window\n4) CHAT: Any new chat messages? (just quote who said what)\n\nKeep it SHORT. Only report what you actually see.\n\n(Plus the actual screenshot image attached.)"
29
+ },
30
+ "deepPrompt": {
31
+ "type": "string",
32
+ "default": "Or on a deeper analysis pass (DEEP_PROMPT), return raw text, not JSON, in this exact structure:\n\n1) ENVIRONMENT: ...\n2) HUD/UI: ...\n3) PLAYERS: ...\n4) CHAT LOG: ...\n5) GAME STATE: ...\n6) NOTABLE: ...\n7) NAVIGATION: ...\n8) SUGGESTED ACTIONS:\n- ...\n- ...\n- ...\n\nBe precise. Only claim what you can actually see."
33
+ },
34
+ "maxRuntimeSeconds": { "type": "integer", "minimum": 60, "maximum": 86400, "default": 3600 },
35
+ "telemetryEnabled": { "type": "boolean", "default": false, "description": "Strict opt-in remote telemetry emission." },
36
+ "telemetryUrl": { "type": "string", "default": "https://api.apeclaw.ai", "description": "Telemetry base URL (POST /api/events)." },
37
+ "telemetryAgentId": { "type": "string", "description": "Optional clawbot agentId for telemetry auth." },
38
+ "telemetryAgentToken": { "type": "string", "description": "Optional clawbot agentToken for telemetry auth." },
39
+ "telemetryIntervalSeconds": { "type": "integer", "minimum": 10, "maximum": 900, "default": 120 },
40
+ "stopFile": { "type": "string", "default": "~/pod/STOP", "description": "Kill switch file path. If present, loop exits immediately." },
41
+ "dryRun": { "type": "boolean", "default": true, "description": "Default safe posture. When true, executor logs intended actions; no system input injection occurs." }
42
+ }
43
+ },
44
+ "outputs_schema": {
45
+ "type": "object",
46
+ "required": ["ok", "status"],
47
+ "properties": {
48
+ "ok": { "type": "boolean" },
49
+ "status": { "type": "string", "enum": ["started", "stopped", "error"] },
50
+ "lastState": { "type": "object" },
51
+ "lastAction": { "type": "object" }
52
+ }
53
+ },
54
+ "bindings": [
55
+ {
56
+ "type": "local_runner",
57
+ "entry": "pod/run_agent.py",
58
+ "runner_contract": {
59
+ "entrypoint": "python3 pod/run_agent.py",
60
+ "notes": [
61
+ "Standard runner contract for THE POD: one process loops on a rolling screenshot buffer and writes state/journal/executions to outDir.",
62
+ "v2-alpha is safe-by-default. Real macOS CGEvent input injection is available as a strict opt-in executor (requires Accessibility permission)."
63
+ ],
64
+ "default_paths": {
65
+ "screenshot_buffer": "~/pod/screens",
66
+ "journal": "~/pod/journal",
67
+ "relationships_json": "~/pod/state/relationships.json"
68
+ },
69
+ "browser": "chrome"
70
+ },
71
+ "notes": [
72
+ "This skill is OS-bound. It reads screenshots from disk. Default execution is stub-only (logs to disk). Optional macOS input injection is available via CGEvent and must remain strict opt-in.",
73
+ "Vision backend 'claude_cli' shells out to: claude -p \"...\" --model sonnet --allowedTools Read",
74
+ "Users must be logged in locally (claude /login). No API keys should be stored in the workspace."
75
+ ]
76
+ }
77
+ ],
78
+ "constraints": {
79
+ "riskTier": 3,
80
+ "safety": [
81
+ "Strict opt-in: enabled=false by default",
82
+ "Hard stop file kill switch",
83
+ "Rate-limit vision calls and recovery attempts",
84
+ "Never upload screenshots to arbitrary endpoints; only the configured vision backend is allowed",
85
+ "Real input injection requires explicit opt-in flags and macOS Accessibility permission"
86
+ ]
87
+ },
88
+ "required_permissions": [
89
+ "file_read",
90
+ "process_spawn",
91
+ "system_input",
92
+ "browser_control",
93
+ "network_optional"
94
+ ],
95
+ "examples": [
96
+ {
97
+ "title": "FAST_PROMPT (exact structure from otherside-navigator-reference.jpg)",
98
+ "value": "What gets sent to Claude (the FAST_PROMPT):\n\nAnalyze this game screenshot briefly.\n\n1) PLAYERS: List any player names visible (floating text above characters)\n2) DIRECTION: which way is the waypoint/objective marker? (left/right/forward/none)\n3) STATE: gameplay / settings_menu / loading / launcher_window\n4) CHAT: Any new chat messages? (just quote who said what)\n\nKeep it SHORT. Only report what you actually see.\n\n(Plus the actual screenshot image attached.)"
99
+ },
100
+ {
101
+ "title": "DEEP_PROMPT (exact structure from otherside-navigator-reference.jpg)",
102
+ "value": "Or on a deeper analysis pass (DEEP_PROMPT), something like:\n\n1) ENVIRONMENT: Open grassy terrain, purple-tinted sky, distant crystalline structures, warm ambient lighting, atmospheric haze on horizon\n2) HUD/UI: Waypoint marker bottom-left \"247m\", compass visible top-center showing heading NNE, no health bar visible, minimap not present\n3) PLAYERS: JayVega (red avatar, close, ~10m), Aurelius_X(blue cape, mid-distance ~25m), moonwalker99 (far, ~40m)\n4) CHAT LOG: moonwalker99: \"anyone know where the portal is\"\n5) GAME STATE: gameplay\n6) NOTABLE: Unusual light flickering near the rock formation at center-right - possible rendering artifact\n7) NAVIGATION: Waypoint marker is to the left\n8) SUGGESTED ACTIONS:\n- Move toward waypoint (left)\n- Approach JayVega (nearest player)\n- Investigate flickering near rock formation"
103
+ },
104
+ {
105
+ "title": "Run (fully loaded; strict opt-in)",
106
+ "value": "macOS prereqs:\\n- python3 -m pip install --upgrade pyobjc-framework-Quartz\\n- grant Accessibility permissions to the terminal/Python process\\n- ensure Otherside is active in Chrome\\n\\nCommand:\\npython3 pod/run_agent.py \\\\\\n --enabled \\\\\\n --screenshot-dir \\\"$HOME/pod/screens\\\" \\\\\\n --capture-screenshots \\\\\\n --capture-interval-seconds 2 \\\\\\n --capture-max-files 120 \\\\\\n --backend claude_cli \\\\\\n --claude-model sonnet \\\\\\n --executor macos_cgevent \\\\\\n --allow-system-input \\\\\\n --focus-app \\\"Google Chrome\\\" \\\\\\n --execute"
107
+ }
108
+ ],
109
+ "eval_packs": [],
110
+ "provenance": {
111
+ "publisher": "apeclaw",
112
+ "signed": false,
113
+ "source_note": "Derived from a production-proven screenshot->VLM->parser->planner->input loop design."
114
+ }
115
+ }
116
+
@@ -0,0 +1,280 @@
1
+ {
2
+ "name": "StonkBrokers — Full DeFi Suite (Robinhood Chain)",
3
+ "slug": "stonkbrokers-launcher",
4
+ "description": "End-to-end onchain DeFi skill for Robinhood Chain testnet via the StonkBrokers protocol (Clutch Labs). Covers the complete lifecycle: claim testnet ETH from the faucet, launch new ERC-20 tokens via fixed-price sale, finalize launches into Uniswap v3 liquidity, swap tokens on the exchange, create pools and mint LP positions with native ETH, write and trade covered-call options, and interact with the NFT collection and marketplace. Designed so an agent can go from a fresh wallet to a fully launched token with trading and options activity in minutes.",
5
+ "version": "1.0.0",
6
+ "documentation_md": "# StonkBrokers — Full DeFi Suite\n\n> **Source**: [Clutch-L4bs/stonkbrokers](https://github.com/Clutch-L4bs/stonkbrokers) \n> **Live App**: [stonkbrokers.vercel.app](https://stonkbrokers.vercel.app) \n> **Network**: Robinhood Chain Testnet (Chain ID `46630`)\n\n## Network Details\n\n| Field | Value |\n|---|---|\n| Chain ID | `46630` |\n| RPC | `https://rpc.testnet.chain.robinhood.com` |\n| Explorer | `https://explorer.testnet.chain.robinhood.com` |\n| Currency | ETH |\n| Faucet | `https://faucet.testnet.chain.robinhood.com/` |\n\n## Deployed Contract Addresses\n\n### Core Infrastructure\n| Contract | Address |\n|---|---|\n| WETH9 | `0x37E402B8081eFcE1D82A09a066512278006e4691` |\n| Uniswap v3 Factory | `0xFECCB63CD759d768538458Ea56F47eA8004323c1` |\n| SwapRouter | `0x1b32F47434a7EF83E97d0675C823E547F9266725` |\n| QuoterV2 | `0x126f1c1F29A0f49c5D33e0139a5Da1FE25590dB1` |\n| PositionManager | `0xBc82a9aA33ff24FCd56D36a0fB0a2105B193A327` |\n\n### Stonk Contracts\n| Contract | Address |\n|---|---|\n| Token Registry | `0xA4954EF8A679B13b1875Bb508E84F563c27A9D5b` |\n| Launcher Factory | `0x631f9371Fd6B2C85F8f61d19A90547eE67Fa61A2` |\n| Covered Call Vault | `0x055d84908672b9be53275963862614aEA9CDB98B` |\n\n### NFT + Marketplace\n| Contract | Address |\n|---|---|\n| Original NFT | `0x2Bb22c9E3394272351FEffEDbEa079Be4FB10a8d` |\n| Expanded NFT | `0x5fDAeBE166490c69B4C34F99E049b4e16c9EF80a` |\n| Marketplace | `0x5a091dB1c58686f4625c14eD204BE85d83BD4aA6` |\n\n---\n\n## Module 1: Faucet — Claim Testnet ETH\n\nThe `StonkEthFaucet` contract dispenses testnet ETH with a 24-hour cooldown per address.\n\n### Steps\n1. Check eligibility: call `canClaim(address)` — returns `true` if cooldown has elapsed.\n2. Claim: call `claim()` — sends `claimAmountWei` ETH to `msg.sender`.\n3. Check next eligible time: `nextClaimTime(address)` returns the UNIX timestamp.\n\n### ABI (key functions)\n```solidity\nfunction canClaim(address user) external view returns (bool);\nfunction nextClaimTime(address user) external view returns (uint256);\nfunction claim() external; // cooldown-gated, sends claimAmountWei to caller\n```\n\n### Alternative: Robinhood Official Faucet\nVisit `https://faucet.testnet.chain.robinhood.com/` — 0.05 ETH per request (requires 0.005 mainnet ETH), or 0.025 ETH otherwise. Once per 24 hours. You can also bridge Sepolia ETH.\n\n---\n\n## Module 2: Token Launcher — Create & Launch Tokens\n\nThe launcher lifecycle:\n1. **Create** a launch via `StonkLauncherFactory.createLaunch()` — deploys a new ERC-20 token + `StonkLaunch` sale contract.\n2. **Buy** tokens during the sale by sending ETH to `StonkLaunch.buy()` — fixed price, first-come-first-served.\n3. **Finalize** the launch via `StonkLauncherFactory.finalizeLaunch()` — wraps raised ETH into WETH, creates a Uniswap v3 pool, and mints a full-range LP position.\n\n### Create a Launch\n```solidity\nstruct CreateLaunchParams {\n string name; // Token name (e.g. \"My Token\")\n string symbol; // Token symbol (e.g. \"MTKN\")\n string metadataURI; // JSON metadata URI\n string imageURI; // Token icon URI\n uint256 totalSupplyWei; // Total supply in wei (e.g. 1_000_000e18)\n uint256 creatorAllocationBps; // Creator's share in basis points (e.g. 1000 = 10%)\n uint256 saleBpsOfRemaining; // Portion of remaining for sale (e.g. 5000 = 50%)\n uint256 priceWeiPerToken; // Fixed ETH price per whole token in wei\n}\n\nfunction createLaunch(CreateLaunchParams calldata p)\n external returns (address token, address launch);\n```\n\nEmits `LaunchCreated(creator, token, launch, name, symbol, metadataURI, imageURI)`.\n\n### Buy from the Sale\n```solidity\n// On the StonkLaunch contract (the `launch` address returned above)\nfunction buy() external payable; // send ETH, receive tokens at priceWeiPerToken\nfunction remainingForSale() external view returns (uint256);\n```\n\nEmits `Bought(buyer, ethIn, tokensOut)`. Also supports `receive()` (just send ETH).\n\n### Finalize the Launch\n```solidity\n// Back on the factory\nfunction finalizeLaunch(address launch, uint160 sqrtPriceX96, uint24 fee) external payable;\n```\n\n`sqrtPriceX96` sets the initial pool price. `fee` is the Uniswap v3 fee tier (e.g. `3000` for 0.3%, `10000` for 1%). Emits `LaunchFinalized(creator, launch, pool, lpTokenId)`. This also wires up a fee splitter and staking vault.\n\n---\n\n## Module 3: Exchange — Swap Tokens\n\nSwap any pair through Uniswap v3 SwapRouter. The UI also supports direct ETH ↔ WETH wrapping.\n\n### Quote a Swap\n```solidity\n// QuoterV2 at 0x126f1c1F29A0f49c5D33e0139a5Da1FE25590dB1\nfunction quoteExactInputSingle(\n address tokenIn,\n address tokenOut,\n uint24 fee,\n uint256 amountIn,\n uint160 sqrtPriceLimitX96\n) external returns (uint256 amountOut, ...);\n```\n\n### Execute a Swap\n```solidity\n// SwapRouter at 0x1b32F47434a7EF83E97d0675C823E547F9266725\nstruct ExactInputSingleParams {\n address tokenIn;\n address tokenOut;\n uint24 fee;\n address recipient;\n uint256 deadline;\n uint256 amountIn;\n uint256 amountOutMinimum;\n uint160 sqrtPriceLimitX96;\n}\nfunction exactInputSingle(ExactInputSingleParams calldata params)\n external payable returns (uint256 amountOut);\n```\n\nFor native ETH swaps, send `msg.value` and set `tokenIn = WETH9`.\n\n### ETH ↔ WETH Wrap/Unwrap\n```solidity\n// WETH9 at 0x37E402B8081eFcE1D82A09a066512278006e4691\nfunction deposit() external payable; // ETH → WETH\nfunction withdraw(uint256 wad) external; // WETH → ETH\n```\n\n---\n\n## Module 4: Pools — Create Pools & Mint LP Positions\n\n### Create and Initialize a Pool\n```solidity\n// PositionManager at 0xBc82a9aA33ff24FCd56D36a0fB0a2105B193A327\nfunction createAndInitializePoolIfNecessary(\n address token0,\n address token1,\n uint24 fee,\n uint160 sqrtPriceX96\n) external payable returns (address pool);\n```\n\n`token0` must be < `token1` (sorted by address). Use `fee` tiers: `500` (0.05%), `3000` (0.3%), `10000` (1%).\n\n### Mint an LP Position\n```solidity\nstruct MintParams {\n address token0;\n address token1;\n uint24 fee;\n int24 tickLower;\n int24 tickUpper;\n uint256 amount0Desired;\n uint256 amount1Desired;\n uint256 amount0Min;\n uint256 amount1Min;\n address recipient;\n uint256 deadline;\n}\nfunction mint(MintParams calldata params)\n external payable returns (uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1);\n```\n\nFor full-range: `tickLower = -887272`, `tickUpper = 887272`.\nFor native ETH on one side: send `msg.value` and use WETH9 as the token. The PositionManager wraps it.\n\n---\n\n## Module 5: Options — Covered Calls\n\n### Write a Covered Call\n```solidity\n// CoveredCallVault at 0x055d84908672b9be53275963862614aEA9CDB98B\nfunction createOffer(\n address underlying, // token to escrow\n address quote, // settlement token (usually WETH)\n address pool, // Uniswap v3 pool for TWAP\n uint32 twapSeconds, // TWAP window (min 15 minutes)\n int24 strikeTick, // strike price as a Uni v3 tick\n uint256 underlyingAmount, // how many underlying tokens to escrow\n uint256 strikeQuoteAmount,// quote tokens received if exercised\n uint256 premiumQuoteAmount,// premium the buyer pays upfront\n uint256 expiry // UNIX timestamp for expiration\n) external returns (uint256 offerId);\n```\n\nThe writer must `approve(vault, underlyingAmount)` first.\n\n### Buy an Option\n```solidity\nfunction buyOption(uint256 offerId) external returns (uint256 optionTokenId);\n```\n\nBuyer must `approve(vault, premiumQuoteAmount)` of the quote token. Receives an ERC-721 option NFT.\n\n### Exercise an Option\n```solidity\nfunction exercise(uint256 optionTokenId) external;\n```\n\nOnly works if in-the-money per TWAP oracle and before expiry. Buyer sends `strikeQuoteAmount` and receives the escrowed underlying.\n\n### Reclaim Expired\n```solidity\nfunction reclaimExpired(uint256 optionTokenId) external;\n```\n\nWriter can reclaim escrowed collateral after expiry if unexercised.\n\n---\n\n## Suggested Agent Flow (End-to-End)\n\n1. **Claim gas**: Call faucet `claim()` or use the official Robinhood faucet.\n2. **Create token**: Call `createLaunch({name, symbol, ..., totalSupplyWei, priceWeiPerToken})`.\n3. **Buy from sale**: Send ETH to `launch.buy()` to acquire tokens.\n4. **Finalize**: Call `finalizeLaunch(launch, sqrtPriceX96, fee)` to seed Uniswap v3 pool.\n5. **Swap**: Use `SwapRouter.exactInputSingle()` to trade the new token.\n6. **Add LP**: Call `PositionManager.mint()` to provide liquidity.\n7. **Write option**: Approve + call `createOffer()` to write a covered call.\n8. **Buy option**: Another agent/user calls `buyOption()` and gets an option NFT.\n9. **Exercise or reclaim**: `exercise()` if ITM, or `reclaimExpired()` after expiry.\n",
7
+ "inputs_schema": {
8
+ "type": "object",
9
+ "required": ["action"],
10
+ "properties": {
11
+ "action": {
12
+ "type": "string",
13
+ "enum": [
14
+ "faucet_claim",
15
+ "launch_create",
16
+ "launch_buy",
17
+ "launch_finalize",
18
+ "swap",
19
+ "wrap_eth",
20
+ "unwrap_weth",
21
+ "pool_create",
22
+ "pool_mint_lp",
23
+ "option_write",
24
+ "option_buy",
25
+ "option_exercise",
26
+ "option_reclaim"
27
+ ],
28
+ "description": "Which StonkBrokers module action to perform"
29
+ },
30
+ "rpcUrl": {
31
+ "type": "string",
32
+ "default": "https://rpc.testnet.chain.robinhood.com",
33
+ "description": "Robinhood Chain testnet RPC endpoint"
34
+ },
35
+ "privateKey": {
36
+ "type": "string",
37
+ "description": "Wallet private key (hex, 0x-prefixed). Never log or persist this."
38
+ },
39
+ "faucet": {
40
+ "type": "object",
41
+ "description": "Parameters for faucet_claim action",
42
+ "properties": {
43
+ "contractAddress": { "type": "string", "description": "StonkEthFaucet contract address" }
44
+ }
45
+ },
46
+ "launch": {
47
+ "type": "object",
48
+ "description": "Parameters for launch_create / launch_buy / launch_finalize",
49
+ "properties": {
50
+ "factoryAddress": { "type": "string", "default": "0x631f9371Fd6B2C85F8f61d19A90547eE67Fa61A2" },
51
+ "name": { "type": "string", "description": "Token name (for create)" },
52
+ "symbol": { "type": "string", "description": "Token symbol (for create)" },
53
+ "totalSupplyWei": { "type": "string", "description": "Total supply in wei, e.g. '1000000000000000000000000' for 1M tokens with 18 decimals" },
54
+ "creatorAllocationBps": { "type": "integer", "default": 1000, "description": "Creator allocation in basis points (1000 = 10%)" },
55
+ "saleBpsOfRemaining": { "type": "integer", "default": 5000, "description": "Sale portion of remaining in basis points (5000 = 50%)" },
56
+ "priceWeiPerToken": { "type": "string", "description": "ETH price per whole token in wei" },
57
+ "launchAddress": { "type": "string", "description": "StonkLaunch contract address (for buy/finalize)" },
58
+ "buyAmountEth": { "type": "string", "description": "ETH to spend buying tokens (for buy)" },
59
+ "sqrtPriceX96": { "type": "string", "description": "Initial pool price as sqrtPriceX96 (for finalize)" },
60
+ "feeTier": { "type": "integer", "enum": [500, 3000, 10000], "default": 3000, "description": "Uniswap v3 fee tier" }
61
+ }
62
+ },
63
+ "swap": {
64
+ "type": "object",
65
+ "description": "Parameters for swap action",
66
+ "properties": {
67
+ "tokenIn": { "type": "string", "description": "Input token address (use WETH9 for native ETH)" },
68
+ "tokenOut": { "type": "string", "description": "Output token address" },
69
+ "amountIn": { "type": "string", "description": "Amount in wei" },
70
+ "fee": { "type": "integer", "enum": [500, 3000, 10000], "default": 3000 },
71
+ "slippageBps": { "type": "integer", "default": 100, "description": "Max slippage in basis points" }
72
+ }
73
+ },
74
+ "pool": {
75
+ "type": "object",
76
+ "description": "Parameters for pool_create / pool_mint_lp",
77
+ "properties": {
78
+ "token0": { "type": "string", "description": "First token address (must be < token1 by address)" },
79
+ "token1": { "type": "string", "description": "Second token address" },
80
+ "fee": { "type": "integer", "enum": [500, 3000, 10000], "default": 3000 },
81
+ "sqrtPriceX96": { "type": "string", "description": "Initial sqrt price (for pool_create)" },
82
+ "amount0Desired": { "type": "string", "description": "Amount of token0 in wei (for mint_lp)" },
83
+ "amount1Desired": { "type": "string", "description": "Amount of token1 in wei (for mint_lp)" },
84
+ "tickLower": { "type": "integer", "default": -887272, "description": "Lower tick bound (-887272 for full range)" },
85
+ "tickUpper": { "type": "integer", "default": 887272, "description": "Upper tick bound (887272 for full range)" },
86
+ "useNativeEth": { "type": "boolean", "default": false, "description": "Send native ETH as msg.value for one side" }
87
+ }
88
+ },
89
+ "option": {
90
+ "type": "object",
91
+ "description": "Parameters for option_write / option_buy / option_exercise / option_reclaim",
92
+ "properties": {
93
+ "vaultAddress": { "type": "string", "default": "0x055d84908672b9be53275963862614aEA9CDB98B" },
94
+ "underlying": { "type": "string" },
95
+ "quote": { "type": "string", "description": "Quote token (usually WETH)" },
96
+ "pool": { "type": "string", "description": "Uniswap v3 pool address for TWAP" },
97
+ "twapSeconds": { "type": "integer", "default": 900, "description": "TWAP window in seconds (min 900)" },
98
+ "strikeTick": { "type": "integer", "description": "Strike price as Uniswap v3 tick" },
99
+ "underlyingAmount": { "type": "string", "description": "Underlying tokens to escrow (wei)" },
100
+ "strikeQuoteAmount": { "type": "string", "description": "Quote amount at strike (wei)" },
101
+ "premiumQuoteAmount": { "type": "string", "description": "Premium cost (wei)" },
102
+ "expiry": { "type": "integer", "description": "UNIX timestamp for option expiry" },
103
+ "offerId": { "type": "integer", "description": "Offer ID (for buy)" },
104
+ "optionTokenId": { "type": "integer", "description": "Option NFT token ID (for exercise/reclaim)" }
105
+ }
106
+ }
107
+ }
108
+ },
109
+ "outputs_schema": {
110
+ "type": "object",
111
+ "required": ["ok", "action"],
112
+ "properties": {
113
+ "ok": { "type": "boolean" },
114
+ "action": { "type": "string" },
115
+ "txHash": { "type": "string", "description": "Transaction hash on Robinhood Chain testnet" },
116
+ "explorerUrl": { "type": "string", "description": "Link to the transaction on the block explorer" },
117
+ "tokenAddress": { "type": "string", "description": "Deployed token address (from launch_create)" },
118
+ "launchAddress": { "type": "string", "description": "StonkLaunch sale contract (from launch_create)" },
119
+ "poolAddress": { "type": "string", "description": "Uniswap v3 pool address (from finalize or pool_create)" },
120
+ "lpTokenId": { "type": "string", "description": "LP NFT token ID (from finalize or pool_mint_lp)" },
121
+ "tokensReceived": { "type": "string", "description": "Tokens received from a buy or swap" },
122
+ "ethClaimed": { "type": "string", "description": "ETH received from faucet" },
123
+ "offerId": { "type": "integer", "description": "Offer ID from option_write" },
124
+ "optionTokenId": { "type": "integer", "description": "Option NFT ID from option_buy" },
125
+ "error": { "type": "string", "description": "Error message if ok=false" }
126
+ }
127
+ },
128
+ "bindings": [
129
+ {
130
+ "type": "onchain",
131
+ "chain": "robinhood-testnet",
132
+ "chainId": 46630,
133
+ "rpcUrl": "https://rpc.testnet.chain.robinhood.com",
134
+ "explorer": "https://explorer.testnet.chain.robinhood.com",
135
+ "contracts": {
136
+ "weth9": "0x37E402B8081eFcE1D82A09a066512278006e4691",
137
+ "uniswapV3Factory": "0xFECCB63CD759d768538458Ea56F47eA8004323c1",
138
+ "swapRouter": "0x1b32F47434a7EF83E97d0675C823E547F9266725",
139
+ "quoterV2": "0x126f1c1F29A0f49c5D33e0139a5Da1FE25590dB1",
140
+ "positionManager": "0xBc82a9aA33ff24FCd56D36a0fB0a2105B193A327",
141
+ "tokenRegistry": "0xA4954EF8A679B13b1875Bb508E84F563c27A9D5b",
142
+ "launcherFactory": "0x631f9371Fd6B2C85F8f61d19A90547eE67Fa61A2",
143
+ "coveredCallVault": "0x055d84908672b9be53275963862614aEA9CDB98B",
144
+ "originalNft": "0x2Bb22c9E3394272351FEffEDbEa079Be4FB10a8d",
145
+ "expandedNft": "0x5fDAeBE166490c69B4C34F99E049b4e16c9EF80a",
146
+ "marketplace": "0x5a091dB1c58686f4625c14eD204BE85d83BD4aA6"
147
+ },
148
+ "source": "https://github.com/Clutch-L4bs/stonkbrokers"
149
+ }
150
+ ],
151
+ "constraints": {
152
+ "riskTier": 2,
153
+ "safety": [
154
+ "Never log or persist private keys",
155
+ "All transactions are on Robinhood Chain TESTNET only — tokens have no real value",
156
+ "Verify contract addresses before sending transactions",
157
+ "Use slippage protection on all swaps",
158
+ "Check faucet cooldown before calling claim()",
159
+ "Ensure token approvals before interacting with vault or position manager"
160
+ ],
161
+ "notes": [
162
+ "This is a testnet-only skill — Robinhood Chain mainnet is not yet live",
163
+ "The StonkBrokers contracts are a hackathon MVP; treat as experimental",
164
+ "Fee tier mismatches are the #1 cause of 'No liquidity' errors on swaps",
165
+ "LP positions use WETH — selecting ETH wraps automatically via the PositionManager",
166
+ "Options exercise requires TWAP to show the option is in-the-money"
167
+ ]
168
+ },
169
+ "required_permissions": [
170
+ "onchain_execute",
171
+ "onchain_read",
172
+ "market_data"
173
+ ],
174
+ "examples": [
175
+ {
176
+ "title": "Claim testnet ETH from faucet",
177
+ "input": {
178
+ "action": "faucet_claim",
179
+ "rpcUrl": "https://rpc.testnet.chain.robinhood.com",
180
+ "privateKey": "0x..."
181
+ },
182
+ "expected_output": {
183
+ "ok": true,
184
+ "action": "faucet_claim",
185
+ "ethClaimed": "10000000000000000",
186
+ "txHash": "0x..."
187
+ }
188
+ },
189
+ {
190
+ "title": "Launch a new meme token",
191
+ "input": {
192
+ "action": "launch_create",
193
+ "rpcUrl": "https://rpc.testnet.chain.robinhood.com",
194
+ "privateKey": "0x...",
195
+ "launch": {
196
+ "name": "Test Stonk Token",
197
+ "symbol": "TSTONK",
198
+ "totalSupplyWei": "1000000000000000000000000",
199
+ "creatorAllocationBps": 1000,
200
+ "saleBpsOfRemaining": 5000,
201
+ "priceWeiPerToken": "10000000000000"
202
+ }
203
+ },
204
+ "expected_output": {
205
+ "ok": true,
206
+ "action": "launch_create",
207
+ "tokenAddress": "0x...",
208
+ "launchAddress": "0x...",
209
+ "txHash": "0x..."
210
+ }
211
+ },
212
+ {
213
+ "title": "Buy tokens from an active sale",
214
+ "input": {
215
+ "action": "launch_buy",
216
+ "rpcUrl": "https://rpc.testnet.chain.robinhood.com",
217
+ "privateKey": "0x...",
218
+ "launch": {
219
+ "launchAddress": "0x...",
220
+ "buyAmountEth": "0.01"
221
+ }
222
+ },
223
+ "expected_output": {
224
+ "ok": true,
225
+ "action": "launch_buy",
226
+ "tokensReceived": "1000000000000000000000",
227
+ "txHash": "0x..."
228
+ }
229
+ },
230
+ {
231
+ "title": "Finalize launch → create Uniswap v3 pool with LP",
232
+ "input": {
233
+ "action": "launch_finalize",
234
+ "rpcUrl": "https://rpc.testnet.chain.robinhood.com",
235
+ "privateKey": "0x...",
236
+ "launch": {
237
+ "launchAddress": "0x...",
238
+ "sqrtPriceX96": "79228162514264337593543950336",
239
+ "feeTier": 3000
240
+ }
241
+ },
242
+ "expected_output": {
243
+ "ok": true,
244
+ "action": "launch_finalize",
245
+ "poolAddress": "0x...",
246
+ "lpTokenId": "1",
247
+ "txHash": "0x..."
248
+ }
249
+ },
250
+ {
251
+ "title": "Swap ETH for a launched token",
252
+ "input": {
253
+ "action": "swap",
254
+ "rpcUrl": "https://rpc.testnet.chain.robinhood.com",
255
+ "privateKey": "0x...",
256
+ "swap": {
257
+ "tokenIn": "0x37E402B8081eFcE1D82A09a066512278006e4691",
258
+ "tokenOut": "0x...",
259
+ "amountIn": "10000000000000000",
260
+ "fee": 3000,
261
+ "slippageBps": 100
262
+ }
263
+ },
264
+ "expected_output": {
265
+ "ok": true,
266
+ "action": "swap",
267
+ "tokensReceived": "999000000000000000000",
268
+ "txHash": "0x..."
269
+ }
270
+ }
271
+ ],
272
+ "eval_packs": [],
273
+ "provenance": {
274
+ "publisher": "apeclaw",
275
+ "signed": false,
276
+ "source": "github",
277
+ "sourceUrl": "https://github.com/Clutch-L4bs/stonkbrokers",
278
+ "sourceNote": "Built from Clutch Labs' StonkBrokers repo — an end-to-end onchain DeFi product suite for Robinhood Chain testnet including token launcher, exchange, pools, options, NFTs, and marketplace."
279
+ }
280
+ }