safehands-pharos 1.5.0 → 2.8.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 (566) hide show
  1. package/.agents/policies/default.json +15 -0
  2. package/.env.example +81 -64
  3. package/README.md +301 -444
  4. package/SECURITY.md +112 -0
  5. package/SKILL.md +59 -0
  6. package/contracts/SafeHandsAttestation.sol +182 -0
  7. package/contracts/SafeHandsRegistry.sol +149 -0
  8. package/dist/agent/SafeHandsGuardianAgent.d.ts +39 -0
  9. package/dist/agent/SafeHandsGuardianAgent.d.ts.map +1 -0
  10. package/dist/agent/SafeHandsGuardianAgent.js +98 -0
  11. package/dist/agent/SafeHandsGuardianAgent.js.map +1 -0
  12. package/dist/agent/agentDecisionFormatter.d.ts +43 -0
  13. package/dist/agent/agentDecisionFormatter.d.ts.map +1 -0
  14. package/dist/agent/agentDecisionFormatter.js +96 -0
  15. package/dist/agent/agentDecisionFormatter.js.map +1 -0
  16. package/dist/agent/agentEnrich.d.ts +28 -0
  17. package/dist/agent/agentEnrich.d.ts.map +1 -0
  18. package/dist/agent/agentEnrich.js +99 -0
  19. package/dist/agent/agentEnrich.js.map +1 -0
  20. package/dist/agent/agentIntentClassifier.d.ts +44 -0
  21. package/dist/agent/agentIntentClassifier.d.ts.map +1 -0
  22. package/dist/agent/agentIntentClassifier.js +77 -0
  23. package/dist/agent/agentIntentClassifier.js.map +1 -0
  24. package/dist/agent/agentPolicyResolver.d.ts +44 -0
  25. package/dist/agent/agentPolicyResolver.d.ts.map +1 -0
  26. package/dist/agent/agentPolicyResolver.js +94 -0
  27. package/dist/agent/agentPolicyResolver.js.map +1 -0
  28. package/dist/agent/agentRuntime.d.ts +12 -0
  29. package/dist/agent/agentRuntime.d.ts.map +1 -0
  30. package/dist/agent/agentRuntime.js +31 -0
  31. package/dist/agent/agentRuntime.js.map +1 -0
  32. package/dist/agent/agentToolRouter.d.ts +24 -0
  33. package/dist/agent/agentToolRouter.d.ts.map +1 -0
  34. package/dist/agent/agentToolRouter.js +89 -0
  35. package/dist/agent/agentToolRouter.js.map +1 -0
  36. package/dist/agent/guardianOperator.d.ts +35 -0
  37. package/dist/agent/guardianOperator.d.ts.map +1 -0
  38. package/dist/agent/guardianOperator.js +65 -0
  39. package/dist/agent/guardianOperator.js.map +1 -0
  40. package/dist/agent/index.d.ts +8 -0
  41. package/dist/agent/index.d.ts.map +1 -0
  42. package/dist/agent/index.js +14 -0
  43. package/dist/agent/index.js.map +1 -0
  44. package/dist/api/activityRoutes.d.ts +70 -0
  45. package/dist/api/activityRoutes.d.ts.map +1 -0
  46. package/dist/api/activityRoutes.js +100 -0
  47. package/dist/api/activityRoutes.js.map +1 -0
  48. package/dist/api/agentRoutes.d.ts +16 -0
  49. package/dist/api/agentRoutes.d.ts.map +1 -0
  50. package/dist/api/agentRoutes.js +37 -0
  51. package/dist/api/agentRoutes.js.map +1 -0
  52. package/dist/api/broadcastRoutes.d.ts +34 -0
  53. package/dist/api/broadcastRoutes.d.ts.map +1 -0
  54. package/dist/api/broadcastRoutes.js +147 -0
  55. package/dist/api/broadcastRoutes.js.map +1 -0
  56. package/dist/api/consolePage.d.ts +2 -0
  57. package/dist/api/consolePage.d.ts.map +1 -0
  58. package/dist/api/consolePage.js +206 -0
  59. package/dist/api/consolePage.js.map +1 -0
  60. package/dist/api/httpHardening.d.ts +75 -0
  61. package/dist/api/httpHardening.d.ts.map +1 -0
  62. package/dist/api/httpHardening.js +122 -0
  63. package/dist/api/httpHardening.js.map +1 -0
  64. package/dist/api/indexerRoutes.d.ts +46 -0
  65. package/dist/api/indexerRoutes.d.ts.map +1 -0
  66. package/dist/api/indexerRoutes.js +75 -0
  67. package/dist/api/indexerRoutes.js.map +1 -0
  68. package/dist/api/paidRoutes.d.ts +8 -0
  69. package/dist/api/paidRoutes.d.ts.map +1 -0
  70. package/dist/api/paidRoutes.js +175 -0
  71. package/dist/api/paidRoutes.js.map +1 -0
  72. package/dist/api/prepareRoutes.d.ts +58 -0
  73. package/dist/api/prepareRoutes.d.ts.map +1 -0
  74. package/dist/api/prepareRoutes.js +90 -0
  75. package/dist/api/prepareRoutes.js.map +1 -0
  76. package/dist/api/response.d.ts +39 -0
  77. package/dist/api/response.d.ts.map +1 -0
  78. package/dist/api/response.js +53 -0
  79. package/dist/api/response.js.map +1 -0
  80. package/dist/api/routes.d.ts +175 -0
  81. package/dist/api/routes.d.ts.map +1 -0
  82. package/dist/api/routes.js +276 -0
  83. package/dist/api/routes.js.map +1 -0
  84. package/dist/api/schemas.d.ts +147 -0
  85. package/dist/api/schemas.d.ts.map +1 -0
  86. package/dist/api/schemas.js +81 -0
  87. package/dist/api/schemas.js.map +1 -0
  88. package/dist/api/server.d.ts +11 -0
  89. package/dist/api/server.d.ts.map +1 -0
  90. package/dist/api/server.js +505 -0
  91. package/dist/api/server.js.map +1 -0
  92. package/dist/api/toolRoutes.d.ts +14 -0
  93. package/dist/api/toolRoutes.d.ts.map +1 -0
  94. package/dist/api/toolRoutes.js +138 -0
  95. package/dist/api/toolRoutes.js.map +1 -0
  96. package/dist/api/walletPrepareRoutes.d.ts +74 -0
  97. package/dist/api/walletPrepareRoutes.d.ts.map +1 -0
  98. package/dist/api/walletPrepareRoutes.js +127 -0
  99. package/dist/api/walletPrepareRoutes.js.map +1 -0
  100. package/dist/api/x402Gate.d.ts +51 -0
  101. package/dist/api/x402Gate.d.ts.map +1 -0
  102. package/dist/api/x402Gate.js +184 -0
  103. package/dist/api/x402Gate.js.map +1 -0
  104. package/dist/cli.d.ts +1 -1
  105. package/dist/cli.d.ts.map +1 -1
  106. package/dist/cli.js +29 -1
  107. package/dist/cli.js.map +1 -1
  108. package/dist/data/ecosystemRegistry.data.d.ts +3 -0
  109. package/dist/data/ecosystemRegistry.data.d.ts.map +1 -0
  110. package/dist/data/ecosystemRegistry.data.js +582 -0
  111. package/dist/data/ecosystemRegistry.data.js.map +1 -0
  112. package/dist/demo.d.ts +0 -0
  113. package/dist/demo.d.ts.map +1 -1
  114. package/dist/demo.js +43 -8
  115. package/dist/demo.js.map +1 -1
  116. package/dist/handsafe.zip +0 -0
  117. package/dist/index.d.ts +0 -0
  118. package/dist/index.d.ts.map +0 -0
  119. package/dist/index.js +212 -135
  120. package/dist/index.js.map +1 -1
  121. package/dist/init.d.ts +0 -0
  122. package/dist/init.d.ts.map +1 -1
  123. package/dist/init.js +72 -10
  124. package/dist/init.js.map +1 -1
  125. package/dist/lib/analysis/abiWords.d.ts +17 -0
  126. package/dist/lib/analysis/abiWords.d.ts.map +1 -0
  127. package/dist/lib/analysis/abiWords.js +48 -0
  128. package/dist/lib/analysis/abiWords.js.map +1 -0
  129. package/dist/lib/analysis/approval.d.ts +29 -0
  130. package/dist/lib/analysis/approval.d.ts.map +1 -0
  131. package/dist/lib/analysis/approval.js +189 -0
  132. package/dist/lib/analysis/approval.js.map +1 -0
  133. package/dist/lib/analysis/calldata.d.ts +60 -0
  134. package/dist/lib/analysis/calldata.d.ts.map +1 -0
  135. package/dist/lib/analysis/calldata.js +464 -0
  136. package/dist/lib/analysis/calldata.js.map +1 -0
  137. package/dist/lib/analysis/contractIntel.d.ts +65 -0
  138. package/dist/lib/analysis/contractIntel.d.ts.map +1 -0
  139. package/dist/lib/analysis/contractIntel.js +320 -0
  140. package/dist/lib/analysis/contractIntel.js.map +1 -0
  141. package/dist/lib/analysis/evm.d.ts +42 -0
  142. package/dist/lib/analysis/evm.d.ts.map +1 -0
  143. package/dist/lib/analysis/evm.js +185 -0
  144. package/dist/lib/analysis/evm.js.map +1 -0
  145. package/dist/lib/analysis/gas.d.ts +4 -0
  146. package/dist/lib/analysis/gas.d.ts.map +1 -0
  147. package/dist/lib/analysis/gas.js +13 -0
  148. package/dist/lib/analysis/gas.js.map +1 -0
  149. package/dist/lib/analysis/index.d.ts +11 -0
  150. package/dist/lib/analysis/index.d.ts.map +1 -0
  151. package/dist/lib/analysis/index.js +16 -0
  152. package/dist/lib/analysis/index.js.map +1 -0
  153. package/dist/lib/analysis/pharosTokens.d.ts +31 -0
  154. package/dist/lib/analysis/pharosTokens.d.ts.map +1 -0
  155. package/dist/lib/analysis/pharosTokens.js +78 -0
  156. package/dist/lib/analysis/pharosTokens.js.map +1 -0
  157. package/dist/lib/analysis/safeTx.d.ts +27 -0
  158. package/dist/lib/analysis/safeTx.d.ts.map +1 -0
  159. package/dist/lib/analysis/safeTx.js +118 -0
  160. package/dist/lib/analysis/safeTx.js.map +1 -0
  161. package/dist/lib/analysis/token.d.ts +21 -0
  162. package/dist/lib/analysis/token.d.ts.map +1 -0
  163. package/dist/lib/analysis/token.js +151 -0
  164. package/dist/lib/analysis/token.js.map +1 -0
  165. package/dist/lib/analysis/types.d.ts +49 -0
  166. package/dist/lib/analysis/types.d.ts.map +1 -0
  167. package/dist/lib/analysis/types.js +10 -0
  168. package/dist/lib/analysis/types.js.map +1 -0
  169. package/dist/lib/analysis/x402.d.ts +24 -0
  170. package/dist/lib/analysis/x402.d.ts.map +1 -0
  171. package/dist/lib/analysis/x402.js +60 -0
  172. package/dist/lib/analysis/x402.js.map +1 -0
  173. package/dist/lib/auditLog.d.ts +1 -0
  174. package/dist/lib/auditLog.d.ts.map +1 -1
  175. package/dist/lib/auditLog.js +0 -0
  176. package/dist/lib/auditLog.js.map +1 -1
  177. package/dist/lib/config.d.ts +77 -0
  178. package/dist/lib/config.d.ts.map +1 -0
  179. package/dist/lib/config.js +120 -0
  180. package/dist/lib/config.js.map +1 -0
  181. package/dist/lib/constants.d.ts +246 -97
  182. package/dist/lib/constants.d.ts.map +1 -1
  183. package/dist/lib/constants.js +334 -127
  184. package/dist/lib/constants.js.map +1 -1
  185. package/dist/lib/dodoApi.d.ts +26 -3
  186. package/dist/lib/dodoApi.d.ts.map +1 -1
  187. package/dist/lib/dodoApi.js +80 -17
  188. package/dist/lib/dodoApi.js.map +1 -1
  189. package/dist/lib/ecosystemRegistry.d.ts +126 -0
  190. package/dist/lib/ecosystemRegistry.d.ts.map +1 -0
  191. package/dist/lib/ecosystemRegistry.js +178 -0
  192. package/dist/lib/ecosystemRegistry.js.map +1 -0
  193. package/dist/lib/envLoader.d.ts +0 -0
  194. package/dist/lib/envLoader.d.ts.map +0 -0
  195. package/dist/lib/envLoader.js +39 -18
  196. package/dist/lib/envLoader.js.map +1 -1
  197. package/dist/lib/goldsky.d.ts +58 -0
  198. package/dist/lib/goldsky.d.ts.map +1 -0
  199. package/dist/lib/goldsky.js +275 -0
  200. package/dist/lib/goldsky.js.map +1 -0
  201. package/dist/lib/guardian/decision.d.ts +23 -0
  202. package/dist/lib/guardian/decision.d.ts.map +1 -0
  203. package/dist/lib/guardian/decision.js +40 -0
  204. package/dist/lib/guardian/decision.js.map +1 -0
  205. package/dist/lib/http.d.ts +0 -1
  206. package/dist/lib/http.d.ts.map +1 -1
  207. package/dist/lib/http.js +297 -32
  208. package/dist/lib/http.js.map +1 -1
  209. package/dist/lib/managedExecution.d.ts +19 -0
  210. package/dist/lib/managedExecution.d.ts.map +1 -0
  211. package/dist/lib/managedExecution.js +64 -0
  212. package/dist/lib/managedExecution.js.map +1 -0
  213. package/dist/lib/merkleBatcher.d.ts +23 -0
  214. package/dist/lib/merkleBatcher.d.ts.map +1 -0
  215. package/dist/lib/merkleBatcher.js +62 -0
  216. package/dist/lib/merkleBatcher.js.map +1 -0
  217. package/dist/lib/networks.d.ts +48 -0
  218. package/dist/lib/networks.d.ts.map +1 -0
  219. package/dist/lib/networks.js +103 -0
  220. package/dist/lib/networks.js.map +1 -0
  221. package/dist/lib/observability/accessContext.d.ts +29 -0
  222. package/dist/lib/observability/accessContext.d.ts.map +1 -0
  223. package/dist/lib/observability/accessContext.js +50 -0
  224. package/dist/lib/observability/accessContext.js.map +1 -0
  225. package/dist/lib/observability/activityStore.d.ts +70 -0
  226. package/dist/lib/observability/activityStore.d.ts.map +1 -0
  227. package/dist/lib/observability/activityStore.js +149 -0
  228. package/dist/lib/observability/activityStore.js.map +1 -0
  229. package/dist/lib/observability/apiKey.d.ts +55 -0
  230. package/dist/lib/observability/apiKey.d.ts.map +1 -0
  231. package/dist/lib/observability/apiKey.js +141 -0
  232. package/dist/lib/observability/apiKey.js.map +1 -0
  233. package/dist/lib/observability/logger.d.ts +30 -0
  234. package/dist/lib/observability/logger.d.ts.map +1 -0
  235. package/dist/lib/observability/logger.js +30 -0
  236. package/dist/lib/observability/logger.js.map +1 -0
  237. package/dist/lib/observability/quota.d.ts +33 -0
  238. package/dist/lib/observability/quota.d.ts.map +1 -0
  239. package/dist/lib/observability/quota.js +49 -0
  240. package/dist/lib/observability/quota.js.map +1 -0
  241. package/dist/lib/observability/requestId.d.ts +8 -0
  242. package/dist/lib/observability/requestId.d.ts.map +1 -0
  243. package/dist/lib/observability/requestId.js +24 -0
  244. package/dist/lib/observability/requestId.js.map +1 -0
  245. package/dist/lib/observability/sanitize.d.ts +77 -0
  246. package/dist/lib/observability/sanitize.d.ts.map +1 -0
  247. package/dist/lib/observability/sanitize.js +228 -0
  248. package/dist/lib/observability/sanitize.js.map +1 -0
  249. package/dist/lib/observability/scopes.d.ts +20 -0
  250. package/dist/lib/observability/scopes.d.ts.map +1 -0
  251. package/dist/lib/observability/scopes.js +77 -0
  252. package/dist/lib/observability/scopes.js.map +1 -0
  253. package/dist/lib/okxDexApi.d.ts +106 -0
  254. package/dist/lib/okxDexApi.d.ts.map +1 -0
  255. package/dist/lib/okxDexApi.js +221 -0
  256. package/dist/lib/okxDexApi.js.map +1 -0
  257. package/dist/lib/persistentJsonStore.d.ts +5 -0
  258. package/dist/lib/persistentJsonStore.d.ts.map +1 -0
  259. package/dist/lib/persistentJsonStore.js +39 -0
  260. package/dist/lib/persistentJsonStore.js.map +1 -0
  261. package/dist/lib/pharos/attestationPublisher.d.ts +50 -0
  262. package/dist/lib/pharos/attestationPublisher.d.ts.map +1 -0
  263. package/dist/lib/pharos/attestationPublisher.js +262 -0
  264. package/dist/lib/pharos/attestationPublisher.js.map +1 -0
  265. package/dist/lib/pharos/ecosystem.d.ts +52 -0
  266. package/dist/lib/pharos/ecosystem.d.ts.map +1 -0
  267. package/dist/lib/pharos/ecosystem.js +431 -0
  268. package/dist/lib/pharos/ecosystem.js.map +1 -0
  269. package/dist/lib/pharos/ecosystemEvidence.d.ts +53 -0
  270. package/dist/lib/pharos/ecosystemEvidence.d.ts.map +1 -0
  271. package/dist/lib/pharos/ecosystemEvidence.js +133 -0
  272. package/dist/lib/pharos/ecosystemEvidence.js.map +1 -0
  273. package/dist/lib/pharos/rpc.d.ts +44 -0
  274. package/dist/lib/pharos/rpc.d.ts.map +1 -0
  275. package/dist/lib/pharos/rpc.js +90 -0
  276. package/dist/lib/pharos/rpc.js.map +1 -0
  277. package/dist/lib/pharos/rpcEvidence.d.ts +49 -0
  278. package/dist/lib/pharos/rpcEvidence.d.ts.map +1 -0
  279. package/dist/lib/pharos/rpcEvidence.js +46 -0
  280. package/dist/lib/pharos/rpcEvidence.js.map +1 -0
  281. package/dist/lib/pharos/rpcMethods.d.ts +46 -0
  282. package/dist/lib/pharos/rpcMethods.d.ts.map +1 -0
  283. package/dist/lib/pharos/rpcMethods.js +176 -0
  284. package/dist/lib/pharos/rpcMethods.js.map +1 -0
  285. package/dist/lib/pharos/spvVerifier.d.ts +47 -0
  286. package/dist/lib/pharos/spvVerifier.d.ts.map +1 -0
  287. package/dist/lib/pharos/spvVerifier.js +105 -0
  288. package/dist/lib/pharos/spvVerifier.js.map +1 -0
  289. package/dist/lib/pharos/userSignedBroadcaster.d.ts +10 -0
  290. package/dist/lib/pharos/userSignedBroadcaster.d.ts.map +1 -0
  291. package/dist/lib/pharos/userSignedBroadcaster.js +50 -0
  292. package/dist/lib/pharos/userSignedBroadcaster.js.map +1 -0
  293. package/dist/lib/pharosClient.d.ts +5 -10
  294. package/dist/lib/pharosClient.d.ts.map +1 -1
  295. package/dist/lib/pharosClient.js +9 -16
  296. package/dist/lib/pharosClient.js.map +1 -1
  297. package/dist/lib/policy/actionPolicyEngine.d.ts +37 -1
  298. package/dist/lib/policy/actionPolicyEngine.d.ts.map +1 -1
  299. package/dist/lib/policy/actionPolicyEngine.js +213 -52
  300. package/dist/lib/policy/actionPolicyEngine.js.map +1 -1
  301. package/dist/lib/policy/agentPolicy.d.ts +29 -0
  302. package/dist/lib/policy/agentPolicy.d.ts.map +1 -0
  303. package/dist/lib/policy/agentPolicy.js +154 -0
  304. package/dist/lib/policy/agentPolicy.js.map +1 -0
  305. package/dist/lib/policy/policyPresets.d.ts +30 -0
  306. package/dist/lib/policy/policyPresets.d.ts.map +1 -0
  307. package/dist/lib/policy/policyPresets.js +124 -0
  308. package/dist/lib/policy/policyPresets.js.map +1 -0
  309. package/dist/lib/policy/writeExecutionGate.d.ts +23 -0
  310. package/dist/lib/policy/writeExecutionGate.d.ts.map +1 -0
  311. package/dist/lib/policy/writeExecutionGate.js +65 -0
  312. package/dist/lib/policy/writeExecutionGate.js.map +1 -0
  313. package/dist/lib/preparedTxStore.d.ts +21 -0
  314. package/dist/lib/preparedTxStore.d.ts.map +1 -0
  315. package/dist/lib/preparedTxStore.js +90 -0
  316. package/dist/lib/preparedTxStore.js.map +1 -0
  317. package/dist/lib/price/chainlinkPushProvider.d.ts +34 -0
  318. package/dist/lib/price/chainlinkPushProvider.d.ts.map +1 -0
  319. package/dist/lib/price/chainlinkPushProvider.js +36 -0
  320. package/dist/lib/price/chainlinkPushProvider.js.map +1 -0
  321. package/dist/lib/price/feedRegistry.d.ts +26 -0
  322. package/dist/lib/price/feedRegistry.d.ts.map +1 -0
  323. package/dist/lib/price/feedRegistry.js +67 -0
  324. package/dist/lib/price/feedRegistry.js.map +1 -0
  325. package/dist/lib/price/priceResolver.d.ts +35 -0
  326. package/dist/lib/price/priceResolver.d.ts.map +1 -0
  327. package/dist/lib/price/priceResolver.js +246 -0
  328. package/dist/lib/price/priceResolver.js.map +1 -0
  329. package/dist/lib/price/supraProvider.d.ts +9 -0
  330. package/dist/lib/price/supraProvider.d.ts.map +1 -0
  331. package/dist/lib/price/supraProvider.js +17 -0
  332. package/dist/lib/price/supraProvider.js.map +1 -0
  333. package/dist/lib/price/types.d.ts +67 -0
  334. package/dist/lib/price/types.d.ts.map +1 -0
  335. package/dist/lib/price/types.js +7 -0
  336. package/dist/lib/price/types.js.map +1 -0
  337. package/dist/lib/productionGuards.d.ts +16 -0
  338. package/dist/lib/productionGuards.d.ts.map +1 -0
  339. package/dist/lib/productionGuards.js +93 -0
  340. package/dist/lib/productionGuards.js.map +1 -0
  341. package/dist/lib/recipientSafety.d.ts +5 -0
  342. package/dist/lib/recipientSafety.d.ts.map +1 -0
  343. package/dist/lib/recipientSafety.js +28 -0
  344. package/dist/lib/recipientSafety.js.map +1 -0
  345. package/dist/lib/riskEngine.d.ts +19 -0
  346. package/dist/lib/riskEngine.d.ts.map +1 -1
  347. package/dist/lib/riskEngine.js +107 -38
  348. package/dist/lib/riskEngine.js.map +1 -1
  349. package/dist/lib/riskInclusion.d.ts +72 -0
  350. package/dist/lib/riskInclusion.d.ts.map +1 -0
  351. package/dist/lib/riskInclusion.js +252 -0
  352. package/dist/lib/riskInclusion.js.map +1 -0
  353. package/dist/lib/safeHandsRegistry.d.ts +32 -0
  354. package/dist/lib/safeHandsRegistry.d.ts.map +1 -0
  355. package/dist/lib/safeHandsRegistry.js +151 -0
  356. package/dist/lib/safeHandsRegistry.js.map +1 -0
  357. package/dist/lib/signer/index.d.ts +3 -3
  358. package/dist/lib/signer/index.d.ts.map +1 -1
  359. package/dist/lib/signer/index.js +33 -11
  360. package/dist/lib/signer/index.js.map +1 -1
  361. package/dist/lib/spendAccumulator.d.ts +24 -1
  362. package/dist/lib/spendAccumulator.d.ts.map +1 -1
  363. package/dist/lib/spendAccumulator.js +76 -6
  364. package/dist/lib/spendAccumulator.js.map +1 -1
  365. package/dist/lib/toolResponse.d.ts +6 -1
  366. package/dist/lib/toolResponse.d.ts.map +1 -1
  367. package/dist/lib/toolResponse.js +13 -9
  368. package/dist/lib/toolResponse.js.map +1 -1
  369. package/dist/lib/validation.d.ts +7 -0
  370. package/dist/lib/validation.d.ts.map +1 -0
  371. package/dist/lib/validation.js +62 -0
  372. package/dist/lib/validation.js.map +1 -0
  373. package/dist/lib/wallet/index.d.ts +8 -12
  374. package/dist/lib/wallet/index.d.ts.map +1 -1
  375. package/dist/lib/wallet/index.js +48 -35
  376. package/dist/lib/wallet/index.js.map +1 -1
  377. package/dist/lib/x402ReplayStore.d.ts +6 -0
  378. package/dist/lib/x402ReplayStore.d.ts.map +1 -0
  379. package/dist/lib/x402ReplayStore.js +79 -0
  380. package/dist/lib/x402ReplayStore.js.map +1 -0
  381. package/dist/safehands.zip +0 -0
  382. package/dist/sdk.d.ts +14 -0
  383. package/dist/sdk.d.ts.map +1 -0
  384. package/dist/sdk.js +25 -0
  385. package/dist/sdk.js.map +1 -0
  386. package/dist/tools/approveToken.d.ts +31 -10
  387. package/dist/tools/approveToken.d.ts.map +1 -1
  388. package/dist/tools/approveToken.js +91 -24
  389. package/dist/tools/approveToken.js.map +1 -1
  390. package/dist/tools/assessRisk.d.ts +13 -26
  391. package/dist/tools/assessRisk.d.ts.map +1 -1
  392. package/dist/tools/assessRisk.js +34 -75
  393. package/dist/tools/assessRisk.js.map +1 -1
  394. package/dist/tools/checkAllowance.d.ts +9 -3
  395. package/dist/tools/checkAllowance.d.ts.map +1 -1
  396. package/dist/tools/checkAllowance.js +27 -5
  397. package/dist/tools/checkAllowance.js.map +1 -1
  398. package/dist/tools/checkTokenSecurity.d.ts +62 -5
  399. package/dist/tools/checkTokenSecurity.d.ts.map +1 -1
  400. package/dist/tools/checkTokenSecurity.js +166 -21
  401. package/dist/tools/checkTokenSecurity.js.map +1 -1
  402. package/dist/tools/createAgentWallet.d.ts +4 -2
  403. package/dist/tools/createAgentWallet.d.ts.map +1 -1
  404. package/dist/tools/createAgentWallet.js +36 -31
  405. package/dist/tools/createAgentWallet.js.map +1 -1
  406. package/dist/tools/estimateGas.d.ts +7 -2
  407. package/dist/tools/estimateGas.d.ts.map +1 -1
  408. package/dist/tools/estimateGas.js +16 -10
  409. package/dist/tools/estimateGas.js.map +1 -1
  410. package/dist/tools/executeSwap.d.ts +56 -8
  411. package/dist/tools/executeSwap.d.ts.map +1 -1
  412. package/dist/tools/executeSwap.js +194 -46
  413. package/dist/tools/executeSwap.js.map +1 -1
  414. package/dist/tools/explainRisk.d.ts +9 -9
  415. package/dist/tools/explainRisk.d.ts.map +1 -1
  416. package/dist/tools/explainRisk.js +5 -4
  417. package/dist/tools/explainRisk.js.map +1 -1
  418. package/dist/tools/getAgentPolicy.d.ts +15 -0
  419. package/dist/tools/getAgentPolicy.d.ts.map +1 -0
  420. package/dist/tools/getAgentPolicy.js +16 -0
  421. package/dist/tools/getAgentPolicy.js.map +1 -0
  422. package/dist/tools/getAgentReputation.d.ts +31 -0
  423. package/dist/tools/getAgentReputation.d.ts.map +1 -0
  424. package/dist/tools/getAgentReputation.js +44 -0
  425. package/dist/tools/getAgentReputation.js.map +1 -0
  426. package/dist/tools/getAgentWallet.d.ts +1 -1
  427. package/dist/tools/getAgentWallet.d.ts.map +1 -1
  428. package/dist/tools/getAgentWallet.js +11 -1
  429. package/dist/tools/getAgentWallet.js.map +1 -1
  430. package/dist/tools/getAgentWalletBalance.d.ts +1 -1
  431. package/dist/tools/getAgentWalletBalance.d.ts.map +1 -1
  432. package/dist/tools/getAgentWalletBalance.js +58 -26
  433. package/dist/tools/getAgentWalletBalance.js.map +1 -1
  434. package/dist/tools/getExecutionHistory.d.ts +1 -1
  435. package/dist/tools/getExecutionHistory.d.ts.map +1 -1
  436. package/dist/tools/getExecutionHistory.js +13 -19
  437. package/dist/tools/getExecutionHistory.js.map +1 -1
  438. package/dist/tools/getGasPrice.d.ts +3 -3
  439. package/dist/tools/getGasPrice.d.ts.map +0 -0
  440. package/dist/tools/getGasPrice.js +7 -7
  441. package/dist/tools/getGasPrice.js.map +1 -1
  442. package/dist/tools/getPoolInfo.d.ts +17 -17
  443. package/dist/tools/getPoolInfo.d.ts.map +1 -1
  444. package/dist/tools/getPoolInfo.js +14 -9
  445. package/dist/tools/getPoolInfo.js.map +1 -1
  446. package/dist/tools/getSpvProof.d.ts +24 -0
  447. package/dist/tools/getSpvProof.d.ts.map +1 -0
  448. package/dist/tools/getSpvProof.js +64 -0
  449. package/dist/tools/getSpvProof.js.map +1 -0
  450. package/dist/tools/getTokenPrice.d.ts +28 -85
  451. package/dist/tools/getTokenPrice.d.ts.map +1 -1
  452. package/dist/tools/getTokenPrice.js +87 -94
  453. package/dist/tools/getTokenPrice.js.map +1 -1
  454. package/dist/tools/getTransactionStatus.d.ts +2 -2
  455. package/dist/tools/getTransactionStatus.d.ts.map +0 -0
  456. package/dist/tools/getTransactionStatus.js +0 -0
  457. package/dist/tools/getTransactionStatus.js.map +0 -0
  458. package/dist/tools/getWalletBalance.d.ts +38 -3
  459. package/dist/tools/getWalletBalance.d.ts.map +1 -1
  460. package/dist/tools/getWalletBalance.js +92 -52
  461. package/dist/tools/getWalletBalance.js.map +1 -1
  462. package/dist/tools/publishRiskScore.d.ts +36 -14
  463. package/dist/tools/publishRiskScore.d.ts.map +1 -1
  464. package/dist/tools/publishRiskScore.js +80 -32
  465. package/dist/tools/publishRiskScore.js.map +1 -1
  466. package/dist/tools/queryGoldsky.d.ts +20 -0
  467. package/dist/tools/queryGoldsky.d.ts.map +1 -0
  468. package/dist/tools/queryGoldsky.js +29 -0
  469. package/dist/tools/queryGoldsky.js.map +1 -0
  470. package/dist/tools/queryRiskRegistry.d.ts +14 -14
  471. package/dist/tools/queryRiskRegistry.d.ts.map +1 -1
  472. package/dist/tools/queryRiskRegistry.js +34 -30
  473. package/dist/tools/queryRiskRegistry.js.map +1 -1
  474. package/dist/tools/safehandsPreflightCheck.d.ts +29 -14
  475. package/dist/tools/safehandsPreflightCheck.d.ts.map +1 -1
  476. package/dist/tools/safehandsPreflightCheck.js +133 -6
  477. package/dist/tools/safehandsPreflightCheck.js.map +1 -1
  478. package/dist/tools/safehandsRiskReport.d.ts +29 -14
  479. package/dist/tools/safehandsRiskReport.d.ts.map +1 -1
  480. package/dist/tools/safehandsRiskReport.js +23 -3
  481. package/dist/tools/safehandsRiskReport.js.map +1 -1
  482. package/dist/tools/safehandsSafeExecute.d.ts +1 -1
  483. package/dist/tools/safehandsSafeExecute.d.ts.map +1 -1
  484. package/dist/tools/safehandsSafeExecute.js +100 -17
  485. package/dist/tools/safehandsSafeExecute.js.map +1 -1
  486. package/dist/tools/safehandsWalletHealth.d.ts +15 -1
  487. package/dist/tools/safehandsWalletHealth.d.ts.map +1 -1
  488. package/dist/tools/safehandsWalletHealth.js +67 -25
  489. package/dist/tools/safehandsWalletHealth.js.map +1 -1
  490. package/dist/tools/safehandsX402Preflight.d.ts +3 -3
  491. package/dist/tools/safehandsX402Preflight.d.ts.map +1 -1
  492. package/dist/tools/safehandsX402Preflight.js +24 -3
  493. package/dist/tools/safehandsX402Preflight.js.map +1 -1
  494. package/dist/tools/sendPayment.d.ts +10 -4
  495. package/dist/tools/sendPayment.d.ts.map +1 -1
  496. package/dist/tools/sendPayment.js +63 -36
  497. package/dist/tools/sendPayment.js.map +1 -1
  498. package/dist/tools/setAgentPolicy.d.ts +75 -0
  499. package/dist/tools/setAgentPolicy.d.ts.map +1 -0
  500. package/dist/tools/setAgentPolicy.js +80 -0
  501. package/dist/tools/setAgentPolicy.js.map +1 -0
  502. package/dist/tools/simulateTransaction.d.ts +7 -3
  503. package/dist/tools/simulateTransaction.d.ts.map +1 -1
  504. package/dist/tools/simulateTransaction.js +42 -9
  505. package/dist/tools/simulateTransaction.js.map +1 -1
  506. package/dist/tools/tokenRegistryStatus.d.ts +25 -5
  507. package/dist/tools/tokenRegistryStatus.d.ts.map +1 -1
  508. package/dist/tools/tokenRegistryStatus.js +61 -31
  509. package/dist/tools/tokenRegistryStatus.js.map +1 -1
  510. package/dist/tools/verifyRiskInclusion.d.ts +59 -0
  511. package/dist/tools/verifyRiskInclusion.d.ts.map +1 -0
  512. package/dist/tools/verifyRiskInclusion.js +40 -0
  513. package/dist/tools/verifyRiskInclusion.js.map +1 -0
  514. package/dist/tools/x402PayAndFetch.d.ts +15 -9
  515. package/dist/tools/x402PayAndFetch.d.ts.map +1 -1
  516. package/dist/tools/x402PayAndFetch.js +163 -20
  517. package/dist/tools/x402PayAndFetch.js.map +1 -1
  518. package/dist/worker.d.ts +3 -0
  519. package/dist/worker.d.ts.map +1 -0
  520. package/dist/worker.js +39 -0
  521. package/dist/worker.js.map +1 -0
  522. package/dist/x402Server.d.ts +1 -1
  523. package/dist/x402Server.d.ts.map +1 -1
  524. package/dist/x402Server.js +144 -35
  525. package/dist/x402Server.js.map +1 -1
  526. package/docs/REVIEWER_QUICKSTART.md +113 -0
  527. package/docs/SAFEHANDS_REVIEWER_DEMO_SCRIPT.md +228 -0
  528. package/package.json +131 -73
  529. package/contracts/RiskRegistry.json +0 -223
  530. package/contracts/RiskRegistry.sol +0 -58
  531. package/dist/lib/testDodoLive.d.ts +0 -2
  532. package/dist/lib/testDodoLive.d.ts.map +0 -1
  533. package/dist/lib/testDodoLive.js +0 -105
  534. package/dist/lib/testDodoLive.js.map +0 -1
  535. package/dist/lib/testLiveSafehands.d.ts +0 -2
  536. package/dist/lib/testLiveSafehands.d.ts.map +0 -1
  537. package/dist/lib/testLiveSafehands.js +0 -93
  538. package/dist/lib/testLiveSafehands.js.map +0 -1
  539. package/dist/lib/testRpc.d.ts +0 -2
  540. package/dist/lib/testRpc.d.ts.map +0 -1
  541. package/dist/lib/testRpc.js +0 -30
  542. package/dist/lib/testRpc.js.map +0 -1
  543. package/dist/lib/testRpcLive.d.ts +0 -2
  544. package/dist/lib/testRpcLive.d.ts.map +0 -1
  545. package/dist/lib/testRpcLive.js +0 -89
  546. package/dist/lib/testRpcLive.js.map +0 -1
  547. package/dist/lib/testTools.d.ts +0 -2
  548. package/dist/lib/testTools.d.ts.map +0 -1
  549. package/dist/lib/testTools.js +0 -397
  550. package/dist/lib/testTools.js.map +0 -1
  551. package/dist/lib/testX402Live.d.ts +0 -2
  552. package/dist/lib/testX402Live.d.ts.map +0 -1
  553. package/dist/lib/testX402Live.js +0 -160
  554. package/dist/lib/testX402Live.js.map +0 -1
  555. package/dist/scripts/checkDeploy.d.ts +0 -2
  556. package/dist/scripts/checkDeploy.d.ts.map +0 -1
  557. package/dist/scripts/checkDeploy.js +0 -25
  558. package/dist/scripts/checkDeploy.js.map +0 -1
  559. package/dist/scripts/deployRegistry.d.ts +0 -2
  560. package/dist/scripts/deployRegistry.d.ts.map +0 -1
  561. package/dist/scripts/deployRegistry.js +0 -101
  562. package/dist/scripts/deployRegistry.js.map +0 -1
  563. package/dist/scripts/testRegistry.d.ts +0 -2
  564. package/dist/scripts/testRegistry.d.ts.map +0 -1
  565. package/dist/scripts/testRegistry.js +0 -44
  566. package/dist/scripts/testRegistry.js.map +0 -1
