@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
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* request() - Basic API for service requesters
|
|
3
|
+
*
|
|
4
|
+
* The simplest way to request a service from AGIRAILS.
|
|
5
|
+
* Specify what you need and your budget, and AGIRAILS finds a provider.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { ACTPClient } from '../ACTPClient';
|
|
11
|
+
import { RequestOptions, RequestResult } from '../level1/types/Options';
|
|
12
|
+
import { serviceDirectory } from './ServiceDirectory';
|
|
13
|
+
import { NoProviderFoundError, TimeoutError, ValidationError } from '../errors';
|
|
14
|
+
import { safeJSONParse, validateServiceName, isValidAddress } from '../utils/security';
|
|
15
|
+
import { Logger } from '../utils/Logger';
|
|
16
|
+
import { ethers } from 'ethers';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Request a service
|
|
20
|
+
*
|
|
21
|
+
* This is the simplest way to request a service on AGIRAILS.
|
|
22
|
+
* Specify the service name, input data, and budget, and AGIRAILS
|
|
23
|
+
* handles finding a provider, creating the transaction, and delivering the result.
|
|
24
|
+
*
|
|
25
|
+
* @param service - Service name (e.g., 'translation', 'echo')
|
|
26
|
+
* @param options - Request options (input, budget, etc.)
|
|
27
|
+
* @returns Promise resolving to request result
|
|
28
|
+
*
|
|
29
|
+
* @throws {NoProviderFoundError} If no provider is found for the service
|
|
30
|
+
* @throws {TimeoutError} If provider doesn't respond within timeout
|
|
31
|
+
* @throws {ProviderRejectedError} If provider rejects the job
|
|
32
|
+
* @throws {DeliveryFailedError} If provider fails to deliver result
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Simplest example
|
|
37
|
+
* const { result } = await request('echo', {
|
|
38
|
+
* input: 'Hello, AGIRAILS!',
|
|
39
|
+
* budget: 1
|
|
40
|
+
* });
|
|
41
|
+
* console.log(result); // 'Hello, AGIRAILS!'
|
|
42
|
+
*
|
|
43
|
+
* // With progress callback
|
|
44
|
+
* const { result } = await request('translation', {
|
|
45
|
+
* input: { text: 'Hello', from: 'en', to: 'de' },
|
|
46
|
+
* budget: 5,
|
|
47
|
+
* onProgress: (status) => {
|
|
48
|
+
* console.log(`${status.state}: ${status.progress}%`);
|
|
49
|
+
* }
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* // With specific provider
|
|
53
|
+
* const { result } = await request('image-gen', {
|
|
54
|
+
* input: { prompt: 'A beautiful sunset' },
|
|
55
|
+
* budget: 10,
|
|
56
|
+
* provider: '0x1234...abcd'
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export async function request(
|
|
61
|
+
service: string,
|
|
62
|
+
options: RequestOptions
|
|
63
|
+
): Promise<RequestResult> {
|
|
64
|
+
// SECURITY FIX (H-2): Validate service name to prevent injection
|
|
65
|
+
const validatedService = validateServiceName(service);
|
|
66
|
+
|
|
67
|
+
const logger = new Logger({ source: 'request' });
|
|
68
|
+
|
|
69
|
+
// Find provider
|
|
70
|
+
const provider = findProvider(validatedService, options.provider);
|
|
71
|
+
|
|
72
|
+
if (!provider) {
|
|
73
|
+
throw new NoProviderFoundError(validatedService, {
|
|
74
|
+
availableProviders: serviceDirectory.findProviders(validatedService),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// SECURITY FIX (RPCURL): Use rpcUrl from options or fallback to network default
|
|
79
|
+
// This allows Level0 request() to work with testnet/mainnet without requiring
|
|
80
|
+
// explicit rpcUrl if user is okay with public RPC endpoints.
|
|
81
|
+
let rpcUrl = options.rpcUrl;
|
|
82
|
+
if (!rpcUrl && (options.network === 'testnet' || options.network === 'mainnet')) {
|
|
83
|
+
// Import getNetwork to get default rpcUrl from network config
|
|
84
|
+
const { getNetwork } = await import('../config/networks');
|
|
85
|
+
const networkName = options.network === 'testnet' ? 'base-sepolia' : 'base-mainnet';
|
|
86
|
+
const networkConfig = getNetwork(networkName);
|
|
87
|
+
rpcUrl = networkConfig.rpcUrl;
|
|
88
|
+
logger.info(`Using default RPC URL for ${networkName}: ${rpcUrl}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Create ACTP client
|
|
92
|
+
const client = await ACTPClient.create({
|
|
93
|
+
mode: options.network === 'testnet' ? 'testnet' : options.network === 'mainnet' ? 'mainnet' : 'mock',
|
|
94
|
+
requesterAddress: getRequesterAddress(options.wallet),
|
|
95
|
+
stateDirectory: options.stateDirectory,
|
|
96
|
+
privateKey: getPrivateKey(options.wallet),
|
|
97
|
+
rpcUrl,
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Calculate deadline
|
|
101
|
+
const deadline = calculateDeadline(options.deadline, options.timeout);
|
|
102
|
+
|
|
103
|
+
// Create transaction with service metadata
|
|
104
|
+
const startTime = Date.now();
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const requesterAddress = getRequesterAddress(options.wallet);
|
|
108
|
+
const amountWei = (options.budget * 1_000_000).toString(); // Convert to USDC wei (6 decimals)
|
|
109
|
+
|
|
110
|
+
// In mock mode, ensure requester has enough funds
|
|
111
|
+
// This is a convenience feature for testing - won't exist in production
|
|
112
|
+
if (client.runtime && 'mintTokens' in client.runtime) {
|
|
113
|
+
const mockRuntime = client.runtime as any;
|
|
114
|
+
const balance = await mockRuntime.getBalance(requesterAddress);
|
|
115
|
+
const balanceBigInt = BigInt(balance);
|
|
116
|
+
const amountBigInt = BigInt(amountWei);
|
|
117
|
+
|
|
118
|
+
if (balanceBigInt < amountBigInt) {
|
|
119
|
+
// Mint enough tokens (with some buffer)
|
|
120
|
+
const toMint = (amountBigInt - balanceBigInt + BigInt(10_000_000)).toString(); // +10 USDC buffer
|
|
121
|
+
await mockRuntime.mintTokens(requesterAddress, toMint);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ARCHITECTURE FIX: Service metadata handling
|
|
126
|
+
// - MockRuntime: Store plaintext for provider matching and input extraction
|
|
127
|
+
// - BlockchainRuntime: Hashes plaintext internally before sending on-chain
|
|
128
|
+
//
|
|
129
|
+
// Provider needs plaintext to:
|
|
130
|
+
// 1. Match service name to handler (findServiceHandler)
|
|
131
|
+
// 2. Extract input data for job execution (extractJobInput)
|
|
132
|
+
//
|
|
133
|
+
// On-chain storage uses bytes32 hash (BlockchainRuntime.validateServiceHash handles this)
|
|
134
|
+
const serviceMetadata = JSON.stringify({
|
|
135
|
+
service: validatedService,
|
|
136
|
+
input: options.input,
|
|
137
|
+
timestamp: Date.now(),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Create transaction with structured metadata
|
|
141
|
+
// MockRuntime stores as-is, BlockchainRuntime hashes for on-chain
|
|
142
|
+
const txId = await client.runtime.createTransaction({
|
|
143
|
+
provider,
|
|
144
|
+
requester: requesterAddress,
|
|
145
|
+
amount: amountWei,
|
|
146
|
+
deadline,
|
|
147
|
+
disputeWindow: options.disputeWindow ?? 172800, // Default 2 days
|
|
148
|
+
serviceDescription: serviceMetadata, // Structured JSON for provider parsing
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Call onProgress if provided
|
|
152
|
+
if (options.onProgress) {
|
|
153
|
+
options.onProgress({
|
|
154
|
+
state: 'initiated',
|
|
155
|
+
progress: 10,
|
|
156
|
+
message: 'Transaction created, waiting for provider...',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Poll for DELIVERED state (provider completes the job)
|
|
161
|
+
const maxWaitTime = options.timeout ?? 300000; // 5 minutes default
|
|
162
|
+
const pollInterval = 2000; // 2 seconds
|
|
163
|
+
const maxAttempts = Math.floor(maxWaitTime / pollInterval);
|
|
164
|
+
|
|
165
|
+
let tx = await client.runtime.getTransaction(txId);
|
|
166
|
+
let attempts = 0;
|
|
167
|
+
let timedOut = false;
|
|
168
|
+
|
|
169
|
+
while (tx && tx.state !== 'DELIVERED' && tx.state !== 'SETTLED' && attempts < maxAttempts) {
|
|
170
|
+
// Check for terminal states that indicate failure
|
|
171
|
+
if (tx.state === 'CANCELLED' || tx.state === 'DISPUTED') {
|
|
172
|
+
throw new Error(`Transaction ${tx.state.toLowerCase()}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Update progress
|
|
176
|
+
if (options.onProgress) {
|
|
177
|
+
const progress = 10 + Math.min(80, (attempts / maxAttempts) * 80);
|
|
178
|
+
options.onProgress({
|
|
179
|
+
state: tx.state.toLowerCase() as any,
|
|
180
|
+
progress,
|
|
181
|
+
message: `Waiting for delivery (${tx.state})...`,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Wait and poll again
|
|
186
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
187
|
+
tx = await client.runtime.getTransaction(txId);
|
|
188
|
+
attempts++;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Check if we got a result
|
|
192
|
+
if (!tx || (tx.state !== 'DELIVERED' && tx.state !== 'SETTLED')) {
|
|
193
|
+
timedOut = true;
|
|
194
|
+
|
|
195
|
+
// SECURITY FIX (H-3): Auto-cancel transaction on timeout if still in early state
|
|
196
|
+
// This prevents funds from being locked indefinitely if provider never responds
|
|
197
|
+
if (tx && (tx.state === 'INITIATED' || tx.state === 'COMMITTED')) {
|
|
198
|
+
try {
|
|
199
|
+
logger.warn('Transaction timed out, cancelling to release funds', {
|
|
200
|
+
txId,
|
|
201
|
+
state: tx.state,
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// ACTUALLY CANCEL THE TRANSACTION
|
|
205
|
+
// Check if runtime has cancelTransaction method
|
|
206
|
+
if ('cancelTransaction' in client.runtime) {
|
|
207
|
+
await (client.runtime as any).cancelTransaction(txId);
|
|
208
|
+
logger.info('Transaction cancelled successfully', { txId });
|
|
209
|
+
|
|
210
|
+
const error = new TimeoutError(maxWaitTime, `Transaction cancelled after timeout`);
|
|
211
|
+
(error as any).txId = txId;
|
|
212
|
+
(error as any).wasCancelled = true;
|
|
213
|
+
throw error;
|
|
214
|
+
} else {
|
|
215
|
+
// Fallback: Transition to CANCELLED state
|
|
216
|
+
await client.runtime.transitionState(txId, 'CANCELLED');
|
|
217
|
+
logger.info('Transaction cancelled successfully (via transitionState)', { txId });
|
|
218
|
+
|
|
219
|
+
const error = new TimeoutError(maxWaitTime, `Transaction cancelled after timeout`);
|
|
220
|
+
(error as any).txId = txId;
|
|
221
|
+
(error as any).wasCancelled = true;
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
} catch (cancelError) {
|
|
225
|
+
logger.error('Failed to cancel timed-out transaction', { txId }, cancelError as Error);
|
|
226
|
+
// Continue with original timeout error
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const error = new TimeoutError(maxWaitTime, `waiting for service '${validatedService}' delivery`);
|
|
231
|
+
(error as any).txId = txId;
|
|
232
|
+
(error as any).currentState = tx?.state || 'UNKNOWN';
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// SECURITY FIX (C-3): Safe JSON parsing with schema validation
|
|
237
|
+
// Extract result from delivery proof
|
|
238
|
+
let deliveredResult: any = {};
|
|
239
|
+
if (tx.deliveryProof) {
|
|
240
|
+
// Define expected schema for delivery proof
|
|
241
|
+
// NOTE: 'type' field with value 'delivery.proof' is the unique wrapper marker
|
|
242
|
+
// (set by ProofGenerator.generateDeliveryProof) that handlers won't naturally return
|
|
243
|
+
const DELIVERY_PROOF_SCHEMA: Record<string, string> = {
|
|
244
|
+
result: 'any',
|
|
245
|
+
data: 'any',
|
|
246
|
+
metadata: 'object',
|
|
247
|
+
proof: 'string',
|
|
248
|
+
timestamp: 'number',
|
|
249
|
+
contentHash: 'string',
|
|
250
|
+
txId: 'string',
|
|
251
|
+
type: 'string', // Unique marker: 'delivery.proof'
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
// Use safeJSONParse with schema validation which:
|
|
255
|
+
// 1. Validates JSON structure
|
|
256
|
+
// 2. Removes __proto__, constructor, prototype properties
|
|
257
|
+
// 3. Prevents prototype pollution attacks
|
|
258
|
+
// 4. Validates against expected schema
|
|
259
|
+
// 5. Checks size limits to prevent DoS
|
|
260
|
+
// 6. Returns null if parsing fails
|
|
261
|
+
const parsed = safeJSONParse(tx.deliveryProof, DELIVERY_PROOF_SCHEMA);
|
|
262
|
+
|
|
263
|
+
if (parsed !== null) {
|
|
264
|
+
deliveredResult = parsed;
|
|
265
|
+
} else {
|
|
266
|
+
// If parsing failed, treat as plain text (but don't execute or eval)
|
|
267
|
+
deliveredResult = { data: tx.deliveryProof };
|
|
268
|
+
logger.warn('Failed to parse delivery proof as JSON', { txId });
|
|
269
|
+
}
|
|
270
|
+
} else if (options.network === 'testnet' || options.network === 'mainnet') {
|
|
271
|
+
// KNOWN LIMITATION: BlockchainRuntime doesn't fetch deliveryProof from IPFS yet
|
|
272
|
+
// Result will be empty until this is implemented
|
|
273
|
+
logger.warn(
|
|
274
|
+
'Delivery proof retrieval not yet implemented for testnet/mainnet. ' +
|
|
275
|
+
'Result may be empty. Use ACTPClient with manual proof handling for production.',
|
|
276
|
+
{ txId, network: options.network }
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// SECURITY FIX (CRITICAL-2): Release escrow only after proper validation
|
|
281
|
+
// For mock mode, auto-release is safe. For testnet/mainnet, require attestation.
|
|
282
|
+
if (tx.state === 'DELIVERED' && tx.escrowId) {
|
|
283
|
+
// Wait for dispute window to expire
|
|
284
|
+
const disputeWindowEnd = (tx.completedAt ?? 0) + tx.disputeWindow;
|
|
285
|
+
const currentTime = client.runtime.time.now();
|
|
286
|
+
|
|
287
|
+
if (currentTime >= disputeWindowEnd) {
|
|
288
|
+
// SECURITY FIX (CRITICAL-2): Only auto-release in mock mode
|
|
289
|
+
// For real networks, the requester should manually verify and release
|
|
290
|
+
// or use attestation-based verification
|
|
291
|
+
const isMockMode = options.network !== 'testnet' && options.network !== 'mainnet';
|
|
292
|
+
|
|
293
|
+
if (isMockMode) {
|
|
294
|
+
try {
|
|
295
|
+
await client.runtime.releaseEscrow(tx.escrowId);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
// Ignore if already released or dispute window still active
|
|
298
|
+
// This is non-critical for result delivery
|
|
299
|
+
}
|
|
300
|
+
} else {
|
|
301
|
+
// For testnet/mainnet, log a warning about manual verification
|
|
302
|
+
logger.warn(
|
|
303
|
+
'Auto-release disabled for non-mock networks. ' +
|
|
304
|
+
'Verify delivery proof and call releaseEscrow() manually, ' +
|
|
305
|
+
'or enable attestation verification in BlockchainRuntime.',
|
|
306
|
+
{ txId, escrowId: tx.escrowId, network: options.network }
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (options.onProgress) {
|
|
313
|
+
options.onProgress({
|
|
314
|
+
state: 'settled',
|
|
315
|
+
progress: 100,
|
|
316
|
+
message: 'Transaction completed!',
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Extract raw handler result from delivery proof wrapper
|
|
321
|
+
// The delivery proof structure is: { type: 'delivery.proof', result: <handler_output>, ... }
|
|
322
|
+
// We return the raw handler output as `result` for better DX
|
|
323
|
+
//
|
|
324
|
+
// IMPORTANT: We check for type === 'delivery.proof' which is the unique marker
|
|
325
|
+
// set by ProofGenerator. This avoids false positives from handlers that happen
|
|
326
|
+
// to return objects with result/contentHash/timestamp fields.
|
|
327
|
+
const isDeliveryProofWrapper = deliveredResult !== null &&
|
|
328
|
+
typeof deliveredResult === 'object' &&
|
|
329
|
+
deliveredResult.type === 'delivery.proof' &&
|
|
330
|
+
'result' in deliveredResult;
|
|
331
|
+
const rawResult = isDeliveryProofWrapper ? deliveredResult.result : deliveredResult;
|
|
332
|
+
|
|
333
|
+
const result: RequestResult = {
|
|
334
|
+
result: rawResult,
|
|
335
|
+
transaction: {
|
|
336
|
+
id: txId,
|
|
337
|
+
provider,
|
|
338
|
+
amount: options.budget,
|
|
339
|
+
fee: options.budget * 0.01, // 1% ACTP fee
|
|
340
|
+
duration: Date.now() - startTime,
|
|
341
|
+
proof: tx.deliveryProof ?? '',
|
|
342
|
+
},
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
return result;
|
|
346
|
+
} catch (error) {
|
|
347
|
+
// Better error handling
|
|
348
|
+
if (error instanceof TimeoutError) {
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Wrap unknown errors
|
|
353
|
+
throw new Error(`Request failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Find provider for service
|
|
359
|
+
*
|
|
360
|
+
* @param service - Service name
|
|
361
|
+
* @param providerOption - Provider selection strategy
|
|
362
|
+
* @returns Provider address or undefined
|
|
363
|
+
*/
|
|
364
|
+
function findProvider(
|
|
365
|
+
service: string,
|
|
366
|
+
providerOption?: string | 'any' | 'best' | 'cheapest'
|
|
367
|
+
): string | undefined {
|
|
368
|
+
// If specific provider specified, use it
|
|
369
|
+
if (providerOption && providerOption !== 'any' && providerOption !== 'best' && providerOption !== 'cheapest') {
|
|
370
|
+
return providerOption;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Otherwise, find from service directory
|
|
374
|
+
const providers = serviceDirectory.findProviders(service);
|
|
375
|
+
|
|
376
|
+
if (providers.length === 0) {
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// For MVP, just return the first provider
|
|
381
|
+
// In V2, implement 'best' and 'cheapest' strategies
|
|
382
|
+
return providers[0];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Get requester address from wallet option
|
|
387
|
+
*
|
|
388
|
+
* SECURITY FIX (HIGH): Properly derive addresses from private keys using ethers
|
|
389
|
+
* Never fabricate addresses or use partial key slices as addresses.
|
|
390
|
+
*
|
|
391
|
+
* @param wallet - Wallet configuration
|
|
392
|
+
* @returns Ethereum address
|
|
393
|
+
* @throws {ValidationError} If address format is invalid
|
|
394
|
+
*/
|
|
395
|
+
function getRequesterAddress(
|
|
396
|
+
wallet?: 'auto' | 'connect' | string | { privateKey: string }
|
|
397
|
+
): string {
|
|
398
|
+
// For mock mode only: generate deterministic address
|
|
399
|
+
// This is only safe because mock mode doesn't involve real funds
|
|
400
|
+
if (!wallet || wallet === 'auto') {
|
|
401
|
+
// Create a valid Ethereum address (40 hex chars) - ONLY for mock mode
|
|
402
|
+
const hex = Buffer.from('requester').toString('hex');
|
|
403
|
+
return '0x' + hex.padEnd(40, '0');
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
if (wallet === 'connect') {
|
|
407
|
+
throw new Error('Browser wallet connection not yet implemented');
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (typeof wallet === 'string') {
|
|
411
|
+
// SECURITY FIX (HIGH): Validate address format
|
|
412
|
+
if (!isValidAddress(wallet)) {
|
|
413
|
+
throw new ValidationError('wallet', `Invalid Ethereum address format: ${wallet}`);
|
|
414
|
+
}
|
|
415
|
+
return wallet.toLowerCase();
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// SECURITY FIX (HIGH): Derive address from private key using ethers
|
|
419
|
+
// This is the correct way to get address from a private key
|
|
420
|
+
try {
|
|
421
|
+
const walletInstance = new ethers.Wallet(wallet.privateKey);
|
|
422
|
+
return walletInstance.address.toLowerCase();
|
|
423
|
+
} catch (error) {
|
|
424
|
+
throw new ValidationError('wallet.privateKey', 'Invalid private key format');
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Get private key from wallet option
|
|
430
|
+
*
|
|
431
|
+
* SECURITY FIX (HIGH): Validate private key format before use
|
|
432
|
+
*
|
|
433
|
+
* @param wallet - Wallet configuration
|
|
434
|
+
* @returns Private key or undefined
|
|
435
|
+
* @throws {ValidationError} If private key format is invalid
|
|
436
|
+
*/
|
|
437
|
+
function getPrivateKey(
|
|
438
|
+
wallet?: 'auto' | 'connect' | string | { privateKey: string }
|
|
439
|
+
): string | undefined {
|
|
440
|
+
if (!wallet || wallet === 'auto' || wallet === 'connect') {
|
|
441
|
+
return undefined;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// If wallet is a string that looks like a private key (0x + 64 hex chars), use it
|
|
445
|
+
// Otherwise treat it as an address and return undefined
|
|
446
|
+
if (typeof wallet === 'string') {
|
|
447
|
+
// Check if it looks like a private key (0x + 64 hex chars)
|
|
448
|
+
if (/^0x[0-9a-fA-F]{64}$/.test(wallet)) {
|
|
449
|
+
// Validate by trying to create a wallet
|
|
450
|
+
try {
|
|
451
|
+
new ethers.Wallet(wallet);
|
|
452
|
+
return wallet;
|
|
453
|
+
} catch {
|
|
454
|
+
throw new ValidationError('wallet', 'Invalid private key format');
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// It's an address, not a private key
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Validate private key format
|
|
462
|
+
if (wallet.privateKey) {
|
|
463
|
+
try {
|
|
464
|
+
new ethers.Wallet(wallet.privateKey);
|
|
465
|
+
return wallet.privateKey;
|
|
466
|
+
} catch {
|
|
467
|
+
throw new ValidationError('wallet.privateKey', 'Invalid private key format');
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return undefined;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Calculate deadline timestamp
|
|
476
|
+
*
|
|
477
|
+
* @param deadline - Deadline option (timestamp or Date)
|
|
478
|
+
* @param timeout - Timeout in milliseconds
|
|
479
|
+
* @returns Deadline timestamp (seconds)
|
|
480
|
+
*/
|
|
481
|
+
function calculateDeadline(
|
|
482
|
+
deadline?: number | Date,
|
|
483
|
+
timeout: number = 300000 // 5 minutes default
|
|
484
|
+
): number {
|
|
485
|
+
if (deadline) {
|
|
486
|
+
if (deadline instanceof Date) {
|
|
487
|
+
return Math.floor(deadline.getTime() / 1000);
|
|
488
|
+
}
|
|
489
|
+
return deadline;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Default: now + timeout
|
|
493
|
+
return Math.floor(Date.now() / 1000) + Math.floor(timeout / 1000);
|
|
494
|
+
}
|