@agirails/sdk 2.0.1-beta → 2.0.2
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/LICENSE +190 -0
- package/README.md +116 -108
- package/bin/actp +10 -0
- package/dist/ACTPClient.d.ts +456 -33
- package/dist/ACTPClient.d.ts.map +1 -1
- package/dist/ACTPClient.js +477 -93
- package/dist/ACTPClient.js.map +1 -1
- package/dist/abi/AgentRegistry.json +782 -0
- package/dist/abi/EscrowVault.json +106 -38
- package/dist/abi/IdentityRegistry.json +316 -0
- package/dist/adapters/BaseAdapter.d.ts +231 -0
- package/dist/adapters/BaseAdapter.d.ts.map +1 -0
- package/dist/adapters/BaseAdapter.js +393 -0
- package/dist/adapters/BaseAdapter.js.map +1 -0
- package/dist/adapters/BeginnerAdapter.d.ts +152 -0
- package/dist/adapters/BeginnerAdapter.d.ts.map +1 -0
- package/dist/adapters/BeginnerAdapter.js +168 -0
- package/dist/adapters/BeginnerAdapter.js.map +1 -0
- package/dist/adapters/IntermediateAdapter.d.ts +211 -0
- package/dist/adapters/IntermediateAdapter.d.ts.map +1 -0
- package/dist/adapters/IntermediateAdapter.js +260 -0
- package/dist/adapters/IntermediateAdapter.js.map +1 -0
- package/dist/adapters/index.d.ts +15 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +26 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/builders/DeliveryProofBuilder.d.ts +60 -1
- package/dist/builders/DeliveryProofBuilder.d.ts.map +1 -1
- package/dist/builders/DeliveryProofBuilder.js +81 -5
- package/dist/builders/DeliveryProofBuilder.js.map +1 -1
- package/dist/builders/QuoteBuilder.d.ts +101 -0
- package/dist/builders/QuoteBuilder.d.ts.map +1 -1
- package/dist/builders/QuoteBuilder.js +120 -3
- package/dist/builders/QuoteBuilder.js.map +1 -1
- package/dist/builders/index.d.ts +4 -0
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +4 -0
- package/dist/builders/index.js.map +1 -1
- package/dist/cli/commands/balance.d.ts +13 -0
- package/dist/cli/commands/balance.d.ts.map +1 -0
- package/dist/cli/commands/balance.js +89 -0
- package/dist/cli/commands/balance.js.map +1 -0
- package/dist/cli/commands/batch.d.ts +24 -0
- package/dist/cli/commands/batch.d.ts.map +1 -0
- package/dist/cli/commands/batch.js +424 -0
- package/dist/cli/commands/batch.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +192 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +143 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/mint.d.ts +13 -0
- package/dist/cli/commands/mint.d.ts.map +1 -0
- package/dist/cli/commands/mint.js +91 -0
- package/dist/cli/commands/mint.js.map +1 -0
- package/dist/cli/commands/pay.d.ts +18 -0
- package/dist/cli/commands/pay.d.ts.map +1 -0
- package/dist/cli/commands/pay.js +87 -0
- package/dist/cli/commands/pay.js.map +1 -0
- package/dist/cli/commands/simulate.d.ts +32 -0
- package/dist/cli/commands/simulate.d.ts.map +1 -0
- package/dist/cli/commands/simulate.js +290 -0
- package/dist/cli/commands/simulate.js.map +1 -0
- package/dist/cli/commands/time.d.ts +29 -0
- package/dist/cli/commands/time.d.ts.map +1 -0
- package/dist/cli/commands/time.js +252 -0
- package/dist/cli/commands/time.js.map +1 -0
- package/dist/cli/commands/tx.d.ts +16 -0
- package/dist/cli/commands/tx.d.ts.map +1 -0
- package/dist/cli/commands/tx.js +379 -0
- package/dist/cli/commands/tx.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +20 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +160 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/index.d.ts +17 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +104 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/client.d.ts +70 -0
- package/dist/cli/utils/client.d.ts.map +1 -0
- package/dist/cli/utils/client.js +240 -0
- package/dist/cli/utils/client.js.map +1 -0
- package/dist/cli/utils/config.d.ts +91 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +240 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/output.d.ts +174 -0
- package/dist/cli/utils/output.d.ts.map +1 -0
- package/dist/cli/utils/output.js +380 -0
- package/dist/cli/utils/output.js.map +1 -0
- package/dist/config/networks.d.ts +28 -0
- package/dist/config/networks.d.ts.map +1 -1
- package/dist/config/networks.js +60 -12
- package/dist/config/networks.js.map +1 -1
- package/dist/errors/index.d.ts +165 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +260 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/index.d.ts +61 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +141 -36
- package/dist/index.js.map +1 -1
- package/dist/level0/Provider.d.ts +106 -0
- package/dist/level0/Provider.d.ts.map +1 -0
- package/dist/level0/Provider.js +10 -0
- package/dist/level0/Provider.js.map +1 -0
- package/dist/level0/ServiceDirectory.d.ts +74 -0
- package/dist/level0/ServiceDirectory.d.ts.map +1 -0
- package/dist/level0/ServiceDirectory.js +122 -0
- package/dist/level0/ServiceDirectory.js.map +1 -0
- package/dist/level0/index.d.ts +10 -0
- package/dist/level0/index.d.ts.map +1 -0
- package/dist/level0/index.js +15 -0
- package/dist/level0/index.js.map +1 -0
- package/dist/level0/provide.d.ts +51 -0
- package/dist/level0/provide.d.ts.map +1 -0
- package/dist/level0/provide.js +113 -0
- package/dist/level0/provide.js.map +1 -0
- package/dist/level0/request.d.ts +53 -0
- package/dist/level0/request.d.ts.map +1 -0
- package/dist/level0/request.js +462 -0
- package/dist/level0/request.js.map +1 -0
- package/dist/level1/Agent.d.ts +472 -0
- package/dist/level1/Agent.d.ts.map +1 -0
- package/dist/level1/Agent.js +1091 -0
- package/dist/level1/Agent.js.map +1 -0
- package/dist/level1/index.d.ts +10 -0
- package/dist/level1/index.d.ts.map +1 -0
- package/dist/level1/index.js +30 -0
- package/dist/level1/index.js.map +1 -0
- package/dist/level1/pricing/PriceCalculator.d.ts +62 -0
- package/dist/level1/pricing/PriceCalculator.d.ts.map +1 -0
- package/dist/level1/pricing/PriceCalculator.js +237 -0
- package/dist/level1/pricing/PriceCalculator.js.map +1 -0
- package/dist/level1/pricing/PricingStrategy.d.ts +179 -0
- package/dist/level1/pricing/PricingStrategy.d.ts.map +1 -0
- package/dist/level1/pricing/PricingStrategy.js +11 -0
- package/dist/level1/pricing/PricingStrategy.js.map +1 -0
- package/dist/level1/types/Job.d.ts +166 -0
- package/dist/level1/types/Job.d.ts.map +1 -0
- package/dist/level1/types/Job.js +11 -0
- package/dist/level1/types/Job.js.map +1 -0
- package/dist/level1/types/Options.d.ts +258 -0
- package/dist/level1/types/Options.d.ts.map +1 -0
- package/dist/level1/types/Options.js +8 -0
- package/dist/level1/types/Options.js.map +1 -0
- package/dist/level1/types/index.d.ts +8 -0
- package/dist/level1/types/index.d.ts.map +1 -0
- package/dist/level1/types/index.js +8 -0
- package/dist/level1/types/index.js.map +1 -0
- package/dist/protocol/ACTPKernel.d.ts +229 -2
- package/dist/protocol/ACTPKernel.d.ts.map +1 -1
- package/dist/protocol/ACTPKernel.js +367 -33
- package/dist/protocol/ACTPKernel.js.map +1 -1
- package/dist/protocol/AgentRegistry.d.ts +177 -0
- package/dist/protocol/AgentRegistry.d.ts.map +1 -0
- package/dist/protocol/AgentRegistry.js +449 -0
- package/dist/protocol/AgentRegistry.js.map +1 -0
- package/dist/protocol/DIDManager.d.ts +289 -0
- package/dist/protocol/DIDManager.d.ts.map +1 -0
- package/dist/protocol/DIDManager.js +481 -0
- package/dist/protocol/DIDManager.js.map +1 -0
- package/dist/protocol/DIDResolver.d.ts +236 -0
- package/dist/protocol/DIDResolver.d.ts.map +1 -0
- package/dist/protocol/DIDResolver.js +495 -0
- package/dist/protocol/DIDResolver.js.map +1 -0
- package/dist/protocol/EASHelper.d.ts +57 -2
- package/dist/protocol/EASHelper.d.ts.map +1 -1
- package/dist/protocol/EASHelper.js +230 -37
- package/dist/protocol/EASHelper.js.map +1 -1
- package/dist/protocol/EscrowVault.d.ts +93 -2
- package/dist/protocol/EscrowVault.d.ts.map +1 -1
- package/dist/protocol/EscrowVault.js +122 -33
- package/dist/protocol/EscrowVault.js.map +1 -1
- package/dist/protocol/EventMonitor.d.ts +45 -1
- package/dist/protocol/EventMonitor.d.ts.map +1 -1
- package/dist/protocol/EventMonitor.js +64 -8
- package/dist/protocol/EventMonitor.js.map +1 -1
- package/dist/protocol/MessageSigner.d.ts +116 -2
- package/dist/protocol/MessageSigner.d.ts.map +1 -1
- package/dist/protocol/MessageSigner.js +215 -9
- package/dist/protocol/MessageSigner.js.map +1 -1
- package/dist/protocol/ProofGenerator.d.ts +93 -0
- package/dist/protocol/ProofGenerator.d.ts.map +1 -1
- package/dist/protocol/ProofGenerator.js +194 -9
- package/dist/protocol/ProofGenerator.js.map +1 -1
- package/dist/protocol/QuoteBuilder.d.ts +8 -0
- package/dist/protocol/QuoteBuilder.d.ts.map +1 -1
- package/dist/protocol/QuoteBuilder.js +8 -0
- package/dist/protocol/QuoteBuilder.js.map +1 -1
- package/dist/runtime/BlockchainRuntime.d.ts +360 -0
- package/dist/runtime/BlockchainRuntime.d.ts.map +1 -0
- package/dist/runtime/BlockchainRuntime.js +767 -0
- package/dist/runtime/BlockchainRuntime.js.map +1 -0
- package/dist/runtime/IACTPRuntime.d.ts +271 -0
- package/dist/runtime/IACTPRuntime.d.ts.map +1 -0
- package/dist/runtime/IACTPRuntime.js +15 -0
- package/dist/runtime/IACTPRuntime.js.map +1 -0
- package/dist/runtime/MockRuntime.d.ts +445 -0
- package/dist/runtime/MockRuntime.d.ts.map +1 -0
- package/dist/runtime/MockRuntime.js +1065 -0
- package/dist/runtime/MockRuntime.js.map +1 -0
- package/dist/runtime/MockStateManager.d.ts +233 -0
- package/dist/runtime/MockStateManager.d.ts.map +1 -0
- package/dist/runtime/MockStateManager.js +533 -0
- package/dist/runtime/MockStateManager.js.map +1 -0
- package/dist/runtime/index.d.ts +14 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +42 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/types/MockState.d.ts +167 -0
- package/dist/runtime/types/MockState.d.ts.map +1 -0
- package/dist/runtime/types/MockState.js +43 -0
- package/dist/runtime/types/MockState.js.map +1 -0
- package/dist/types/agent.d.ts +76 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +8 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/did.d.ts +192 -0
- package/dist/types/did.d.ts.map +1 -0
- package/dist/types/did.js +38 -0
- package/dist/types/did.js.map +1 -0
- package/dist/types/eip712.d.ts +34 -0
- package/dist/types/eip712.d.ts.map +1 -1
- package/dist/types/eip712.js +31 -5
- package/dist/types/eip712.js.map +1 -1
- package/dist/types/escrow.d.ts +17 -10
- package/dist/types/escrow.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/message.d.ts +32 -0
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js +4 -0
- package/dist/types/message.js.map +1 -1
- package/dist/types/state.d.ts +28 -0
- package/dist/types/state.d.ts.map +1 -1
- package/dist/types/state.js +37 -6
- package/dist/types/state.js.map +1 -1
- package/dist/types/transaction.d.ts +17 -0
- package/dist/types/transaction.d.ts.map +1 -1
- package/dist/utils/ErrorRecoveryGuide.d.ts +125 -0
- package/dist/utils/ErrorRecoveryGuide.d.ts.map +1 -0
- package/dist/utils/ErrorRecoveryGuide.js +579 -0
- package/dist/utils/ErrorRecoveryGuide.js.map +1 -0
- package/dist/utils/Helpers.d.ts +453 -0
- package/dist/utils/Helpers.d.ts.map +1 -0
- package/dist/utils/Helpers.js +623 -0
- package/dist/utils/Helpers.js.map +1 -0
- package/dist/utils/IPFSClient.d.ts +113 -0
- package/dist/utils/IPFSClient.d.ts.map +1 -1
- package/dist/utils/IPFSClient.js +128 -7
- package/dist/utils/IPFSClient.js.map +1 -1
- package/dist/utils/Logger.d.ts +195 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +382 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/NonceManager.d.ts +234 -1
- package/dist/utils/NonceManager.d.ts.map +1 -1
- package/dist/utils/NonceManager.js +372 -7
- package/dist/utils/NonceManager.js.map +1 -1
- package/dist/utils/RateLimiter.d.ts +253 -0
- package/dist/utils/RateLimiter.d.ts.map +1 -0
- package/dist/utils/RateLimiter.js +424 -0
- package/dist/utils/RateLimiter.js.map +1 -0
- package/dist/utils/ReceivedNonceTracker.d.ts +175 -0
- package/dist/utils/ReceivedNonceTracker.d.ts.map +1 -1
- package/dist/utils/ReceivedNonceTracker.js +261 -5
- package/dist/utils/ReceivedNonceTracker.js.map +1 -1
- package/dist/utils/SDKLifecycle.d.ts +156 -0
- package/dist/utils/SDKLifecycle.d.ts.map +1 -0
- package/dist/utils/SDKLifecycle.js +347 -0
- package/dist/utils/SDKLifecycle.js.map +1 -0
- package/dist/utils/SecureNonce.d.ts +57 -0
- package/dist/utils/SecureNonce.d.ts.map +1 -0
- package/dist/utils/SecureNonce.js +80 -0
- package/dist/utils/SecureNonce.js.map +1 -0
- package/dist/utils/Semaphore.d.ts +123 -0
- package/dist/utils/Semaphore.d.ts.map +1 -0
- package/dist/utils/Semaphore.js +247 -0
- package/dist/utils/Semaphore.js.map +1 -0
- package/dist/utils/UsedAttestationTracker.d.ts +167 -0
- package/dist/utils/UsedAttestationTracker.d.ts.map +1 -0
- package/dist/utils/UsedAttestationTracker.js +309 -0
- package/dist/utils/UsedAttestationTracker.js.map +1 -0
- package/dist/utils/canonicalJson.d.ts +22 -0
- package/dist/utils/canonicalJson.d.ts.map +1 -1
- package/dist/utils/canonicalJson.js +26 -3
- package/dist/utils/canonicalJson.js.map +1 -1
- package/dist/utils/computeTypeHash.d.ts +14 -0
- package/dist/utils/computeTypeHash.d.ts.map +1 -1
- package/dist/utils/computeTypeHash.js +19 -2
- package/dist/utils/computeTypeHash.js.map +1 -1
- package/dist/utils/fsSafe.d.ts +14 -0
- package/dist/utils/fsSafe.d.ts.map +1 -0
- package/dist/utils/fsSafe.js +89 -0
- package/dist/utils/fsSafe.js.map +1 -0
- package/dist/utils/index.d.ts +15 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +51 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/security.d.ts +147 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +391 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/utils/validation.d.ts +40 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +184 -7
- package/dist/utils/validation.js.map +1 -1
- package/package.json +54 -37
- package/src/ACTPClient.ts +692 -178
- package/src/abi/AgentRegistry.json +782 -0
- package/src/abi/EscrowVault.json +106 -38
- package/src/abi/IdentityRegistry.json +316 -0
- package/src/adapters/BaseAdapter.ts +473 -0
- package/src/adapters/BeginnerAdapter.ts +232 -0
- package/src/adapters/IntermediateAdapter.ts +316 -0
- package/src/adapters/index.ts +25 -0
- package/src/builders/DeliveryProofBuilder.ts +3 -2
- package/src/cli/commands/balance.ts +110 -0
- package/src/cli/commands/batch.ts +487 -0
- package/src/cli/commands/config.ts +231 -0
- package/src/cli/commands/init.ts +161 -0
- package/src/cli/commands/mint.ts +116 -0
- package/src/cli/commands/pay.ts +113 -0
- package/src/cli/commands/simulate.ts +345 -0
- package/src/cli/commands/time.ts +303 -0
- package/src/cli/commands/tx.ts +448 -0
- package/src/cli/commands/watch.ts +211 -0
- package/src/cli/index.ts +116 -0
- package/src/cli/utils/client.ts +249 -0
- package/src/cli/utils/config.ts +282 -0
- package/src/cli/utils/output.ts +465 -0
- package/src/config/networks.ts +32 -9
- package/src/errors/index.ts +298 -1
- package/src/index.ts +207 -71
- package/src/level0/Provider.ts +117 -0
- package/src/level0/ServiceDirectory.ts +131 -0
- package/src/level0/index.ts +10 -0
- package/src/level0/provide.ts +131 -0
- package/src/level0/request.ts +494 -0
- package/src/level1/Agent.ts +1432 -0
- package/src/level1/index.ts +10 -0
- package/src/level1/pricing/PriceCalculator.ts +255 -0
- package/src/level1/pricing/PricingStrategy.ts +198 -0
- package/src/level1/types/Job.ts +179 -0
- package/src/level1/types/Options.ts +291 -0
- package/src/level1/types/index.ts +8 -0
- package/src/protocol/ACTPKernel.ts +175 -23
- package/src/protocol/AgentRegistry.ts +559 -0
- package/src/protocol/DIDManager.ts +629 -0
- package/src/protocol/DIDResolver.ts +554 -0
- package/src/protocol/EASHelper.ts +230 -46
- package/src/protocol/EscrowVault.ts +68 -50
- package/src/protocol/EventMonitor.ts +44 -15
- package/src/protocol/MessageSigner.ts +193 -13
- package/src/protocol/ProofGenerator.ts +223 -4
- package/src/runtime/BlockchainRuntime.ts +993 -0
- package/src/runtime/IACTPRuntime.ts +284 -0
- package/src/runtime/MockRuntime.ts +1244 -0
- package/src/runtime/MockStateManager.ts +576 -0
- package/src/runtime/index.ts +25 -0
- package/src/runtime/types/MockState.ts +227 -0
- package/src/types/agent.ts +79 -0
- package/src/types/did.ts +223 -0
- package/src/types/escrow.ts +12 -11
- package/src/types/index.ts +5 -1
- package/src/types/state.ts +12 -3
- package/src/types/transaction.ts +4 -1
- package/src/utils/ErrorRecoveryGuide.ts +675 -0
- package/src/utils/Helpers.ts +688 -0
- package/src/utils/IPFSClient.ts +122 -5
- package/src/utils/Logger.ts +484 -0
- package/src/utils/NonceManager.ts +305 -8
- package/src/utils/RateLimiter.ts +534 -0
- package/src/utils/ReceivedNonceTracker.ts +170 -0
- package/src/utils/SDKLifecycle.ts +416 -0
- package/src/utils/SecureNonce.ts +78 -0
- package/src/utils/Semaphore.ts +276 -0
- package/src/utils/UsedAttestationTracker.ts +387 -0
- package/src/utils/fsSafe.ts +75 -0
- package/src/utils/index.ts +80 -0
- package/src/utils/security.ts +418 -0
- package/src/utils/validation.ts +164 -0
- package/src/__tests__/ProofGenerator.test.ts +0 -124
- package/src/__tests__/QuoteBuilder.test.ts +0 -516
- package/src/__tests__/StateMachine.test.ts +0 -82
- package/src/__tests__/builders/DeliveryProofBuilder.test.ts +0 -581
- package/src/__tests__/integration/ACTPClient.test.ts +0 -263
- package/src/__tests__/integration.test.ts +0 -289
- package/src/__tests__/protocol/EASHelper.test.ts +0 -472
- package/src/__tests__/protocol/EventMonitor.test.ts +0 -382
- package/src/__tests__/security/ACTPKernel.security.test.ts +0 -1167
- package/src/__tests__/security/EscrowVault.security.test.ts +0 -570
- package/src/__tests__/security/MessageSigner.security.test.ts +0 -286
- package/src/__tests__/security/NonceReplay.security.test.ts +0 -501
- package/src/__tests__/security/validation.security.test.ts +0 -376
- package/src/__tests__/utils/IPFSClient.test.ts +0 -262
- package/src/__tests__/utils/NonceManager.test.ts +0 -205
- package/src/__tests__/utils/canonicalJson.test.ts +0 -153
|
@@ -9,31 +9,100 @@ const ACTPKernel_json_1 = __importDefault(require("../abi/ACTPKernel.json"));
|
|
|
9
9
|
const types_1 = require("../types");
|
|
10
10
|
const errors_1 = require("../errors");
|
|
11
11
|
const validation_1 = require("../utils/validation");
|
|
12
|
+
/**
|
|
13
|
+
* ACTPKernel - Smart contract wrapper
|
|
14
|
+
* Reference: Yellow Paper §3 (ACTP Kernel Specification)
|
|
15
|
+
*/
|
|
12
16
|
class ACTPKernel {
|
|
13
17
|
constructor(address, signer, gasSettings) {
|
|
14
18
|
this.address = address;
|
|
15
19
|
this.contract = new ethers_1.Contract(address, ACTPKernel_json_1.default, signer);
|
|
16
20
|
this.gasSettings = gasSettings;
|
|
17
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Get kernel contract address
|
|
24
|
+
*/
|
|
18
25
|
getAddress() {
|
|
19
26
|
return this.address;
|
|
20
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Get the underlying ethers Contract instance.
|
|
30
|
+
*
|
|
31
|
+
* SECURITY FIX (C-3): Provides public access to contract for EventMonitor
|
|
32
|
+
* instead of accessing private field via bracket notation.
|
|
33
|
+
*
|
|
34
|
+
* @returns ethers Contract instance
|
|
35
|
+
*/
|
|
36
|
+
getContract() {
|
|
37
|
+
return this.contract;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get gas buffer multiplier based on operation complexity
|
|
41
|
+
* V6 Security Enhancement: Operation-specific gas buffers
|
|
42
|
+
* Reference: SDK_SECURITY_ANALYSIS-Ultra-Think.md Lines 326-337
|
|
43
|
+
*/
|
|
21
44
|
getGasBufferMultiplier(operation) {
|
|
22
45
|
const buffers = {
|
|
23
|
-
'createTransaction': 1.15,
|
|
24
|
-
'transitionState': 1.20,
|
|
25
|
-
'releaseEscrow': 1.30,
|
|
26
|
-
'raiseDispute': 1.25,
|
|
27
|
-
'resolveDispute': 1.30,
|
|
28
|
-
'cancelTransaction': 1.15,
|
|
29
|
-
'anchorAttestation': 1.15
|
|
46
|
+
'createTransaction': 1.15, // 15% - Simple state initialization
|
|
47
|
+
'transitionState': 1.20, // 20% - Standard state change
|
|
48
|
+
'releaseEscrow': 1.30, // 30% - Multi-recipient disbursement
|
|
49
|
+
'raiseDispute': 1.25, // 25% - Large proof data handling
|
|
50
|
+
'resolveDispute': 1.30, // 30% - Complex multi-party settlement
|
|
51
|
+
'cancelTransaction': 1.15, // 15% - Simple state change
|
|
52
|
+
'anchorAttestation': 1.15 // 15% - Simple attestation anchoring
|
|
30
53
|
};
|
|
31
|
-
return buffers[operation] || 1.20;
|
|
54
|
+
return buffers[operation] || 1.20; // Default 20% for unknown operations
|
|
32
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Build transaction options with gas settings and estimated gas
|
|
58
|
+
* V6 Enhancement: Dynamic buffer based on operation type
|
|
59
|
+
*
|
|
60
|
+
* SECURITY FIX (C-3): Gas estimation manipulation attack protection
|
|
61
|
+
* - Enforces operation-specific minimum gas floors (not global 100k)
|
|
62
|
+
* - Validates gas limit doesn't exceed block gas limit (DoS prevention)
|
|
63
|
+
* - Uses safe BigInt arithmetic with overflow detection
|
|
64
|
+
* - Prevents floating-point arithmetic (uses BPS - basis points)
|
|
65
|
+
*/
|
|
33
66
|
buildTxOptions(estimatedGas, operation = 'default') {
|
|
67
|
+
// SECURITY FIX (C-3): Operation-specific minimum gas floors
|
|
68
|
+
// Malicious contracts could return artificially low gas estimates to cause txs to fail
|
|
69
|
+
const MIN_GAS_FLOORS = {
|
|
70
|
+
'createTransaction': 120000n, // Create + event emission
|
|
71
|
+
'transitionState': 80000n, // State update + event
|
|
72
|
+
'releaseEscrow': 220000n, // Multi-recipient disbursement + events
|
|
73
|
+
'raiseDispute': 100000n, // Large proof data encoding
|
|
74
|
+
'resolveDispute': 250000n, // Complex multi-party settlement
|
|
75
|
+
'cancelTransaction': 60000n, // Simple state change
|
|
76
|
+
'anchorAttestation': 80000n, // Attestation storage
|
|
77
|
+
'default': 100000n // Conservative fallback
|
|
78
|
+
};
|
|
79
|
+
const minFloor = MIN_GAS_FLOORS[operation] || MIN_GAS_FLOORS['default'];
|
|
80
|
+
const safeEstimate = estimatedGas > minFloor ? estimatedGas : minFloor;
|
|
34
81
|
const bufferMultiplier = this.getGasBufferMultiplier(operation);
|
|
82
|
+
// SECURITY FIX (C-3): Safe BigInt arithmetic using BPS (basis points)
|
|
83
|
+
// Multiply by (bufferMultiplier * 10000) and divide by 10000
|
|
84
|
+
// Example: 1.15x = (115 * 10000) / 10000 = 11500 / 10000
|
|
85
|
+
// This avoids floating-point precision issues entirely
|
|
86
|
+
const bufferNumerator = BigInt(Math.floor(bufferMultiplier * 10000));
|
|
87
|
+
const bufferDenominator = 10000n;
|
|
88
|
+
const gasLimit = (safeEstimate * bufferNumerator) / bufferDenominator;
|
|
89
|
+
// SECURITY FIX (C-3): Overflow detection
|
|
90
|
+
// After multiplication and division, result MUST be >= original estimate
|
|
91
|
+
if (gasLimit < safeEstimate) {
|
|
92
|
+
throw new Error(`Gas calculation overflow detected for operation "${operation}". ` +
|
|
93
|
+
`Estimate: ${safeEstimate}, Buffer: ${bufferMultiplier}x, Result: ${gasLimit}. ` +
|
|
94
|
+
`This indicates an arithmetic overflow - please report this bug.`);
|
|
95
|
+
}
|
|
96
|
+
// SECURITY FIX (C-3): Block gas limit check (Base L2 = 30M gas)
|
|
97
|
+
// Prevents DoS by requesting excessive gas that can never be included
|
|
98
|
+
const MAX_BLOCK_GAS_LIMIT = 30000000n;
|
|
99
|
+
if (gasLimit > MAX_BLOCK_GAS_LIMIT) {
|
|
100
|
+
throw new Error(`Gas limit ${gasLimit} exceeds maximum block gas limit ${MAX_BLOCK_GAS_LIMIT} for operation "${operation}". ` +
|
|
101
|
+
`This transaction cannot be executed on-chain. ` +
|
|
102
|
+
`Estimated gas: ${estimatedGas}, Min floor: ${minFloor}, Buffer: ${bufferMultiplier}x.`);
|
|
103
|
+
}
|
|
35
104
|
const options = {
|
|
36
|
-
gasLimit
|
|
105
|
+
gasLimit
|
|
37
106
|
};
|
|
38
107
|
if (this.gasSettings?.maxFeePerGas) {
|
|
39
108
|
options.maxFeePerGas = this.gasSettings.maxFeePerGas;
|
|
@@ -43,22 +112,45 @@ class ACTPKernel {
|
|
|
43
112
|
}
|
|
44
113
|
return options;
|
|
45
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Create a new transaction
|
|
117
|
+
* Reference: Yellow Paper §3.4.1
|
|
118
|
+
*
|
|
119
|
+
* Contract signature: createTransaction(provider, requester, amount, deadline, disputeWindow, serviceHash)
|
|
120
|
+
* Returns: bytes32 transactionId (generated by contract)
|
|
121
|
+
*/
|
|
46
122
|
async createTransaction(params) {
|
|
47
123
|
const { provider, requester, amount, deadline, disputeWindow, metadata = '0x0000000000000000000000000000000000000000000000000000000000000000' } = params;
|
|
124
|
+
// Input validation
|
|
48
125
|
(0, validation_1.validateAddress)(provider, 'provider');
|
|
49
126
|
(0, validation_1.validateAddress)(requester, 'requester');
|
|
50
127
|
(0, validation_1.validateAmount)(amount, 'amount');
|
|
51
128
|
(0, validation_1.validateDeadline)(deadline, 'deadline');
|
|
52
129
|
(0, validation_1.validateDisputeWindow)(disputeWindow, 'disputeWindow');
|
|
53
130
|
try {
|
|
131
|
+
// ethers v6: use getFunction() for typed access
|
|
54
132
|
const createTxFunc = this.contract.getFunction('createTransaction');
|
|
55
|
-
|
|
133
|
+
// Contract signature: createTransaction(provider, requester, amount, deadline, disputeWindow, serviceHash)
|
|
134
|
+
const estimatedGas = await createTxFunc.estimateGas(provider, requester, amount, deadline, disputeWindow, metadata // serviceHash
|
|
135
|
+
);
|
|
136
|
+
// Build tx options with gas settings (15% buffer for simple state initialization)
|
|
56
137
|
const txOptions = this.buildTxOptions(estimatedGas, 'createTransaction');
|
|
57
|
-
|
|
58
|
-
|
|
138
|
+
// Per ABI: createTransaction returns transactionId directly
|
|
139
|
+
// Contract signature: function createTransaction(...) external returns (bytes32 transactionId)
|
|
140
|
+
const tx = await createTxFunc(provider, requester, amount, deadline, disputeWindow, metadata, // serviceHash
|
|
141
|
+
txOptions);
|
|
142
|
+
const receipt = await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
59
143
|
if (!receipt) {
|
|
60
144
|
throw new Error('Transaction receipt not available');
|
|
61
145
|
}
|
|
146
|
+
// Extract transactionId from TransactionCreated event
|
|
147
|
+
// Event signature: TransactionCreated(bytes32 indexed transactionId, address indexed requester, address indexed provider, ...)
|
|
148
|
+
//
|
|
149
|
+
// DOCUMENTATION (CRITICAL-3): Note parameter order difference:
|
|
150
|
+
// - Function: createTransaction(provider, requester, ...) - provider is first
|
|
151
|
+
// - Event: TransactionCreated(txId, requester, provider, ...) - requester is first after txId
|
|
152
|
+
// This is INTENTIONAL - function names main actor (provider), event logs initiator first (requester)
|
|
153
|
+
// SDK correctly uses named args (parsedLog.args.transactionId) to avoid confusion
|
|
62
154
|
for (const log of receipt.logs) {
|
|
63
155
|
try {
|
|
64
156
|
const parsedLog = this.contract.interface.parseLog({
|
|
@@ -66,10 +158,12 @@ class ACTPKernel {
|
|
|
66
158
|
data: log.data
|
|
67
159
|
});
|
|
68
160
|
if (parsedLog && parsedLog.name === 'TransactionCreated') {
|
|
161
|
+
// Use named arg for clarity (avoids index confusion with swapped provider/requester)
|
|
69
162
|
return parsedLog.args.transactionId || parsedLog.args[0];
|
|
70
163
|
}
|
|
71
164
|
}
|
|
72
165
|
catch (e) {
|
|
166
|
+
// Skip logs that don't match our interface
|
|
73
167
|
continue;
|
|
74
168
|
}
|
|
75
169
|
}
|
|
@@ -79,25 +173,43 @@ class ACTPKernel {
|
|
|
79
173
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
80
174
|
}
|
|
81
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Transition transaction state
|
|
178
|
+
* Reference: Yellow Paper §3.2
|
|
179
|
+
*/
|
|
82
180
|
async transitionState(txId, newState, proof = '0x') {
|
|
181
|
+
// Input validation
|
|
83
182
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
183
|
+
// Validate transition
|
|
84
184
|
const currentTx = await this.getTransaction(txId);
|
|
85
185
|
if (!types_1.StateMachine.isValidTransition(currentTx.state, newState)) {
|
|
86
186
|
const validStates = types_1.StateMachine.getNextValidStates(currentTx.state).map((s) => types_1.State[s]);
|
|
87
187
|
throw new errors_1.InvalidStateTransitionError(currentTx.state, newState, validStates);
|
|
88
188
|
}
|
|
89
189
|
try {
|
|
190
|
+
// ethers v6: use getFunction()
|
|
90
191
|
const transitionFunc = this.contract.getFunction('transitionState');
|
|
192
|
+
// Estimate gas with safety buffer (20% for standard state transitions)
|
|
91
193
|
const estimatedGas = await transitionFunc.estimateGas(txId, newState, proof);
|
|
92
194
|
const txOptions = this.buildTxOptions(estimatedGas, 'transitionState');
|
|
93
195
|
const tx = await transitionFunc(txId, newState, proof, txOptions);
|
|
94
|
-
await tx.wait(2);
|
|
196
|
+
await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
95
197
|
}
|
|
96
198
|
catch (error) {
|
|
97
199
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
98
200
|
}
|
|
99
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Submit quote for transaction (AIP-2)
|
|
204
|
+
* Reference: AIP-2 §4.1 (Provider workflow)
|
|
205
|
+
*
|
|
206
|
+
* Transitions transaction from INITIATED → QUOTED with quote hash stored on-chain
|
|
207
|
+
*
|
|
208
|
+
* @param txId - Transaction ID (bytes32)
|
|
209
|
+
* @param quoteHash - Keccak256 hash of canonical JSON quote message
|
|
210
|
+
*/
|
|
100
211
|
async submitQuote(txId, quoteHash) {
|
|
212
|
+
// Input validation
|
|
101
213
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
102
214
|
if (!/^0x[a-fA-F0-9]{64}$/.test(quoteHash)) {
|
|
103
215
|
throw new errors_1.ValidationError('quoteHash', 'Must be valid bytes32 hex string');
|
|
@@ -105,61 +217,217 @@ class ACTPKernel {
|
|
|
105
217
|
if (quoteHash === '0x0000000000000000000000000000000000000000000000000000000000000000') {
|
|
106
218
|
throw new errors_1.ValidationError('quoteHash', 'Cannot be zero hash');
|
|
107
219
|
}
|
|
220
|
+
// Validate current state is INITIATED
|
|
108
221
|
const currentTx = await this.getTransaction(txId);
|
|
109
222
|
if (currentTx.state !== types_1.State.INITIATED) {
|
|
110
223
|
throw new errors_1.InvalidStateTransitionError(currentTx.state, types_1.State.QUOTED, ['INITIATED']);
|
|
111
224
|
}
|
|
225
|
+
// Encode quote hash as bytes proof
|
|
112
226
|
const abiCoder = ethers_1.AbiCoder.defaultAbiCoder();
|
|
113
227
|
const proof = abiCoder.encode(['bytes32'], [quoteHash]);
|
|
228
|
+
// Transition to QUOTED state with quote hash
|
|
114
229
|
await this.transitionState(txId, types_1.State.QUOTED, proof);
|
|
115
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Link escrow to transaction
|
|
233
|
+
*
|
|
234
|
+
* CRITICAL: This is the ONLY way to create escrow per AIP-3 spec.
|
|
235
|
+
* SDK should NOT call EscrowVault.createEscrow() directly (onlyKernel modifier).
|
|
236
|
+
*
|
|
237
|
+
* What happens internally:
|
|
238
|
+
* 1. ACTPKernel validates transaction state, permissions, deadline
|
|
239
|
+
* 2. Kernel calls IEscrowValidator(escrowContract).createEscrow(...)
|
|
240
|
+
* 3. EscrowVault pulls USDC from consumer (must approve USDC first!)
|
|
241
|
+
* 4. Events emitted: EscrowLinked
|
|
242
|
+
* 5. **State transition behavior varies** (see below)
|
|
243
|
+
*
|
|
244
|
+
* STATE TRANSITION BEHAVIOR:
|
|
245
|
+
* - **AIP-3 Spec (Source Code)**: Should auto-transition INITIATED/QUOTED → COMMITTED
|
|
246
|
+
* - **Deployed Contract**: Behavior is INCONSISTENT - sometimes auto-transitions, sometimes doesn't
|
|
247
|
+
* - **Recommended Practice**: Always check state after linkEscrow() and manually transition if needed
|
|
248
|
+
*
|
|
249
|
+
* ```typescript
|
|
250
|
+
* await client.kernel.linkEscrow(txId, escrowVault, escrowId);
|
|
251
|
+
* let tx = await client.kernel.getTransaction(txId);
|
|
252
|
+
* if (tx.state !== State.COMMITTED) {
|
|
253
|
+
* await client.kernel.transitionState(txId, State.COMMITTED);
|
|
254
|
+
* }
|
|
255
|
+
* ```
|
|
256
|
+
*
|
|
257
|
+
* Prerequisites:
|
|
258
|
+
* - Transaction in INITIATED or QUOTED state
|
|
259
|
+
* - Consumer has approved USDC to EscrowVault address
|
|
260
|
+
* (use EscrowVault.approveToken() before calling this)
|
|
261
|
+
*
|
|
262
|
+
* @param txId - Transaction ID (bytes32)
|
|
263
|
+
* @param escrowContract - EscrowVault contract address
|
|
264
|
+
* @param escrowId - Unique escrow identifier (bytes32, consumer-generated)
|
|
265
|
+
* @throws {ValidationError} If inputs invalid
|
|
266
|
+
* @throws {TransactionRevertedError} If state invalid, deadline passed, or insufficient USDC
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* // Step 1: Approve USDC to EscrowVault (NOT to Kernel!)
|
|
271
|
+
* await client.escrow.approveToken(BASE_SEPOLIA.contracts.usdc, amount);
|
|
272
|
+
*
|
|
273
|
+
* // Step 2: Generate unique escrow ID
|
|
274
|
+
* const escrowId = ethers.id(`escrow-${Date.now()}`);
|
|
275
|
+
*
|
|
276
|
+
* // Step 3: Link escrow (creates escrow + auto-transitions to COMMITTED)
|
|
277
|
+
* await client.kernel.linkEscrow(txId, escrowVaultAddress, escrowId);
|
|
278
|
+
*
|
|
279
|
+
* // Step 4: Verify state is COMMITTED (auto-transitioned, no manual call needed)
|
|
280
|
+
* const tx = await client.kernel.getTransaction(txId);
|
|
281
|
+
* expect(tx.state).to.equal(State.COMMITTED);
|
|
282
|
+
* ```
|
|
283
|
+
*
|
|
284
|
+
* Reference: Yellow Paper §3.4.2, AIP-3 §3.2 (ACTPKernel.sol lines 244-276)
|
|
285
|
+
*/
|
|
116
286
|
async linkEscrow(txId, escrowContract, escrowId) {
|
|
287
|
+
// Input validation
|
|
117
288
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
118
289
|
(0, validation_1.validateAddress)(escrowContract, 'escrowContract');
|
|
119
|
-
(0, validation_1.validateTxId)(escrowId, 'escrowId');
|
|
290
|
+
(0, validation_1.validateTxId)(escrowId, 'escrowId'); // escrowId is also bytes32
|
|
120
291
|
try {
|
|
292
|
+
// ethers v6: use getFunction()
|
|
121
293
|
const linkEscrowFunc = this.contract.getFunction('linkEscrow');
|
|
294
|
+
// Estimate gas with safety buffer (20% for linking escrow)
|
|
122
295
|
const estimatedGas = await linkEscrowFunc.estimateGas(txId, escrowContract, escrowId);
|
|
123
296
|
const txOptions = this.buildTxOptions(estimatedGas, 'transitionState');
|
|
124
297
|
const tx = await linkEscrowFunc(txId, escrowContract, escrowId, txOptions);
|
|
298
|
+
// Wait for 2 confirmations to ensure state is updated on RPC nodes (Base Sepolia reorg safety)
|
|
125
299
|
await tx.wait(2);
|
|
126
300
|
}
|
|
127
301
|
catch (error) {
|
|
128
302
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
129
303
|
}
|
|
130
304
|
}
|
|
131
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Release milestone payment
|
|
307
|
+
*
|
|
308
|
+
* SECURITY FIX (CRITICAL-2): Contract ABI has only 2 params (txId, amount), not 3.
|
|
309
|
+
* The milestoneId is NOT part of the current ACTPKernel V1 contract.
|
|
310
|
+
* Per ABI: releaseMilestone(bytes32 transactionId, uint256 amount)
|
|
311
|
+
*
|
|
312
|
+
* @param txId - Transaction ID (bytes32)
|
|
313
|
+
* @param amount - Amount to release (uint256)
|
|
314
|
+
* @deprecated milestoneId parameter - removed as contract doesn't support it
|
|
315
|
+
*/
|
|
316
|
+
async releaseMilestone(txId, amount) {
|
|
317
|
+
// Input validation
|
|
132
318
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
133
319
|
(0, validation_1.validateAmount)(amount, 'amount');
|
|
134
|
-
if (milestoneId < 0) {
|
|
135
|
-
throw new errors_1.ValidationError('milestoneId', 'Milestone ID cannot be negative');
|
|
136
|
-
}
|
|
137
320
|
try {
|
|
321
|
+
// ethers v6: use getFunction()
|
|
138
322
|
const releaseMilestoneFunc = this.contract.getFunction('releaseMilestone');
|
|
139
|
-
|
|
323
|
+
// SECURITY FIX (CRITICAL-2): Contract only takes 2 params (txId, amount)
|
|
324
|
+
// Estimate gas with safety buffer (30% for escrow release operations)
|
|
325
|
+
const estimatedGas = await releaseMilestoneFunc.estimateGas(txId, amount);
|
|
140
326
|
const txOptions = this.buildTxOptions(estimatedGas, 'releaseEscrow');
|
|
141
|
-
const tx = await releaseMilestoneFunc(txId,
|
|
142
|
-
await tx.wait(2);
|
|
327
|
+
const tx = await releaseMilestoneFunc(txId, amount, txOptions);
|
|
328
|
+
await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
143
329
|
}
|
|
144
330
|
catch (error) {
|
|
145
331
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
146
332
|
}
|
|
147
333
|
}
|
|
334
|
+
/**
|
|
335
|
+
* Release full escrow (settle transaction)
|
|
336
|
+
*
|
|
337
|
+
* ⚠️ CRITICAL SECURITY WARNING (C-2): Attestation UID Validation Bypass
|
|
338
|
+
*
|
|
339
|
+
* **DO NOT call this method directly from your application code!**
|
|
340
|
+
*
|
|
341
|
+
* ACTPKernel V1 contract accepts any attestationUID without validation.
|
|
342
|
+
* A malicious provider can:
|
|
343
|
+
* - Submit an attestation from a different transaction
|
|
344
|
+
* - Re-use an old attestation (replay attack)
|
|
345
|
+
* - Submit a forged attestation with fake delivery proof
|
|
346
|
+
*
|
|
347
|
+
* **REQUIRED: Use secure wrapper methods instead:**
|
|
348
|
+
*
|
|
349
|
+
* 1. **BeginnerAdapter.completePayment()** (recommended for most users)
|
|
350
|
+
* - Automatically verifies attestation before release
|
|
351
|
+
* - Validates attestation belongs to this transaction
|
|
352
|
+
* - Checks attestation hasn't been used before
|
|
353
|
+
* - Handles all state transitions
|
|
354
|
+
*
|
|
355
|
+
* 2. **IntermediateAdapter.releaseEscrow()** (for more control)
|
|
356
|
+
* - Explicitly requires attestation verification
|
|
357
|
+
* - Throws error if attestation invalid or missing
|
|
358
|
+
* - Allows custom verification logic
|
|
359
|
+
*
|
|
360
|
+
* 3. **Manual verification** (advanced users only):
|
|
361
|
+
* ```typescript
|
|
362
|
+
* // Step 1: Get transaction details
|
|
363
|
+
* const tx = await kernel.getTransaction(txId);
|
|
364
|
+
*
|
|
365
|
+
* // Step 2: Verify attestation if EAS is configured
|
|
366
|
+
* if (easHelper && tx.attestationUID && tx.attestationUID !== '0x0...0') {
|
|
367
|
+
* const isValid = await easHelper.verifyDeliveryAttestation(
|
|
368
|
+
* tx.attestationUID,
|
|
369
|
+
* tx.requester
|
|
370
|
+
* );
|
|
371
|
+
* if (!isValid) {
|
|
372
|
+
* throw new Error('Invalid or fraudulent delivery attestation');
|
|
373
|
+
* }
|
|
374
|
+
* }
|
|
375
|
+
*
|
|
376
|
+
* // Step 3: Only now is it safe to release
|
|
377
|
+
* await kernel.releaseEscrow(txId);
|
|
378
|
+
* ```
|
|
379
|
+
*
|
|
380
|
+
* **Why this matters:**
|
|
381
|
+
* - Without verification, you risk paying for work never delivered
|
|
382
|
+
* - Provider can steal funds by re-using attestations from other transactions
|
|
383
|
+
* - No on-chain enforcement (contract V1 limitation, fixed in V2)
|
|
384
|
+
*
|
|
385
|
+
* **For testnet/mainnet deployments:**
|
|
386
|
+
* - MUST configure easConfig in ACTPClient
|
|
387
|
+
* - MUST use wrapper methods (Beginner/Intermediate adapters)
|
|
388
|
+
* - NEVER call this method directly unless attestation verified
|
|
389
|
+
*
|
|
390
|
+
* @param txId - Transaction ID to settle
|
|
391
|
+
* @throws {ValidationError} If txId is invalid
|
|
392
|
+
* @throws {TransactionRevertedError} If contract reverts
|
|
393
|
+
*
|
|
394
|
+
* @see {@link BeginnerAdapter.completePayment} Recommended method with built-in verification
|
|
395
|
+
* @see {@link IntermediateAdapter.releaseEscrow} Explicit verification method
|
|
396
|
+
* @see {@link EASHelper.verifyDeliveryAttestation} Manual verification helper
|
|
397
|
+
*/
|
|
148
398
|
async releaseEscrow(txId) {
|
|
399
|
+
// Input validation
|
|
149
400
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
150
401
|
try {
|
|
402
|
+
// ethers v6: use getFunction()
|
|
151
403
|
const releaseEscrowFunc = this.contract.getFunction('releaseEscrow');
|
|
404
|
+
// Estimate gas with safety buffer (30% for escrow release operations)
|
|
152
405
|
const estimatedGas = await releaseEscrowFunc.estimateGas(txId);
|
|
153
406
|
const txOptions = this.buildTxOptions(estimatedGas, 'releaseEscrow');
|
|
154
407
|
const tx = await releaseEscrowFunc(txId, txOptions);
|
|
155
|
-
await tx.wait(2);
|
|
408
|
+
await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
156
409
|
}
|
|
157
410
|
catch (error) {
|
|
158
411
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
159
412
|
}
|
|
160
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Get transaction by ID
|
|
416
|
+
*/
|
|
161
417
|
async getTransaction(txId) {
|
|
162
|
-
|
|
418
|
+
let txData;
|
|
419
|
+
try {
|
|
420
|
+
txData = await this.contract.getTransaction(txId);
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
const reason = error?.reason || error?.shortMessage || error?.message || '';
|
|
424
|
+
// Deployed kernel reverts on missing transactions (e.g., "Tx missing")
|
|
425
|
+
if (typeof reason === 'string' && reason.toLowerCase().includes('tx missing')) {
|
|
426
|
+
throw new errors_1.TransactionNotFoundError(txId);
|
|
427
|
+
}
|
|
428
|
+
throw new Error(`Failed to fetch transaction ${txId}: ${typeof reason === 'string' ? reason : String(reason)}`);
|
|
429
|
+
}
|
|
430
|
+
// Check if transaction exists (createdAt !== 0)
|
|
163
431
|
if (txData.createdAt === 0 || txData.createdAt === 0n) {
|
|
164
432
|
throw new errors_1.TransactionNotFoundError(txId);
|
|
165
433
|
}
|
|
@@ -170,55 +438,98 @@ class ACTPKernel {
|
|
|
170
438
|
amount: txData.amount,
|
|
171
439
|
state: (typeof txData.state === 'bigint' ? Number(txData.state) : txData.state),
|
|
172
440
|
createdAt: typeof txData.createdAt === 'bigint' ? Number(txData.createdAt) : txData.createdAt,
|
|
441
|
+
updatedAt: typeof txData.updatedAt === 'bigint' ? Number(txData.updatedAt) : txData.updatedAt,
|
|
173
442
|
deadline: typeof txData.deadline === 'bigint' ? Number(txData.deadline) : txData.deadline,
|
|
174
443
|
disputeWindow: typeof txData.disputeWindow === 'bigint' ? Number(txData.disputeWindow) : txData.disputeWindow,
|
|
175
444
|
escrowContract: txData.escrowContract,
|
|
176
445
|
escrowId: txData.escrowId,
|
|
177
|
-
|
|
446
|
+
serviceHash: txData.serviceHash,
|
|
447
|
+
attestationUID: txData.attestationUID,
|
|
448
|
+
// Use metadata field (quote hash for QUOTED state) if available, fallback to serviceHash
|
|
449
|
+
metadata: txData.metadata || txData.serviceHash,
|
|
450
|
+
platformFeeBpsLocked: typeof txData.platformFeeBpsLocked === 'bigint'
|
|
451
|
+
? Number(txData.platformFeeBpsLocked)
|
|
452
|
+
: txData.platformFeeBpsLocked
|
|
178
453
|
};
|
|
179
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Get economic parameters (fee structure)
|
|
457
|
+
*
|
|
458
|
+
* SECURITY FIX (CRITICAL-4): Contract doesn't have getEconomicParams() function.
|
|
459
|
+
* Must call individual getters: platformFeeBps(), requesterPenaltyBps(), feeRecipient()
|
|
460
|
+
* Per ACTPKernel.json ABI lines 576-586, 619-630, 351-361
|
|
461
|
+
*/
|
|
180
462
|
async getEconomicParams() {
|
|
181
|
-
|
|
463
|
+
// SECURITY FIX (CRITICAL-4): Call individual view functions in parallel
|
|
464
|
+
// Contract ABI has: platformFeeBps(), requesterPenaltyBps(), feeRecipient()
|
|
465
|
+
// NOT a combined getEconomicParams() function
|
|
466
|
+
const [platformFeeBps, requesterPenaltyBps, feeRecipient] = await Promise.all([
|
|
467
|
+
this.contract.platformFeeBps(),
|
|
468
|
+
this.contract.requesterPenaltyBps(),
|
|
469
|
+
this.contract.feeRecipient()
|
|
470
|
+
]);
|
|
182
471
|
return {
|
|
183
|
-
baseFeeNumerator: Number(
|
|
184
|
-
baseFeeDenominator: 10000,
|
|
185
|
-
feeRecipient:
|
|
186
|
-
requesterPenaltyBps: Number(
|
|
187
|
-
providerPenaltyBps: 0
|
|
472
|
+
baseFeeNumerator: Number(platformFeeBps),
|
|
473
|
+
baseFeeDenominator: 10000, // BPS is always out of 10000
|
|
474
|
+
feeRecipient: feeRecipient,
|
|
475
|
+
requesterPenaltyBps: Number(requesterPenaltyBps),
|
|
476
|
+
providerPenaltyBps: 0 // Not in current contract ABI, will be added in future version
|
|
188
477
|
};
|
|
189
478
|
}
|
|
479
|
+
/**
|
|
480
|
+
* Estimate gas for transaction creation
|
|
481
|
+
*/
|
|
190
482
|
async estimateCreateTransaction(params) {
|
|
191
483
|
const { provider, requester, amount, deadline, disputeWindow, metadata = '0x0000000000000000000000000000000000000000000000000000000000000000' } = params;
|
|
484
|
+
// ethers v6: use getFunction()
|
|
192
485
|
const createTxFunc = this.contract.getFunction('createTransaction');
|
|
193
486
|
return await createTxFunc.estimateGas(provider, requester, amount, deadline, disputeWindow, metadata);
|
|
194
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* Raise dispute on delivered transaction
|
|
490
|
+
* Reference: Yellow Paper §3.4 (Dispute Management)
|
|
491
|
+
*/
|
|
195
492
|
async raiseDispute(txId, reason, evidence) {
|
|
196
493
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
494
|
+
// Encode dispute proof with reason and evidence (IPFS hash)
|
|
197
495
|
const abiCoder = ethers_1.AbiCoder.defaultAbiCoder();
|
|
198
496
|
const proofData = abiCoder.encode(['string', 'string'], [reason, evidence]);
|
|
199
497
|
try {
|
|
498
|
+
// ethers v6: use getFunction()
|
|
200
499
|
const transitionFunc = this.contract.getFunction('transitionState');
|
|
500
|
+
// Estimate gas with safety buffer (25% for large proof data)
|
|
201
501
|
const estimatedGas = await transitionFunc.estimateGas(txId, types_1.State.DISPUTED, proofData);
|
|
202
502
|
const txOptions = this.buildTxOptions(estimatedGas, 'raiseDispute');
|
|
203
503
|
const tx = await transitionFunc(txId, types_1.State.DISPUTED, proofData, txOptions);
|
|
204
|
-
await tx.wait(2);
|
|
504
|
+
await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
205
505
|
}
|
|
206
506
|
catch (error) {
|
|
207
507
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
208
508
|
}
|
|
209
509
|
}
|
|
510
|
+
/**
|
|
511
|
+
* Resolve/settle dispute with payment split
|
|
512
|
+
* Reference: Yellow Paper §3.4
|
|
513
|
+
*
|
|
514
|
+
* Disputes are settled via transitionState(SETTLED, proof) per §3.2
|
|
515
|
+
* The kernel contract decodes the proof and handles escrow disbursement
|
|
516
|
+
*/
|
|
210
517
|
async resolveDispute(txId, resolution) {
|
|
211
518
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
212
519
|
const { requesterAmount, providerAmount, mediatorAmount, mediator } = resolution;
|
|
520
|
+
// Validate amounts are non-negative
|
|
213
521
|
if (requesterAmount < 0n || providerAmount < 0n || mediatorAmount < 0n) {
|
|
214
522
|
throw new Error('Dispute resolution amounts cannot be negative');
|
|
215
523
|
}
|
|
524
|
+
// Validate mediator address if mediator amount > 0
|
|
216
525
|
if (mediatorAmount > 0n) {
|
|
217
526
|
if (!mediator) {
|
|
218
527
|
throw new Error('Mediator address required when mediator amount > 0');
|
|
219
528
|
}
|
|
220
529
|
(0, validation_1.validateAddress)(mediator, 'mediator');
|
|
221
530
|
}
|
|
531
|
+
// Encode resolution proof (128 bytes: 3x uint256 + address)
|
|
532
|
+
// Kernel contract will decode this in _decodeResolutionProof and disburse funds
|
|
222
533
|
const abiCoder = ethers_1.AbiCoder.defaultAbiCoder();
|
|
223
534
|
const proofData = abiCoder.encode(['uint256', 'uint256', 'uint256', 'address'], [
|
|
224
535
|
requesterAmount,
|
|
@@ -227,30 +538,53 @@ class ACTPKernel {
|
|
|
227
538
|
mediator || ethers_1.ethers.getAddress('0x0000000000000000000000000000000000000000')
|
|
228
539
|
]);
|
|
229
540
|
try {
|
|
541
|
+
// ethers v6: use getFunction()
|
|
230
542
|
const transitionFunc = this.contract.getFunction('transitionState');
|
|
543
|
+
// Settle dispute via state transition to SETTLED with resolution proof (30% buffer)
|
|
231
544
|
const estimatedGas = await transitionFunc.estimateGas(txId, types_1.State.SETTLED, proofData);
|
|
232
545
|
const txOptions = this.buildTxOptions(estimatedGas, 'resolveDispute');
|
|
233
546
|
const tx = await transitionFunc(txId, types_1.State.SETTLED, proofData, txOptions);
|
|
234
|
-
await tx.wait(2);
|
|
547
|
+
await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
235
548
|
}
|
|
236
549
|
catch (error) {
|
|
237
550
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|
|
238
551
|
}
|
|
239
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Settle disputed transaction (alias for resolveDispute)
|
|
555
|
+
*/
|
|
240
556
|
async settleDispute(txId, resolution) {
|
|
241
557
|
return this.resolveDispute(txId, resolution);
|
|
242
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* Anchor an EAS attestation UID to a transaction (delivery proof)
|
|
561
|
+
* Reference: AIP-4 (Delivery Proof and EAS Attestation Standard)
|
|
562
|
+
*
|
|
563
|
+
* @param txId - Transaction ID
|
|
564
|
+
* @param attestationUID - EAS attestation UID from provider
|
|
565
|
+
* @throws {ValidationError} If inputs are invalid
|
|
566
|
+
* @throws {TransactionRevertedError} If contract reverts
|
|
567
|
+
*
|
|
568
|
+
* @example
|
|
569
|
+
* ```typescript
|
|
570
|
+
* const easHelper = new EASHelper(signer, easConfig);
|
|
571
|
+
* const attestation = await easHelper.attestDeliveryProof(proof, recipient);
|
|
572
|
+
* await kernel.anchorAttestation(txId, attestation.uid);
|
|
573
|
+
* ```
|
|
574
|
+
*/
|
|
243
575
|
async anchorAttestation(txId, attestationUID) {
|
|
244
576
|
(0, validation_1.validateTxId)(txId, 'txId');
|
|
577
|
+
// Validate attestationUID format (32-byte hex string)
|
|
245
578
|
if (!attestationUID || !/^0x[a-fA-F0-9]{64}$/.test(attestationUID)) {
|
|
246
579
|
throw new errors_1.ValidationError('attestationUID', 'Must be 32-byte hex string (0x...)');
|
|
247
580
|
}
|
|
248
581
|
try {
|
|
582
|
+
// ethers v6: use getFunction()
|
|
249
583
|
const anchorFunc = this.contract.getFunction('anchorAttestation');
|
|
250
584
|
const estimatedGas = await anchorFunc.estimateGas(txId, attestationUID);
|
|
251
585
|
const txOptions = this.buildTxOptions(estimatedGas, 'anchorAttestation');
|
|
252
586
|
const tx = await anchorFunc(txId, attestationUID, txOptions);
|
|
253
|
-
await tx.wait(2);
|
|
587
|
+
await tx.wait(2); // Wait for 2 confirmations (Base L2 reorg safety)
|
|
254
588
|
}
|
|
255
589
|
catch (error) {
|
|
256
590
|
throw new errors_1.TransactionRevertedError(error.transactionHash, error.reason || error.message);
|