safehands-pharos 1.4.0 → 2.6.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.
- package/.agents/policies/default.json +15 -0
- package/.env.example +81 -64
- package/README.md +301 -333
- package/SECURITY.md +112 -0
- package/SKILL.md +59 -0
- package/contracts/SafeHandsAttestation.sol +182 -0
- package/contracts/SafeHandsRegistry.sol +149 -0
- package/dist/agent/SafeHandsGuardianAgent.d.ts +39 -0
- package/dist/agent/SafeHandsGuardianAgent.d.ts.map +1 -0
- package/dist/agent/SafeHandsGuardianAgent.js +98 -0
- package/dist/agent/SafeHandsGuardianAgent.js.map +1 -0
- package/dist/agent/agentDecisionFormatter.d.ts +43 -0
- package/dist/agent/agentDecisionFormatter.d.ts.map +1 -0
- package/dist/agent/agentDecisionFormatter.js +96 -0
- package/dist/agent/agentDecisionFormatter.js.map +1 -0
- package/dist/agent/agentEnrich.d.ts +28 -0
- package/dist/agent/agentEnrich.d.ts.map +1 -0
- package/dist/agent/agentEnrich.js +99 -0
- package/dist/agent/agentEnrich.js.map +1 -0
- package/dist/agent/agentIntentClassifier.d.ts +44 -0
- package/dist/agent/agentIntentClassifier.d.ts.map +1 -0
- package/dist/agent/agentIntentClassifier.js +77 -0
- package/dist/agent/agentIntentClassifier.js.map +1 -0
- package/dist/agent/agentPolicyResolver.d.ts +44 -0
- package/dist/agent/agentPolicyResolver.d.ts.map +1 -0
- package/dist/agent/agentPolicyResolver.js +94 -0
- package/dist/agent/agentPolicyResolver.js.map +1 -0
- package/dist/agent/agentRuntime.d.ts +12 -0
- package/dist/agent/agentRuntime.d.ts.map +1 -0
- package/dist/agent/agentRuntime.js +31 -0
- package/dist/agent/agentRuntime.js.map +1 -0
- package/dist/agent/agentToolRouter.d.ts +24 -0
- package/dist/agent/agentToolRouter.d.ts.map +1 -0
- package/dist/agent/agentToolRouter.js +89 -0
- package/dist/agent/agentToolRouter.js.map +1 -0
- package/dist/agent/guardianOperator.d.ts +35 -0
- package/dist/agent/guardianOperator.d.ts.map +1 -0
- package/dist/agent/guardianOperator.js +65 -0
- package/dist/agent/guardianOperator.js.map +1 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +14 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/api/activityRoutes.d.ts +70 -0
- package/dist/api/activityRoutes.d.ts.map +1 -0
- package/dist/api/activityRoutes.js +100 -0
- package/dist/api/activityRoutes.js.map +1 -0
- package/dist/api/agentRoutes.d.ts +16 -0
- package/dist/api/agentRoutes.d.ts.map +1 -0
- package/dist/api/agentRoutes.js +37 -0
- package/dist/api/agentRoutes.js.map +1 -0
- package/dist/api/broadcastRoutes.d.ts +34 -0
- package/dist/api/broadcastRoutes.d.ts.map +1 -0
- package/dist/api/broadcastRoutes.js +147 -0
- package/dist/api/broadcastRoutes.js.map +1 -0
- package/dist/api/consolePage.d.ts +2 -0
- package/dist/api/consolePage.d.ts.map +1 -0
- package/dist/api/consolePage.js +206 -0
- package/dist/api/consolePage.js.map +1 -0
- package/dist/api/httpHardening.d.ts +75 -0
- package/dist/api/httpHardening.d.ts.map +1 -0
- package/dist/api/httpHardening.js +122 -0
- package/dist/api/httpHardening.js.map +1 -0
- package/dist/api/indexerRoutes.d.ts +46 -0
- package/dist/api/indexerRoutes.d.ts.map +1 -0
- package/dist/api/indexerRoutes.js +75 -0
- package/dist/api/indexerRoutes.js.map +1 -0
- package/dist/api/paidRoutes.d.ts +8 -0
- package/dist/api/paidRoutes.d.ts.map +1 -0
- package/dist/api/paidRoutes.js +175 -0
- package/dist/api/paidRoutes.js.map +1 -0
- package/dist/api/prepareRoutes.d.ts +58 -0
- package/dist/api/prepareRoutes.d.ts.map +1 -0
- package/dist/api/prepareRoutes.js +90 -0
- package/dist/api/prepareRoutes.js.map +1 -0
- package/dist/api/response.d.ts +39 -0
- package/dist/api/response.d.ts.map +1 -0
- package/dist/api/response.js +53 -0
- package/dist/api/response.js.map +1 -0
- package/dist/api/routes.d.ts +175 -0
- package/dist/api/routes.d.ts.map +1 -0
- package/dist/api/routes.js +276 -0
- package/dist/api/routes.js.map +1 -0
- package/dist/api/schemas.d.ts +147 -0
- package/dist/api/schemas.d.ts.map +1 -0
- package/dist/api/schemas.js +81 -0
- package/dist/api/schemas.js.map +1 -0
- package/dist/api/server.d.ts +11 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +505 -0
- package/dist/api/server.js.map +1 -0
- package/dist/api/toolRoutes.d.ts +14 -0
- package/dist/api/toolRoutes.d.ts.map +1 -0
- package/dist/api/toolRoutes.js +138 -0
- package/dist/api/toolRoutes.js.map +1 -0
- package/dist/api/walletPrepareRoutes.d.ts +74 -0
- package/dist/api/walletPrepareRoutes.d.ts.map +1 -0
- package/dist/api/walletPrepareRoutes.js +127 -0
- package/dist/api/walletPrepareRoutes.js.map +1 -0
- package/dist/api/x402Gate.d.ts +51 -0
- package/dist/api/x402Gate.d.ts.map +1 -0
- package/dist/api/x402Gate.js +184 -0
- package/dist/api/x402Gate.js.map +1 -0
- package/dist/cli.d.ts +5 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +154 -124
- package/dist/cli.js.map +1 -1
- package/dist/data/ecosystemRegistry.data.d.ts +3 -0
- package/dist/data/ecosystemRegistry.data.d.ts.map +1 -0
- package/dist/data/ecosystemRegistry.data.js +582 -0
- package/dist/data/ecosystemRegistry.data.js.map +1 -0
- package/dist/demo.d.ts +1 -1
- package/dist/demo.d.ts.map +1 -1
- package/dist/demo.js +206 -171
- package/dist/demo.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +249 -164
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +127 -65
- package/dist/init.js.map +1 -1
- package/dist/lib/analysis/approval.d.ts +29 -0
- package/dist/lib/analysis/approval.d.ts.map +1 -0
- package/dist/lib/analysis/approval.js +162 -0
- package/dist/lib/analysis/approval.js.map +1 -0
- package/dist/lib/analysis/calldata.d.ts +60 -0
- package/dist/lib/analysis/calldata.d.ts.map +1 -0
- package/dist/lib/analysis/calldata.js +349 -0
- package/dist/lib/analysis/calldata.js.map +1 -0
- package/dist/lib/analysis/contractIntel.d.ts +65 -0
- package/dist/lib/analysis/contractIntel.d.ts.map +1 -0
- package/dist/lib/analysis/contractIntel.js +320 -0
- package/dist/lib/analysis/contractIntel.js.map +1 -0
- package/dist/lib/analysis/evm.d.ts +42 -0
- package/dist/lib/analysis/evm.d.ts.map +1 -0
- package/dist/lib/analysis/evm.js +185 -0
- package/dist/lib/analysis/evm.js.map +1 -0
- package/dist/lib/analysis/gas.d.ts +4 -0
- package/dist/lib/analysis/gas.d.ts.map +1 -0
- package/dist/lib/analysis/gas.js +13 -0
- package/dist/lib/analysis/gas.js.map +1 -0
- package/dist/lib/analysis/index.d.ts +11 -0
- package/dist/lib/analysis/index.d.ts.map +1 -0
- package/dist/lib/analysis/index.js +16 -0
- package/dist/lib/analysis/index.js.map +1 -0
- package/dist/lib/analysis/pharosTokens.d.ts +31 -0
- package/dist/lib/analysis/pharosTokens.d.ts.map +1 -0
- package/dist/lib/analysis/pharosTokens.js +78 -0
- package/dist/lib/analysis/pharosTokens.js.map +1 -0
- package/dist/lib/analysis/safeTx.d.ts +27 -0
- package/dist/lib/analysis/safeTx.d.ts.map +1 -0
- package/dist/lib/analysis/safeTx.js +118 -0
- package/dist/lib/analysis/safeTx.js.map +1 -0
- package/dist/lib/analysis/token.d.ts +21 -0
- package/dist/lib/analysis/token.d.ts.map +1 -0
- package/dist/lib/analysis/token.js +151 -0
- package/dist/lib/analysis/token.js.map +1 -0
- package/dist/lib/analysis/types.d.ts +49 -0
- package/dist/lib/analysis/types.d.ts.map +1 -0
- package/dist/lib/analysis/types.js +10 -0
- package/dist/lib/analysis/types.js.map +1 -0
- package/dist/lib/analysis/x402.d.ts +24 -0
- package/dist/lib/analysis/x402.d.ts.map +1 -0
- package/dist/lib/analysis/x402.js +60 -0
- package/dist/lib/analysis/x402.js.map +1 -0
- package/dist/lib/auditLog.d.ts +1 -0
- package/dist/lib/auditLog.d.ts.map +1 -1
- package/dist/lib/auditLog.js +0 -0
- package/dist/lib/auditLog.js.map +1 -1
- package/dist/lib/config.d.ts +77 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +120 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +452 -291
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +509 -292
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/dodoApi.d.ts +101 -78
- package/dist/lib/dodoApi.d.ts.map +1 -1
- package/dist/lib/dodoApi.js +259 -196
- package/dist/lib/dodoApi.js.map +1 -1
- package/dist/lib/ecosystemRegistry.d.ts +116 -0
- package/dist/lib/ecosystemRegistry.d.ts.map +1 -0
- package/dist/lib/ecosystemRegistry.js +178 -0
- package/dist/lib/ecosystemRegistry.js.map +1 -0
- package/dist/lib/envLoader.d.ts +2 -0
- package/dist/lib/envLoader.d.ts.map +1 -0
- package/dist/lib/envLoader.js +65 -0
- package/dist/lib/envLoader.js.map +1 -0
- package/dist/lib/goldsky.d.ts +58 -0
- package/dist/lib/goldsky.d.ts.map +1 -0
- package/dist/lib/goldsky.js +275 -0
- package/dist/lib/goldsky.js.map +1 -0
- package/dist/lib/guardian/decision.d.ts +23 -0
- package/dist/lib/guardian/decision.d.ts.map +1 -0
- package/dist/lib/guardian/decision.js +40 -0
- package/dist/lib/guardian/decision.js.map +1 -0
- package/dist/lib/http.d.ts +13 -14
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +383 -118
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/managedExecution.d.ts +19 -0
- package/dist/lib/managedExecution.d.ts.map +1 -0
- package/dist/lib/managedExecution.js +64 -0
- package/dist/lib/managedExecution.js.map +1 -0
- package/dist/lib/merkleBatcher.d.ts +23 -0
- package/dist/lib/merkleBatcher.d.ts.map +1 -0
- package/dist/lib/merkleBatcher.js +62 -0
- package/dist/lib/merkleBatcher.js.map +1 -0
- package/dist/lib/networks.d.ts +48 -0
- package/dist/lib/networks.d.ts.map +1 -0
- package/dist/lib/networks.js +103 -0
- package/dist/lib/networks.js.map +1 -0
- package/dist/lib/observability/accessContext.d.ts +29 -0
- package/dist/lib/observability/accessContext.d.ts.map +1 -0
- package/dist/lib/observability/accessContext.js +50 -0
- package/dist/lib/observability/accessContext.js.map +1 -0
- package/dist/lib/observability/activityStore.d.ts +70 -0
- package/dist/lib/observability/activityStore.d.ts.map +1 -0
- package/dist/lib/observability/activityStore.js +149 -0
- package/dist/lib/observability/activityStore.js.map +1 -0
- package/dist/lib/observability/apiKey.d.ts +55 -0
- package/dist/lib/observability/apiKey.d.ts.map +1 -0
- package/dist/lib/observability/apiKey.js +141 -0
- package/dist/lib/observability/apiKey.js.map +1 -0
- package/dist/lib/observability/logger.d.ts +30 -0
- package/dist/lib/observability/logger.d.ts.map +1 -0
- package/dist/lib/observability/logger.js +30 -0
- package/dist/lib/observability/logger.js.map +1 -0
- package/dist/lib/observability/quota.d.ts +33 -0
- package/dist/lib/observability/quota.d.ts.map +1 -0
- package/dist/lib/observability/quota.js +49 -0
- package/dist/lib/observability/quota.js.map +1 -0
- package/dist/lib/observability/requestId.d.ts +8 -0
- package/dist/lib/observability/requestId.d.ts.map +1 -0
- package/dist/lib/observability/requestId.js +24 -0
- package/dist/lib/observability/requestId.js.map +1 -0
- package/dist/lib/observability/sanitize.d.ts +77 -0
- package/dist/lib/observability/sanitize.d.ts.map +1 -0
- package/dist/lib/observability/sanitize.js +228 -0
- package/dist/lib/observability/sanitize.js.map +1 -0
- package/dist/lib/observability/scopes.d.ts +20 -0
- package/dist/lib/observability/scopes.d.ts.map +1 -0
- package/dist/lib/observability/scopes.js +77 -0
- package/dist/lib/observability/scopes.js.map +1 -0
- package/dist/lib/okxDexApi.d.ts +106 -0
- package/dist/lib/okxDexApi.d.ts.map +1 -0
- package/dist/lib/okxDexApi.js +221 -0
- package/dist/lib/okxDexApi.js.map +1 -0
- package/dist/lib/persistentJsonStore.d.ts +5 -0
- package/dist/lib/persistentJsonStore.d.ts.map +1 -0
- package/dist/lib/persistentJsonStore.js +39 -0
- package/dist/lib/persistentJsonStore.js.map +1 -0
- package/dist/lib/pharos/attestationPublisher.d.ts +50 -0
- package/dist/lib/pharos/attestationPublisher.d.ts.map +1 -0
- package/dist/lib/pharos/attestationPublisher.js +262 -0
- package/dist/lib/pharos/attestationPublisher.js.map +1 -0
- package/dist/lib/pharos/ecosystem.d.ts +52 -0
- package/dist/lib/pharos/ecosystem.d.ts.map +1 -0
- package/dist/lib/pharos/ecosystem.js +431 -0
- package/dist/lib/pharos/ecosystem.js.map +1 -0
- package/dist/lib/pharos/ecosystemEvidence.d.ts +53 -0
- package/dist/lib/pharos/ecosystemEvidence.d.ts.map +1 -0
- package/dist/lib/pharos/ecosystemEvidence.js +133 -0
- package/dist/lib/pharos/ecosystemEvidence.js.map +1 -0
- package/dist/lib/pharos/rpc.d.ts +44 -0
- package/dist/lib/pharos/rpc.d.ts.map +1 -0
- package/dist/lib/pharos/rpc.js +90 -0
- package/dist/lib/pharos/rpc.js.map +1 -0
- package/dist/lib/pharos/rpcEvidence.d.ts +49 -0
- package/dist/lib/pharos/rpcEvidence.d.ts.map +1 -0
- package/dist/lib/pharos/rpcEvidence.js +46 -0
- package/dist/lib/pharos/rpcEvidence.js.map +1 -0
- package/dist/lib/pharos/rpcMethods.d.ts +46 -0
- package/dist/lib/pharos/rpcMethods.d.ts.map +1 -0
- package/dist/lib/pharos/rpcMethods.js +176 -0
- package/dist/lib/pharos/rpcMethods.js.map +1 -0
- package/dist/lib/pharos/spvVerifier.d.ts +47 -0
- package/dist/lib/pharos/spvVerifier.d.ts.map +1 -0
- package/dist/lib/pharos/spvVerifier.js +105 -0
- package/dist/lib/pharos/spvVerifier.js.map +1 -0
- package/dist/lib/pharos/userSignedBroadcaster.d.ts +10 -0
- package/dist/lib/pharos/userSignedBroadcaster.d.ts.map +1 -0
- package/dist/lib/pharos/userSignedBroadcaster.js +50 -0
- package/dist/lib/pharos/userSignedBroadcaster.js.map +1 -0
- package/dist/lib/pharosClient.d.ts +53 -58
- package/dist/lib/pharosClient.d.ts.map +1 -1
- package/dist/lib/pharosClient.js +56 -63
- package/dist/lib/pharosClient.js.map +1 -1
- package/dist/lib/policy/actionPolicyEngine.d.ts +89 -53
- package/dist/lib/policy/actionPolicyEngine.d.ts.map +1 -1
- package/dist/lib/policy/actionPolicyEngine.js +373 -212
- package/dist/lib/policy/actionPolicyEngine.js.map +1 -1
- package/dist/lib/policy/agentPolicy.d.ts +29 -0
- package/dist/lib/policy/agentPolicy.d.ts.map +1 -0
- package/dist/lib/policy/agentPolicy.js +154 -0
- package/dist/lib/policy/agentPolicy.js.map +1 -0
- package/dist/lib/policy/policyPresets.d.ts +30 -0
- package/dist/lib/policy/policyPresets.d.ts.map +1 -0
- package/dist/lib/policy/policyPresets.js +124 -0
- package/dist/lib/policy/policyPresets.js.map +1 -0
- package/dist/lib/policy/writeExecutionGate.d.ts +23 -0
- package/dist/lib/policy/writeExecutionGate.d.ts.map +1 -0
- package/dist/lib/policy/writeExecutionGate.js +65 -0
- package/dist/lib/policy/writeExecutionGate.js.map +1 -0
- package/dist/lib/preparedTxStore.d.ts +21 -0
- package/dist/lib/preparedTxStore.d.ts.map +1 -0
- package/dist/lib/preparedTxStore.js +90 -0
- package/dist/lib/preparedTxStore.js.map +1 -0
- package/dist/lib/price/chainlinkPushProvider.d.ts +34 -0
- package/dist/lib/price/chainlinkPushProvider.d.ts.map +1 -0
- package/dist/lib/price/chainlinkPushProvider.js +36 -0
- package/dist/lib/price/chainlinkPushProvider.js.map +1 -0
- package/dist/lib/price/feedRegistry.d.ts +26 -0
- package/dist/lib/price/feedRegistry.d.ts.map +1 -0
- package/dist/lib/price/feedRegistry.js +67 -0
- package/dist/lib/price/feedRegistry.js.map +1 -0
- package/dist/lib/price/priceResolver.d.ts +35 -0
- package/dist/lib/price/priceResolver.d.ts.map +1 -0
- package/dist/lib/price/priceResolver.js +246 -0
- package/dist/lib/price/priceResolver.js.map +1 -0
- package/dist/lib/price/supraProvider.d.ts +9 -0
- package/dist/lib/price/supraProvider.d.ts.map +1 -0
- package/dist/lib/price/supraProvider.js +17 -0
- package/dist/lib/price/supraProvider.js.map +1 -0
- package/dist/lib/price/types.d.ts +67 -0
- package/dist/lib/price/types.d.ts.map +1 -0
- package/dist/lib/price/types.js +7 -0
- package/dist/lib/price/types.js.map +1 -0
- package/dist/lib/productionGuards.d.ts +16 -0
- package/dist/lib/productionGuards.d.ts.map +1 -0
- package/dist/lib/productionGuards.js +93 -0
- package/dist/lib/productionGuards.js.map +1 -0
- package/dist/lib/recipientSafety.d.ts +5 -0
- package/dist/lib/recipientSafety.d.ts.map +1 -0
- package/dist/lib/recipientSafety.js +28 -0
- package/dist/lib/recipientSafety.js.map +1 -0
- package/dist/lib/riskEngine.d.ts +45 -26
- package/dist/lib/riskEngine.d.ts.map +1 -1
- package/dist/lib/riskEngine.js +346 -283
- package/dist/lib/riskEngine.js.map +1 -1
- package/dist/lib/riskInclusion.d.ts +72 -0
- package/dist/lib/riskInclusion.d.ts.map +1 -0
- package/dist/lib/riskInclusion.js +252 -0
- package/dist/lib/riskInclusion.js.map +1 -0
- package/dist/lib/safeHandsRegistry.d.ts +32 -0
- package/dist/lib/safeHandsRegistry.d.ts.map +1 -0
- package/dist/lib/safeHandsRegistry.js +151 -0
- package/dist/lib/safeHandsRegistry.js.map +1 -0
- package/dist/lib/signer/index.d.ts +24 -24
- package/dist/lib/signer/index.d.ts.map +1 -1
- package/dist/lib/signer/index.js +110 -88
- package/dist/lib/signer/index.js.map +1 -1
- package/dist/lib/spendAccumulator.d.ts +24 -1
- package/dist/lib/spendAccumulator.d.ts.map +1 -1
- package/dist/lib/spendAccumulator.js +76 -6
- package/dist/lib/spendAccumulator.js.map +1 -1
- package/dist/lib/toolResponse.d.ts +30 -25
- package/dist/lib/toolResponse.d.ts.map +1 -1
- package/dist/lib/toolResponse.js +57 -53
- package/dist/lib/toolResponse.js.map +1 -1
- package/dist/lib/validation.d.ts +7 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +62 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/wallet/index.d.ts +33 -37
- package/dist/lib/wallet/index.d.ts.map +1 -1
- package/dist/lib/wallet/index.js +141 -128
- package/dist/lib/wallet/index.js.map +1 -1
- package/dist/lib/x402ReplayStore.d.ts +6 -0
- package/dist/lib/x402ReplayStore.d.ts.map +1 -0
- package/dist/lib/x402ReplayStore.js +79 -0
- package/dist/lib/x402ReplayStore.js.map +1 -0
- package/dist/safehands.zip +0 -0
- package/dist/sdk.d.ts +14 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +25 -0
- package/dist/sdk.js.map +1 -0
- package/dist/tools/approveToken.d.ts +66 -45
- package/dist/tools/approveToken.d.ts.map +1 -1
- package/dist/tools/approveToken.js +152 -85
- package/dist/tools/approveToken.js.map +1 -1
- package/dist/tools/assessRisk.d.ts +66 -79
- package/dist/tools/assessRisk.d.ts.map +1 -1
- package/dist/tools/assessRisk.js +63 -104
- package/dist/tools/assessRisk.js.map +1 -1
- package/dist/tools/checkAllowance.d.ts +49 -43
- package/dist/tools/checkAllowance.d.ts.map +1 -1
- package/dist/tools/checkAllowance.js +78 -56
- package/dist/tools/checkAllowance.js.map +1 -1
- package/dist/tools/checkTokenSecurity.d.ts +103 -46
- package/dist/tools/checkTokenSecurity.d.ts.map +1 -1
- package/dist/tools/checkTokenSecurity.js +240 -95
- package/dist/tools/checkTokenSecurity.js.map +1 -1
- package/dist/tools/createAgentWallet.d.ts +30 -26
- package/dist/tools/createAgentWallet.d.ts.map +1 -1
- package/dist/tools/createAgentWallet.js +87 -58
- package/dist/tools/createAgentWallet.js.map +1 -1
- package/dist/tools/estimateGas.d.ts +84 -79
- package/dist/tools/estimateGas.d.ts.map +1 -1
- package/dist/tools/estimateGas.js +130 -124
- package/dist/tools/estimateGas.js.map +1 -1
- package/dist/tools/executeSwap.d.ts +109 -61
- package/dist/tools/executeSwap.d.ts.map +1 -1
- package/dist/tools/executeSwap.js +289 -141
- package/dist/tools/executeSwap.js.map +1 -1
- package/dist/tools/explainRisk.d.ts +29 -29
- package/dist/tools/explainRisk.d.ts.map +1 -1
- package/dist/tools/explainRisk.js +33 -32
- package/dist/tools/explainRisk.js.map +1 -1
- package/dist/tools/getAgentPolicy.d.ts +15 -0
- package/dist/tools/getAgentPolicy.d.ts.map +1 -0
- package/dist/tools/getAgentPolicy.js +16 -0
- package/dist/tools/getAgentPolicy.js.map +1 -0
- package/dist/tools/getAgentReputation.d.ts +31 -0
- package/dist/tools/getAgentReputation.d.ts.map +1 -0
- package/dist/tools/getAgentReputation.js +44 -0
- package/dist/tools/getAgentReputation.js.map +1 -0
- package/dist/tools/getAgentWallet.d.ts +21 -21
- package/dist/tools/getAgentWallet.d.ts.map +1 -1
- package/dist/tools/getAgentWallet.js +37 -27
- package/dist/tools/getAgentWallet.js.map +1 -1
- package/dist/tools/getAgentWalletBalance.d.ts +11 -11
- package/dist/tools/getAgentWalletBalance.d.ts.map +1 -1
- package/dist/tools/getAgentWalletBalance.js +102 -70
- package/dist/tools/getAgentWalletBalance.js.map +1 -1
- package/dist/tools/getExecutionHistory.d.ts +49 -49
- package/dist/tools/getExecutionHistory.d.ts.map +1 -1
- package/dist/tools/getExecutionHistory.js +148 -154
- package/dist/tools/getExecutionHistory.js.map +1 -1
- package/dist/tools/getGasPrice.d.ts +43 -43
- package/dist/tools/getGasPrice.d.ts.map +0 -0
- package/dist/tools/getGasPrice.js +59 -59
- package/dist/tools/getGasPrice.js.map +1 -1
- package/dist/tools/getPoolInfo.d.ts +75 -75
- package/dist/tools/getPoolInfo.d.ts.map +1 -1
- package/dist/tools/getPoolInfo.js +142 -137
- package/dist/tools/getPoolInfo.js.map +1 -1
- package/dist/tools/getSpvProof.d.ts +24 -0
- package/dist/tools/getSpvProof.d.ts.map +1 -0
- package/dist/tools/getSpvProof.js +64 -0
- package/dist/tools/getSpvProof.js.map +1 -0
- package/dist/tools/getTokenPrice.d.ts +56 -113
- package/dist/tools/getTokenPrice.d.ts.map +1 -1
- package/dist/tools/getTokenPrice.js +110 -117
- package/dist/tools/getTokenPrice.js.map +1 -1
- package/dist/tools/getTransactionStatus.d.ts +43 -43
- package/dist/tools/getTransactionStatus.d.ts.map +0 -0
- package/dist/tools/getTransactionStatus.js +59 -59
- package/dist/tools/getTransactionStatus.js.map +0 -0
- package/dist/tools/getWalletBalance.d.ts +103 -68
- package/dist/tools/getWalletBalance.d.ts.map +1 -1
- package/dist/tools/getWalletBalance.js +127 -87
- package/dist/tools/getWalletBalance.js.map +1 -1
- package/dist/tools/publishRiskScore.d.ts +85 -63
- package/dist/tools/publishRiskScore.d.ts.map +1 -1
- package/dist/tools/publishRiskScore.js +136 -88
- package/dist/tools/publishRiskScore.js.map +1 -1
- package/dist/tools/queryGoldsky.d.ts +20 -0
- package/dist/tools/queryGoldsky.d.ts.map +1 -0
- package/dist/tools/queryGoldsky.js +29 -0
- package/dist/tools/queryGoldsky.js.map +1 -0
- package/dist/tools/queryRiskRegistry.d.ts +38 -38
- package/dist/tools/queryRiskRegistry.d.ts.map +1 -1
- package/dist/tools/queryRiskRegistry.js +59 -55
- package/dist/tools/queryRiskRegistry.js.map +1 -1
- package/dist/tools/safehandsPreflightCheck.d.ts +92 -77
- package/dist/tools/safehandsPreflightCheck.d.ts.map +1 -1
- package/dist/tools/safehandsPreflightCheck.js +174 -47
- package/dist/tools/safehandsPreflightCheck.js.map +1 -1
- package/dist/tools/safehandsRiskReport.d.ts +96 -81
- package/dist/tools/safehandsRiskReport.d.ts.map +1 -1
- package/dist/tools/safehandsRiskReport.js +48 -28
- package/dist/tools/safehandsRiskReport.js.map +1 -1
- package/dist/tools/safehandsSafeExecute.d.ts +20 -20
- package/dist/tools/safehandsSafeExecute.d.ts.map +1 -1
- package/dist/tools/safehandsSafeExecute.js +164 -81
- package/dist/tools/safehandsSafeExecute.js.map +1 -1
- package/dist/tools/safehandsWalletHealth.d.ts +28 -14
- package/dist/tools/safehandsWalletHealth.d.ts.map +1 -1
- package/dist/tools/safehandsWalletHealth.js +145 -103
- package/dist/tools/safehandsWalletHealth.js.map +1 -1
- package/dist/tools/safehandsX402Preflight.d.ts +26 -26
- package/dist/tools/safehandsX402Preflight.d.ts.map +1 -1
- package/dist/tools/safehandsX402Preflight.js +86 -65
- package/dist/tools/safehandsX402Preflight.js.map +1 -1
- package/dist/tools/sendPayment.d.ts +63 -57
- package/dist/tools/sendPayment.d.ts.map +1 -1
- package/dist/tools/sendPayment.js +144 -117
- package/dist/tools/sendPayment.js.map +1 -1
- package/dist/tools/setAgentPolicy.d.ts +75 -0
- package/dist/tools/setAgentPolicy.d.ts.map +1 -0
- package/dist/tools/setAgentPolicy.js +80 -0
- package/dist/tools/setAgentPolicy.js.map +1 -0
- package/dist/tools/simulateTransaction.d.ts +64 -60
- package/dist/tools/simulateTransaction.d.ts.map +1 -1
- package/dist/tools/simulateTransaction.js +116 -83
- package/dist/tools/simulateTransaction.js.map +1 -1
- package/dist/tools/tokenRegistryStatus.d.ts +46 -26
- package/dist/tools/tokenRegistryStatus.d.ts.map +1 -1
- package/dist/tools/tokenRegistryStatus.js +126 -96
- package/dist/tools/tokenRegistryStatus.js.map +1 -1
- package/dist/tools/verifyRiskInclusion.d.ts +59 -0
- package/dist/tools/verifyRiskInclusion.d.ts.map +1 -0
- package/dist/tools/verifyRiskInclusion.js +40 -0
- package/dist/tools/verifyRiskInclusion.js.map +1 -0
- package/dist/tools/x402PayAndFetch.d.ts +87 -81
- package/dist/tools/x402PayAndFetch.d.ts.map +1 -1
- package/dist/tools/x402PayAndFetch.js +295 -152
- package/dist/tools/x402PayAndFetch.js.map +1 -1
- package/dist/worker.d.ts +3 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +39 -0
- package/dist/worker.js.map +1 -0
- package/dist/x402Server.d.ts +1 -1
- package/dist/x402Server.d.ts.map +1 -1
- package/dist/x402Server.js +409 -252
- package/dist/x402Server.js.map +1 -1
- package/docs/REVIEWER_QUICKSTART.md +113 -0
- package/docs/SAFEHANDS_REVIEWER_DEMO_SCRIPT.md +228 -0
- package/package.json +130 -83
- package/contracts/RiskRegistry.json +0 -223
- package/contracts/RiskRegistry.sol +0 -58
- package/dist/lib/testDodoLive.d.ts +0 -2
- package/dist/lib/testDodoLive.d.ts.map +0 -1
- package/dist/lib/testDodoLive.js +0 -105
- package/dist/lib/testDodoLive.js.map +0 -1
- package/dist/lib/testLiveSafehands.d.ts +0 -2
- package/dist/lib/testLiveSafehands.d.ts.map +0 -1
- package/dist/lib/testLiveSafehands.js +0 -93
- package/dist/lib/testLiveSafehands.js.map +0 -1
- package/dist/lib/testRpc.d.ts +0 -2
- package/dist/lib/testRpc.d.ts.map +0 -1
- package/dist/lib/testRpc.js +0 -30
- package/dist/lib/testRpc.js.map +0 -1
- package/dist/lib/testRpcLive.d.ts +0 -2
- package/dist/lib/testRpcLive.d.ts.map +0 -1
- package/dist/lib/testRpcLive.js +0 -89
- package/dist/lib/testRpcLive.js.map +0 -1
- package/dist/lib/testTools.d.ts +0 -2
- package/dist/lib/testTools.d.ts.map +0 -1
- package/dist/lib/testTools.js +0 -398
- package/dist/lib/testTools.js.map +0 -1
- package/dist/lib/testX402Live.d.ts +0 -2
- package/dist/lib/testX402Live.d.ts.map +0 -1
- package/dist/lib/testX402Live.js +0 -160
- package/dist/lib/testX402Live.js.map +0 -1
- package/dist/scripts/checkDeploy.d.ts +0 -2
- package/dist/scripts/checkDeploy.d.ts.map +0 -1
- package/dist/scripts/checkDeploy.js +0 -25
- package/dist/scripts/checkDeploy.js.map +0 -1
- package/dist/scripts/deployRegistry.d.ts +0 -2
- package/dist/scripts/deployRegistry.d.ts.map +0 -1
- package/dist/scripts/deployRegistry.js +0 -101
- package/dist/scripts/deployRegistry.js.map +0 -1
- package/dist/scripts/testRegistry.d.ts +0 -2
- package/dist/scripts/testRegistry.d.ts.map +0 -1
- package/dist/scripts/testRegistry.js +0 -44
- package/dist/scripts/testRegistry.js.map +0 -1
- package/examples/dashboard/index.html +0 -337
- package/examples/pharos-skill-engine/SKILL.safehands.md +0 -85
- package/examples/pharos-skill-engine/assets/safehands/example-actions.json +0 -49
- package/examples/pharos-skill-engine/assets/safehands/policy-defaults.json +0 -11
- package/examples/pharos-skill-engine/references/safehands.md +0 -345
- package/examples/scenario-hack.ts +0 -38
- package/skill/SKILL.md +0 -133
- package/skill/assets/safehands/example-actions.json +0 -49
- package/skill/assets/safehands/policy-defaults.json +0 -11
- package/skill/references/safehands.md +0 -345
package/dist/lib/riskEngine.js
CHANGED
|
@@ -1,284 +1,347 @@
|
|
|
1
|
-
// ─── Risk Scoring Engine
|
|
2
|
-
// 5-dimension risk assessment engine for SafeHands.
|
|
3
|
-
// Weights: liquidity 25%, slippage 25%, counterparty 20%,
|
|
4
|
-
// balance 15%, market conditions 15%
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (score <=
|
|
25
|
-
return "
|
|
26
|
-
if (score <=
|
|
27
|
-
return "
|
|
28
|
-
return "
|
|
29
|
-
}
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return { score:
|
|
231
|
-
}
|
|
232
|
-
catch {
|
|
233
|
-
reasons.push(
|
|
234
|
-
return { score:
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
1
|
+
// ─── Risk Scoring Engine (ADVISORY) ────────────────────────────────────
|
|
2
|
+
// 5-dimension risk assessment engine for SafeHands.
|
|
3
|
+
// Weights: liquidity 25%, slippage 25%, counterparty 20%,
|
|
4
|
+
// balance 15%, market conditions 15%
|
|
5
|
+
//
|
|
6
|
+
// This engine never gates execution. Its output is advisory: published
|
|
7
|
+
// on-chain as part of the assessment record (publish_risk_score) and fed to
|
|
8
|
+
// the actionPolicyEngine as evidence (riskEvidenceFromAssessment) — the
|
|
9
|
+
// policy engine is the sole ALLOW/BLOCK decider on write paths
|
|
10
|
+
// (docs/DECISION_CONTRACT.md).
|
|
11
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
12
|
+
import { publicClient } from "./pharosClient.js";
|
|
13
|
+
import { getDodoRoute, isNativeToken, resolveTokenAddress, resolveTokenDecimals, toWei, DodoNotConfiguredError, } from "./dodoApi.js";
|
|
14
|
+
import { RISK_WEIGHTS, RISK_BLOCK_THRESHOLD, COUNTERPARTY_CRITICAL_THRESHOLD, MAX_SLIPPAGE_PCT, MAX_BALANCE_USAGE_PCT, ERC20_ABI, CHAIN_ID, } from "./constants.js";
|
|
15
|
+
import { addressTrustEvidence } from "./ecosystemRegistry.js";
|
|
16
|
+
import { formatEther, isAddress, parseEther } from "viem";
|
|
17
|
+
// ─── Helpers ───────────────────────────────────────────────────────────
|
|
18
|
+
function clamp(value, min = 0, max = 100) {
|
|
19
|
+
return Math.max(min, Math.min(max, value));
|
|
20
|
+
}
|
|
21
|
+
function computeRiskLevel(score) {
|
|
22
|
+
if (score <= 30)
|
|
23
|
+
return "low";
|
|
24
|
+
if (score <= 60)
|
|
25
|
+
return "medium";
|
|
26
|
+
if (score <= 80)
|
|
27
|
+
return "high";
|
|
28
|
+
return "critical";
|
|
29
|
+
}
|
|
30
|
+
function computeRecommendation(score) {
|
|
31
|
+
if (score <= 30)
|
|
32
|
+
return "proceed";
|
|
33
|
+
if (score <= RISK_BLOCK_THRESHOLD)
|
|
34
|
+
return "caution";
|
|
35
|
+
return "block";
|
|
36
|
+
}
|
|
37
|
+
function weightedAverage(breakdown) {
|
|
38
|
+
const w = RISK_WEIGHTS;
|
|
39
|
+
return Math.round(breakdown.liquidityRisk * w.liquidityRisk +
|
|
40
|
+
breakdown.slippageRisk * w.slippageRisk +
|
|
41
|
+
breakdown.counterpartyRisk * w.counterpartyRisk +
|
|
42
|
+
breakdown.balanceRisk * w.balanceRisk +
|
|
43
|
+
breakdown.marketConditionRisk * w.marketConditionRisk);
|
|
44
|
+
}
|
|
45
|
+
// ─── Individual Risk Scorers ───────────────────────────────────────────
|
|
46
|
+
/**
|
|
47
|
+
* Pre-fetches the DODO route quote once for swap actions.
|
|
48
|
+
* Both scoreLiquidity and scoreSlippage use this cached result.
|
|
49
|
+
* `notConfigured` distinguishes the structural provider-not-configured state
|
|
50
|
+
* (SWAP_LIQUIDITY_NOT_CONFIGURED) from a transient fetch failure.
|
|
51
|
+
*/
|
|
52
|
+
async function fetchSwapQuote(input) {
|
|
53
|
+
if (input.action !== "swap")
|
|
54
|
+
return { quote: null, notConfigured: false };
|
|
55
|
+
try {
|
|
56
|
+
const quote = await getDodoRoute({
|
|
57
|
+
fromToken: input.tokenIn,
|
|
58
|
+
toToken: input.tokenOut,
|
|
59
|
+
amountHuman: input.amount,
|
|
60
|
+
walletAddress: input.walletAddress,
|
|
61
|
+
});
|
|
62
|
+
return { quote, notConfigured: false };
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return { quote: null, notConfigured: err instanceof DodoNotConfiguredError };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function scoreLiquidity(input, quote, notConfigured) {
|
|
69
|
+
const reasons = [];
|
|
70
|
+
if (input.action !== "swap")
|
|
71
|
+
return { score: 0, reasons };
|
|
72
|
+
if (!quote) {
|
|
73
|
+
reasons.push(notConfigured
|
|
74
|
+
? `Swap liquidity provider is not configured for chainId ${CHAIN_ID} (SWAP_LIQUIDITY_NOT_CONFIGURED); liquidity cannot be verified on this network.`
|
|
75
|
+
: "Failed to fetch liquidity data: route provider unavailable.");
|
|
76
|
+
return { score: 70, reasons };
|
|
77
|
+
}
|
|
78
|
+
if (!quote.routeAvailable) {
|
|
79
|
+
reasons.push("No swap route available; liquidity may be exhausted");
|
|
80
|
+
return { score: 100, reasons };
|
|
81
|
+
}
|
|
82
|
+
const impact = Math.abs(quote.priceImpact);
|
|
83
|
+
if (impact > 5) {
|
|
84
|
+
reasons.push(`High price impact: ${impact.toFixed(2)}%`);
|
|
85
|
+
return { score: clamp(80 + impact), reasons };
|
|
86
|
+
}
|
|
87
|
+
if (impact > 2) {
|
|
88
|
+
reasons.push(`Moderate price impact: ${impact.toFixed(2)}%`);
|
|
89
|
+
return { score: clamp(40 + impact * 10), reasons };
|
|
90
|
+
}
|
|
91
|
+
reasons.push(`Price impact acceptable: ${impact.toFixed(2)}%`);
|
|
92
|
+
return { score: clamp(impact * 15), reasons };
|
|
93
|
+
}
|
|
94
|
+
function scoreSlippage(input, quote, notConfigured) {
|
|
95
|
+
const reasons = [];
|
|
96
|
+
if (input.action !== "swap")
|
|
97
|
+
return { score: 0, reasons };
|
|
98
|
+
if (!quote) {
|
|
99
|
+
reasons.push(notConfigured
|
|
100
|
+
? `Slippage cannot be estimated: swap route provider not configured for chainId ${CHAIN_ID} (SWAP_LIQUIDITY_NOT_CONFIGURED).`
|
|
101
|
+
: "Slippage estimation failed: route provider unavailable.");
|
|
102
|
+
return { score: 60, reasons };
|
|
103
|
+
}
|
|
104
|
+
if (!quote.routeAvailable) {
|
|
105
|
+
reasons.push("Cannot estimate slippage: no route");
|
|
106
|
+
return { score: 90, reasons };
|
|
107
|
+
}
|
|
108
|
+
const impact = Math.abs(quote.priceImpact);
|
|
109
|
+
if (impact > MAX_SLIPPAGE_PCT) {
|
|
110
|
+
reasons.push(`Slippage exceeds max ${MAX_SLIPPAGE_PCT}%: estimated ${impact.toFixed(2)}%`);
|
|
111
|
+
return { score: clamp(80 + (impact - MAX_SLIPPAGE_PCT) * 5), reasons };
|
|
112
|
+
}
|
|
113
|
+
reasons.push(`Estimated slippage: ${impact.toFixed(2)}%`);
|
|
114
|
+
return { score: clamp(impact * 16), reasons };
|
|
115
|
+
}
|
|
116
|
+
async function scoreCounterparty(input, quote) {
|
|
117
|
+
const reasons = [];
|
|
118
|
+
if (input.action === "swap") {
|
|
119
|
+
// Registry-driven counterparty trust ONLY. The former unconditional
|
|
120
|
+
// "DODO protocol (known) → 5" relaxed risk with a testnet-provenance claim
|
|
121
|
+
// that holds on no network per the ecosystem registry.
|
|
122
|
+
const router = quote?.routeAvailable && isAddress(quote.to) ? quote.to : null;
|
|
123
|
+
if (!router) {
|
|
124
|
+
reasons.push("Swap counterparty (router) could not be determined; no route data to evaluate.");
|
|
125
|
+
return { score: 55, reasons };
|
|
126
|
+
}
|
|
127
|
+
const evidence = addressTrustEvidence(router, CHAIN_ID);
|
|
128
|
+
if (evidence.verifiedCanonical) {
|
|
129
|
+
reasons.push(`Swap router ${evidence.contractLabel ?? router} is VERIFIED in the SafeHands ecosystem registry.`);
|
|
130
|
+
return { score: 5, reasons };
|
|
131
|
+
}
|
|
132
|
+
if (evidence.recognized) {
|
|
133
|
+
reasons.push(`Swap router matches ecosystem-registry entry "${evidence.contractLabel}" (${evidence.verificationStatus}); recognition only, not a safety signal.`);
|
|
134
|
+
return { score: 40, reasons };
|
|
135
|
+
}
|
|
136
|
+
reasons.push(`Swap router ${router} is not in the SafeHands ecosystem registry: unverified counterparty (the execution allowlist still constrains which router may execute at write time).`);
|
|
137
|
+
return { score: 55, reasons };
|
|
138
|
+
}
|
|
139
|
+
// For transfers, check the recipient address
|
|
140
|
+
const to = input.toAddress;
|
|
141
|
+
if (!to) {
|
|
142
|
+
reasons.push("No recipient address provided");
|
|
143
|
+
return { score: 100, reasons };
|
|
144
|
+
}
|
|
145
|
+
if (!isAddress(to)) {
|
|
146
|
+
reasons.push("Invalid EVM address format");
|
|
147
|
+
return { score: 100, reasons };
|
|
148
|
+
}
|
|
149
|
+
// Zero address check
|
|
150
|
+
if (to === "0x0000000000000000000000000000000000000000") {
|
|
151
|
+
reasons.push("Sending to zero address; tokens will be burned");
|
|
152
|
+
return { score: 95, reasons };
|
|
153
|
+
}
|
|
154
|
+
// Self-send check
|
|
155
|
+
if (to.toLowerCase() === input.walletAddress.toLowerCase()) {
|
|
156
|
+
reasons.push("Sending to own address; likely unintended");
|
|
157
|
+
return { score: 50, reasons };
|
|
158
|
+
}
|
|
159
|
+
// Check if address has code (is a contract)
|
|
160
|
+
try {
|
|
161
|
+
const code = await publicClient.getCode({ address: to });
|
|
162
|
+
if (code && code !== "0x") {
|
|
163
|
+
reasons.push("Recipient is a contract address; verify intent");
|
|
164
|
+
return { score: 40, reasons };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// RPC error, non-critical
|
|
169
|
+
}
|
|
170
|
+
// Check if address has any transaction history (has balance)
|
|
171
|
+
try {
|
|
172
|
+
const balance = await publicClient.getBalance({ address: to });
|
|
173
|
+
if (balance === 0n) {
|
|
174
|
+
reasons.push("Recipient has zero balance; new or unused address");
|
|
175
|
+
return { score: 30, reasons };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Non-critical
|
|
180
|
+
}
|
|
181
|
+
reasons.push("Recipient address looks valid");
|
|
182
|
+
return { score: 10, reasons };
|
|
183
|
+
}
|
|
184
|
+
async function scoreBalance(input) {
|
|
185
|
+
const reasons = [];
|
|
186
|
+
try {
|
|
187
|
+
const walletAddr = input.walletAddress;
|
|
188
|
+
if (input.action === "transfer" || (input.action === "swap" && isNativeToken(input.tokenIn || "PROS"))) {
|
|
189
|
+
// Check native PROS balance
|
|
190
|
+
const balance = await publicClient.getBalance({ address: walletAddr });
|
|
191
|
+
const amountWei = parseEther(input.amount);
|
|
192
|
+
const gasBuffer = parseEther("0.01"); // ~0.01 PROS for gas
|
|
193
|
+
if (balance < amountWei + gasBuffer) {
|
|
194
|
+
const balanceHuman = formatEther(balance);
|
|
195
|
+
reasons.push(`Insufficient PROS balance: have ${balanceHuman}, need ${input.amount} + gas`);
|
|
196
|
+
return { score: 100, reasons };
|
|
197
|
+
}
|
|
198
|
+
const usagePct = Number((amountWei * 100n) / balance);
|
|
199
|
+
if (usagePct > MAX_BALANCE_USAGE_PCT) {
|
|
200
|
+
reasons.push(`Using ${usagePct}% of wallet balance; high exposure`);
|
|
201
|
+
return { score: clamp(60 + (usagePct - MAX_BALANCE_USAGE_PCT)), reasons };
|
|
202
|
+
}
|
|
203
|
+
reasons.push(`Balance sufficient, using ${usagePct}% of wallet`);
|
|
204
|
+
return { score: clamp(usagePct / 3), reasons };
|
|
205
|
+
}
|
|
206
|
+
// ERC-20 token balance check
|
|
207
|
+
if (input.tokenIn) {
|
|
208
|
+
const tokenAddress = resolveTokenAddress(input.tokenIn);
|
|
209
|
+
const decimals = resolveTokenDecimals(input.tokenIn);
|
|
210
|
+
const amountWei = BigInt(toWei(input.amount, decimals));
|
|
211
|
+
const balance = (await publicClient.readContract({
|
|
212
|
+
address: tokenAddress,
|
|
213
|
+
abi: ERC20_ABI,
|
|
214
|
+
functionName: "balanceOf",
|
|
215
|
+
args: [walletAddr],
|
|
216
|
+
}));
|
|
217
|
+
if (balance < amountWei) {
|
|
218
|
+
reasons.push(`Insufficient ${input.tokenIn} balance`);
|
|
219
|
+
return { score: 100, reasons };
|
|
220
|
+
}
|
|
221
|
+
// Also check gas balance
|
|
222
|
+
const ethBalance = await publicClient.getBalance({ address: walletAddr });
|
|
223
|
+
if (ethBalance < parseEther("0.005")) {
|
|
224
|
+
reasons.push("Very low PROS balance for gas fees");
|
|
225
|
+
return { score: 80, reasons };
|
|
226
|
+
}
|
|
227
|
+
reasons.push("Token and gas balance sufficient");
|
|
228
|
+
return { score: 5, reasons };
|
|
229
|
+
}
|
|
230
|
+
return { score: 0, reasons: ["Balance check skipped"] };
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
reasons.push(`Balance check failed: ${err.message}`);
|
|
234
|
+
return { score: 50, reasons, degraded: true };
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async function scoreMarketCondition(_input) {
|
|
238
|
+
const reasons = [];
|
|
239
|
+
try {
|
|
240
|
+
// Check recent block production rate as a proxy for chain health
|
|
241
|
+
const latestBlock = await publicClient.getBlock({ blockTag: "latest" });
|
|
242
|
+
const prevBlock = await publicClient.getBlock({
|
|
243
|
+
blockNumber: latestBlock.number - 10n,
|
|
244
|
+
});
|
|
245
|
+
const timeDiff = Number(latestBlock.timestamp - prevBlock.timestamp);
|
|
246
|
+
const avgBlockTime = timeDiff / 10;
|
|
247
|
+
if (avgBlockTime > 30) {
|
|
248
|
+
reasons.push(`Slow block production: ~${avgBlockTime.toFixed(1)}s/block; chain may be congested`);
|
|
249
|
+
return { score: 60, reasons };
|
|
250
|
+
}
|
|
251
|
+
if (avgBlockTime > 15) {
|
|
252
|
+
reasons.push(`Slightly elevated block times: ~${avgBlockTime.toFixed(1)}s/block`);
|
|
253
|
+
return { score: 30, reasons };
|
|
254
|
+
}
|
|
255
|
+
// Check gas price
|
|
256
|
+
const gasPrice = await publicClient.getGasPrice();
|
|
257
|
+
const gasPriceGwei = Number(gasPrice) / 1e9;
|
|
258
|
+
if (gasPriceGwei > 100) {
|
|
259
|
+
reasons.push(`High gas price: ${gasPriceGwei.toFixed(1)} Gwei`);
|
|
260
|
+
return { score: 50, reasons };
|
|
261
|
+
}
|
|
262
|
+
reasons.push(`Chain healthy: ~${avgBlockTime.toFixed(1)}s/block, ${gasPriceGwei.toFixed(1)} Gwei gas`);
|
|
263
|
+
return { score: 5, reasons };
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
reasons.push("Could not assess market conditions");
|
|
267
|
+
return { score: 20, reasons };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// ─── Main Risk Assessment ──────────────────────────────────────────────
|
|
271
|
+
export async function assessRisk(input) {
|
|
272
|
+
// Fetch DODO route once and share between liquidity + slippage + counterparty scorers
|
|
273
|
+
const { quote: swapQuote, notConfigured: swapProviderNotConfigured } = await fetchSwapQuote(input);
|
|
274
|
+
const [counterparty, balance, market] = await Promise.all([
|
|
275
|
+
scoreCounterparty(input, swapQuote),
|
|
276
|
+
scoreBalance(input),
|
|
277
|
+
scoreMarketCondition(input),
|
|
278
|
+
]);
|
|
279
|
+
const liquidity = scoreLiquidity(input, swapQuote, swapProviderNotConfigured);
|
|
280
|
+
const slippage = scoreSlippage(input, swapQuote, swapProviderNotConfigured);
|
|
281
|
+
const breakdown = {
|
|
282
|
+
liquidityRisk: liquidity.score,
|
|
283
|
+
slippageRisk: slippage.score,
|
|
284
|
+
counterpartyRisk: counterparty.score,
|
|
285
|
+
balanceRisk: balance.score,
|
|
286
|
+
marketConditionRisk: market.score,
|
|
287
|
+
};
|
|
288
|
+
const riskScore = clamp(weightedAverage(breakdown));
|
|
289
|
+
const riskLevel = computeRiskLevel(riskScore);
|
|
290
|
+
let recommendation = computeRecommendation(riskScore);
|
|
291
|
+
// Fail-closed on missing CRITICAL data. A swap whose route/liquidity could
|
|
292
|
+
// not be fetched, or any action whose balance check threw, must NOT be scored as
|
|
293
|
+
// safe on degraded inputs. Mark degraded and refuse to "proceed" silently.
|
|
294
|
+
const degradedReasons = [];
|
|
295
|
+
if (input.action === "swap" && swapQuote === null) {
|
|
296
|
+
degradedReasons.push(swapProviderNotConfigured
|
|
297
|
+
? `Swap liquidity provider is not configured for chainId ${CHAIN_ID} (SWAP_LIQUIDITY_NOT_CONFIGURED); this is a permanent configuration state on this network, not a transient outage.`
|
|
298
|
+
: "Liquidity/slippage could not be assessed: swap route fetch failed.");
|
|
299
|
+
}
|
|
300
|
+
if (balance.degraded) {
|
|
301
|
+
degradedReasons.push("Wallet balance could not be verified; RPC unavailable.");
|
|
302
|
+
}
|
|
303
|
+
const degraded = degradedReasons.length > 0;
|
|
304
|
+
if (degraded && recommendation === "proceed") {
|
|
305
|
+
recommendation = "caution";
|
|
306
|
+
}
|
|
307
|
+
// Advisory escalation mirroring the policy engine's `risk_counterparty`
|
|
308
|
+
// check (the actual block mechanism). Kept so the published recommendation
|
|
309
|
+
// stays honest for critically-risky transfers (missing / invalid / zero
|
|
310
|
+
// recipient): weighted heuristics alone can never cross the block threshold
|
|
311
|
+
// for a transfer, so without this the on-chain record would say "caution"
|
|
312
|
+
// where the policy engine blocks.
|
|
313
|
+
if (input.action === "transfer" && counterparty.score >= COUNTERPARTY_CRITICAL_THRESHOLD) {
|
|
314
|
+
recommendation = "block";
|
|
315
|
+
}
|
|
316
|
+
const reasons = [
|
|
317
|
+
...liquidity.reasons,
|
|
318
|
+
...slippage.reasons,
|
|
319
|
+
...counterparty.reasons,
|
|
320
|
+
...balance.reasons,
|
|
321
|
+
...market.reasons,
|
|
322
|
+
];
|
|
323
|
+
let suggestion;
|
|
324
|
+
if (recommendation === "proceed") {
|
|
325
|
+
suggestion = "Risk is within acceptable range. Proceed with the transaction.";
|
|
326
|
+
}
|
|
327
|
+
else if (recommendation === "caution") {
|
|
328
|
+
suggestion =
|
|
329
|
+
"Moderate risk detected. Review the risk breakdown carefully before proceeding. Consider reducing the amount or adjusting parameters.";
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
suggestion =
|
|
333
|
+
"High risk detected: execution blocked for safety. Review the reasons and adjust your transaction parameters significantly before retrying.";
|
|
334
|
+
}
|
|
335
|
+
return {
|
|
336
|
+
riskScore,
|
|
337
|
+
riskLevel,
|
|
338
|
+
recommendation,
|
|
339
|
+
breakdown,
|
|
340
|
+
reasons,
|
|
341
|
+
suggestion,
|
|
342
|
+
degraded,
|
|
343
|
+
degradedReasons,
|
|
344
|
+
...(input.action === "swap" ? { swapProviderNotConfigured } : {}),
|
|
345
|
+
};
|
|
346
|
+
}
|
|
284
347
|
//# sourceMappingURL=riskEngine.js.map
|