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
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// ─── Activity Store ────────────────────────────────────────────────────
|
|
2
|
+
// In-memory, fixed-capacity ring buffer of sanitized activity items, plus
|
|
3
|
+
// O(1) cumulative counters for the public summary/metrics endpoints. No DB, no
|
|
4
|
+
// external service, no file I/O. Bounded memory by construction. Per-process /
|
|
5
|
+
// per-instance (documented): on multi-instance deployments each instance keeps
|
|
6
|
+
// its own window — acceptable for a public, illustrative activity feed.
|
|
7
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
8
|
+
const DEFAULT_CAPACITY = 500;
|
|
9
|
+
const MIN_CAPACITY = 10;
|
|
10
|
+
const MAX_CAPACITY = 5000;
|
|
11
|
+
function emptyDecisions() {
|
|
12
|
+
return { ALLOW: 0, BLOCK: 0, REQUIRE_CONFIRMATION: 0, PREPARE_ONLY: 0, NONE: 0 };
|
|
13
|
+
}
|
|
14
|
+
function emptyRisks() {
|
|
15
|
+
return { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0, UNKNOWN: 0 };
|
|
16
|
+
}
|
|
17
|
+
function emptyCallers() {
|
|
18
|
+
return { api: 0, agent: 0, a2a: 0, unknown: 0 };
|
|
19
|
+
}
|
|
20
|
+
function emptyAccessTiers() {
|
|
21
|
+
return { anonymous: 0, "api-key": 0, agent: 0, a2a: 0 };
|
|
22
|
+
}
|
|
23
|
+
function clampCapacity(n) {
|
|
24
|
+
if (!Number.isFinite(n))
|
|
25
|
+
return DEFAULT_CAPACITY;
|
|
26
|
+
return Math.min(MAX_CAPACITY, Math.max(MIN_CAPACITY, Math.floor(n)));
|
|
27
|
+
}
|
|
28
|
+
export class ActivityStore {
|
|
29
|
+
capacity;
|
|
30
|
+
buf;
|
|
31
|
+
head = 0; // next write slot
|
|
32
|
+
size = 0;
|
|
33
|
+
startedAtMs = Date.now();
|
|
34
|
+
lastActivityAt = null;
|
|
35
|
+
recorded = 0;
|
|
36
|
+
rateLimited = 0;
|
|
37
|
+
rateLimitedByTier = emptyAccessTiers();
|
|
38
|
+
byCaller = emptyCallers();
|
|
39
|
+
byAccessTier = emptyAccessTiers();
|
|
40
|
+
byDecision = emptyDecisions();
|
|
41
|
+
byRisk = emptyRisks();
|
|
42
|
+
byEndpoint = {};
|
|
43
|
+
byPolicyPreset = {};
|
|
44
|
+
constructor(capacity = DEFAULT_CAPACITY) {
|
|
45
|
+
this.capacity = clampCapacity(capacity);
|
|
46
|
+
this.buf = new Array(this.capacity);
|
|
47
|
+
}
|
|
48
|
+
/** Resize/reset the ring (used at server start from env). Clears all state. */
|
|
49
|
+
configure(capacity) {
|
|
50
|
+
this.capacity = clampCapacity(capacity);
|
|
51
|
+
this.reset();
|
|
52
|
+
}
|
|
53
|
+
/** Clear the buffer + counters (tests + reconfigure). */
|
|
54
|
+
reset() {
|
|
55
|
+
this.buf = new Array(this.capacity);
|
|
56
|
+
this.head = 0;
|
|
57
|
+
this.size = 0;
|
|
58
|
+
this.startedAtMs = Date.now();
|
|
59
|
+
this.lastActivityAt = null;
|
|
60
|
+
this.recorded = 0;
|
|
61
|
+
this.rateLimited = 0;
|
|
62
|
+
this.rateLimitedByTier = emptyAccessTiers();
|
|
63
|
+
this.byCaller = emptyCallers();
|
|
64
|
+
this.byAccessTier = emptyAccessTiers();
|
|
65
|
+
this.byDecision = emptyDecisions();
|
|
66
|
+
this.byRisk = emptyRisks();
|
|
67
|
+
this.byEndpoint = {};
|
|
68
|
+
this.byPolicyPreset = {};
|
|
69
|
+
}
|
|
70
|
+
record(item) {
|
|
71
|
+
this.buf[this.head] = item;
|
|
72
|
+
this.head = (this.head + 1) % this.capacity;
|
|
73
|
+
if (this.size < this.capacity)
|
|
74
|
+
this.size++;
|
|
75
|
+
this.recorded++;
|
|
76
|
+
this.lastActivityAt = item.ts;
|
|
77
|
+
this.byCaller[item.callerType] = (this.byCaller[item.callerType] ?? 0) + 1;
|
|
78
|
+
const tier = (item.accessTier ?? "anonymous");
|
|
79
|
+
if (tier in this.byAccessTier)
|
|
80
|
+
this.byAccessTier[tier]++;
|
|
81
|
+
else
|
|
82
|
+
this.byAccessTier.anonymous++;
|
|
83
|
+
const dKey = (item.decision ?? "NONE");
|
|
84
|
+
if (dKey in this.byDecision)
|
|
85
|
+
this.byDecision[dKey]++;
|
|
86
|
+
else
|
|
87
|
+
this.byDecision.NONE++;
|
|
88
|
+
const rKey = (item.riskLevel ?? "UNKNOWN");
|
|
89
|
+
if (rKey in this.byRisk)
|
|
90
|
+
this.byRisk[rKey]++;
|
|
91
|
+
else
|
|
92
|
+
this.byRisk.UNKNOWN++;
|
|
93
|
+
this.byEndpoint[item.endpoint] = (this.byEndpoint[item.endpoint] ?? 0) + 1;
|
|
94
|
+
const preset = item.policyPreset ?? "none";
|
|
95
|
+
this.byPolicyPreset[preset] = (this.byPolicyPreset[preset] ?? 0) + 1;
|
|
96
|
+
}
|
|
97
|
+
/** Count a rate-limited (429) request that never reached a handler. */
|
|
98
|
+
recordRateLimited(tier) {
|
|
99
|
+
this.rateLimited++;
|
|
100
|
+
if (tier && tier in this.rateLimitedByTier)
|
|
101
|
+
this.rateLimitedByTier[tier]++;
|
|
102
|
+
}
|
|
103
|
+
/** Newest-first slice of the most recent items (sanitized copies). */
|
|
104
|
+
recent(limit) {
|
|
105
|
+
const n = Math.min(Math.max(0, Math.floor(limit)), this.size);
|
|
106
|
+
const out = [];
|
|
107
|
+
for (let i = 0; i < n; i++) {
|
|
108
|
+
const idx = (this.head - 1 - i + this.capacity * 2) % this.capacity;
|
|
109
|
+
const item = this.buf[idx];
|
|
110
|
+
if (item)
|
|
111
|
+
out.push(item);
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
summary() {
|
|
116
|
+
return {
|
|
117
|
+
window: { capacity: this.capacity, size: this.size },
|
|
118
|
+
totals: {
|
|
119
|
+
recorded: this.recorded,
|
|
120
|
+
rateLimited: this.rateLimited,
|
|
121
|
+
byCaller: { ...this.byCaller },
|
|
122
|
+
byAccessTier: { ...this.byAccessTier },
|
|
123
|
+
byDecision: { ...this.byDecision },
|
|
124
|
+
byRisk: { ...this.byRisk },
|
|
125
|
+
byEndpoint: { ...this.byEndpoint },
|
|
126
|
+
byPolicyPreset: { ...this.byPolicyPreset },
|
|
127
|
+
},
|
|
128
|
+
lastActivityAt: this.lastActivityAt,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
metrics() {
|
|
132
|
+
return {
|
|
133
|
+
uptimeSeconds: Math.floor((Date.now() - this.startedAtMs) / 1000),
|
|
134
|
+
totalChecks: this.byCaller.api,
|
|
135
|
+
totalAgentChecks: this.byCaller.agent,
|
|
136
|
+
totalA2AChecks: this.byCaller.a2a,
|
|
137
|
+
totalBlocked: this.byDecision.BLOCK,
|
|
138
|
+
totalRequireConfirmation: this.byDecision.REQUIRE_CONFIRMATION,
|
|
139
|
+
totalPrepareOnly: this.byDecision.PREPARE_ONLY,
|
|
140
|
+
totalAllowed: this.byDecision.ALLOW,
|
|
141
|
+
totalRateLimited: this.rateLimited,
|
|
142
|
+
rateLimitedByTier: { ...this.rateLimitedByTier },
|
|
143
|
+
ring: { capacity: this.capacity, size: this.size },
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** Process-wide singleton used by the server + activity routes. */
|
|
148
|
+
export const activityStore = new ActivityStore();
|
|
149
|
+
//# sourceMappingURL=activityStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activityStore.js","sourceRoot":"","sources":["../../../src/lib/observability/activityStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Scope } from "./scopes.js";
|
|
2
|
+
export interface ApiKeyConfig {
|
|
3
|
+
/** At least one key configured via SAFEHANDS_API_KEYS. */
|
|
4
|
+
configured: boolean;
|
|
5
|
+
/** Gate non-public endpoints (only when configured). */
|
|
6
|
+
required: boolean;
|
|
7
|
+
/** Public read API open by default (SAFEHANDS_PUBLIC_READ_ENABLED !== "false"). */
|
|
8
|
+
publicReadEnabled: boolean;
|
|
9
|
+
/** keyId (hash prefix) → full sha256 hex. Never the raw key. */
|
|
10
|
+
hashes: Map<string, string>;
|
|
11
|
+
/** keyId → granted scopes. Bare keys receive the default read bundle. */
|
|
12
|
+
scopes: Map<string, Set<Scope>>;
|
|
13
|
+
}
|
|
14
|
+
export type ApiKeyStatus = "anonymous" | "valid" | "invalid";
|
|
15
|
+
export interface ApiKeyResolution {
|
|
16
|
+
status: ApiKeyStatus;
|
|
17
|
+
keyId: string | null;
|
|
18
|
+
/** Granted scopes for a valid key (null when anonymous/invalid). */
|
|
19
|
+
scopes: Set<Scope> | null;
|
|
20
|
+
}
|
|
21
|
+
type Env = Record<string, string | undefined>;
|
|
22
|
+
type Headers = Record<string, string | string[] | undefined>;
|
|
23
|
+
/**
|
|
24
|
+
* Endpoints that remain open even when SAFEHANDS_REQUIRE_API_KEY=true.
|
|
25
|
+
* The `/paid/*` bundle entrypoints are listed so PUBLIC x402 users/agents reach them
|
|
26
|
+
* without an API key — payment (x402), not an API key, gates those routes. (An explicitly
|
|
27
|
+
* INVALID key is still rejected everywhere except /health.)
|
|
28
|
+
*/
|
|
29
|
+
export declare const ALWAYS_OPEN_PATHS: Set<string>;
|
|
30
|
+
export declare function loadApiKeyConfig(env?: Env): ApiKeyConfig;
|
|
31
|
+
/** Extract a presented key from `X-Api-Key` or `Authorization: Bearer <key>`. */
|
|
32
|
+
export declare function extractApiKey(headers: Headers): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Resolve a request's API-key status. Never returns the raw key. `anonymous`
|
|
35
|
+
* when none presented; `valid` (+keyId) on match; `invalid` otherwise.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveApiKey(headers: Headers, cfg: ApiKeyConfig): ApiKeyResolution;
|
|
38
|
+
export interface AccessDecision {
|
|
39
|
+
allow: boolean;
|
|
40
|
+
code: string | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Pure access decision for a path given the resolved key + config.
|
|
44
|
+
* • /health is always open (Railway healthcheck).
|
|
45
|
+
* • An explicitly INVALID key is rejected everywhere else.
|
|
46
|
+
* • ALWAYS_OPEN paths are open even when keys are required.
|
|
47
|
+
* • When `required`, a valid key is necessary, and the key must carry the
|
|
48
|
+
* endpoint's scope. Scope is only enforced in require-key mode; when the public
|
|
49
|
+
* read API is open (default), scopes are recorded as identity, never gates.
|
|
50
|
+
* (A valid resolution with `scopes` omitted skips the scope check — the live
|
|
51
|
+
* `resolveApiKey` always populates scopes for valid keys.)
|
|
52
|
+
*/
|
|
53
|
+
export declare function evaluateAccess(path: string, resolution: ApiKeyResolution, cfg: ApiKeyConfig): AccessDecision;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=apiKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiKey.d.ts","sourceRoot":"","sources":["../../../src/lib/observability/apiKey.ts"],"names":[],"mappings":"AAgBA,OAAO,EAA4D,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEnG,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,UAAU,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,QAAQ,EAAE,OAAO,CAAC;IAClB,mFAAmF;IACnF,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,yEAAyE;IACzE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;CACjC;AAED,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oEAAoE;IACpE,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;CAC3B;AAED,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAC9C,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,aAe5B,CAAC;AAMH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,GAAiB,GAAG,YAAY,CA2BrE;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAY7D;AAWD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,gBAAgB,CAUnF;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,gBAAgB,EAC5B,GAAG,EAAE,YAAY,GAChB,cAAc,CAchB"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// ─── API Key Foundation (optional, access-control only) ────────────────
|
|
2
|
+
// Optional identity / rate-limit / access-control foundation. NOT a payment
|
|
3
|
+
// mechanism — paid endpoints use x402 gating (api/x402Gate.ts, env-gated via
|
|
4
|
+
// X402_PAY_TO + X402_FACILITATOR_URL). The public read API stays OPEN by default.
|
|
5
|
+
//
|
|
6
|
+
// Behavior:
|
|
7
|
+
// • SAFEHANDS_API_KEYS unset/empty ⇒ open; anonymous allowed everywhere.
|
|
8
|
+
// • Keys are hashed (sha256) at load; raw keys are never stored or returned.
|
|
9
|
+
// A request references its key only by `keyId` (hash prefix) in logs/activity.
|
|
10
|
+
// • SAFEHANDS_REQUIRE_API_KEY=true (only meaningful when keys are configured)
|
|
11
|
+
// gates the non-public endpoints; truly public endpoints stay open.
|
|
12
|
+
// • Supplying an INVALID key is always an error (401), anywhere except /health.
|
|
13
|
+
// Pure + offline. No signing/wallet/write primitives.
|
|
14
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
15
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
16
|
+
import { DEFAULT_READ_SCOPES, parseScopes, scopeForPath, hasScope } from "./scopes.js";
|
|
17
|
+
/**
|
|
18
|
+
* Endpoints that remain open even when SAFEHANDS_REQUIRE_API_KEY=true.
|
|
19
|
+
* The `/paid/*` bundle entrypoints are listed so PUBLIC x402 users/agents reach them
|
|
20
|
+
* without an API key — payment (x402), not an API key, gates those routes. (An explicitly
|
|
21
|
+
* INVALID key is still rejected everywhere except /health.)
|
|
22
|
+
*/
|
|
23
|
+
export const ALWAYS_OPEN_PATHS = new Set([
|
|
24
|
+
"/health",
|
|
25
|
+
"/demo",
|
|
26
|
+
"/infra/status",
|
|
27
|
+
"/public-config",
|
|
28
|
+
"/activity/summary",
|
|
29
|
+
"/activity/recent",
|
|
30
|
+
"/metrics/public",
|
|
31
|
+
"/paid/assess-risk",
|
|
32
|
+
"/paid/check-token-security",
|
|
33
|
+
"/paid/simulate-transaction",
|
|
34
|
+
"/paid/token-price",
|
|
35
|
+
"/paid/pool-info",
|
|
36
|
+
"/paid/swap-route",
|
|
37
|
+
"/paid/risk-report",
|
|
38
|
+
]);
|
|
39
|
+
function sha256hex(value) {
|
|
40
|
+
return createHash("sha256").update(value, "utf8").digest("hex");
|
|
41
|
+
}
|
|
42
|
+
export function loadApiKeyConfig(env = process.env) {
|
|
43
|
+
const entries = (env.SAFEHANDS_API_KEYS ?? "")
|
|
44
|
+
.split(",")
|
|
45
|
+
.map((e) => e.trim())
|
|
46
|
+
.filter(Boolean);
|
|
47
|
+
const hashes = new Map();
|
|
48
|
+
const scopes = new Map();
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
// Backward-compatible scoped format: `rawKey` or `rawKey#scopeA|scopeB`.
|
|
51
|
+
// Split on the FIRST `#` only; a bare key (no `#`) gets the default read bundle.
|
|
52
|
+
const hashIdx = entry.indexOf("#");
|
|
53
|
+
const rawKey = (hashIdx >= 0 ? entry.slice(0, hashIdx) : entry).trim();
|
|
54
|
+
if (!rawKey)
|
|
55
|
+
continue;
|
|
56
|
+
const scopeStr = hashIdx >= 0 ? entry.slice(hashIdx + 1) : null;
|
|
57
|
+
const hash = sha256hex(rawKey);
|
|
58
|
+
const keyId = hash.slice(0, 8);
|
|
59
|
+
hashes.set(keyId, hash);
|
|
60
|
+
scopes.set(keyId, scopeStr !== null ? parseScopes(scopeStr) : new Set(DEFAULT_READ_SCOPES));
|
|
61
|
+
}
|
|
62
|
+
const configured = hashes.size > 0;
|
|
63
|
+
return {
|
|
64
|
+
configured,
|
|
65
|
+
required: env.SAFEHANDS_REQUIRE_API_KEY === "true" && configured,
|
|
66
|
+
publicReadEnabled: env.SAFEHANDS_PUBLIC_READ_ENABLED !== "false",
|
|
67
|
+
hashes,
|
|
68
|
+
scopes,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Extract a presented key from `X-Api-Key` or `Authorization: Bearer <key>`. */
|
|
72
|
+
export function extractApiKey(headers) {
|
|
73
|
+
const x = headers["x-api-key"];
|
|
74
|
+
const xVal = Array.isArray(x) ? x[0] : x;
|
|
75
|
+
if (typeof xVal === "string" && xVal.trim().length > 0)
|
|
76
|
+
return xVal.trim();
|
|
77
|
+
const auth = headers["authorization"];
|
|
78
|
+
const authVal = Array.isArray(auth) ? auth[0] : auth;
|
|
79
|
+
if (typeof authVal === "string") {
|
|
80
|
+
const m = /^Bearer\s+(.+)$/i.exec(authVal.trim());
|
|
81
|
+
if (m && m[1].trim().length > 0)
|
|
82
|
+
return m[1].trim();
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
function timingSafeHexEqual(a, b) {
|
|
87
|
+
if (a.length !== b.length)
|
|
88
|
+
return false;
|
|
89
|
+
try {
|
|
90
|
+
return timingSafeEqual(Buffer.from(a, "hex"), Buffer.from(b, "hex"));
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolve a request's API-key status. Never returns the raw key. `anonymous`
|
|
98
|
+
* when none presented; `valid` (+keyId) on match; `invalid` otherwise.
|
|
99
|
+
*/
|
|
100
|
+
export function resolveApiKey(headers, cfg) {
|
|
101
|
+
const provided = extractApiKey(headers);
|
|
102
|
+
if (!provided)
|
|
103
|
+
return { status: "anonymous", keyId: null, scopes: null };
|
|
104
|
+
const hash = sha256hex(provided);
|
|
105
|
+
const keyId = hash.slice(0, 8);
|
|
106
|
+
const expected = cfg.hashes.get(keyId);
|
|
107
|
+
if (expected && timingSafeHexEqual(expected, hash)) {
|
|
108
|
+
return { status: "valid", keyId, scopes: cfg.scopes.get(keyId) ?? new Set() };
|
|
109
|
+
}
|
|
110
|
+
return { status: "invalid", keyId: null, scopes: null };
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Pure access decision for a path given the resolved key + config.
|
|
114
|
+
* • /health is always open (Railway healthcheck).
|
|
115
|
+
* • An explicitly INVALID key is rejected everywhere else.
|
|
116
|
+
* • ALWAYS_OPEN paths are open even when keys are required.
|
|
117
|
+
* • When `required`, a valid key is necessary, and the key must carry the
|
|
118
|
+
* endpoint's scope. Scope is only enforced in require-key mode; when the public
|
|
119
|
+
* read API is open (default), scopes are recorded as identity, never gates.
|
|
120
|
+
* (A valid resolution with `scopes` omitted skips the scope check — the live
|
|
121
|
+
* `resolveApiKey` always populates scopes for valid keys.)
|
|
122
|
+
*/
|
|
123
|
+
export function evaluateAccess(path, resolution, cfg) {
|
|
124
|
+
if (path === "/health")
|
|
125
|
+
return { allow: true, code: null };
|
|
126
|
+
if (resolution.status === "invalid")
|
|
127
|
+
return { allow: false, code: "INVALID_API_KEY" };
|
|
128
|
+
if (ALWAYS_OPEN_PATHS.has(path))
|
|
129
|
+
return { allow: true, code: null };
|
|
130
|
+
if (cfg.required && resolution.status !== "valid") {
|
|
131
|
+
return { allow: false, code: "API_KEY_REQUIRED" };
|
|
132
|
+
}
|
|
133
|
+
if (cfg.required && resolution.status === "valid" && resolution.scopes) {
|
|
134
|
+
const needed = scopeForPath(path);
|
|
135
|
+
if (needed && !hasScope(resolution.scopes, needed)) {
|
|
136
|
+
return { allow: false, code: "INSUFFICIENT_SCOPE" };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { allow: true, code: null };
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=apiKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiKey.js","sourceRoot":"","sources":["../../../src/lib/observability/apiKey.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface RequestLogEntry {
|
|
2
|
+
ts: string;
|
|
3
|
+
level: "info" | "warn";
|
|
4
|
+
event: "request";
|
|
5
|
+
requestId: string;
|
|
6
|
+
method: string;
|
|
7
|
+
path: string;
|
|
8
|
+
status: number;
|
|
9
|
+
durationMs: number;
|
|
10
|
+
callerType?: string | null;
|
|
11
|
+
decision?: string | null;
|
|
12
|
+
rateLimited?: boolean;
|
|
13
|
+
/** keyId (hash prefix) only — NEVER the raw API key. */
|
|
14
|
+
apiKeyId?: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface LoggingConfig {
|
|
17
|
+
enabled: boolean;
|
|
18
|
+
format: "json";
|
|
19
|
+
}
|
|
20
|
+
/** Pure: shape a log entry into a single JSON line (no trailing newline). */
|
|
21
|
+
export declare function formatRequestLog(entry: RequestLogEntry): string;
|
|
22
|
+
type Sink = (line: string) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Emit a request log line. Never throws (logging must not affect request
|
|
25
|
+
* handling). Disabled via config so tests/dev can silence output. `sink` is
|
|
26
|
+
* injectable for tests.
|
|
27
|
+
*/
|
|
28
|
+
export declare function logRequest(entry: RequestLogEntry, config?: LoggingConfig, sink?: Sink): void;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/lib/observability/logger.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAE/D;AAED,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAMnC;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,eAAe,EACtB,MAAM,GAAE,aAAiD,EACzD,IAAI,GAAE,IAAkB,GACvB,IAAI,CAON"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// ─── Structured Request Logger ─────────────────────────────────────────
|
|
2
|
+
// One JSON line per request to stdout (Railway captures stdout). Whitelisted
|
|
3
|
+
// fields ONLY — never bodies, headers, query strings, client IP, API keys,
|
|
4
|
+
// private keys, full RPC URLs, or raw signed transactions. `formatRequestLog`
|
|
5
|
+
// is pure (returns the line); `logRequest` is the thin, never-throw emitter
|
|
6
|
+
// (mirrors the discipline of lib/auditLog.ts). No signing/wallet primitives.
|
|
7
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
8
|
+
/** Pure: shape a log entry into a single JSON line (no trailing newline). */
|
|
9
|
+
export function formatRequestLog(entry) {
|
|
10
|
+
return JSON.stringify(entry);
|
|
11
|
+
}
|
|
12
|
+
const defaultSink = (line) => {
|
|
13
|
+
process.stdout.write(line + "\n");
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Emit a request log line. Never throws (logging must not affect request
|
|
17
|
+
* handling). Disabled via config so tests/dev can silence output. `sink` is
|
|
18
|
+
* injectable for tests.
|
|
19
|
+
*/
|
|
20
|
+
export function logRequest(entry, config = { enabled: true, format: "json" }, sink = defaultSink) {
|
|
21
|
+
if (!config.enabled)
|
|
22
|
+
return;
|
|
23
|
+
try {
|
|
24
|
+
sink(formatRequestLog(entry));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// swallow — logging must never break the response path
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/lib/observability/logger.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAuB3E,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAID,MAAM,WAAW,GAAS,CAAC,IAAI,EAAE,EAAE;IACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAsB,EACtB,SAAwB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EACzD,OAAa,WAAW;IAExB,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO;IAC5B,IAAI,CAAC;QACH,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;IACzD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type QuotaTier = "anonymous" | "api-key" | "agent" | "a2a";
|
|
2
|
+
export declare const QUOTA_TIERS: readonly QuotaTier[];
|
|
3
|
+
export interface QuotaConfig {
|
|
4
|
+
enabled: boolean;
|
|
5
|
+
windowMs: number;
|
|
6
|
+
/** Max requests per window, per tier. */
|
|
7
|
+
max: Record<QuotaTier, number>;
|
|
8
|
+
}
|
|
9
|
+
export interface QuotaState {
|
|
10
|
+
tier: QuotaTier;
|
|
11
|
+
limit: number;
|
|
12
|
+
remaining: number;
|
|
13
|
+
limited: boolean;
|
|
14
|
+
/** Unix seconds at which the current window resets. */
|
|
15
|
+
resetAtSec: number;
|
|
16
|
+
/** Seconds until reset (for Retry-After). */
|
|
17
|
+
retryAfterSec: number;
|
|
18
|
+
}
|
|
19
|
+
/** Map an access-context callerType to a quota tier (fail-safe to anonymous). */
|
|
20
|
+
export declare function tierForCaller(callerType: string): QuotaTier;
|
|
21
|
+
export declare class QuotaLimiter {
|
|
22
|
+
private cfg;
|
|
23
|
+
private buckets;
|
|
24
|
+
constructor(cfg: QuotaConfig);
|
|
25
|
+
/** Reconfigure + clear state (used at server start / tests). */
|
|
26
|
+
configure(cfg: QuotaConfig): void;
|
|
27
|
+
/**
|
|
28
|
+
* Count one request against the (tier, identifier) bucket and return the
|
|
29
|
+
* resulting state. `identifier` MUST be a trusted value (keyId or IP).
|
|
30
|
+
*/
|
|
31
|
+
consume(tier: QuotaTier, identifier: string, now?: number): QuotaState;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=quota.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota.d.ts","sourceRoot":"","sources":["../../../src/lib/observability/quota.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,GAAG,KAAK,CAAC;AAElE,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAA6C,CAAC;AAE1F,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAE3D;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,OAAO,CAAyD;gBAE5D,GAAG,EAAE,WAAW;IAI5B,gEAAgE;IAChE,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAKjC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,UAAU;CAkBnF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// ─── Tiered In-Memory Quota ──────────────────────────────────────
|
|
2
|
+
// Generalizes the base in-memory rate limiter into per-caller-tier quota.
|
|
3
|
+
// No Redis, no DB, no external dependency — a bounded in-memory bucket Map.
|
|
4
|
+
//
|
|
5
|
+
// Buckets are keyed by a TRUSTED identifier only: `key:<keyId>` for a valid API
|
|
6
|
+
// key, else the client IP. Untrusted body identity (agentId/a2aPeerId) is NEVER
|
|
7
|
+
// a quota key — it is gameable. The tier (anonymous | api-key | agent | a2a)
|
|
8
|
+
// selects the limit. Pure logic + state; no signing/wallet/write primitives.
|
|
9
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
10
|
+
export const QUOTA_TIERS = ["anonymous", "api-key", "agent", "a2a"];
|
|
11
|
+
/** Map an access-context callerType to a quota tier (fail-safe to anonymous). */
|
|
12
|
+
export function tierForCaller(callerType) {
|
|
13
|
+
return QUOTA_TIERS.includes(callerType) ? callerType : "anonymous";
|
|
14
|
+
}
|
|
15
|
+
export class QuotaLimiter {
|
|
16
|
+
cfg;
|
|
17
|
+
buckets = new Map();
|
|
18
|
+
constructor(cfg) {
|
|
19
|
+
this.cfg = cfg;
|
|
20
|
+
}
|
|
21
|
+
/** Reconfigure + clear state (used at server start / tests). */
|
|
22
|
+
configure(cfg) {
|
|
23
|
+
this.cfg = cfg;
|
|
24
|
+
this.buckets.clear();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Count one request against the (tier, identifier) bucket and return the
|
|
28
|
+
* resulting state. `identifier` MUST be a trusted value (keyId or IP).
|
|
29
|
+
*/
|
|
30
|
+
consume(tier, identifier, now = Date.now()) {
|
|
31
|
+
const limit = this.cfg.max[tier] ?? this.cfg.max.anonymous;
|
|
32
|
+
const bucketKey = `${tier}:${identifier}`;
|
|
33
|
+
let bucket = this.buckets.get(bucketKey);
|
|
34
|
+
if (!bucket || bucket.resetAt <= now) {
|
|
35
|
+
bucket = { count: 0, resetAt: now + this.cfg.windowMs };
|
|
36
|
+
this.buckets.set(bucketKey, bucket);
|
|
37
|
+
}
|
|
38
|
+
bucket.count += 1;
|
|
39
|
+
return {
|
|
40
|
+
tier,
|
|
41
|
+
limit,
|
|
42
|
+
remaining: Math.max(0, limit - bucket.count),
|
|
43
|
+
limited: bucket.count > limit,
|
|
44
|
+
resetAtSec: Math.ceil(bucket.resetAt / 1000),
|
|
45
|
+
retryAfterSec: Math.max(0, Math.ceil((bucket.resetAt - now) / 1000)),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=quota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota.js","sourceRoot":"","sources":["../../../src/lib/observability/quota.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,0EAA0E;AAC1E,4EAA4E;AAC5E,EAAE;AACF,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,2EAA2E;AAI3E,MAAM,CAAC,MAAM,WAAW,GAAyB,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAoB1F,iFAAiF;AACjF,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAQ,WAAiC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAE,UAAwB,CAAC,CAAC,CAAC,WAAW,CAAC;AAC3G,CAAC;AAED,MAAM,OAAO,YAAY;IACf,GAAG,CAAc;IACjB,OAAO,GAAG,IAAI,GAAG,EAA8C,CAAC;IAExE,YAAY,GAAgB;QAC1B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,gEAAgE;IAChE,SAAS,CAAC,GAAgB;QACxB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,IAAe,EAAE,UAAkB,EAAE,MAAc,IAAI,CAAC,GAAG,EAAE;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC;QAC3D,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,UAAU,EAAE,CAAC;QAC1C,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;YACrC,MAAM,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YACxD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QAClB,OAAO;YACL,IAAI;YACJ,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;YAC5C,OAAO,EAAE,MAAM,CAAC,KAAK,GAAG,KAAK;YAC7B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;YAC5C,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;SACrE,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function isValidRequestId(value: unknown): value is string;
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a request id from an inbound header value. Honors a safe
|
|
4
|
+
* `X-Request-Id` if present; otherwise mints a new UUID. Array header values
|
|
5
|
+
* (duplicate headers) take the first entry.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveRequestId(header?: string | string[] | null): string;
|
|
8
|
+
//# sourceMappingURL=requestId.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestId.d.ts","sourceRoot":"","sources":["../../../src/lib/observability/requestId.ts"],"names":[],"mappings":"AAYA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,MAAM,CAI1E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ─── Request ID ────────────────────────────────────────────────────────
|
|
2
|
+
// Correlation id for logs + activity. Accepts a caller-supplied `X-Request-Id`
|
|
3
|
+
// only when it matches a strict, safe charset (defends against header/log
|
|
4
|
+
// injection); otherwise generates a fresh UUID. Pure + deterministic given its
|
|
5
|
+
// input (aside from the random fallback). No secrets, no I/O.
|
|
6
|
+
// ────────────────────────────────────────────────────────────────────────
|
|
7
|
+
import { randomUUID } from "node:crypto";
|
|
8
|
+
/** Safe inbound request-id: short, printable, no whitespace/control chars. */
|
|
9
|
+
const REQUEST_ID_RE = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
10
|
+
export function isValidRequestId(value) {
|
|
11
|
+
return typeof value === "string" && REQUEST_ID_RE.test(value);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a request id from an inbound header value. Honors a safe
|
|
15
|
+
* `X-Request-Id` if present; otherwise mints a new UUID. Array header values
|
|
16
|
+
* (duplicate headers) take the first entry.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveRequestId(header) {
|
|
19
|
+
const raw = Array.isArray(header) ? header[0] : header;
|
|
20
|
+
if (isValidRequestId(raw))
|
|
21
|
+
return raw;
|
|
22
|
+
return randomUUID();
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=requestId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestId.js","sourceRoot":"","sources":["../../../src/lib/observability/requestId.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,+EAA+E;AAC/E,0EAA0E;AAC1E,+EAA+E;AAC/E,8DAA8D;AAC9D,2EAA2E;AAE3E,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,8EAA8E;AAC9E,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAEjD,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiC;IAChE,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACvD,IAAI,gBAAgB,CAAC,GAAG,CAAC;QAAE,OAAO,GAAG,CAAC;IACtC,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
|