package/README.md CHANGED
@@ -1,444 +1,301 @@
1
- # SafeHands-Pharos — Transaction Safety Firewall for AI Agents
2
-
3
- > **Most Pharos skills let an agent *do* things — check balances, swap, pay, deploy.**
4
- > **SafeHands is the one that decides whether the agent *should*.**
5
-
6
- ```bash
7
- npx safehands-pharos skill safehands_preflight_check --input-json \
8
- '{"actionType":"approve_token","chainId":688689,"tokenAddress":"0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8","spenderAddress":"0x000000000000000000000000000000000000dEaD","approvalAmount":"max"}'
9
- ```
10
-
11
- Sample output:
12
-
13
- ```json
14
- {
15
- "success": true,
16
- "data": {
17
- "decision": "BLOCK",
18
- "riskLevel": "HIGH",
19
- "safeToExecute": false,
20
- "reasons": [
21
- "Unlimited approval requested."
22
- ],
23
- "requiredActions": [
24
- "Use a limited approval amount."
25
- ],
26
- "checks": [
27
- { "name": "mainnet_guard", "status": "pass", "message": "Action is not targeting mainnet." },
28
- { "name": "chain_id", "status": "pass", "message": "Chain ID is Pharos Atlantic Testnet (688689)." },
29
- { "name": "environment", "status": "pass", "message": "Environment is atlantic-testnet." },
30
- { "name": "approval_amount", "status": "fail", "message": "Unlimited approval is blocked by default." }
31
- ],
32
- "environment": "atlantic-testnet",
33
- "chainId": 688689,
34
- "isMainnet": false,
35
- "tokenRegistry": {
36
- "symbol": "USDC",
37
- "status": "SKILL_ENGINE_CANONICAL_TOKEN",
38
- "verificationStatus": "DOCS_VERIFIED_FROM_PHAROS_SKILL_ENGINE"
39
- },
40
- "source": "safehands_preflight_check"
41
- },
42
- "error": null,
43
- "timestamp": "2026-06-14T00:00:00.000Z"
44
- }
45
- ```
46
-
47
- That's the whole idea: **before** an agent approves a token, swaps, sends a payment,
48
- or pays an x402 resource, SafeHands runs a policy check and returns `ALLOW`, `WARN`,
49
- or `BLOCK` with a plain-English reason. If `BLOCK`, the agent stops. No transaction,
50
- no loss.
51
-
52
- **Live preflight examples:** see [DEMO.md](DEMO.md) — real ALLOW and BLOCK outputs.
53
-
54
- <p align="center">
55
- <img src="https://img.shields.io/badge/TypeScript-3178C6?style=for-the-badge&logo=typescript&logoColor=white" />
56
- <img src="https://img.shields.io/badge/MCP_Skill-000000?style=for-the-badge" />
57
- <img src="https://img.shields.io/badge/Pharos_Atlantic-688689-blueviolet?style=for-the-badge" />
58
- <img src="https://img.shields.io/badge/Tools-27-orange?style=for-the-badge" />
59
- <img src="https://img.shields.io/badge/Testnet_Only-SAFE-blue?style=for-the-badge" />
60
- </p>
61
-
62
- > **Testnet only.** SafeHands targets Pharos Atlantic Testnet (Chain ID 688689). Not audited for mainnet use.
63
-
64
- ---
65
-
66
- ## Why AI Agents Need This
67
-
68
- Generic Web3 tools answer: *"Can this transaction be sent?"*
69
- SafeHands answers: **"Should this action be allowed at all?"**
70
-
71
- | Risk | What goes wrong without SafeHands | SafeHands guardrail |
72
- |------|----------------------------------|---------------------|
73
- | Unlimited approval | Agent approves malicious spender forever | Blocked by default |
74
- | Wrong chain | Agent signs on mainnet by mistake | Blocked |
75
- | Risky x402 URL | Agent pays a localhost / private IP | Blocked (SSRF guard) |
76
- | Overspending | Agent drains wallet in one session | Daily cap enforced |
77
- | Unknown token | Agent swaps unverified contract | Warns, requires review |
78
- | Missing signer | Agent attempts write without wallet | Structured error returned |
79
-
80
- SafeHands is a **Pharos Skill Engine-compatible MCP package** — a composable guardrail layer that any agent can add in front of any action, without modifying existing skill logic.
81
-
82
- ---
83
-
84
- ## Getting Started
85
-
86
- ### Step 1 — Try it now (no setup, no wallet)
87
-
88
- ```bash
89
- npx safehands-pharos --demo
90
- ```
91
-
92
- Runs 10 live safety checks in your terminal: ALLOW/BLOCK decisions, wallet health, token registry, x402 preflight, risk report. No config, no private key, no transactions.
93
-
94
- ---
95
-
96
- ### Step 2 — Connect to your AI agent
97
-
98
- Pick **one** depending on how you use AI agents:
99
-
100
- #### Claude Desktop
101
-
102
- Add to your `claude_desktop_config.json`, then restart Claude Desktop:
103
-
104
- ```json
105
- {
106
- "mcpServers": {
107
- "safehands": {
108
- "command": "npx",
109
- "args": ["safehands-pharos"]
110
- }
111
- }
112
- }
113
- ```
114
-
115
- All 27 SafeHands tools appear automatically in every Claude conversation.
116
-
117
- #### Anvita Flow
118
-
119
- Add as an MCP server in Anvita Flow settings:
120
-
121
- ```json
122
- { "command": "npx", "args": ["safehands-pharos"] }
123
- ```
124
-
125
- #### Terminal / scripts (CLI)
126
-
127
- Call any tool directly without connecting to an AI client:
128
-
129
- ```bash
130
- npx safehands-pharos skill safehands_preflight_check \
131
- '{"actionType":"send_payment","chainId":688689,"amount":"0.001","recipient":"0x1234567890123456789012345678901234567890"}'
132
- ```
133
-
134
- ---
135
-
136
- ### Step 3 — (Optional) Enable write operations
137
-
138
- By default, SafeHands is **read-only**: preflight checks, risk scoring, token registry, wallet health. No private key needed.
139
-
140
- To unlock swaps, payments, and approvals, run the setup wizard:
141
-
142
- ```bash
143
- npx safehands-pharos init
144
- ```
145
-
146
- Or set manually in a `.env` file in your working directory:
147
-
148
- ```env
149
- WALLET_MODE=env # env | managed-testnet
150
- PRIVATE_KEY=0x... # testnet key only — never mainnet
151
- WRITE_TOOLS_ENABLED=true
152
- MAX_TX_AMOUNT_PHRS=0.1 # per-transaction cap
153
- MAX_DAILY_SPEND_USD=10 # daily spend cap
154
- ```
155
-
156
- ---
157
-
158
- ## Calling Tools from the CLI
159
-
160
- ```bash
161
- # Short form (recommended)
162
- npx safehands-pharos skill <tool> '<json>'
163
-
164
- # With flag
165
- npx safehands-pharos skill <tool> -i '<json>'
166
-
167
- # Explicit flag
168
- npx safehands-pharos skill <tool> --input-json '<json>'
169
- ```
170
-
171
- Examples:
172
-
173
- ```bash
174
- # Preflight check before a swap
175
- npx safehands-pharos skill safehands_preflight_check \
176
- '{"actionType":"execute_swap","tokenIn":"PHRS","tokenOut":"USDC","amount":"0.01","chainId":688689,"isMainnet":false}'
177
-
178
- # Check wallet balance
179
- npx safehands-pharos skill get_wallet_balance \
180
- '{"walletAddress":"0xYourWallet"}'
181
-
182
- # Assess risk score
183
- npx safehands-pharos skill assess_risk \
184
- '{"action":"swap","tokenIn":"PHRS","tokenOut":"USDC","amount":"0.01","walletAddress":"0xYourWallet"}'
185
-
186
- # Classify a token address
187
- npx safehands-pharos skill token_registry_status \
188
- '{"tokenAddress":"0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8"}'
189
- ```
190
-
191
- ---
192
-
193
- ## All 27 Tools
194
-
195
- All tools return the same response envelope:
196
-
197
- ```json
198
- {
199
- "success": true,
200
- "data": { ... },
201
- "error": null,
202
- "timestamp": "2026-06-13T00:00:00.000Z"
203
- }
204
- ```
205
-
206
- On failure: `success: false`, `data: null`, `error: { code, message, retryable }`.
207
-
208
- ### SafeHands Guardrail Tools
209
-
210
- | Tool | What it does | CLI |
211
- |------|-------------|-----|
212
- | `safehands_preflight_check` | ALLOW / WARN / BLOCK before any action | |
213
- | `safehands_safe_execute` | Preflight + execute in one call | ✓ |
214
- | `safehands_wallet_health` | Wallet, signer, gas, x402 readiness | ✓ |
215
- | `safehands_x402_preflight` | URL safety + payment check before x402 | ✓ |
216
- | `safehands_risk_report` | Human-readable risk summary | |
217
- | `explain_risk` | Translate ALLOW/WARN/BLOCK into plain English | ✓ |
218
- | `token_registry_status` | Canonical / custom / unknown token check | ✓ |
219
-
220
- ### Safety & Analysis Tools
221
-
222
- | Tool | What it does | CLI |
223
- |------|-------------|-----|
224
- | `assess_risk` | 5-dimension risk score (0–100) | ✓ |
225
- | `check_token_security` | GoPlus token security profile | |
226
- | `simulate_transaction` | Dry-run before broadcasting | ✓ |
227
- | `estimate_gas` | Gas estimate + sufficiency check | ✓ |
228
- | `check_allowance` | ERC-20 allowance check | MCP |
229
-
230
- ### Market & Chain Data
231
-
232
- | Tool | What it does | CLI |
233
- |------|-------------|-----|
234
- | `get_wallet_balance` | PHRS / USDC / USDT balances | |
235
- | `get_token_price` | Token price via DODO | ✓ |
236
- | `get_gas_price` | Current network gas price | MCP |
237
- | `get_pool_info` | FaroSwap / DODO pool info | MCP |
238
- | `get_transaction_status` | TX status by hash | ✓ |
239
- | `get_execution_history` | Wallet transfer history (ERC-20 + native) | MCP |
240
-
241
- ### Write Tools *(require `WRITE_TOOLS_ENABLED=true`)*
242
-
243
- | Tool | What it does | CLI |
244
- |------|-------------|-----|
245
- | `execute_swap` | Swap tokens via FaroSwap / DODO | MCP |
246
- | `send_payment` | Send native PHRS | MCP |
247
- | `approve_token` | ERC-20 approval (unlimited blocked by default) | MCP |
248
- | `publish_risk_score` | Publish risk score to RiskRegistry contract | MCP |
249
- | `x402_pay_and_fetch` | Fetch x402 resource, pay only after HTTP 402 | MCP |
250
-
251
- ### Risk Registry
252
-
253
- | Tool | What it does | CLI |
254
- |------|-------------|-----|
255
- | `query_risk_registry` | Read on-chain risk score | ✓ |
256
-
257
- ### Managed Wallet Tools
258
-
259
- | Tool | What it does | CLI |
260
- |------|-------------|-----|
261
- | `create_agent_wallet` | Create testnet wallet (AES-256-GCM encrypted) | ✓ |
262
- | `get_agent_wallet` | Wallet address + metadata (no private key) | ✓ |
263
- | `get_agent_wallet_balance` | Managed wallet balances | ✓ |
264
-
265
- > **CLI** = callable via `npx safehands-pharos skill <tool> '<json>'`
266
- > **MCP** = available via Claude Desktop / Anvita Flow only
267
-
268
- ---
269
-
270
- ## Configuration
271
-
272
- If you cloned the repo, copy the example file:
273
-
274
- ```bash
275
- cp .env.example .env # then edit .env with your settings
276
- ```
277
-
278
- If you installed via `npx` or `npm install`, create a `.env` in your working directory with these settings:
279
-
280
- ```env
281
- # Wallet mode
282
- WALLET_MODE=none # none | env | managed-testnet
283
- PRIVATE_KEY= # required when WALLET_MODE=env
284
- WALLET_STORE_PATH= # optional: persist managed wallets to disk
285
-
286
- # Write gates (all off by default)
287
- WRITE_TOOLS_ENABLED=false
288
- ALLOW_UNLIMITED_APPROVAL=false
289
-
290
- # Spend limits
291
- MAX_TX_AMOUNT_PHRS=0.1 # max PHRS per transaction
292
- MAX_DAILY_SPEND_USD=10 # daily cap across all wallets
293
- PHRS_USD_PRICE=1.0 # used for daily spend accounting
294
-
295
- # DODO API (required for swaps and price data)
296
- DODO_API_KEY=
297
- ```
298
-
299
- ### Wallet modes explained
300
-
301
- | Mode | How it works |
302
- |------|-------------|
303
- | `none` | No signer — read-only tools only (safe default) |
304
- | `env` | Reads `PRIVATE_KEY` from `.env` |
305
- | `managed-testnet` | Uses wallet created via `create_agent_wallet` |
306
-
307
- ### Persistent managed wallets
308
-
309
- By default, wallets created with `create_agent_wallet` are in-memory and lost on restart. To persist them:
310
-
311
- ```env
312
- WALLET_STORE_PATH=./.agents/wallets.json
313
- WALLET_ENCRYPTION_KEY=your-strong-secret
314
- ```
315
-
316
- Private keys are AES-256-GCM encrypted on disk. The `.agents/` folder is gitignored.
317
-
318
- ---
319
-
320
- ## Security Defaults
321
-
322
- SafeHands ships safe by default — nothing is enabled without explicit opt-in:
323
-
324
- - `WRITE_TOOLS_ENABLED=false` — no on-chain writes without opt-in
325
- - `WALLET_MODE=none` — no signer loaded on startup
326
- - Unlimited token approvals blocked
327
- - Mainnet actions blocked
328
- - SSRF-sensitive x402 URLs blocked
329
- - Private keys never returned in responses or logs
330
- - Daily spend cap enforced in-memory per wallet
331
-
332
- ---
333
-
334
- ## x402 Support
335
-
336
- SafeHands acts as both an x402 client and server.
337
-
338
- **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.
339
-
340
- **Server** (`npm run x402-server`): Exposes paid endpoints. A live instance runs at:
341
-
342
- ```
343
- https://safehands-pharos-production.up.railway.app
344
- ```
345
-
346
- | Endpoint | Type | Price |
347
- |----------|------|-------|
348
- | `GET /supported` | Free | — |
349
- | `GET /health` | Free | — |
350
- | `GET /assess-risk` | Paid | 0.001 USDC |
351
- | `GET /check-token-security` | Paid | 0.001 USDC |
352
- | `GET /simulate-transaction` | Paid | 0.001 USDC |
353
-
354
- ---
355
-
356
- ## Examples
357
-
358
- **Prompt-injection attack scenario** — SafeHands blocking an unlimited token approval triggered by a simulated prompt-injection attack:
359
-
360
- ```bash
361
- npx safehands-pharos skill safehands_preflight_check \
362
- '{"actionType":"approve_token","chainId":688689,"approvalAmount":"max","spender":"0xBadActor12300000000000000000000000000000"}'
363
- ```
364
-
365
- Expected output: `BLOCK` — `"Unlimited approval is blocked by default."`
366
-
367
- **Live server** — the SafeHands x402 server runs at:
368
-
369
- ```
370
- https://safehands-pharos-production.up.railway.app
371
- ```
372
-
373
- Hit `/preflight?actionType=send_payment&amount=0.001&chainId=688689&recipient=0x1234...` for a live ALLOW/WARN/BLOCK response with no setup required.
374
-
375
- ---
376
-
377
- ## Network Info
378
-
379
- | Item | Value |
380
- |------|-------|
381
- | Chain ID | `688689` |
382
- | RPC | `https://atlantic.dplabs-internal.com` |
383
- | Explorer | `https://atlantic.pharosscan.xyz` |
384
- | USDC | `0xE0BE08c77f415F577A1B3A9aD7a1Df1479564ec8` |
385
- | RiskRegistry | `0x61962a6c812ee9f57b207e1ea47c19ae70bb7141` |
386
-
387
- **Proof of life — live on-chain tx:**
388
-
389
- | What | Value |
390
- |------|-------|
391
- | Action | `publish_risk_score` → RiskRegistry |
392
- | Tx Hash | [`0x6a58f636...fdefc`](https://atlantic.pharosscan.xyz/tx/0x6a58f636814458c09304db3d7c4f5f48e764f6439649fbb786cddb32c77fdefc) |
393
- | Block | `24168297` |
394
- | Gas Used | `140,187` |
395
-
396
- ---
397
-
398
- ## Testing
399
-
400
- ```bash
401
- npm run build # compile TypeScript
402
- npm run demo # run 10 live safety checks in terminal (no wallet needed)
403
- npm run dev # run MCP server in dev mode (tsx, no build step)
404
- ```
405
-
406
- For manual testing, use the CLI directly after building:
407
-
408
- ```bash
409
- # Build first
410
- npm run build
411
-
412
- # Then call any tool
413
- node dist/index.js skill safehands_preflight_check \
414
- '{"actionType":"approve_token","chainId":688689,"approvalAmount":"max"}'
415
- ```
416
-
417
- ---
418
-
419
- ## Known Limitations
420
-
421
- - Testnet-only — not audited for mainnet
422
- - Managed wallet encryption is AES-256-GCM but not KMS/Vault grade
423
- - `get_token_price` and swap routing require a DODO API key
424
- - GoPlus token security does not support Pharos testnet (Chain 688689) — `check_token_security` returns a clear error
425
- - DODO reverse routes (e.g. USDT → PHRS) have no liquidity on testnet
426
- - x402 client and server are implemented with the official `@x402/fetch` and `@x402/evm` SDKs and verified against a local x402-compatible server. They have not yet been verified against live third-party x402 endpoints on Pharos.
427
-
428
- ---
429
-
430
- ## Roadmap
431
-
432
- SafeHands is designed to grow from a single-project guardrail into **shared safety infrastructure** for the Pharos agent economy.
433
-
434
- **Near-term**
435
- - **Per-agent spend limits** — a `set_spend_limits` / `get_spend_limits` tool pair so each agent carries its own policy instead of a shared global cap. Stored in the existing AES-256-GCM encrypted wallet store.
436
- - **x402 live endpoint verification** — validate SafeHands's x402 preflight against production third-party x402 endpoints on Pharos as they become available.
437
-
438
- **Medium-term**
439
- - **Community risk registry** — as more agents publish scores to the on-chain RiskRegistry (`0x61962a6c812ee9f57b207e1ea47c19ae70bb7141`), `query_risk_registry` becomes shared reputation infrastructure. A malicious contract blocked by one agent is flagged for all agents across the ecosystem.
440
- - **Cross-chain x402 guardrails** — SafeHands's x402 preflight logic is protocol-level, not Pharos-specific. The same guardrail pattern can protect agents making x402 payments on AgentCash (Base / Solana) or any other compatible network.
441
-
442
- **Long-term**
443
- - **Mainnet support** — currently testnet-only by design. Mainnet requires a full re-audit of every safety check, formal verification of the RiskRegistry contract, and KMS/Vault-grade key management before it can be trusted with real funds.
444
- - **Standardized guardrail interface** — a community spec so any Pharos skill can expose a `preflight(action) → ALLOW | WARN | BLOCK` interface and compose with SafeHands, rather than each skill reinventing safety logic independently.
1
+ <p align="center">
2
+ <img src="assets/banner.svg" alt="SafeHands: the transaction firewall for AI agent finance on Pharos Pacific Mainnet" width="100%">
3
+ </p>
4
+
5
+ # SafeHands
6
+
7
+ **The transaction firewall for AI agent finance on Pharos: deterministic `ALLOW` / `REQUIRE_CONFIRMATION` / `BLOCK` verdicts *before* a wallet signs.**
8
+
9
+ *No custody. No blind signing. Policy first, execution second.*
10
+
11
+ AI agents are starting to run real financial workflows on Pharos: payments, treasury actions, swaps, bridges, liquidity operations, and interactions with tokenized real-world assets. An agent doing that work can sign almost anything: an unlimited token approval, a swap on the wrong chain, a payment to a malicious x402 endpoint, a transfer of a tokenized asset to an unvetted counterparty. SafeHands is the firewall that stands *before* the signature. A deterministic policy engine analyzes each intent (calldata, token, spender, counterparty, amount, chain) and returns one of four verdicts (`ALLOW`, `BLOCK`, `REQUIRE_CONFIRMATION`, `PREPARE_ONLY`) with a plain-English reason. You act on your own wallet; SafeHands never holds keys and never signs for you.
12
+
13
+ In **hosted Anvita mode**, SafeHands provides no-custody, read-only safety verdicts; it does not sign, broadcast, or execute transactions today. In **self-hosted integrations**, the same policy model can gate execution itself. It ships as an MCP server, an HTTP API, and a CLI, exposing 33 tools that any agent in the Pharos ecosystem can call against Pharos Pacific Mainnet (chain `1672`).
14
+
15
+ [![CI](https://github.com/SZtch/safehands-pharos/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/SZtch/safehands-pharos/actions/workflows/ci.yml)
16
+ ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)
17
+ ![Pharos Pacific Mainnet](https://img.shields.io/badge/Pharos_Pacific_Mainnet-1672-6d28d9)
18
+ ![33 tools](https://img.shields.io/badge/tools-33-0891b2)
19
+ ![Hosted mode: no-custody verdict](https://img.shields.io/badge/hosted-no--custody_verdict-16a34a)
20
+ ![License: MIT](https://img.shields.io/badge/license-MIT-black)
21
+
22
+ ### Which SafeHands is for me?
23
+
24
+ One deterministic policy engine, delivered where you need the verdict: from a zero-infra hosted call to a self-hosted integration:
25
+
26
+ | You are… | Use | What it is |
27
+ |---|---|---|
28
+ | A **user or Steward agent** that wants a pre-execution verdict | the **Anvita Flow hosted skill** | Zero-infra, no keys, no custody: you get the verdict *before* you sign. The hosted deliverable in [`anvita/safehands/`](anvita/safehands/), live on Anvita Flow as `safehands`. |
29
+ | A **developer** wiring safety into your own agent | the **npm package**: MCP server, CLI & SDK | `npx … --demo`, drop it into any MCP client, or `import { evaluateActionPolicy } from "safehands-pharos"`. The verdict path is the product; write tools are reference-only and stay gated behind env flags + a signer + the same verdict. |
30
+ | An **operator** who wants the HTTP API | the **self-hosted reference backend** | `node dist/api/server.js` → `http://localhost:4022`; free verdict endpoints plus the optional x402-gated `/paid/*` bundle. |
31
+
32
+ > **Read-only hosted mode is a security property, not a tier.** Because the hosted verdict layer holds no keys and signs nothing, every other agent can safely put it *in front of* their transactions: a firewall that can't move funds is one nobody has to trust with funds. Signing stays with you.
33
+
34
+ The compact hosted engine returns an `allow / warn / block` risk recommendation; the full policy engine (npm/API) returns the four-value decision. They map cleanly but score independently, and their thresholds intentionally differ: see [`docs/DECISION_CONTRACT.md`](docs/DECISION_CONTRACT.md), and never compare raw scores across them.
35
+
36
+ ## SafeHands on Anvita Flow
37
+
38
+ SafeHands is live on [Anvita Flow](https://flow.anvita.xyz/home) as **`safehands`**, a fully hosted, non-custodial Service Agent for the Pharos Agent Carnival.
39
+
40
+ Users can ask their Steward Agent to find **`safehands`** and evaluate a blockchain action before signing. The verdict is computed by a deterministic risk engine, not guessed by an LLM.
41
+
42
+ No external server, private keys, or wallet custody are required.
43
+
44
+ Hosted package: [`anvita/safehands/`](anvita/safehands/)
45
+ Integration guide: **[docs/ANVITA_FLOW.md](docs/ANVITA_FLOW.md)**
46
+ Building an agent that should call SafeHands before signing? Start at **[docs/AGENT_INTEGRATION.md](docs/AGENT_INTEGRATION.md)**.
47
+
48
+ ---
49
+ ## Try it in 10 seconds
50
+
51
+ **One command, zero infrastructure**: no config, no wallet, no keys, no transactions:
52
+
53
+ ```bash
54
+ npx -y safehands-pharos --demo
55
+ # (from source: npx -y github:SZtch/safehands-pharos --demo · or locally: git clone → npm install → node dist/index.js --demo)
56
+ ```
57
+
58
+ Watch the deterministic policy engine issue real safety decisions (`ALLOW`, `BLOCK`, `REQUIRE_CONFIRMATION`) against Pharos Pacific Mainnet. It runs twelve deterministic safety checks in your terminal (wallet health, policy decisions, token-registry lookups, x402 preflight, SSRF blocking, risk scoring, RWA transfer-compliance and settlement-cap scenarios) and touches nothing on-chain. The full check list and expected outputs are in [docs/REVIEWER_QUICKSTART.md](docs/REVIEWER_QUICKSTART.md).
59
+
60
+ <details>
61
+ <summary>Sample output: one of the twelve checks</summary>
62
+
63
+ ```text
64
+ $ npx safehands-pharos --demo
65
+
66
+ 🛡️ SafeHands-Pharos Deterministic Demo
67
+ Environment: pacific-mainnet
68
+ Chain ID: 1672
69
+ Mode: non-destructive demo, no real transactions broadcast
70
+
71
+ 3. Unlimited Approval Preflight: BLOCK
72
+
73
+ safehands_preflight_check
74
+ {
75
+ "success": true,
76
+ "data": {
77
+ "decision": "BLOCK",
78
+ "riskLevel": "HIGH",
79
+ "safeToExecute": false,
80
+ "reasons": ["Unlimited approval requested."],
81
+ "requiredActions": ["Use a limited approval amount."]
82
+ },
83
+ "error": null
84
+ }
85
+ ```
86
+
87
+ </details>
88
+
89
+ ## Run the API yourself (optional self-host)
90
+
91
+ To exercise the HTTP API directly, self-host the zero-custody reference backend locally against Pharos Pacific Mainnet; no API key needed for the public surface:
92
+
93
+ ```bash
94
+ npm install --include=dev && npm run build
95
+ node dist/api/server.js # read-only API on http://localhost:4022 (PORT env to change)
96
+ ```
97
+
98
+ ```bash
99
+ # Health + network config
100
+ curl -s http://localhost:4022/health
101
+ curl -s http://localhost:4022/public-config
102
+
103
+ # Real preflight decision from the live policy engine
104
+ curl -s -X POST http://localhost:4022/tools/safehands_preflight_check \
105
+ -H "content-type: application/json" \
106
+ -d '{"actionType":"approve_token","chainId":1672,"approvalToken":"USDC","spender":"0x000000000000000000000000000000000000dEaD","approvalAmount":"max"}'
107
+
108
+ # On-chain reputation read (live attestation contract)
109
+ curl -s -X POST http://localhost:4022/tools/get_agent_reputation \
110
+ -H "content-type: application/json" \
111
+ -d '{"address":"0x6730d3a2A217108AB53CCFe60ffdAd05D3C124e5"}'
112
+
113
+ # x402-gated endpoint. Fail-closed by default: without x402 config this returns 503.
114
+ # With X402_PAY_TO and a reachable external X402_FACILITATOR_URL set, it returns a
115
+ # real HTTP 402 challenge (mainnet USDC, eip155:1672).
116
+ curl -s -i http://localhost:4022/paid/risk-report
117
+ ```
118
+
119
+ Interactive browser demo (while the local API runs): **http://localhost:4022/demo**. Full curl walkthrough: [docs/SAFEHANDS_REVIEWER_DEMO_SCRIPT.md](docs/SAFEHANDS_REVIEWER_DEMO_SCRIPT.md).
120
+
121
+ ---
122
+
123
+ ## What it does
124
+
125
+ SafeHands sits between an agent's *intent* and the *signature*. Before any action, the agent calls `safehands_preflight_check` (or one of the specialized preflight tools) and gets back a decision:
126
+
127
+ <p align="center">
128
+ <img src="assets/architecture.svg" alt="SafeHands architecture: agent intent flows through the deterministic policy engine to a four-value decision; the user signs with their own wallet; Pharos mainnet records the attestation audit trail, risk registry, and composable reputation" width="100%">
129
+ </p>
130
+
131
+ The decision is **deterministic**: the policy engine decides, not a model. An LLM can advise, but it cannot override a policy it dislikes.
132
+
133
+ ### What it catches
134
+
135
+ | Risk | Without SafeHands | With SafeHands |
136
+ |------|-------------------|----------------|
137
+ | Unlimited token approval | Agent grants a malicious spender forever | `BLOCK`: unlimited approvals off by default |
138
+ | Unsupported chain | Agent targets a non-Pharos network (e.g. Ethereum) | `BLOCK`: chain-ID guard |
139
+ | Malicious x402 endpoint | Agent pays a localhost / private-IP URL | `BLOCK`: SSRF + redirect guard |
140
+ | Wallet drain | Agent overspends in one session | `BLOCK`: per-agent + daily spend cap |
141
+ | Unknown token | Agent swaps an unverified contract | `REQUIRE_CONFIRMATION` |
142
+ | Arbitrary contract call | Agent calls an unknown contract | `REQUIRE_CONFIRMATION` |
143
+ | Bad input | Agent passes `-1` or the zero address | `VALIDATION_ERROR` |
144
+ | Unregistered tokenized asset | Agent approves an unknown asset contract to an unverified spender | `REQUIRE_CONFIRMATION`: human review required |
145
+ | Oversized settlement | Agent settles a real-world invoice above the policy cap | `BLOCK`: deterministic spend limit |
146
+
147
+ ## Why this matters for Real-Fi & RWA
148
+
149
+ Pharos is a Real-Fi chain: the environment where agent-driven payments, treasury operations, and tokenized real-world assets settle. Those assets carry obligations memecoins do not (asset legitimacy, transfer restrictions, audit trails, settlement discipline, counterparty trust), and an agent can repeat a mistake a thousand times. SafeHands is the pre-execution safety layer for exactly those obligations: the read/policy path is live on mainnet today, and the write-side attestation path is a working opt-in. Demo scenarios 11-12 show the RWA flows end-to-end; the full live-vs-roadmap mapping is in **[docs/REALFI_RWA_ALIGNMENT.md](docs/REALFI_RWA_ALIGNMENT.md)**.
150
+
151
+ ## What it is, and is not
152
+
153
+ SafeHands is a **transaction firewall**, not a wallet. It is not a custody service, a private-key manager, a signer, a DEX, or a bridge. It does not issue tokenized assets, does not manage real-world assets, and is not a compliance authority: it is the deterministic checkpoint agent-finance flows run through before execution. It renders the verdict; you keep the signature.
154
+
155
+ **Today, hosted (Anvita Flow):** a read-only, zero-custody pre-execution verdict. It holds no keys, signs nothing, broadcasts nothing, and executes nothing. You always sign and send with your own wallet.
156
+
157
+ **Advanced, self-hosted integration (MCP / CLI / SDK / HTTP API):** the same verdict engine, embeddable in your own agent. Execution tools (`execute_swap`, `send_payment`, `approve_token`, …) exist in the codebase as a **reference** for how a signing path binds to the verdict: every write is gated by the policy engine plus the write-execution gate (`actionPolicyEngine` is the sole ALLOW/BLOCK decider; `writeExecutionGate` refuses to proceed without a passing verdict wired in). They are **OFF by default, experimental, and unaudited**, run **self-hosted and single-tenant only**, and the public server refuses to enable them: a boot guard fails fast if managed execution is configured on a public host. The audited, production surface is the read-only verdict layer.
158
+
159
+ ## Execution modes
160
+
161
+ | Mode | Key / wallet | Where it runs | Use for |
162
+ |------|--------------|---------------|---------|
163
+ | **Read-only preflight** *(default)* | none | hosted or local | Safety checks, risk analysis, demos |
164
+ | **User-signed** | your own wallet | anywhere | SafeHands validates; you sign externally, then it verifies + relays the broadcast |
165
+ | **Managed execution** | local encrypted wallet | self-hosted only | Full agent autonomy on mainnet, opt-in |
166
+ | **Env wallet** *(advanced)* | `PRIVATE_KEY` in env | local dev | Local mainnet development |
167
+
168
+ Read-only usage needs no `.env`, no private key, and no authorization.
169
+
170
+ ---
171
+
172
+ ## Install
173
+
174
+ ```bash
175
+ npx skills add SZtch/safehands-pharos
176
+ ```
177
+
178
+ ### Claude Desktop (or any MCP client)
179
+
180
+ Add to `claude_desktop_config.json` and restart. The default is read-only, with no keys, wallet, or setup:
181
+
182
+ ```json
183
+ {
184
+ "mcpServers": {
185
+ "safehands": {
186
+ "command": "npx",
187
+ "args": ["-y", "github:SZtch/safehands-pharos"]
188
+ }
189
+ }
190
+ }
191
+ ```
192
+
193
+ Then ask: *"Run a SafeHands preflight on this payment."*
194
+
195
+ To run **self-hosted managed execution** on your own machine, add an `env` block (`WALLET_MODE=managed-mainnet`, `WRITE_TOOLS_ENABLED=true`). SafeHands creates a local AES-256-GCM-encrypted wallet on first run; you fund it from a faucet and authorize it before write tools unlock. See [.env.example](.env.example) and [docs/PRODUCTION_BACKEND.md](docs/PRODUCTION_BACKEND.md).
196
+
197
+ ### CLI
198
+
199
+ ```bash
200
+ npx safehands-pharos skill safehands_preflight_check \
201
+ '{"actionType":"approve_token","chainId":1672,"approvalToken":"USDC","spender":"0x000000000000000000000000000000000000dEaD","approvalAmount":"max"}'
202
+ ```
203
+
204
+ Every tool returns the same envelope: `{ "success": true, "data": { … }, "error": null, "timestamp": "…" }`.
205
+
206
+ ## The 33 tools
207
+
208
+ One policy engine behind MCP, HTTP, and CLI. The safety-preflight, risk, and market/chain tools are public and keyless; execution tools are OFF by default behind env gates plus the policy verdict. Full catalog: **[docs/TOOLS.md](docs/TOOLS.md)**.
209
+
210
+ ## Per-agent policy
211
+
212
+ Different agents can carry different risk thresholds (`conservative` / `balanced` (default) / `advanced` / `custom`). Hard safety rules (mainnet guard, zero address, SSRF, unauthorized managed execution) are never overridable by any profile. Policies live in `.agents/policies/`; raising a limit requires an explicit saved config, so runtime or prompt injection cannot silently widen it. Profile limits: **[docs/POLICY_PROFILES.md](docs/POLICY_PROFILES.md)**.
213
+
214
+ ## x402
215
+
216
+ SafeHands makes agent-driven x402 payments safer by validating the HTTP 402 requirement before anything is signed or settled:
217
+
218
+ - `safehands_x402_preflight`: no payment, no auth, URL + amount safety
219
+ - `x402_pay_and_fetch`: gated execution behind policy limits
220
+ - SSRF and redirect-SSRF are blocked; payment amount, token, and per-agent caps are enforced
221
+ - Replay/idempotency is backed by a durable store (Upstash Redis when configured, local JSON fallback)
222
+
223
+ ## On-chain registry + attestation
224
+
225
+ SafeHands deploys two contracts to Pharos Pacific Mainnet: a **registry** (authorized operators/agents, Merkle risk roots, `verifyRiskRecord` view) and an **attestation** contract (privacy-preserving verified-safe records + reputation).
226
+
227
+ | | |
228
+ |---|---|
229
+ | Registry | [`0x428e02bf85412e7242d991cd6725ec59e8b06c8d`](https://www.pharosscan.xyz/address/0x428e02bf85412e7242d991cd6725ec59e8b06c8d) |
230
+ | Attestation | [`0x71a7a87b3b1ab6d86204cad691bb32fd75b4588c`](https://www.pharosscan.xyz/address/0x71a7a87b3b1ab6d86204cad691bb32fd75b4588c) |
231
+ | Network | Pharos Pacific Mainnet (chain `1672`) |
232
+ | Source | `contracts/SafeHandsRegistry.sol`, `contracts/SafeHandsAttestation.sol` |
233
+
234
+ When the attested-broadcast path is enabled and a user-signed transaction is broadcast successfully, SafeHands writes an attestation on-chain: hashed context only (`preparedTransactionHash`, `policyHash`, `metadataHash`) plus the `txHash`, never raw calldata, keys, amounts, recipients, or intent. Attestation gas is paid by a dedicated `SAFEHANDS_ATTESTER_PRIVATE_KEY` separate from any user wallet. The backend reads the contract addresses from `SAFEHANDS_REGISTRY_ADDRESS` / `SAFEHANDS_ATTESTATION_ADDRESS`, so you can point at your own redeploy without touching code.
235
+
236
+ ## Network
237
+
238
+ | | Pharos Pacific Mainnet |
239
+ |---|---|
240
+ | Chain ID | `1672` |
241
+ | Native token | `PROS` |
242
+ | RPC | `https://rpc.pharos.xyz` |
243
+ | Explorer | `https://www.pharosscan.xyz` |
244
+
245
+ Pharos Atlantic Testnet (`688689`) remains readable for legacy checks but is deprecated for execution.
246
+
247
+ ## Security defaults
248
+
249
+ SafeHands ships closed. Nothing runs without an explicit opt-in:
250
+
251
+ - `WRITE_TOOLS_ENABLED=false`: no write tools
252
+ - `WALLET_MODE=none`: no wallet created (`managed-mainnet` is opt-in, self-hosted only)
253
+ - Unlimited approvals blocked
254
+ - Mainnet execution disabled until write/signing env gates are set
255
+ - SSRF-sensitive URLs blocked
256
+ - Private keys never returned in responses or logs
257
+ - Per-agent policy limits and daily spend caps enforced
258
+ - Managed execution gated by on-chain registry authorization
259
+ - A boot guard refuses managed/write execution on a public host
260
+
261
+ ---
262
+
263
+ ## Testing
264
+
265
+ ```bash
266
+ npm run build # compile
267
+ npm test # hermetic deterministic suite (policy, x402 gate, write-auth, risk-inclusion; no network)
268
+ npm run demo # live safety checks in the terminal
269
+ npm run test:contracts # Hardhat contract tests (offline smoke fallback)
270
+ npm run test:all # build + test + demo + contracts
271
+ ```
272
+
273
+ `npm test` needs no wallet, key, or network and never broadcasts. Live read-only RPC checks run separately via `npm run test:live`. The live user-signed broadcast path is opt-in (`SAFEHANDS_USER_SIGNED_BROADCAST_ENABLED=true SAFEHANDS_LIVE_BROADCAST_TEST=true npm run test:live-broadcast`).
274
+
275
+ ## Configuration
276
+
277
+ Read-only preflight works with **no `.env` at all**. Every write/execution/attestation capability is opt-in behind an env flag. The full annotated reference (network, safety gates, managed execution, attestation, x402, production hosting) is in **[.env.example](.env.example)**; self-host operations are in **[docs/PRODUCTION_BACKEND.md](docs/PRODUCTION_BACKEND.md)**.
278
+
279
+ ## Known limitations
280
+
281
+ - Managed-wallet encryption is AES-256-GCM, not KMS/Vault-grade; not intended for custody of large amounts.
282
+ - User-signed broadcast (`POST /broadcast/signed`) is live but disabled by default; without `SAFEHANDS_USER_SIGNED_BROADCAST_ENABLED=true` it runs verify-only.
283
+ - GoPlus token security does not cover Pharos testnet (`688689`). On Pacific Mainnet (`1672`) GoPlus coverage is still new: tokens it has not yet indexed return a fail-closed `UNVERIFIED` result (never "safe").
284
+ - Canonical token prices come from Chainlink Push Engine feeds on Pharos Pacific Mainnet. If the public RPC is temporarily rate-limited, SafeHands may serve a clearly flagged bounded cached oracle value; stale feeds fail closed.
285
+ - DODO / FaroSwap route checks can occasionally lack liquidity for exotic pairs; this affects pool/route/swap tooling, not canonical `get_token_price`.
286
+
287
+ ## Roadmap
288
+
289
+ The goal: be the safety decision every AI agent consults *before* it acts on-chain. One rule holds throughout: **the safety verdict stays deterministic. The model advises; the policy engine decides.** The arc is a single verdict engine moving from *advising* an action (hosted, today) to *gating* it (verdict-bound signing) without the safety logic ever changing.
290
+
291
+ **Shipped (v2.8.0):** 33-tool agent surface across MCP, HTTP, and CLI; hosted Anvita engine at read-path capability parity (offline calldata/approval decoding, dangerous-admin recognition, MultiSend aggregation, operator recipient denylist), plus registry-only name resolution (`resolve_alias`), wallet balance and portfolio reads valued via live Chainlink with a holdings-exposure factor on fund-moving intents, EIP-1967 proxy inspection, ERC-4626 vault / AMM pool safety probes with escalate-only composition, an approval-hygiene sweep (`get_active_approvals`: canonical tokens x registry-verified spenders, live allowance reads), verdict hash-binding (keccak256 digest + expiry on intent and calldata verdicts), a chain-identity-checked fallback RPC, and Merkle-verified on-chain records (the committed batch is rebuilt and matched against `currentMerkleRoot` before any record is shown, and withheld in full if it does not match); deterministic policy engine (mainnet guard, approval limits, SSRF guard, spend caps); `execute_swap` with a second, registry-verified venue (OKX DEX aggregator; reference write path, off by default); registry + attestation contracts live on Pharos Pacific Mainnet; GoPlus token-security and Goldsky indexing; x402 preflight and gated `pay_and_fetch`.
292
+
293
+ **Next:** L1 risk-root committer automation, a data-availability serving endpoint, broader cross-agent reputation reads, and compliance-provider integrations for RWA flows (TRM Labs screening, Circle CCTP settlement; currently roadmap, not integrated).
294
+
295
+ **Contracts v2 (designed, not scheduled):** committed-root history, content-addressed data availability (IPFS CID instead of a mutable URL), verdict revocation, reproducible verdicts, and intent tickets that bind a verdict to one exact transaction. Full reasoning: **[docs/CONTRACTS_V2_DESIGN.md](docs/CONTRACTS_V2_DESIGN.md)**.
296
+
297
+ ---
298
+
299
+ ## License
300
+
301
+ MIT © [SZtch](https://github.com/SZtch)