safehands-pharos 1.2.0 β 1.2.4
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.
- package/.env.example +26 -0
- package/README.md +311 -350
- package/contracts/RiskRegistry.json +75 -1
- package/contracts/RiskRegistry.sol +29 -1
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +91 -0
- package/dist/cli.js.map +1 -0
- package/dist/demo.d.ts +2 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +172 -0
- package/dist/demo.js.map +1 -0
- package/dist/index.js +181 -169
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +2 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +66 -0
- package/dist/init.js.map +1 -0
- package/dist/lib/constants.d.ts +122 -7
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +139 -13
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/dodoApi.d.ts +14 -0
- package/dist/lib/dodoApi.d.ts.map +1 -1
- package/dist/lib/dodoApi.js +78 -22
- package/dist/lib/dodoApi.js.map +1 -1
- package/dist/lib/http.d.ts +15 -0
- package/dist/lib/http.d.ts.map +1 -0
- package/dist/lib/http.js +119 -0
- package/dist/lib/http.js.map +1 -0
- package/dist/lib/pharosClient.d.ts +4 -3
- package/dist/lib/pharosClient.d.ts.map +1 -1
- package/dist/lib/pharosClient.js +8 -5
- package/dist/lib/pharosClient.js.map +1 -1
- package/dist/lib/policy/actionPolicyEngine.d.ts +54 -0
- package/dist/lib/policy/actionPolicyEngine.d.ts.map +1 -0
- package/dist/lib/policy/actionPolicyEngine.js +213 -0
- package/dist/lib/policy/actionPolicyEngine.js.map +1 -0
- package/dist/lib/signer/index.d.ts +25 -0
- package/dist/lib/signer/index.d.ts.map +1 -0
- package/dist/lib/signer/index.js +90 -0
- package/dist/lib/signer/index.js.map +1 -0
- package/dist/lib/testDodoLive.d.ts +2 -0
- package/dist/lib/testDodoLive.d.ts.map +1 -0
- package/dist/lib/testDodoLive.js +105 -0
- package/dist/lib/testDodoLive.js.map +1 -0
- package/dist/lib/testLiveSafehands.d.ts +2 -0
- package/dist/lib/testLiveSafehands.d.ts.map +1 -0
- package/dist/lib/testLiveSafehands.js +93 -0
- package/dist/lib/testLiveSafehands.js.map +1 -0
- package/dist/lib/testRpcLive.d.ts +2 -0
- package/dist/lib/testRpcLive.d.ts.map +1 -0
- package/dist/lib/testRpcLive.js +89 -0
- package/dist/lib/testRpcLive.js.map +1 -0
- package/dist/lib/testTools.js +363 -354
- package/dist/lib/testTools.js.map +1 -1
- package/dist/lib/testX402Live.d.ts +2 -0
- package/dist/lib/testX402Live.d.ts.map +1 -0
- package/dist/lib/testX402Live.js +160 -0
- package/dist/lib/testX402Live.js.map +1 -0
- package/dist/lib/toolResponse.d.ts +26 -0
- package/dist/lib/toolResponse.d.ts.map +1 -0
- package/dist/lib/toolResponse.js +54 -0
- package/dist/lib/toolResponse.js.map +1 -0
- package/dist/lib/wallet/index.d.ts +19 -0
- package/dist/lib/wallet/index.d.ts.map +1 -0
- package/dist/lib/wallet/index.js +71 -0
- package/dist/lib/wallet/index.js.map +1 -0
- package/dist/tools/approveToken.d.ts +19 -20
- package/dist/tools/approveToken.d.ts.map +1 -1
- package/dist/tools/approveToken.js +44 -21
- package/dist/tools/approveToken.js.map +1 -1
- package/dist/tools/assessRisk.d.ts +22 -9
- package/dist/tools/assessRisk.d.ts.map +1 -1
- package/dist/tools/assessRisk.js +32 -9
- package/dist/tools/assessRisk.js.map +1 -1
- package/dist/tools/checkAllowance.d.ts +6 -6
- package/dist/tools/checkTokenSecurity.d.ts +9 -16
- package/dist/tools/checkTokenSecurity.d.ts.map +1 -1
- package/dist/tools/checkTokenSecurity.js +17 -22
- package/dist/tools/checkTokenSecurity.js.map +1 -1
- package/dist/tools/createAgentWallet.d.ts +27 -0
- package/dist/tools/createAgentWallet.d.ts.map +1 -0
- package/dist/tools/createAgentWallet.js +60 -0
- package/dist/tools/createAgentWallet.js.map +1 -0
- package/dist/tools/estimateGas.d.ts +31 -21
- package/dist/tools/estimateGas.d.ts.map +1 -1
- package/dist/tools/estimateGas.js +91 -95
- package/dist/tools/estimateGas.js.map +1 -1
- package/dist/tools/executeSwap.d.ts +13 -29
- package/dist/tools/executeSwap.d.ts.map +1 -1
- package/dist/tools/executeSwap.js +68 -46
- package/dist/tools/executeSwap.js.map +1 -1
- package/dist/tools/explainRisk.d.ts +30 -0
- package/dist/tools/explainRisk.d.ts.map +1 -0
- package/dist/tools/explainRisk.js +33 -0
- package/dist/tools/explainRisk.js.map +1 -0
- package/dist/tools/getAgentWallet.d.ts +22 -0
- package/dist/tools/getAgentWallet.d.ts.map +1 -0
- package/dist/tools/getAgentWallet.js +28 -0
- package/dist/tools/getAgentWallet.js.map +1 -0
- package/dist/tools/getAgentWalletBalance.d.ts +12 -0
- package/dist/tools/getAgentWalletBalance.d.ts.map +1 -0
- package/dist/tools/getAgentWalletBalance.js +71 -0
- package/dist/tools/getAgentWalletBalance.js.map +1 -0
- package/dist/tools/getExecutionHistory.d.ts +4 -4
- package/dist/tools/getGasPrice.d.ts +26 -8
- package/dist/tools/getGasPrice.d.ts.map +1 -1
- package/dist/tools/getGasPrice.js +43 -35
- package/dist/tools/getGasPrice.js.map +1 -1
- package/dist/tools/getPoolInfo.d.ts +47 -59
- package/dist/tools/getPoolInfo.d.ts.map +1 -1
- package/dist/tools/getPoolInfo.js +96 -57
- package/dist/tools/getPoolInfo.js.map +1 -1
- package/dist/tools/getTokenPrice.d.ts +95 -9
- package/dist/tools/getTokenPrice.d.ts.map +1 -1
- package/dist/tools/getTokenPrice.js +95 -56
- package/dist/tools/getTokenPrice.js.map +1 -1
- package/dist/tools/getWalletBalance.d.ts +40 -11
- package/dist/tools/getWalletBalance.d.ts.map +1 -1
- package/dist/tools/getWalletBalance.js +64 -47
- package/dist/tools/getWalletBalance.js.map +1 -1
- package/dist/tools/publishRiskScore.d.ts +12 -10
- package/dist/tools/publishRiskScore.d.ts.map +1 -1
- package/dist/tools/publishRiskScore.js +33 -19
- package/dist/tools/publishRiskScore.js.map +1 -1
- package/dist/tools/queryRiskRegistry.d.ts +3 -3
- package/dist/tools/safehandsPreflightCheck.d.ts +78 -0
- package/dist/tools/safehandsPreflightCheck.d.ts.map +1 -0
- package/dist/tools/safehandsPreflightCheck.js +48 -0
- package/dist/tools/safehandsPreflightCheck.js.map +1 -0
- package/dist/tools/safehandsRiskReport.d.ts +82 -0
- package/dist/tools/safehandsRiskReport.d.ts.map +1 -0
- package/dist/tools/safehandsRiskReport.js +29 -0
- package/dist/tools/safehandsRiskReport.js.map +1 -0
- package/dist/tools/safehandsSafeExecute.d.ts +21 -0
- package/dist/tools/safehandsSafeExecute.d.ts.map +1 -0
- package/dist/tools/safehandsSafeExecute.js +76 -0
- package/dist/tools/safehandsSafeExecute.js.map +1 -0
- package/dist/tools/safehandsWalletHealth.d.ts +15 -0
- package/dist/tools/safehandsWalletHealth.d.ts.map +1 -0
- package/dist/tools/safehandsWalletHealth.js +104 -0
- package/dist/tools/safehandsWalletHealth.js.map +1 -0
- package/dist/tools/safehandsX402Preflight.d.ts +27 -0
- package/dist/tools/safehandsX402Preflight.d.ts.map +1 -0
- package/dist/tools/safehandsX402Preflight.js +66 -0
- package/dist/tools/safehandsX402Preflight.js.map +1 -0
- package/dist/tools/sendPayment.d.ts +13 -35
- package/dist/tools/sendPayment.d.ts.map +1 -1
- package/dist/tools/sendPayment.js +53 -47
- package/dist/tools/sendPayment.js.map +1 -1
- package/dist/tools/simulateTransaction.d.ts +4 -4
- package/dist/tools/tokenRegistryStatus.d.ts +27 -0
- package/dist/tools/tokenRegistryStatus.d.ts.map +1 -0
- package/dist/tools/tokenRegistryStatus.js +97 -0
- package/dist/tools/tokenRegistryStatus.js.map +1 -0
- package/dist/tools/x402PayAndFetch.d.ts +40 -16
- package/dist/tools/x402PayAndFetch.d.ts.map +1 -1
- package/dist/tools/x402PayAndFetch.js +115 -47
- package/dist/tools/x402PayAndFetch.js.map +1 -1
- package/dist/x402Server.js +149 -115
- package/dist/x402Server.js.map +1 -1
- package/examples/pharos-skill-engine/SKILL.safehands.md +85 -0
- package/examples/pharos-skill-engine/assets/safehands/example-actions.json +49 -0
- package/examples/pharos-skill-engine/assets/safehands/policy-defaults.json +11 -0
- package/examples/pharos-skill-engine/references/safehands.md +345 -0
- package/examples/scenario-hack.ts +38 -0
- package/package.json +19 -5
- package/skill/SKILL.md +127 -0
- package/skill/assets/safehands/example-actions.json +49 -0
- package/skill/assets/safehands/policy-defaults.json +11 -0
- package/skill/references/safehands.md +345 -0
- package/.agents/skill/safehands/SKILL.md +0 -200
- package/.agents/skill/safehands/assets/networks.json +0 -24
- package/.agents/skill/safehands/assets/tokens.json +0 -60
package/README.md
CHANGED
|
@@ -1,481 +1,442 @@
|
|
|
1
1
|
<p align="center">
|
|
2
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
|
|
3
|
+
<img src="https://img.shields.io/badge/MCP_Skill-000000?style=for-the-badge" />
|
|
4
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-
|
|
6
|
-
<img src="https://img.shields.io/badge/
|
|
7
|
-
<img src="https://img.shields.io/badge/Security-Self--Audited-blue?style=for-the-badge" />
|
|
8
|
-
<img src="https://img.shields.io/npm/v/safehands-pharos?style=for-the-badge&logo=npm&logoColor=white&color=CB3837" />
|
|
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" />
|
|
9
7
|
</p>
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
# SafeHands-Pharos: Transaction Safety Firewall for AI Agents
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
<strong>The execution safety layer for Pharos agents.</strong><br/>
|
|
15
|
-
<em>"Agents that execute without thinking are dangerous. SafeHands executes anything on Pharos β but never blindly."</em>
|
|
16
|
-
</p>
|
|
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.
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<a href="https://www.npmjs.com/package/safehands-pharos">npm</a>
|
|
28
|
-
</p>
|
|
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.
|
|
29
22
|
|
|
30
23
|
---
|
|
31
24
|
|
|
32
|
-
##
|
|
25
|
+
## Why AI Agents Need Transaction Safety Middleware
|
|
33
26
|
|
|
34
|
-
|
|
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:
|
|
35
28
|
|
|
36
|
-
|
|
29
|
+
> **Should this action be allowed at all?**
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|------|----------------|
|
|
40
|
-
| **Slippage attacks** | Agent swaps at a terrible price β thin liquidity, high impact, value lost |
|
|
41
|
-
| **Blind transfers** | Agent sends to a wrong, empty, or flagged address β funds gone |
|
|
42
|
-
| **Failed transactions** | Agent wastes gas on transactions destined to revert β no pre-check |
|
|
43
|
-
| **No cross-agent trust** | Agent B interacts with a wallet that Agent A already flagged as dangerous |
|
|
31
|
+
Common agent-execution risks:
|
|
44
32
|
|
|
45
|
-
|
|
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 |
|
|
46
41
|
|
|
47
42
|
---
|
|
48
43
|
|
|
49
|
-
##
|
|
44
|
+
## What SafeHands Is, and What It Is Not
|
|
50
45
|
|
|
51
|
-
SafeHands is
|
|
46
|
+
SafeHands is a **Transaction Safety Firewall / Guardrail Skill** for Pharos agents. SafeHands is a guardrail layer before execution, not a generic Web3 toolbox.
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
β π‘οΈ SafeHands Layer β
|
|
62
|
-
β β
|
|
63
|
-
β 1. assess_risk β Score 12/100, proceed β
|
|
64
|
-
β 2. simulate_transaction β Would succeed, 166 USDC β
|
|
65
|
-
β 3. estimate_gas β 0.004 PHRS, sufficient β
|
|
66
|
-
β 4. execute_swap β β
TX confirmed β
|
|
67
|
-
β β
|
|
68
|
-
β Score > 80? β π« BLOCKED automatically β
|
|
69
|
-
β Score < 80? β β
PROCEED with full transparency β
|
|
70
|
-
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
71
|
-
β
|
|
72
|
-
βΌ
|
|
73
|
-
Pharos Atlantic
|
|
74
|
-
(on-chain)
|
|
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
|
|
75
56
|
```
|
|
76
57
|
|
|
77
|
-
|
|
58
|
+
### Difference from Reputation Systems
|
|
78
59
|
|
|
79
|
-
|
|
60
|
+
SafeHands is also different from pure reputation systems:
|
|
80
61
|
|
|
81
|
-
|
|
|
62
|
+
| System type | Main question |
|
|
82
63
|
|---|---|
|
|
83
|
-
| Agent
|
|
84
|
-
|
|
|
85
|
-
| Agent wastes gas on transaction that reverts | `simulate_transaction` catches revert reason before execution |
|
|
86
|
-
| Agent B interacts with wallet Agent A flagged dangerous | `query_risk_registry` returns score 92 β interaction refused |
|
|
64
|
+
| Agent reputation, such as AgentLeash-style trust systems | "Can I trust this agent?" |
|
|
65
|
+
| SafeHands | "Can I trust this action right now?" |
|
|
87
66
|
|
|
88
|
-
|
|
67
|
+
SafeHands can use reputation signals, but its core purpose is **action-level risk gating**.
|
|
89
68
|
|
|
90
|
-
|
|
91
|
-
|-----------|--------|----------------|
|
|
92
|
-
| Liquidity Risk | 25% | DODO route available? Price impact? |
|
|
93
|
-
| Slippage Risk | 25% | Estimated slippage from DODO quote |
|
|
94
|
-
| Counterparty Risk | 20% | Address valid? Zero address? Self-send? |
|
|
95
|
-
| Balance Risk | 15% | Sufficient balance + gas buffer? |
|
|
96
|
-
| Market Condition Risk | 15% | Block times, gas price, chain health |
|
|
69
|
+
---
|
|
97
70
|
|
|
98
|
-
|
|
99
|
-
- `0β30` β β
**proceed**
|
|
100
|
-
- `31β60` β β οΈ **caution** β review recommended
|
|
101
|
-
- `61β80` β π **high** β agent warned
|
|
102
|
-
- `81β100` β π« **block** β execution prevented
|
|
71
|
+
## Pharos Atlantic Testnet Context
|
|
103
72
|
|
|
104
|
-
|
|
73
|
+
Default project configuration:
|
|
105
74
|
|
|
106
|
-
|
|
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` |
|
|
107
85
|
|
|
108
|
-
|
|
86
|
+
The project treats router and pool addresses that are not directly verified from official docs as **project-configured**, not universal canonical values.
|
|
109
87
|
|
|
110
|
-
|
|
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.
|
|
111
91
|
|
|
112
|
-
|
|
92
|
+
---
|
|
113
93
|
|
|
114
|
-
|
|
115
|
-
|---|------|------|-------------|
|
|
116
|
-
| 1 | `assess_risk` | Read+Write | 5-dimension risk score (0β100). Auto-publishes to on-chain RiskRegistry when `privateKey` provided. |
|
|
117
|
-
| 2 | `check_token_security` | Read | Check token security, honeypot risk, buy/sell tax, and mint privileges via GoPlus Security API. |
|
|
118
|
-
| 3 | `simulate_transaction` | Read | Dry run via `eth_call` β zero gas. Returns expected output, gas estimate, revert reasons. |
|
|
119
|
-
| 4 | `estimate_gas` | Read | Gas cost in PHRS and USD. Checks wallet sufficiency before execution. |
|
|
94
|
+
## Official Pharos Skill Engine Alignment
|
|
120
95
|
|
|
121
|
-
|
|
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.
|
|
122
102
|
|
|
123
|
-
|
|
124
|
-
|---|------|------|-------------|
|
|
125
|
-
| 5 | `execute_swap` | Write | Swap via FaroSwap (DODO) with built-in risk gate. Blocks if score > 80. |
|
|
126
|
-
| 6 | `send_payment` | Write | Native PHRS transfer with address validation, balance checks, exposure warnings. |
|
|
127
|
-
| 7 | `approve_token` | Write | ERC-20 approval for DODO router. Supports exact amount or `"max"`. |
|
|
103
|
+
---
|
|
128
104
|
|
|
129
|
-
|
|
105
|
+
## Supported Usage Modes
|
|
130
106
|
|
|
131
|
-
|
|
132
|
-
|---|------|------|-------------|
|
|
133
|
-
| 8 | `get_token_price` | Read | Real-time PHRS/USDC/USDT price from DODO liquidity quotes. |
|
|
134
|
-
| 9 | `get_pool_info` | Read | DODO pool data for any token pair β price ratio, impact, fees. |
|
|
135
|
-
| 10 | `get_gas_price` | Read | Current gas price with trend classification and cost estimates. |
|
|
107
|
+
SafeHands supports three usage modes:
|
|
136
108
|
|
|
137
|
-
|
|
109
|
+
1. **MCP server usage** for Claude Desktop, Anvita Flow, and other MCP-compatible clients.
|
|
110
|
+
2. **npm/npx CLI usage** for terminal and CI checks.
|
|
111
|
+
3. **Pharos Skill Engine reference-file usage** through the `skill/` package.
|
|
138
112
|
|
|
139
|
-
|
|
140
|
-
|---|------|------|-------------|
|
|
141
|
-
| 11 | `get_wallet_balance` | Read | PHRS, USDC, USDT balances with total USD estimate. |
|
|
142
|
-
| 12 | `check_allowance` | Read | ERC-20 allowance for DODO router. Reports if approval needed. |
|
|
143
|
-
| 13 | `get_transaction_status` | Read | TX lookup by hash β status, block, gas, explorer link. |
|
|
144
|
-
| 14 | `get_execution_history` | Read | On-chain audit trail. Categorizes swaps, transfers, other. |
|
|
113
|
+
---
|
|
145
114
|
|
|
146
|
-
|
|
115
|
+
## Quick Start
|
|
147
116
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
117
|
+
```bash
|
|
118
|
+
npm install
|
|
119
|
+
npm run build
|
|
120
|
+
npm run test:all
|
|
121
|
+
npm run demo
|
|
122
|
+
```
|
|
152
123
|
|
|
153
|
-
|
|
124
|
+
Run as MCP server:
|
|
154
125
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
126
|
+
```bash
|
|
127
|
+
npx safehands-pharos
|
|
128
|
+
```
|
|
158
129
|
|
|
159
|
-
|
|
130
|
+
Show CLI help:
|
|
160
131
|
|
|
161
|
-
|
|
132
|
+
```bash
|
|
133
|
+
npx safehands-pharos --help
|
|
134
|
+
```
|
|
162
135
|
|
|
163
|
-
|
|
136
|
+
Run deterministic demo:
|
|
164
137
|
|
|
165
|
-
|
|
138
|
+
```bash
|
|
139
|
+
npx safehands-pharos --demo
|
|
140
|
+
```
|
|
166
141
|
|
|
167
|
-
|
|
142
|
+
Run a Skill Engine-compatible CLI call:
|
|
168
143
|
|
|
144
|
+
```bash
|
|
145
|
+
npx safehands-pharos skill safehands_preflight_check --input-json '{"actionType":"approve_token","chainId":688689,"isMainnet":false,"approvalAmount":"max","spender":"0x0000000000000000000000000000000000000001"}'
|
|
169
146
|
```
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
147
|
+
|
|
148
|
+
The CLI returns the standard response envelope:
|
|
149
|
+
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"success": true,
|
|
153
|
+
"data": {
|
|
154
|
+
"decision": "BLOCK",
|
|
155
|
+
"riskLevel": "HIGH",
|
|
156
|
+
"safeToExecute": false,
|
|
157
|
+
"reasons": ["Unlimited approval requested."],
|
|
158
|
+
"requiredActions": ["Use a limited approval amount."],
|
|
159
|
+
"environment": "atlantic-testnet",
|
|
160
|
+
"chainId": 688689,
|
|
161
|
+
"isMainnet": false
|
|
162
|
+
},
|
|
163
|
+
"error": null,
|
|
164
|
+
"timestamp": "2026-06-12T00:00:00.000Z"
|
|
165
|
+
}
|
|
179
166
|
```
|
|
180
167
|
|
|
181
|
-
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Environment Setup
|
|
182
171
|
|
|
183
|
-
|
|
172
|
+
Copy `.env.example` if you need local configuration:
|
|
184
173
|
|
|
174
|
+
```bash
|
|
175
|
+
cp .env.example .env
|
|
185
176
|
```
|
|
186
|
-
Agent receives: "Is this wallet safe to interact with?"
|
|
187
177
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
178
|
+
Safe defaults:
|
|
179
|
+
|
|
180
|
+
```env
|
|
181
|
+
WALLET_MODE=none
|
|
182
|
+
WRITE_TOOLS_ENABLED=false
|
|
183
|
+
ALLOW_UNLIMITED_APPROVAL=false
|
|
184
|
+
ALLOW_LOCAL_X402_FETCH=false
|
|
191
185
|
```
|
|
192
186
|
|
|
193
|
-
|
|
187
|
+
Read-only and preflight tools do not require a private key. Write tools require `WRITE_TOOLS_ENABLED=true` and a safe signer source.
|
|
194
188
|
|
|
195
|
-
|
|
189
|
+
### πΎ Agent Wallet Backups
|
|
190
|
+
By default, testnet wallets created via `create_agent_wallet` are strictly **In-Memory** and will not persist after the MCP server restarts.
|
|
191
|
+
To enable persistent local storage for your AI agent wallets, set the following environment variable:
|
|
192
|
+
```env
|
|
193
|
+
WALLET_STORE_PATH=./.agents/wallets.json
|
|
194
|
+
```
|
|
195
|
+
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).
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
---
|
|
198
198
|
|
|
199
|
-
|
|
199
|
+
## MCP Tools: 27 Total
|
|
200
200
|
|
|
201
|
-
|
|
202
|
-
|---|---|---|
|
|
203
|
-
| **Read-only** (11 tools) | `simulate_transaction`, `estimate_gas`, `get_token_price`, `get_pool_info`, `get_gas_price`, `get_wallet_balance`, `check_allowance`, `get_transaction_status`, `get_execution_history`, `query_risk_registry`, `check_token_security` | Any agent, no wallet needed |
|
|
204
|
-
| **Read+Write** (1 tool) | `assess_risk` | Scores risk without a key; auto-publishes to RiskRegistry with key |
|
|
205
|
-
| **Write** (5 tools) | `execute_swap`, `send_payment`, `approve_token`, `publish_risk_score`, `x402_pay_and_fetch` | Agents with privateKey |
|
|
201
|
+
SafeHands currently exposes **27 MCP tools**:
|
|
206
202
|
|
|
207
|
-
|
|
203
|
+
- 17 legacy/core Web3 safety/execution tools
|
|
204
|
+
- 3 managed testnet wallet tools
|
|
205
|
+
- 7 branded SafeHands guardrail tools
|
|
208
206
|
|
|
209
|
-
###
|
|
207
|
+
### Branded SafeHands Guardrail Tools
|
|
210
208
|
|
|
211
|
-
|
|
209
|
+
| Tool | Purpose |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `safehands_preflight_check` | Policy-based ALLOW/WARN/BLOCK check before execution |
|
|
212
|
+
| `safehands_safe_execute` | Guarded wrapper around payment, approval, swap, and x402 execution |
|
|
213
|
+
| `safehands_wallet_health` | Checks whether an agent wallet is ready to act |
|
|
214
|
+
| `safehands_x402_preflight` | Checks URL, payment amount, token, signer, and x402 safety before paying |
|
|
215
|
+
| `safehands_risk_report` | Generates a human-readable risk report for demos and judges |
|
|
216
|
+
| `explain_risk` | Converts policy results into plain-English explanations |
|
|
217
|
+
| `token_registry_status` | Classifies token addresses as canonical, test, custom, unknown, or invalid |
|
|
212
218
|
|
|
213
|
-
|
|
214
|
-
Agent A assesses wallet X β publish_risk_score β On-Chain Registry
|
|
215
|
-
β
|
|
216
|
-
Agent B wants to trade β query_risk_registry ββββββββ
|
|
217
|
-
with wallet X "Score 87, block"
|
|
218
|
-
```
|
|
219
|
+
### Core Safety and Execution Tools
|
|
219
220
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
221
|
+
| Tool | Type | Purpose |
|
|
222
|
+
|---|---|---|
|
|
223
|
+
| `assess_risk` | Read / optional write | 5-dimension risk score |
|
|
224
|
+
| `check_token_security` | Read | GoPlus token security profile |
|
|
225
|
+
| `simulate_transaction` | Read | Dry-run transaction simulation |
|
|
226
|
+
| `estimate_gas` | Read | Gas estimate and sufficiency check |
|
|
227
|
+
| `execute_swap` | Write | FaroSwap/DODO swap with guardrails |
|
|
228
|
+
| `send_payment` | Write | Native PHRS payment |
|
|
229
|
+
| `approve_token` | Write | ERC-20 approval with unlimited-approval guard |
|
|
230
|
+
| `get_token_price` | Read | Token price data |
|
|
231
|
+
| `get_pool_info` | Read | DODO/FaroSwap pool and route info |
|
|
232
|
+
| `get_gas_price` | Read | Current gas price |
|
|
233
|
+
| `get_wallet_balance` | Read | Wallet balances |
|
|
234
|
+
| `check_allowance` | Read | ERC-20 allowance check |
|
|
235
|
+
| `get_transaction_status` | Read | Transaction status by hash |
|
|
236
|
+
| `get_execution_history` | Read | Wallet transaction history |
|
|
237
|
+
| `publish_risk_score` | Write | Publish score to RiskRegistry |
|
|
238
|
+
| `query_risk_registry` | Read | Query on-chain risk score |
|
|
239
|
+
| `x402_pay_and_fetch` | Write when HTTP 402 | Fetch x402 resources and pay only after a payment challenge |
|
|
240
|
+
|
|
241
|
+
### Managed Testnet Wallet Tools
|
|
242
|
+
|
|
243
|
+
| Tool | Purpose |
|
|
244
|
+
|---|---|
|
|
245
|
+
| `create_agent_wallet` | Explicitly create a managed testnet wallet |
|
|
246
|
+
| `get_agent_wallet` | Return public wallet metadata, never private key |
|
|
247
|
+
| `get_agent_wallet_balance` | Check managed wallet balances |
|
|
224
248
|
|
|
225
249
|
---
|
|
226
250
|
|
|
227
|
-
##
|
|
251
|
+
## Policy Engine Behavior
|
|
228
252
|
|
|
229
|
-
|
|
253
|
+
The reusable policy engine lives at:
|
|
230
254
|
|
|
231
|
-
|
|
255
|
+
```text
|
|
256
|
+
src/lib/policy/actionPolicyEngine.ts
|
|
257
|
+
```
|
|
232
258
|
|
|
233
|
-
|
|
259
|
+
Supported action types:
|
|
234
260
|
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
}
|
|
261
|
+
```text
|
|
262
|
+
send_payment
|
|
263
|
+
approve_token
|
|
264
|
+
execute_swap
|
|
265
|
+
x402_pay_and_fetch
|
|
266
|
+
publish_risk_score
|
|
267
|
+
custom_contract_call
|
|
244
268
|
```
|
|
245
269
|
|
|
246
|
-
|
|
270
|
+
Key guardrails:
|
|
247
271
|
|
|
248
|
-
|
|
272
|
+
- Block mainnet actions.
|
|
273
|
+
- Block chain ID mismatch.
|
|
274
|
+
- Block unlimited approvals by default.
|
|
275
|
+
- Block SSRF-sensitive x402 URLs.
|
|
276
|
+
- Block payment above configured limits.
|
|
277
|
+
- Block x402 payment above `MAX_X402_PAYMENT_USDC`.
|
|
278
|
+
- Block approvals above `MAX_APPROVAL_AMOUNT_USDC` unless consciously configured.
|
|
279
|
+
- Warn when a token is custom, non-registry, or token-security provider is unavailable.
|
|
280
|
+
- Require confirmation for medium-risk actions.
|
|
281
|
+
- Allow low-risk Pharos Atlantic Testnet actions.
|
|
249
282
|
|
|
250
|
-
|
|
251
|
-
git clone https://github.com/SZtch/safehands-pharos.git
|
|
252
|
-
cd safehands-pharos
|
|
253
|
-
npm install
|
|
254
|
-
npm run build
|
|
255
|
-
```
|
|
283
|
+
---
|
|
256
284
|
|
|
257
|
-
|
|
285
|
+
## x402 Behavior
|
|
258
286
|
|
|
259
|
-
|
|
260
|
-
{
|
|
261
|
-
"mcpServers": {
|
|
262
|
-
"safehands": {
|
|
263
|
-
"command": "node",
|
|
264
|
-
"args": ["/absolute/path/to/safehands-pharos/dist/index.js"]
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
```
|
|
287
|
+
SafeHands has both x402 client and server behavior:
|
|
269
288
|
|
|
270
|
-
###
|
|
289
|
+
### Free endpoints
|
|
271
290
|
|
|
272
|
-
|
|
291
|
+
- `GET /supported`
|
|
292
|
+
- `GET /health`
|
|
273
293
|
|
|
274
|
-
**
|
|
294
|
+
These do **not** require a user private key.
|
|
275
295
|
|
|
276
|
-
|
|
277
|
-
{
|
|
278
|
-
"mcpServers": {
|
|
279
|
-
"safehands": {
|
|
280
|
-
"command": "npx",
|
|
281
|
-
"args": ["-y", "safehands-pharos"],
|
|
282
|
-
"env": {
|
|
283
|
-
"PRIVATE_KEY": "0xYOUR_PRIVATE_KEY",
|
|
284
|
-
"WALLET_ADDRESS": "0xYOUR_WALLET_ADDRESS"
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
```
|
|
296
|
+
### Paid endpoints
|
|
290
297
|
|
|
291
|
-
|
|
298
|
+
- `GET /assess-risk`
|
|
299
|
+
- `GET /check-token-security`
|
|
300
|
+
- `GET /simulate-transaction`
|
|
292
301
|
|
|
293
|
-
|
|
294
|
-
PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
|
|
295
|
-
WALLET_ADDRESS=0xYOUR_WALLET_ADDRESS_HERE
|
|
296
|
-
```
|
|
302
|
+
Expected demo price: `0.001 USDC`.
|
|
297
303
|
|
|
298
|
-
|
|
304
|
+
Client flow:
|
|
299
305
|
|
|
300
|
-
|
|
306
|
+
1. Fetch normally first.
|
|
307
|
+
2. If HTTP 200, return `paymentExecuted=false`.
|
|
308
|
+
3. If HTTP 402, run SafeHands x402 preflight.
|
|
309
|
+
4. Request signer only after HTTP 402.
|
|
310
|
+
5. Do not log or return signed payment payloads.
|
|
301
311
|
|
|
302
|
-
|
|
303
|
-
npm run test:rpc
|
|
304
|
-
```
|
|
312
|
+
---
|
|
305
313
|
|
|
306
|
-
|
|
307
|
-
π Connecting to Pharos Atlantic Testnet...
|
|
308
|
-
Chain ID returned: 688689
|
|
309
|
-
β
SUCCESS β Chain ID matches expected 688689
|
|
310
|
-
```
|
|
314
|
+
## Using SafeHands with Pharos Skill Engine
|
|
311
315
|
|
|
312
|
-
|
|
316
|
+
SafeHands includes a Pharos Skill Engine adapter under:
|
|
313
317
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
```solidity
|
|
326
|
-
contract RiskRegistry {
|
|
327
|
-
struct RiskRecord {
|
|
328
|
-
uint256 score;
|
|
329
|
-
string riskLevel;
|
|
330
|
-
string recommendation;
|
|
331
|
-
uint256 timestamp;
|
|
332
|
-
address assessedBy;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
function publish(address wallet, uint256 score, string riskLevel, string recommendation) external;
|
|
336
|
-
function query(address wallet) external view returns (RiskRecord memory);
|
|
337
|
-
}
|
|
318
|
+
> **Note:** The canonical publishable Skill package is in `skill/`. The `examples/pharos-skill-engine/` folder is retained as an integration example.
|
|
319
|
+
|
|
320
|
+
```text
|
|
321
|
+
examples/pharos-skill-engine/
|
|
322
|
+
βββ SKILL.safehands.md
|
|
323
|
+
βββ references/
|
|
324
|
+
β βββ safehands.md
|
|
325
|
+
βββ assets/
|
|
326
|
+
βββ safehands/
|
|
327
|
+
βββ policy-defaults.json
|
|
328
|
+
βββ example-actions.json
|
|
338
329
|
```
|
|
339
330
|
|
|
340
|
-
|
|
331
|
+
The reference files teach the Skill Engine how to call SafeHands through terminal commands such as:
|
|
341
332
|
|
|
342
|
-
|
|
333
|
+
```bash
|
|
334
|
+
npx safehands-pharos skill safehands_preflight_check --input-json '<json>'
|
|
335
|
+
npx safehands-pharos skill safehands_x402_preflight --input-json '<json>'
|
|
336
|
+
npx safehands-pharos skill safehands_wallet_health --input-json '{}'
|
|
337
|
+
npx safehands-pharos skill token_registry_status --input-json '{"tokenAddress":"0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8"}'
|
|
338
|
+
```
|
|
343
339
|
|
|
344
|
-
|
|
340
|
+
Use SafeHands before Pharos Skill Engine performs write actions. SafeHands complements the Skill Engine and should not be treated as a replacement.
|
|
345
341
|
|
|
346
|
-
|
|
342
|
+
---
|
|
347
343
|
|
|
348
|
-
|
|
344
|
+
## Security Guardrails
|
|
349
345
|
|
|
350
|
-
|
|
351
|
-
|------|---------|--------|
|
|
352
|
-
| `execute_swap` | [`0xdb814a33...`](https://atlantic.pharosscan.xyz/tx/0xdb814a334337d47a3d2b18cbe4f9015356a3842412dada6ca2138d14287f50cb) | 0.01 PHRS β 0.0317 USDC |
|
|
353
|
-
| `send_payment` | [`0xbf26b767...`](https://atlantic.pharosscan.xyz/tx/0xbf26b767cb8a5e599b6acaec90998a66577dbec9036526e7c1876a43a1e79471) | 0.001 PHRS sent |
|
|
354
|
-
| `approve_token` | [`0xca21ac22...`](https://atlantic.pharosscan.xyz/tx/0xca21ac22c870f1bc69c432f1f02c9459066f390a1dead92fca8b0d1119d30422) | 100 USDC approved |
|
|
355
|
-
| `publish_risk_score` | [`0x3f5cefe5...`](https://atlantic.pharosscan.xyz/tx/0x3f5cefe5725512b57f3dc7c08bb8f588fa3691fc4592ccec66ba2cb6ef4c9a3a) | Score 3 published |
|
|
356
|
-
| Registry deploy | [`0x7f2106b5...`](https://atlantic.pharosscan.xyz/tx/0x7f2106b5bc8c5eddcd2ea7782669ccb0b4a107da4943cffd5d49357ab5820d2e) | Contract created |
|
|
346
|
+
SafeHands defaults to defensive behavior:
|
|
357
347
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
6 β β
PASS β check_allowance β allowance=100, needsApproval=false
|
|
369
|
-
7 β β
PASS β estimate_gas β gas=624491, cost=0.00624491 PHRS, sufficien...
|
|
370
|
-
8 β β
PASS β get_gas_price β 10.0000 Gwei, trend=normal
|
|
371
|
-
9 β β
PASS β get_pool_info β available=false, no pool
|
|
372
|
-
10 β β
PASS β execute_swap β out=0.0317053705 USDC, tx=0xdb814a334337d47...
|
|
373
|
-
11 β β
PASS β send_payment β sent 0.001 PHRS, tx=0xbf26b767cb8a5e599b6ac...
|
|
374
|
-
12 β β
PASS β approve_token β approved 100 USDC, tx=0xca21ac22c870f1bc69c...
|
|
375
|
-
13 β β
PASS β get_transaction_status β status=success, block=23970700
|
|
376
|
-
14 β β
PASS β publish_risk_score β score=3, tx=0x3f5cefe5725512b57f3dc7c08bb8f...
|
|
377
|
-
15 β β
PASS β query_risk_registry β score=3, level=low, ts=2026-06-11T11:53:17....
|
|
378
|
-
16 β β
PASS β check_token_security β score=100, honeypot=false
|
|
379
|
-
17 β β
PASS β get_execution_history β 5 txs
|
|
380
|
-
```
|
|
348
|
+
- `WRITE_TOOLS_ENABLED=false` by default.
|
|
349
|
+
- `WALLET_MODE=none` by default.
|
|
350
|
+
- No wallet is created on install, import, or startup.
|
|
351
|
+
- Managed wallets are created only through `create_agent_wallet`.
|
|
352
|
+
- Private keys are never returned in MCP or CLI responses.
|
|
353
|
+
- Private keys and payment proofs are not logged.
|
|
354
|
+
- Unlimited approvals are blocked unless explicitly allowed.
|
|
355
|
+
- SSRF-sensitive x402 URLs are blocked unless local testing is explicitly enabled.
|
|
356
|
+
- Mainnet actions are blocked.
|
|
357
|
+
- External API failures return structured errors rather than crashing tool calls.
|
|
381
358
|
|
|
382
359
|
---
|
|
383
360
|
|
|
384
|
-
##
|
|
361
|
+
## Demo
|
|
385
362
|
|
|
386
|
-
|
|
363
|
+
Run:
|
|
387
364
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
- `GET /check-token-security` (Paid: USDC 0.001) β Verify contract security, honeypots, and token code privileges.
|
|
392
|
-
- `GET /simulate-transaction` (Paid: USDC 0.001) β Perform dry-runs of transfers and swaps.
|
|
365
|
+
```bash
|
|
366
|
+
npm run demo
|
|
367
|
+
```
|
|
393
368
|
|
|
394
|
-
|
|
395
|
-
1. **Challenge:** When a client fetches a gated resource, the server replies with `HTTP 402 Payment Required` and a Base64-encoded `PAYMENT-REQUIRED` header specifying token address, receiver wallet, and pricing details.
|
|
396
|
-
2. **On-Chain Settlement:** The client signs a standard authorization envelope with their private key, transferring the micro-payment directly to the recipient wallet.
|
|
397
|
-
3. **Resubmission:** The client resubmits the request, appending the payload signature in the `PAYMENT-SIGNATURE` header.
|
|
398
|
-
4. **Unlocking Content:** The integrated Facilitator verifies the signature, settles the transfer on-chain, and responds with `HTTP 200 OK` carrying the resource response payload.
|
|
369
|
+
or:
|
|
399
370
|
|
|
400
|
-
### Quick Start (Server)
|
|
401
|
-
Start the paid server:
|
|
402
371
|
```bash
|
|
403
|
-
|
|
372
|
+
npx safehands-pharos --demo
|
|
404
373
|
```
|
|
405
374
|
|
|
406
|
-
|
|
407
|
-
Use the `x402_pay_and_fetch` tool:
|
|
408
|
-
```json
|
|
409
|
-
{
|
|
410
|
-
"name": "x402_pay_and_fetch",
|
|
411
|
-
"arguments": {
|
|
412
|
-
"url": "http://localhost:4021/assess-risk?action=swap&tokenIn=PHRS&tokenOut=USDC&amount=0.01&walletAddress=0x6730d3a2a217108ab53ccfe60ffdad05d3c124e5"
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
```
|
|
375
|
+
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.
|
|
416
376
|
|
|
417
377
|
---
|
|
418
378
|
|
|
419
|
-
##
|
|
420
|
-
|
|
421
|
-
Security self-audit β compliant with Pharos Skill Scanner guidelines:
|
|
422
|
-
|
|
423
|
-
- β
**Private keys never stored** β passed per-request, never logged or persisted
|
|
424
|
-
- β
**No hardcoded secrets** β all sensitive config via `.env`
|
|
425
|
-
- β
**No shell execution** β pure TypeScript with viem RPC calls
|
|
426
|
-
- β
**No file system abuse** β no local file reads/writes during tool execution
|
|
427
|
-
- β
**Risk gating on execution** β `execute_swap` and `send_payment` run full risk assessment before execution. All write tools enforce safety checks before touching the chain.
|
|
428
|
-
- β
**Automatic blocking** β score > 80 halts execution, no silent failures
|
|
379
|
+
## Real Testnet Verification
|
|
429
380
|
|
|
430
|
-
|
|
381
|
+
SafeHands includes live verification commands that test against real Pharos Atlantic Testnet infrastructure:
|
|
431
382
|
|
|
432
|
-
|
|
383
|
+
| Command | What it does | Requires |
|
|
384
|
+
|---------|-------------|----------|
|
|
385
|
+
| `npm run test:rpc:live` | Reads chain ID, block number, optional wallet balance from live RPC | Network access |
|
|
386
|
+
| `npm run test:live:safehands` | Runs 7 CLI safety checks against built dist (no broadcast) | Built dist |
|
|
387
|
+
| `npm run test:x402:live` | Tests x402 free/paid endpoint behavior locally | Nothing |
|
|
388
|
+
| `npm run test:dodo:live` | Tests DODO API route if `DODO_API_KEY` set; skips cleanly if not | `DODO_API_KEY` (optional) |
|
|
433
389
|
|
|
434
|
-
|
|
435
|
-
|---------|----------|---------|----------|
|
|
436
|
-
| **Pharos RPC** | `atlantic.dplabs-internal.com` | On-chain reads/writes | Standard JSON-RPC calls (public data) |
|
|
437
|
-
| **DODO Route API** | `api.dodoex.io` | DEX swap routing & quotes | Public token addresses, amounts |
|
|
438
|
-
| **GoPlus Security API** | `api.gopluslabs.io` | Token contract security scanning | Public token contract address |
|
|
390
|
+
**Important distinctions:**
|
|
439
391
|
|
|
440
|
-
|
|
392
|
+
1. **Live RPC checks** (`test:rpc`, `test:rpc:live`) connect to the real Pharos Atlantic Testnet RPC and read chain ID + block number.
|
|
393
|
+
2. **Live CLI checks** (`test:live:safehands`) run real CLI invocations against built dist, testing policy decisions deterministically.
|
|
394
|
+
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.
|
|
395
|
+
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.
|
|
396
|
+
5. **Smoke tests** (`test:all`) are deterministic and do not require network connectivity (except DODO/RPC-dependent tools, which degrade gracefully).
|
|
397
|
+
6. **Address verification statuses** (DOCS_VERIFIED, DOCS_DEMO_NON_OFFICIAL, PROJECT_CONFIGURED) are sourced from `docs/reports/OFFICIAL_DOCS_ALIGNMENT_REPORT.md`.
|
|
398
|
+
7. **No real transactions are broadcast by default.** Write tools require explicit `WRITE_TOOLS_ENABLED=true`.
|
|
441
399
|
|
|
442
400
|
---
|
|
443
401
|
|
|
444
|
-
##
|
|
402
|
+
## Tests and Validation
|
|
445
403
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
-
|
|
450
|
-
|
|
451
|
-
|
|
404
|
+
```bash
|
|
405
|
+
npm ci
|
|
406
|
+
npm run build
|
|
407
|
+
npx tsc -p tsconfig.all.json --pretty false
|
|
408
|
+
npm run test:all # 43-point smoke test suite
|
|
409
|
+
npm audit --omit=dev --audit-level=high
|
|
410
|
+
npm pack --dry-run
|
|
411
|
+
```
|
|
452
412
|
|
|
453
|
-
|
|
454
|
-
- [x] Publish `safehands-pharos` to npm
|
|
455
|
-
- [x] One-line install: `npx safehands-pharos`
|
|
456
|
-
- [ ] Configurable risk thresholds per-agent
|
|
413
|
+
Live verification (requires network):
|
|
457
414
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
415
|
+
```bash
|
|
416
|
+
npm run test:rpc # Basic RPC connectivity
|
|
417
|
+
npm run test:rpc:live # Full live RPC verification with structured output
|
|
418
|
+
npm run test:live:safehands # 7 CLI safety checks (read-only)
|
|
419
|
+
npm run test:x402:live # x402 behavior checks (local server)
|
|
420
|
+
npm run test:dodo:live # DODO API check (requires DODO_API_KEY, skips if missing)
|
|
421
|
+
```
|
|
462
422
|
|
|
463
|
-
|
|
464
|
-
- [x] **x402 Paywall & Monetization:** Native integration with the Pharos x402 HTTP-payment standard. Enable SafeHands to charge micro-amounts of USDC per risk assessment request, allowing agents to monetize their safety gating services autonomously.
|
|
465
|
-
- [ ] ELFi lending protocol integration
|
|
466
|
-
- [ ] Multi-hop route optimization for large swaps
|
|
467
|
-
- [ ] Smart contract escrow for agent-to-agent payments
|
|
468
|
-
- [ ] Cross-chain risk assessment (Pharos Mainnet)
|
|
423
|
+
`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.
|
|
469
424
|
|
|
470
425
|
---
|
|
471
426
|
|
|
472
|
-
##
|
|
427
|
+
## Known Limitations and TODOs
|
|
473
428
|
|
|
474
|
-
|
|
429
|
+
- Testnet-only, not audited for mainnet use.
|
|
430
|
+
- Managed wallet storage is testnet-grade unless a real KMS/Vault is integrated.
|
|
431
|
+
- DODO/FaroSwap router addresses are project-configured unless official docs confirm them.
|
|
432
|
+
- GoPlus/DODO/FaroSwap availability depends on external services and API limits.
|
|
433
|
+
- `npm audit` for production dependencies is clean; full dev audit may report dev-only dependency issues depending on upstream packages.
|
|
434
|
+
- Formal unit tests with mocked RPC/DODO/GoPlus providers would improve long-term maintainability.
|
|
475
435
|
|
|
476
436
|
---
|
|
477
437
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
438
|
+
## Hackathon Summary
|
|
439
|
+
|
|
440
|
+
**Project name:** SafeHands-Pharos: Transaction Safety Firewall for AI Agents
|
|
441
|
+
|
|
442
|
+
**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.
|