safehands-pharos 1.2.6 → 1.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 (153) hide show
  1. package/.env.example +64 -26
  2. package/README.md +333 -445
  3. package/dist/cli.d.ts +5 -5
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +124 -98
  6. package/dist/cli.js.map +1 -1
  7. package/dist/demo.d.ts +1 -1
  8. package/dist/demo.js +171 -171
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.js +138 -87
  11. package/dist/index.js.map +1 -1
  12. package/dist/init.d.ts +1 -1
  13. package/dist/init.js +65 -65
  14. package/dist/lib/auditLog.d.ts +9 -0
  15. package/dist/lib/auditLog.d.ts.map +1 -0
  16. package/dist/lib/auditLog.js +30 -0
  17. package/dist/lib/auditLog.js.map +1 -0
  18. package/dist/lib/constants.d.ts +291 -291
  19. package/dist/lib/constants.js +292 -292
  20. package/dist/lib/dodoApi.d.ts +78 -70
  21. package/dist/lib/dodoApi.d.ts.map +1 -1
  22. package/dist/lib/dodoApi.js +196 -178
  23. package/dist/lib/dodoApi.js.map +1 -1
  24. package/dist/lib/http.d.ts +14 -14
  25. package/dist/lib/http.js +118 -118
  26. package/dist/lib/pharosClient.d.ts +58 -58
  27. package/dist/lib/pharosClient.d.ts.map +1 -1
  28. package/dist/lib/pharosClient.js +63 -53
  29. package/dist/lib/pharosClient.js.map +1 -1
  30. package/dist/lib/policy/actionPolicyEngine.d.ts +53 -53
  31. package/dist/lib/policy/actionPolicyEngine.js +212 -212
  32. package/dist/lib/policy/actionPolicyEngine.js.map +1 -1
  33. package/dist/lib/riskEngine.d.ts +26 -26
  34. package/dist/lib/riskEngine.js +283 -283
  35. package/dist/lib/signer/index.d.ts +24 -24
  36. package/dist/lib/signer/index.d.ts.map +1 -1
  37. package/dist/lib/signer/index.js +88 -89
  38. package/dist/lib/signer/index.js.map +1 -1
  39. package/dist/lib/spendAccumulator.d.ts +10 -0
  40. package/dist/lib/spendAccumulator.d.ts.map +1 -0
  41. package/dist/lib/spendAccumulator.js +54 -0
  42. package/dist/lib/spendAccumulator.js.map +1 -0
  43. package/dist/lib/testDodoLive.d.ts +1 -1
  44. package/dist/lib/testDodoLive.js +104 -104
  45. package/dist/lib/testLiveSafehands.d.ts +1 -1
  46. package/dist/lib/testLiveSafehands.js +92 -92
  47. package/dist/lib/testRpc.d.ts +1 -1
  48. package/dist/lib/testRpc.js +29 -29
  49. package/dist/lib/testRpcLive.d.ts +1 -1
  50. package/dist/lib/testRpcLive.js +88 -88
  51. package/dist/lib/testTools.d.ts +1 -1
  52. package/dist/lib/testTools.js +397 -397
  53. package/dist/lib/testX402Live.d.ts +1 -1
  54. package/dist/lib/testX402Live.js +159 -159
  55. package/dist/lib/toolResponse.d.ts +25 -25
  56. package/dist/lib/toolResponse.js +53 -53
  57. package/dist/lib/wallet/index.d.ts +37 -18
  58. package/dist/lib/wallet/index.d.ts.map +1 -1
  59. package/dist/lib/wallet/index.js +128 -70
  60. package/dist/lib/wallet/index.js.map +1 -1
  61. package/dist/scripts/checkDeploy.d.ts +1 -1
  62. package/dist/scripts/checkDeploy.js +24 -24
  63. package/dist/scripts/deployRegistry.d.ts +1 -1
  64. package/dist/scripts/deployRegistry.js +100 -100
  65. package/dist/scripts/testRegistry.d.ts +1 -1
  66. package/dist/scripts/testRegistry.js +43 -43
  67. package/dist/tools/approveToken.d.ts +45 -46
  68. package/dist/tools/approveToken.d.ts.map +1 -1
  69. package/dist/tools/approveToken.js +85 -83
  70. package/dist/tools/approveToken.js.map +1 -1
  71. package/dist/tools/assessRisk.d.ts +79 -79
  72. package/dist/tools/assessRisk.d.ts.map +1 -1
  73. package/dist/tools/assessRisk.js +104 -93
  74. package/dist/tools/assessRisk.js.map +1 -1
  75. package/dist/tools/checkAllowance.d.ts +43 -36
  76. package/dist/tools/checkAllowance.d.ts.map +1 -1
  77. package/dist/tools/checkAllowance.js +56 -42
  78. package/dist/tools/checkAllowance.js.map +1 -1
  79. package/dist/tools/checkTokenSecurity.d.ts +46 -46
  80. package/dist/tools/checkTokenSecurity.d.ts.map +1 -1
  81. package/dist/tools/checkTokenSecurity.js +95 -88
  82. package/dist/tools/checkTokenSecurity.js.map +1 -1
  83. package/dist/tools/createAgentWallet.d.ts +26 -26
  84. package/dist/tools/createAgentWallet.d.ts.map +1 -1
  85. package/dist/tools/createAgentWallet.js +58 -59
  86. package/dist/tools/createAgentWallet.js.map +1 -1
  87. package/dist/tools/estimateGas.d.ts +79 -79
  88. package/dist/tools/estimateGas.js +124 -124
  89. package/dist/tools/executeSwap.d.ts +61 -59
  90. package/dist/tools/executeSwap.d.ts.map +1 -1
  91. package/dist/tools/executeSwap.js +141 -129
  92. package/dist/tools/executeSwap.js.map +1 -1
  93. package/dist/tools/explainRisk.d.ts +29 -29
  94. package/dist/tools/explainRisk.js +32 -32
  95. package/dist/tools/getAgentWallet.d.ts +21 -21
  96. package/dist/tools/getAgentWallet.js +27 -27
  97. package/dist/tools/getAgentWalletBalance.d.ts +11 -11
  98. package/dist/tools/getAgentWalletBalance.js +70 -70
  99. package/dist/tools/getExecutionHistory.d.ts +49 -51
  100. package/dist/tools/getExecutionHistory.d.ts.map +1 -1
  101. package/dist/tools/getExecutionHistory.js +154 -93
  102. package/dist/tools/getExecutionHistory.js.map +1 -1
  103. package/dist/tools/getGasPrice.d.ts +43 -43
  104. package/dist/tools/getGasPrice.js +59 -59
  105. package/dist/tools/getPoolInfo.d.ts +75 -75
  106. package/dist/tools/getPoolInfo.js +137 -137
  107. package/dist/tools/getTokenPrice.d.ts +113 -113
  108. package/dist/tools/getTokenPrice.js +117 -117
  109. package/dist/tools/getTransactionStatus.d.ts +43 -57
  110. package/dist/tools/getTransactionStatus.d.ts.map +1 -1
  111. package/dist/tools/getTransactionStatus.js +59 -67
  112. package/dist/tools/getTransactionStatus.js.map +1 -1
  113. package/dist/tools/getWalletBalance.d.ts +68 -68
  114. package/dist/tools/getWalletBalance.js +87 -87
  115. package/dist/tools/publishRiskScore.d.ts +63 -63
  116. package/dist/tools/publishRiskScore.d.ts.map +1 -1
  117. package/dist/tools/publishRiskScore.js +88 -85
  118. package/dist/tools/publishRiskScore.js.map +1 -1
  119. package/dist/tools/queryRiskRegistry.d.ts +38 -48
  120. package/dist/tools/queryRiskRegistry.d.ts.map +1 -1
  121. package/dist/tools/queryRiskRegistry.js +55 -60
  122. package/dist/tools/queryRiskRegistry.js.map +1 -1
  123. package/dist/tools/safehandsPreflightCheck.d.ts +77 -77
  124. package/dist/tools/safehandsPreflightCheck.js +47 -47
  125. package/dist/tools/safehandsRiskReport.d.ts +81 -81
  126. package/dist/tools/safehandsRiskReport.js +28 -28
  127. package/dist/tools/safehandsSafeExecute.d.ts +20 -20
  128. package/dist/tools/safehandsSafeExecute.d.ts.map +1 -1
  129. package/dist/tools/safehandsSafeExecute.js +81 -75
  130. package/dist/tools/safehandsSafeExecute.js.map +1 -1
  131. package/dist/tools/safehandsWalletHealth.d.ts +14 -14
  132. package/dist/tools/safehandsWalletHealth.js +103 -103
  133. package/dist/tools/safehandsX402Preflight.d.ts +26 -26
  134. package/dist/tools/safehandsX402Preflight.js +65 -65
  135. package/dist/tools/sendPayment.d.ts +57 -58
  136. package/dist/tools/sendPayment.d.ts.map +1 -1
  137. package/dist/tools/sendPayment.js +117 -108
  138. package/dist/tools/sendPayment.js.map +1 -1
  139. package/dist/tools/simulateTransaction.d.ts +60 -81
  140. package/dist/tools/simulateTransaction.d.ts.map +1 -1
  141. package/dist/tools/simulateTransaction.js +83 -88
  142. package/dist/tools/simulateTransaction.js.map +1 -1
  143. package/dist/tools/tokenRegistryStatus.d.ts +26 -26
  144. package/dist/tools/tokenRegistryStatus.js +96 -96
  145. package/dist/tools/x402PayAndFetch.d.ts +81 -81
  146. package/dist/tools/x402PayAndFetch.d.ts.map +1 -1
  147. package/dist/tools/x402PayAndFetch.js +152 -149
  148. package/dist/tools/x402PayAndFetch.js.map +1 -1
  149. package/dist/x402Server.d.ts +1 -1
  150. package/dist/x402Server.js +252 -252
  151. package/examples/dashboard/index.html +337 -0
  152. package/package.json +83 -82
  153. package/skill/SKILL.md +133 -133
package/README.md CHANGED
@@ -1,445 +1,333 @@
1
- <p align="center">
2
- <img src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white" />
3
- <img src="https://img.shields.io/badge/MCP_Skill-000000?style=for-the-badge" />
4
- <img src="https://img.shields.io/badge/Pharos_Atlantic-688689-blueviolet?style=for-the-badge" />
5
- <img src="https://img.shields.io/badge/Tools-27-orange?style=for-the-badge" />
6
- <img src="https://img.shields.io/badge/Testnet_Only-SAFE-blue?style=for-the-badge" />
7
- </p>
8
-
9
- # SafeHands-Pharos: Transaction Safety Firewall for AI Agents
10
-
11
- SafeHands-Pharos is a **Pharos Skill Engine-compatible MCP package** that protects AI agents before they execute payments, token approvals, swaps, x402 paid requests, or contract interactions.
12
-
13
- Before an AI agent sends a payment, approves tokens, swaps assets, publishes risk data, or pays an x402 resource, SafeHands runs a policy-based preflight check and returns a deterministic decision:
14
-
15
- ```text
16
- ALLOW | WARN | BLOCK | REQUIRE_CONFIRMATION | REQUIRE_FUNDING | REQUIRE_TOKEN_REVIEW
17
- ```
18
-
19
- Every decision includes a risk level, human-readable reasons, required next actions, environment metadata, and structured JSON that agents can parse.
20
-
21
- > **Testnet scope:** SafeHands targets **Pharos Atlantic Testnet only**. It is not audited for mainnet and should not be used with mainnet funds.
22
-
23
- ---
24
-
25
- ## Why AI Agents Need Transaction Safety Middleware
26
-
27
- Autonomous agents can now hold wallets, call APIs, pay x402 resources, approve tokens, and interact on-chain. Generic Web3 tools usually answer: "Can this transaction be sent?" SafeHands answers a more important question first:
28
-
29
- > **Should this action be allowed at all?**
30
-
31
- Common agent-execution risks:
32
-
33
- | Risk | What can go wrong | SafeHands guardrail |
34
- |---|---|---|
35
- | Unlimited approval | Agent approves a malicious spender forever | Blocks unlimited approval by default |
36
- | Wrong chain | Agent signs on mainnet or the wrong testnet | Blocks mainnet and chain ID mismatch |
37
- | Risky x402 URL | Agent pays or fetches SSRF-sensitive endpoints | Blocks localhost/private IPs by default |
38
- | Overspending | Agent pays above configured limits | Blocks payments above limits |
39
- | Unknown token | Agent swaps/approves unverified token | Warns or requires token review |
40
- | Missing signer | Agent tries write action without safe signer | Returns structured signer error |
41
-
42
- ---
43
-
44
- ## What SafeHands Is, and What It Is Not
45
-
46
- SafeHands is a **Transaction Safety Firewall / Guardrail Skill** for Pharos agents. SafeHands is a guardrail layer before execution, not a generic Web3 toolbox.
47
-
48
- It is **not** a generic Web3 toolbox and does not replace Pharos Skill Engine. It complements the Skill Engine by adding a safety layer before execution:
49
-
50
- ```text
51
- User intent
52
- SafeHands preflight
53
- → ALLOW / WARN / BLOCK
54
- Pharos Skill Engine or MCP execution if safe
55
- → SafeHands risk report
56
- ```
57
-
58
- ### Difference from Reputation Systems
59
-
60
- SafeHands is also different from pure reputation systems:
61
-
62
- | System type | Main question |
63
- |---|---|
64
- | Agent reputation, such as AgentLeash-style trust systems | "Can I trust this agent?" |
65
- | SafeHands | "Can I trust this action right now?" |
66
-
67
- SafeHands can use reputation signals, but its core purpose is **action-level risk gating**.
68
-
69
- ---
70
-
71
- ## Pharos Atlantic Testnet Context
72
-
73
- Default project configuration:
74
-
75
- | Item | Value |
76
- |---|---|
77
- | Environment | `atlantic-testnet` |
78
- | Chain ID | `688689` |
79
- | RPC URL | `https://atlantic.dplabs-internal.com` |
80
- | Explorer | `https://atlantic.pharosscan.xyz/` |
81
- | Mainnet support | `false` |
82
- | RiskRegistry | `0x61962a6c812ee9f57b207e1ea47c19ae70bb7141` |
83
- | Primary Pharos Skill Engine USDC | `0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8` |
84
- | Alternate Circle-referenced USDC | `0xcfC8330f4BCAB529c625D12781b1C19466A9Fc8B` |
85
-
86
- The project treats router and pool addresses that are not directly verified from official docs as **project-configured**, not universal canonical values.
87
-
88
- ### 🧠 Smart Liquidity Fallback
89
- Testnet liquidity is often fragmented or missing. SafeHands includes a **Smart Fallback Engine** within its DODO API integration.
90
- If an AI agent requests a swap to the primary `USDC` token and the routing engine returns `NO_ROUTE_AVAILABLE`, SafeHands will automatically and silently retry the route query using the `Alternate Circle-referenced USDC` address. This prevents unnecessary transaction failures during live agent demos.
91
-
92
- ---
93
-
94
- ## Official Pharos Skill Engine Alignment
95
-
96
- - SafeHands follows the official `SKILL.md` + `references` + `assets` structure (found in the `skill/` package directory).
97
- - SafeHands complements Pharos Skill Engine by adding preflight safety checks before write actions.
98
- - Pharos Skill Engine provides general on-chain capabilities.
99
- - SafeHands answers: "Is this action safe to execute?"
100
- - Default network remains Pharos Atlantic Testnet.
101
- - No mainnet readiness is claimed.
102
-
103
- ---
104
-
105
- ## Supported Usage Modes
106
-
107
- SafeHands supports three usage modes:
108
-
109
- 1. **Pharos Skill Engine (Recommended for Agents):** Install directly into your AI agent project via GitHub:
110
- ```bash
111
- npx skills add SZtch/safehands-pharos
112
- ```
113
- 2. **MCP server usage:** Run directly as a standard MCP server for Claude Desktop, Anvita Flow, etc.
114
- 3. **npm/npx CLI usage:** Run manually in the terminal for testing and CI checks.
115
-
116
- ---
117
-
118
- ## Quick Start
119
-
120
- ```bash
121
- npm install
122
- npm run build
123
- npm run test:all
124
- npm run demo
125
- ```
126
-
127
- Run as MCP server:
128
-
129
- ```bash
130
- npx safehands-pharos
131
- ```
132
-
133
- Show CLI help:
134
-
135
- ```bash
136
- npx safehands-pharos --help
137
- ```
138
-
139
- Run deterministic demo:
140
-
141
- ```bash
142
- npx safehands-pharos --demo
143
- ```
144
-
145
- Run a Skill Engine-compatible CLI call:
146
-
147
- ```bash
148
- npx safehands-pharos skill safehands_preflight_check --input-json '{"actionType":"approve_token","chainId":688689,"isMainnet":false,"approvalAmount":"max","spender":"0x0000000000000000000000000000000000000001"}'
149
- ```
150
-
151
- The CLI returns the standard response envelope:
152
-
153
- ```json
154
- {
155
- "success": true,
156
- "data": {
157
- "decision": "BLOCK",
158
- "riskLevel": "HIGH",
159
- "safeToExecute": false,
160
- "reasons": ["Unlimited approval requested."],
161
- "requiredActions": ["Use a limited approval amount."],
162
- "environment": "atlantic-testnet",
163
- "chainId": 688689,
164
- "isMainnet": false
165
- },
166
- "error": null,
167
- "timestamp": "2026-06-12T00:00:00.000Z"
168
- }
169
- ```
170
-
171
- ---
172
-
173
- ## Environment Setup
174
-
175
- Copy `.env.example` if you need local configuration:
176
-
177
- ```bash
178
- cp .env.example .env
179
- ```
180
-
181
- Safe defaults:
182
-
183
- ```env
184
- WALLET_MODE=none
185
- WRITE_TOOLS_ENABLED=false
186
- ALLOW_UNLIMITED_APPROVAL=false
187
- ALLOW_LOCAL_X402_FETCH=false
188
- ```
189
-
190
- Read-only and preflight tools do not require a private key. Write tools require `WRITE_TOOLS_ENABLED=true` and a safe signer source.
191
-
192
- ### 💾 Agent Wallet Backups
193
- By default, testnet wallets created via `create_agent_wallet` are strictly **In-Memory** and will not persist after the MCP server restarts.
194
- To enable persistent local storage for your AI agent wallets, set the following environment variable:
195
- ```env
196
- WALLET_STORE_PATH=./.agents/wallets.json
197
- ```
198
- This will securely XOR-obfuscate and save the agent's private key to your local `.agents` folder (which is explicitly ignored by Git to prevent accidental leakage).
199
-
200
- ---
201
-
202
- ## MCP Tools: 27 Total
203
-
204
- SafeHands currently exposes **27 MCP tools**:
205
-
206
- - 17 legacy/core Web3 safety/execution tools
207
- - 3 managed testnet wallet tools
208
- - 7 branded SafeHands guardrail tools
209
-
210
- ### Branded SafeHands Guardrail Tools
211
-
212
- | Tool | Purpose |
213
- |---|---|
214
- | `safehands_preflight_check` | Policy-based ALLOW/WARN/BLOCK check before execution |
215
- | `safehands_safe_execute` | Guarded wrapper around payment, approval, swap, and x402 execution |
216
- | `safehands_wallet_health` | Checks whether an agent wallet is ready to act |
217
- | `safehands_x402_preflight` | Checks URL, payment amount, token, signer, and x402 safety before paying |
218
- | `safehands_risk_report` | Generates a human-readable risk report for demos and judges |
219
- | `explain_risk` | Converts policy results into plain-English explanations |
220
- | `token_registry_status` | Classifies token addresses as canonical, test, custom, unknown, or invalid |
221
-
222
- ### Core Safety and Execution Tools
223
-
224
- | Tool | Type | Purpose |
225
- |---|---|---|
226
- | `assess_risk` | Read / optional write | 5-dimension risk score |
227
- | `check_token_security` | Read | GoPlus token security profile |
228
- | `simulate_transaction` | Read | Dry-run transaction simulation |
229
- | `estimate_gas` | Read | Gas estimate and sufficiency check |
230
- | `execute_swap` | Write | FaroSwap/DODO swap with guardrails |
231
- | `send_payment` | Write | Native PHRS payment |
232
- | `approve_token` | Write | ERC-20 approval with unlimited-approval guard |
233
- | `get_token_price` | Read | Token price data |
234
- | `get_pool_info` | Read | DODO/FaroSwap pool and route info |
235
- | `get_gas_price` | Read | Current gas price |
236
- | `get_wallet_balance` | Read | Wallet balances |
237
- | `check_allowance` | Read | ERC-20 allowance check |
238
- | `get_transaction_status` | Read | Transaction status by hash |
239
- | `get_execution_history` | Read | Wallet transaction history |
240
- | `publish_risk_score` | Write | Publish score to RiskRegistry |
241
- | `query_risk_registry` | Read | Query on-chain risk score |
242
- | `x402_pay_and_fetch` | Write when HTTP 402 | Fetch x402 resources and pay only after a payment challenge |
243
-
244
- ### Managed Testnet Wallet Tools
245
-
246
- | Tool | Purpose |
247
- |---|---|
248
- | `create_agent_wallet` | Explicitly create a managed testnet wallet |
249
- | `get_agent_wallet` | Return public wallet metadata, never private key |
250
- | `get_agent_wallet_balance` | Check managed wallet balances |
251
-
252
- ---
253
-
254
- ## Policy Engine Behavior
255
-
256
- The reusable policy engine lives at:
257
-
258
- ```text
259
- src/lib/policy/actionPolicyEngine.ts
260
- ```
261
-
262
- Supported action types:
263
-
264
- ```text
265
- send_payment
266
- approve_token
267
- execute_swap
268
- x402_pay_and_fetch
269
- publish_risk_score
270
- custom_contract_call
271
- ```
272
-
273
- Key guardrails:
274
-
275
- - Block mainnet actions.
276
- - Block chain ID mismatch.
277
- - Block unlimited approvals by default.
278
- - Block SSRF-sensitive x402 URLs.
279
- - Block payment above configured limits.
280
- - Block x402 payment above `MAX_X402_PAYMENT_USDC`.
281
- - Block approvals above `MAX_APPROVAL_AMOUNT_USDC` unless consciously configured.
282
- - Warn when a token is custom, non-registry, or token-security provider is unavailable.
283
- - Require confirmation for medium-risk actions.
284
- - Allow low-risk Pharos Atlantic Testnet actions.
285
-
286
- ---
287
-
288
- ## x402 Behavior
289
-
290
- SafeHands has both x402 client and server behavior:
291
-
292
- ### Free endpoints
293
-
294
- - `GET /supported`
295
- - `GET /health`
296
-
297
- These do **not** require a user private key.
298
-
299
- ### Paid endpoints
300
-
301
- - `GET /assess-risk`
302
- - `GET /check-token-security`
303
- - `GET /simulate-transaction`
304
-
305
- Expected demo price: `0.001 USDC`.
306
-
307
- Client flow:
308
-
309
- 1. Fetch normally first.
310
- 2. If HTTP 200, return `paymentExecuted=false`.
311
- 3. If HTTP 402, run SafeHands x402 preflight.
312
- 4. Request signer only after HTTP 402.
313
- 5. Do not log or return signed payment payloads.
314
-
315
- ---
316
-
317
- ## Using SafeHands with Pharos Skill Engine
318
-
319
- SafeHands includes a Pharos Skill Engine adapter under:
320
-
321
- > **Note:** The canonical publishable Skill package is in `skill/`. The `examples/pharos-skill-engine/` folder is retained as an integration example.
322
-
323
- ```text
324
- examples/pharos-skill-engine/
325
- ├── SKILL.safehands.md
326
- ├── references/
327
- │ └── safehands.md
328
- └── assets/
329
- └── safehands/
330
- ├── policy-defaults.json
331
- └── example-actions.json
332
- ```
333
-
334
- The reference files teach the Skill Engine how to call SafeHands through terminal commands such as:
335
-
336
- ```bash
337
- npx safehands-pharos skill safehands_preflight_check --input-json '<json>'
338
- npx safehands-pharos skill safehands_x402_preflight --input-json '<json>'
339
- npx safehands-pharos skill safehands_wallet_health --input-json '{}'
340
- npx safehands-pharos skill token_registry_status --input-json '{"tokenAddress":"0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8"}'
341
- ```
342
-
343
- Use SafeHands before Pharos Skill Engine performs write actions. SafeHands complements the Skill Engine and should not be treated as a replacement.
344
-
345
- ---
346
-
347
- ## Security Guardrails
348
-
349
- SafeHands defaults to defensive behavior:
350
-
351
- - `WRITE_TOOLS_ENABLED=false` by default.
352
- - `WALLET_MODE=none` by default.
353
- - No wallet is created on install, import, or startup.
354
- - Managed wallets are created only through `create_agent_wallet`.
355
- - Private keys are never returned in MCP or CLI responses.
356
- - Private keys and payment proofs are not logged.
357
- - Unlimited approvals are blocked unless explicitly allowed.
358
- - SSRF-sensitive x402 URLs are blocked unless local testing is explicitly enabled.
359
- - Mainnet actions are blocked.
360
- - External API failures return structured errors rather than crashing tool calls.
361
-
362
- ---
363
-
364
- ## Demo
365
-
366
- Run:
367
-
368
- ```bash
369
- npm run demo
370
- ```
371
-
372
- or:
373
-
374
- ```bash
375
- npx safehands-pharos --demo
376
- ```
377
-
378
- The default demo is deterministic and non-destructive. It shows wallet health, allowed preflight, blocked approval, token registry status, x402 preflight, free x402 endpoint behavior, paid x402 without signer, SSRF blocking, write-tool blocking, and a human-readable risk explanation.
379
-
380
- ---
381
-
382
- ## Real Testnet Verification
383
-
384
- SafeHands includes live verification commands that test against real Pharos Atlantic Testnet infrastructure:
385
-
386
- | Command | What it does | Requires |
387
- |---------|-------------|----------|
388
- | `npm run test:rpc:live` | Reads chain ID, block number, optional wallet balance from live RPC | Network access |
389
- | `npm run test:live:safehands` | Runs 7 CLI safety checks against built dist (no broadcast) | Built dist |
390
- | `npm run test:x402:live` | Tests x402 free/paid endpoint behavior locally | Nothing |
391
- | `npm run test:dodo:live` | Tests DODO API route if `DODO_API_KEY` set; skips cleanly if not | `DODO_API_KEY` (optional) |
392
-
393
- **Important distinctions:**
394
-
395
- 1. **Live RPC checks** (`test:rpc`, `test:rpc:live`) connect to the real Pharos Atlantic Testnet RPC and read chain ID + block number.
396
- 2. **Live CLI checks** (`test:live:safehands`) run real CLI invocations against built dist, testing policy decisions deterministically.
397
- 3. **x402 behavior checks** (`test:x402:live`) use a **local test server** labeled `LOCAL_X402_SERVER_DOCS_BEHAVIOR_TEST`. They do not connect to a remote Pharos x402 endpoint.
398
- 4. **DODO checks** (`test:dodo:live`) performs live read-only DODO/FaroSwap checks when `DODO_API_KEY` is configured. The public API key can be provided through an environment variable. The key is not required for the normal deterministic demo. A missing key results in a clean skip. A live API pass does not automatically make router addresses docs-verified.
399
- 5. **Smoke tests** (`test:all`) are deterministic and do not require network connectivity (except DODO/RPC-dependent tools, which degrade gracefully).
400
- 6. **Address verification statuses** (DOCS_VERIFIED, DOCS_DEMO_NON_OFFICIAL, PROJECT_CONFIGURED) are sourced from `docs/reports/OFFICIAL_DOCS_ALIGNMENT_REPORT.md`.
401
- 7. **No real transactions are broadcast by default.** Write tools require explicit `WRITE_TOOLS_ENABLED=true`.
402
-
403
- ---
404
-
405
- ## Tests and Validation
406
-
407
- ```bash
408
- npm ci
409
- npm run build
410
- npx tsc -p tsconfig.all.json --pretty false
411
- npm run test:all # 43-point smoke test suite
412
- npm audit --omit=dev --audit-level=high
413
- npm pack --dry-run
414
- ```
415
-
416
- Live verification (requires network):
417
-
418
- ```bash
419
- npm run test:rpc # Basic RPC connectivity
420
- npm run test:rpc:live # Full live RPC verification with structured output
421
- npm run test:live:safehands # 7 CLI safety checks (read-only)
422
- npm run test:x402:live # x402 behavior checks (local server)
423
- npm run test:dodo:live # DODO API check (requires DODO_API_KEY, skips if missing)
424
- ```
425
-
426
- `test:rpc` and `test:rpc:live` depend on DNS/network access to Pharos RPC and may fail in restricted environments. This should be reported honestly as a provider/network limitation, not hidden.
427
-
428
- ---
429
-
430
- ## Known Limitations and TODOs
431
-
432
- - Testnet-only, not audited for mainnet use.
433
- - Managed wallet storage is testnet-grade unless a real KMS/Vault is integrated.
434
- - DODO/FaroSwap router addresses are project-configured unless official docs confirm them.
435
- - GoPlus/DODO/FaroSwap availability depends on external services and API limits.
436
- - `npm audit` for production dependencies is clean; full dev audit may report dev-only dependency issues depending on upstream packages.
437
- - Formal unit tests with mocked RPC/DODO/GoPlus providers would improve long-term maintainability.
438
-
439
- ---
440
-
441
- ## Hackathon Summary
442
-
443
- **Project name:** SafeHands-Pharos: Transaction Safety Firewall for AI Agents
444
-
445
- **Short description:** SafeHands-Pharos is a Pharos Skill Engine-compatible MCP package that protects AI agents before they execute payments, token approvals, swaps, or x402 paid requests by returning ALLOW, WARN, or BLOCK decisions with human-readable risk explanations.
1
+ <p align="center">
2
+ <img src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white" />
3
+ <img src="https://img.shields.io/badge/MCP_Skill-000000?style=for-the-badge" />
4
+ <img src="https://img.shields.io/badge/Pharos_Atlantic-688689-blueviolet?style=for-the-badge" />
5
+ <img src="https://img.shields.io/badge/Tools-27-orange?style=for-the-badge" />
6
+ <img src="https://img.shields.io/badge/Testnet_Only-SAFE-blue?style=for-the-badge" />
7
+ </p>
8
+
9
+ # SafeHands-Pharos Transaction Safety Firewall for AI Agents
10
+
11
+ SafeHands is a **Pharos Skill Engine-compatible MCP package** that acts as a safety layer before your AI agent executes any on-chain action — payments, swaps, token approvals, or x402 paid requests.
12
+
13
+ Every action goes through a preflight check first:
14
+
15
+ ```
16
+ Agent wants to act
17
+
18
+ safehands_preflight_check
19
+
20
+ ALLOW → safe, proceed
21
+ WARN → proceed with caution
22
+ BLOCK → stop, reason explained
23
+ ```
24
+
25
+ > **Testnet only.** SafeHands targets Pharos Atlantic Testnet (Chain ID 688689). Not audited for mainnet use.
26
+
27
+ ---
28
+
29
+ ## Getting Started
30
+
31
+ ### Install via Pharos Skill Engine
32
+
33
+ ```bash
34
+ npx skills add SZtch/safehands-pharos
35
+ ```
36
+
37
+ ### Connect to Claude Desktop
38
+
39
+ Add to `claude_desktop_config.json`:
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "safehands": {
45
+ "command": "npx",
46
+ "args": ["safehands-pharos"]
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ Restart Claude Desktop — SafeHands tools appear automatically in every conversation.
53
+
54
+ ### Connect to Anvita Flow
55
+
56
+ Add as MCP server in Anvita Flow settings:
57
+
58
+ ```json
59
+ {
60
+ "command": "npx",
61
+ "args": ["safehands-pharos"]
62
+ }
63
+ ```
64
+
65
+ ### First-time setup
66
+
67
+ ```bash
68
+ npx safehands-pharos init
69
+ ```
70
+
71
+ Interactive wizard that configures your `.env` — wallet mode, spend limits, write gates.
72
+
73
+ ### Run the demo
74
+
75
+ ```bash
76
+ npx safehands-pharos --demo
77
+ ```
78
+
79
+ Non-destructive demo: shows ALLOW, BLOCK, wallet health, token registry, x402 preflight, and risk report — no real transactions.
80
+
81
+ ---
82
+
83
+ ## Start with These 3 Tools
84
+
85
+ | Goal | Tool |
86
+ |------|------|
87
+ | Check if an action is safe | `safehands_preflight_check` |
88
+ | Check wallet / signer readiness | `safehands_wallet_health` |
89
+ | Execute with built-in safety gate | `safehands_safe_execute` |
90
+
91
+ ---
92
+
93
+ ## Calling Tools from the CLI
94
+
95
+ ```bash
96
+ # Short form (recommended)
97
+ npx safehands-pharos skill <tool> '<json>'
98
+
99
+ # With flag
100
+ npx safehands-pharos skill <tool> -i '<json>'
101
+
102
+ # Explicit flag
103
+ npx safehands-pharos skill <tool> --input-json '<json>'
104
+ ```
105
+
106
+ Examples:
107
+
108
+ ```bash
109
+ # Preflight check before a swap
110
+ npx safehands-pharos skill safehands_preflight_check \
111
+ '{"actionType":"execute_swap","tokenIn":"PHRS","tokenOut":"USDC","amount":"0.01","chainId":688689,"isMainnet":false}'
112
+
113
+ # Check wallet balance
114
+ npx safehands-pharos skill get_wallet_balance \
115
+ '{"walletAddress":"0xYourWallet"}'
116
+
117
+ # Assess risk score
118
+ npx safehands-pharos skill assess_risk \
119
+ '{"action":"swap","tokenIn":"PHRS","tokenOut":"USDC","amount":"0.01","walletAddress":"0xYourWallet"}'
120
+
121
+ # Classify a token address
122
+ npx safehands-pharos skill token_registry_status \
123
+ '{"tokenAddress":"0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8"}'
124
+ ```
125
+
126
+ ---
127
+
128
+ ## All 27 Tools
129
+
130
+ All tools return the same response envelope:
131
+
132
+ ```json
133
+ {
134
+ "success": true,
135
+ "data": { ... },
136
+ "error": null,
137
+ "timestamp": "2026-06-13T00:00:00.000Z"
138
+ }
139
+ ```
140
+
141
+ On failure: `success: false`, `data: null`, `error: { code, message, retryable }`.
142
+
143
+ ### SafeHands Guardrail Tools
144
+
145
+ | Tool | What it does | CLI |
146
+ |------|-------------|-----|
147
+ | `safehands_preflight_check` | ALLOW / WARN / BLOCK before any action | ✓ |
148
+ | `safehands_safe_execute` | Preflight + execute in one call | ✓ |
149
+ | `safehands_wallet_health` | Wallet, signer, gas, x402 readiness | ✓ |
150
+ | `safehands_x402_preflight` | URL safety + payment check before x402 | ✓ |
151
+ | `safehands_risk_report` | Human-readable risk summary | ✓ |
152
+ | `explain_risk` | Translate ALLOW/WARN/BLOCK into plain English | ✓ |
153
+ | `token_registry_status` | Canonical / custom / unknown token check | ✓ |
154
+
155
+ ### Safety & Analysis Tools
156
+
157
+ | Tool | What it does | CLI |
158
+ |------|-------------|-----|
159
+ | `assess_risk` | 5-dimension risk score (0–100) | ✓ |
160
+ | `check_token_security` | GoPlus token security profile | ✓ |
161
+ | `simulate_transaction` | Dry-run before broadcasting | ✓ |
162
+ | `estimate_gas` | Gas estimate + sufficiency check | ✓ |
163
+ | `check_allowance` | ERC-20 allowance check | MCP |
164
+
165
+ ### Market & Chain Data
166
+
167
+ | Tool | What it does | CLI |
168
+ |------|-------------|-----|
169
+ | `get_wallet_balance` | PHRS / USDC / USDT balances | ✓ |
170
+ | `get_token_price` | Token price via DODO | ✓ |
171
+ | `get_gas_price` | Current network gas price | MCP |
172
+ | `get_pool_info` | FaroSwap / DODO pool info | MCP |
173
+ | `get_transaction_status` | TX status by hash | ✓ |
174
+ | `get_execution_history` | Wallet transfer history (ERC-20 + native) | MCP |
175
+
176
+ ### Write Tools *(require `WRITE_TOOLS_ENABLED=true`)*
177
+
178
+ | Tool | What it does | CLI |
179
+ |------|-------------|-----|
180
+ | `execute_swap` | Swap tokens via FaroSwap / DODO | MCP |
181
+ | `send_payment` | Send native PHRS | MCP |
182
+ | `approve_token` | ERC-20 approval (unlimited blocked by default) | MCP |
183
+ | `publish_risk_score` | Publish risk score to RiskRegistry contract | MCP |
184
+ | `x402_pay_and_fetch` | Fetch x402 resource, pay only after HTTP 402 | MCP |
185
+
186
+ ### Risk Registry
187
+
188
+ | Tool | What it does | CLI |
189
+ |------|-------------|-----|
190
+ | `query_risk_registry` | Read on-chain risk score | |
191
+
192
+ ### Managed Wallet Tools
193
+
194
+ | Tool | What it does | CLI |
195
+ |------|-------------|-----|
196
+ | `create_agent_wallet` | Create testnet wallet (AES-256-GCM encrypted) | ✓ |
197
+ | `get_agent_wallet` | Wallet address + metadata (no private key) | ✓ |
198
+ | `get_agent_wallet_balance` | Managed wallet balances | |
199
+
200
+ > **CLI** = callable via `npx safehands-pharos skill <tool> '<json>'`
201
+ > **MCP** = available via Claude Desktop / Anvita Flow only
202
+
203
+ ---
204
+
205
+ ## Configuration
206
+
207
+ Copy the example file:
208
+
209
+ ```bash
210
+ cp .env.example .env
211
+ ```
212
+
213
+ Key settings:
214
+
215
+ ```env
216
+ # Wallet mode
217
+ WALLET_MODE=none # none | env | managed-testnet
218
+ PRIVATE_KEY= # required when WALLET_MODE=env
219
+ WALLET_STORE_PATH= # optional: persist managed wallets to disk
220
+
221
+ # Write gates (all off by default)
222
+ WRITE_TOOLS_ENABLED=false
223
+ ALLOW_UNLIMITED_APPROVAL=false
224
+
225
+ # Spend limits
226
+ MAX_TX_AMOUNT_PHRS=0.1 # max PHRS per transaction
227
+ MAX_DAILY_SPEND_USD=10 # daily cap across all wallets
228
+ PHRS_USD_PRICE=1.0 # used for daily spend accounting
229
+
230
+ # DODO API (required for swaps and price data)
231
+ DODO_API_KEY=
232
+ ```
233
+
234
+ ### Wallet modes explained
235
+
236
+ | Mode | How it works |
237
+ |------|-------------|
238
+ | `none` | No signer read-only tools only (safe default) |
239
+ | `env` | Reads `PRIVATE_KEY` from `.env` |
240
+ | `managed-testnet` | Uses wallet created via `create_agent_wallet` |
241
+
242
+ ### Persistent managed wallets
243
+
244
+ By default, wallets created with `create_agent_wallet` are in-memory and lost on restart. To persist them:
245
+
246
+ ```env
247
+ WALLET_STORE_PATH=./.agents/wallets.json
248
+ WALLET_ENCRYPTION_KEY=your-strong-secret
249
+ ```
250
+
251
+ Private keys are AES-256-GCM encrypted on disk. The `.agents/` folder is gitignored.
252
+
253
+ ---
254
+
255
+ ## Security Defaults
256
+
257
+ SafeHands ships safe by default — nothing is enabled without explicit opt-in:
258
+
259
+ - `WRITE_TOOLS_ENABLED=false` — no on-chain writes without opt-in
260
+ - `WALLET_MODE=none` — no signer loaded on startup
261
+ - Unlimited token approvals blocked
262
+ - Mainnet actions blocked
263
+ - SSRF-sensitive x402 URLs blocked
264
+ - Private keys never returned in responses or logs
265
+ - Daily spend cap enforced in-memory per wallet
266
+
267
+ ---
268
+
269
+ ## Why AI Agents Need This
270
+
271
+ Generic Web3 tools answer: *"Can this transaction be sent?"*
272
+ SafeHands answers: **"Should this action be allowed at all?"**
273
+
274
+ | Risk | What goes wrong | SafeHands guardrail |
275
+ |------|----------------|---------------------|
276
+ | Unlimited approval | Agent approves malicious spender forever | Blocked by default |
277
+ | Wrong chain | Agent signs on mainnet | Blocked |
278
+ | Risky x402 URL | Agent pays a localhost/private IP | Blocked |
279
+ | Overspending | Agent drains wallet | Daily cap enforced |
280
+ | Unknown token | Agent swaps unverified token | Warns or requires review |
281
+ | Missing signer | Agent tries write without wallet | Structured error returned |
282
+
283
+ ---
284
+
285
+ ## x402 Support
286
+
287
+ SafeHands acts as both an x402 client and server.
288
+
289
+ **Client** (`x402_pay_and_fetch`): Fetches a resource normally first. If the server returns HTTP 402, SafeHands runs a preflight check, requests the signer, pays, and retries — all in one tool call. Payment proofs are never logged.
290
+
291
+ **Server** (`npm run x402-server`): Exposes paid endpoints:
292
+
293
+ | Endpoint | Type | Price |
294
+ |----------|------|-------|
295
+ | `GET /supported` | Free | — |
296
+ | `GET /health` | Free | — |
297
+ | `GET /assess-risk` | Paid | 0.001 USDC |
298
+ | `GET /check-token-security` | Paid | 0.001 USDC |
299
+ | `GET /simulate-transaction` | Paid | 0.001 USDC |
300
+
301
+ ---
302
+
303
+ ## Network Info
304
+
305
+ | Item | Value |
306
+ |------|-------|
307
+ | Chain ID | `688689` |
308
+ | RPC | `https://atlantic.dplabs-internal.com` |
309
+ | Explorer | `https://atlantic.pharosscan.xyz` |
310
+ | USDC | `0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8` |
311
+ | RiskRegistry | `0x61962a6c812ee9f57b207e1ea47c19ae70bb7141` |
312
+
313
+ ---
314
+
315
+ ## Testing
316
+
317
+ ```bash
318
+ npm run build
319
+ npm run test:all # 43-point smoke test (no network needed)
320
+ npm run test:rpc:live # live RPC connectivity check
321
+ npm run test:live:safehands # 7 CLI safety checks against built dist
322
+ npm run test:dodo:live # DODO API check (skips if DODO_API_KEY not set)
323
+ ```
324
+
325
+ ---
326
+
327
+ ## Known Limitations
328
+
329
+ - Testnet-only — not audited for mainnet
330
+ - Managed wallet encryption is AES-256-GCM but not KMS/Vault grade
331
+ - `get_token_price` and swap routing require a DODO API key
332
+ - GoPlus token security does not support Pharos testnet (Chain 688689) — `check_token_security` returns a clear error
333
+ - DODO reverse routes (e.g. USDT → PHRS) have no liquidity on testnet