@opendatalabs/vana-sdk 0.1.0-alpha.eebb656 → 0.1.0-alpha.ef15099
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/README.md +67 -351
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +33 -1
- package/dist/browser.js.map +1 -1
- package/dist/chains/definitions.cjs +9 -6
- package/dist/chains/definitions.cjs.map +1 -1
- package/dist/chains/definitions.d.ts +2 -0
- package/dist/chains/definitions.js +9 -6
- package/dist/chains/definitions.js.map +1 -1
- package/dist/chains/index.cjs.map +1 -1
- package/dist/chains/index.d.ts +30 -1
- package/dist/chains/index.js.map +1 -1
- package/dist/client/enhancedResponse.cjs +164 -0
- package/dist/client/enhancedResponse.cjs.map +1 -0
- package/dist/client/enhancedResponse.d.ts +120 -0
- package/dist/client/enhancedResponse.js +138 -0
- package/dist/client/enhancedResponse.js.map +1 -0
- package/dist/config/chains.cjs.map +1 -1
- package/dist/config/chains.d.ts +99 -0
- package/dist/config/chains.js.map +1 -1
- package/dist/config/contracts.config.cjs +400 -0
- package/dist/config/contracts.config.cjs.map +1 -0
- package/dist/config/contracts.config.d.ts +84 -0
- package/dist/config/contracts.config.js +375 -0
- package/dist/config/contracts.config.js.map +1 -0
- package/dist/config/default-services.cjs +60 -0
- package/dist/config/default-services.cjs.map +1 -0
- package/dist/config/default-services.d.ts +46 -0
- package/dist/config/default-services.js +33 -0
- package/dist/config/default-services.js.map +1 -0
- package/dist/config/default-services.test.d.ts +1 -0
- package/dist/contracts/contractController.cjs +1 -1
- package/dist/contracts/contractController.cjs.map +1 -1
- package/dist/contracts/contractController.d.ts +66 -10
- package/dist/contracts/contractController.js +1 -1
- package/dist/contracts/contractController.js.map +1 -1
- package/dist/controllers/__tests__/data-consistency-integration.test.d.ts +7 -0
- package/dist/controllers/__tests__/operations.processQueue.test.d.ts +1 -0
- package/dist/controllers/accessSettlement.cjs +289 -0
- package/dist/controllers/accessSettlement.cjs.map +1 -0
- package/dist/controllers/accessSettlement.d.ts +157 -0
- package/dist/controllers/accessSettlement.js +265 -0
- package/dist/controllers/accessSettlement.js.map +1 -0
- package/dist/controllers/accessSettlement.test.d.ts +1 -0
- package/dist/controllers/base.cjs +116 -0
- package/dist/controllers/base.cjs.map +1 -0
- package/dist/controllers/base.d.ts +94 -0
- package/dist/controllers/base.js +92 -0
- package/dist/controllers/base.js.map +1 -0
- package/dist/controllers/data.cjs +634 -352
- package/dist/controllers/data.cjs.map +1 -1
- package/dist/controllers/data.d.ts +348 -213
- package/dist/controllers/data.js +647 -355
- package/dist/controllers/data.js.map +1 -1
- package/dist/controllers/operations.cjs +430 -0
- package/dist/controllers/operations.cjs.map +1 -0
- package/dist/controllers/operations.d.ts +229 -0
- package/dist/controllers/operations.js +406 -0
- package/dist/controllers/operations.js.map +1 -0
- package/dist/controllers/permissions.cjs +943 -443
- package/dist/controllers/permissions.cjs.map +1 -1
- package/dist/controllers/permissions.d.ts +201 -120
- package/dist/controllers/permissions.js +943 -443
- package/dist/controllers/permissions.js.map +1 -1
- package/dist/controllers/protocol.cjs +14 -10
- package/dist/controllers/protocol.cjs.map +1 -1
- package/dist/controllers/protocol.d.ts +30 -31
- package/dist/controllers/protocol.js +14 -10
- package/dist/controllers/protocol.js.map +1 -1
- package/dist/controllers/runtimePermissions.cjs +272 -0
- package/dist/controllers/runtimePermissions.cjs.map +1 -0
- package/dist/controllers/runtimePermissions.d.ts +152 -0
- package/dist/controllers/runtimePermissions.js +251 -0
- package/dist/controllers/runtimePermissions.js.map +1 -0
- package/dist/controllers/runtimePermissions.test.d.ts +1 -0
- package/dist/controllers/schemas.cjs +113 -43
- package/dist/controllers/schemas.cjs.map +1 -1
- package/dist/controllers/schemas.d.ts +90 -43
- package/dist/controllers/schemas.js +113 -43
- package/dist/controllers/schemas.js.map +1 -1
- package/dist/controllers/server.cjs +276 -60
- package/dist/controllers/server.cjs.map +1 -1
- package/dist/controllers/server.d.ts +159 -54
- package/dist/controllers/server.js +276 -60
- package/dist/controllers/server.js.map +1 -1
- package/dist/core/__tests__/health.test.d.ts +1 -0
- package/dist/core/__tests__/inMemoryNonceManager.test.d.ts +1 -0
- package/dist/core/__tests__/nonceManager.test.d.ts +1 -0
- package/dist/core/__tests__/pollingManager.test.d.ts +4 -0
- package/dist/core/apiClient.cjs +53 -3
- package/dist/core/apiClient.cjs.map +1 -1
- package/dist/core/apiClient.d.ts +132 -7
- package/dist/core/apiClient.js +53 -3
- package/dist/core/apiClient.js.map +1 -1
- package/dist/core/generics.cjs +30 -3
- package/dist/core/generics.cjs.map +1 -1
- package/dist/core/generics.d.ts +95 -6
- package/dist/core/generics.js +30 -3
- package/dist/core/generics.js.map +1 -1
- package/dist/core/health.cjs +289 -0
- package/dist/core/health.cjs.map +1 -0
- package/dist/core/health.d.ts +143 -0
- package/dist/core/health.js +265 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/inMemoryNonceManager.cjs +138 -0
- package/dist/core/inMemoryNonceManager.cjs.map +1 -0
- package/dist/core/inMemoryNonceManager.d.ts +69 -0
- package/dist/core/inMemoryNonceManager.js +114 -0
- package/dist/core/inMemoryNonceManager.js.map +1 -0
- package/dist/core/nonceManager.cjs +304 -0
- package/dist/core/nonceManager.cjs.map +1 -0
- package/dist/core/nonceManager.d.ts +116 -0
- package/dist/core/nonceManager.js +280 -0
- package/dist/core/nonceManager.js.map +1 -0
- package/dist/core/pollingManager.cjs +292 -0
- package/dist/core/pollingManager.cjs.map +1 -0
- package/dist/core/pollingManager.d.ts +120 -0
- package/dist/core/pollingManager.js +268 -0
- package/dist/core/pollingManager.js.map +1 -0
- package/dist/core.cjs +164 -36
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +69 -10
- package/dist/core.js +167 -37
- package/dist/core.js.map +1 -1
- package/dist/crypto/ecies/__tests__/constants.test.d.ts +1 -1
- package/dist/crypto/ecies/__tests__/interface.test.d.ts +1 -0
- package/dist/crypto/ecies/__tests__/serialization.test.d.ts +8 -0
- package/dist/crypto/ecies/__tests__/utils.test.d.ts +1 -0
- package/dist/crypto/ecies/base.cjs +59 -23
- package/dist/crypto/ecies/base.cjs.map +1 -1
- package/dist/crypto/ecies/base.js +59 -23
- package/dist/crypto/ecies/base.js.map +1 -1
- package/dist/crypto/ecies/constants.cjs +2 -10
- package/dist/crypto/ecies/constants.cjs.map +1 -1
- package/dist/crypto/ecies/constants.d.ts +0 -9
- package/dist/crypto/ecies/constants.js +1 -8
- package/dist/crypto/ecies/constants.js.map +1 -1
- package/dist/crypto/ecies/interface.cjs +19 -2
- package/dist/crypto/ecies/interface.cjs.map +1 -1
- package/dist/crypto/ecies/interface.js +19 -2
- package/dist/crypto/ecies/interface.js.map +1 -1
- package/dist/errors.cjs +45 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +104 -0
- package/dist/errors.js +43 -0
- package/dist/errors.js.map +1 -1
- package/dist/generated/abi/AccessSettlementImplementation.cjs +635 -0
- package/dist/generated/abi/AccessSettlementImplementation.cjs.map +1 -0
- package/dist/generated/abi/AccessSettlementImplementation.d.ts +468 -0
- package/dist/generated/abi/AccessSettlementImplementation.js +611 -0
- package/dist/generated/abi/AccessSettlementImplementation.js.map +1 -0
- package/dist/generated/abi/AttestationPolicyImplementation.cjs +614 -0
- package/dist/generated/abi/AttestationPolicyImplementation.cjs.map +1 -0
- package/dist/generated/abi/AttestationPolicyImplementation.d.ts +449 -0
- package/dist/generated/abi/AttestationPolicyImplementation.js +590 -0
- package/dist/generated/abi/AttestationPolicyImplementation.js.map +1 -0
- package/dist/generated/abi/ComputeEngineImplementation.cjs.map +1 -1
- package/dist/generated/abi/ComputeEngineImplementation.js.map +1 -1
- package/dist/generated/abi/{DLPTreasuryImplementation.cjs → ComputeEngineTreasuryImplementation.cjs} +16 -92
- package/dist/generated/abi/ComputeEngineTreasuryImplementation.cjs.map +1 -0
- package/dist/generated/abi/{DLPTreasuryImplementation.d.ts → ComputeEngineTreasuryImplementation.d.ts} +9 -67
- package/dist/generated/abi/{DLPTreasuryImplementation.js → ComputeEngineTreasuryImplementation.js} +12 -88
- package/dist/generated/abi/ComputeEngineTreasuryImplementation.js.map +1 -0
- package/dist/generated/abi/ComputeInstructionRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/ComputeInstructionRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/DATFactoryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DATFactoryImplementation.js.map +1 -1
- package/dist/generated/abi/DATImplementation.cjs.map +1 -1
- package/dist/generated/abi/DATImplementation.js.map +1 -1
- package/dist/generated/abi/DATPausableImplementation.cjs.map +1 -1
- package/dist/generated/abi/DATPausableImplementation.js.map +1 -1
- package/dist/generated/abi/DATVotesImplementation.cjs.map +1 -1
- package/dist/generated/abi/DATVotesImplementation.js.map +1 -1
- package/dist/generated/abi/DLPPerformanceImplementation.cjs +42 -0
- package/dist/generated/abi/DLPPerformanceImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPPerformanceImplementation.d.ts +32 -0
- package/dist/generated/abi/DLPPerformanceImplementation.js +42 -0
- package/dist/generated/abi/DLPPerformanceImplementation.js.map +1 -1
- package/dist/generated/abi/DLPRegistryImplementation.cjs +5 -5
- package/dist/generated/abi/DLPRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPRegistryImplementation.d.ts +4 -4
- package/dist/generated/abi/DLPRegistryImplementation.js +5 -5
- package/dist/generated/abi/DLPRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/DLPRegistryTreasuryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPRegistryTreasuryImplementation.js.map +1 -1
- package/dist/generated/abi/DLPRewardDeployerImplementation.cjs +166 -2
- package/dist/generated/abi/DLPRewardDeployerImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPRewardDeployerImplementation.d.ts +129 -2
- package/dist/generated/abi/DLPRewardDeployerImplementation.js +166 -2
- package/dist/generated/abi/DLPRewardDeployerImplementation.js.map +1 -1
- package/dist/generated/abi/DLPRewardSwapImplementation.cjs.map +1 -1
- package/dist/generated/abi/DLPRewardSwapImplementation.js.map +1 -1
- package/dist/generated/abi/DataLiquidityPoolImplementation.cjs +282 -100
- package/dist/generated/abi/DataLiquidityPoolImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataLiquidityPoolImplementation.d.ts +218 -79
- package/dist/generated/abi/DataLiquidityPoolImplementation.js +281 -99
- package/dist/generated/abi/DataLiquidityPoolImplementation.js.map +1 -1
- package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs +167 -19
- package/dist/generated/abi/DataPortabilityGranteesImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataPortabilityGranteesImplementation.d.ts +127 -14
- package/dist/generated/abi/DataPortabilityGranteesImplementation.js +167 -19
- package/dist/generated/abi/DataPortabilityGranteesImplementation.js.map +1 -1
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.cjs +0 -19
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.d.ts +0 -14
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.js +0 -19
- package/dist/generated/abi/DataPortabilityPermissionsImplementation.js.map +1 -1
- package/dist/generated/abi/DataPortabilityServersImplementation.cjs +0 -19
- package/dist/generated/abi/DataPortabilityServersImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataPortabilityServersImplementation.d.ts +0 -14
- package/dist/generated/abi/DataPortabilityServersImplementation.js +0 -19
- package/dist/generated/abi/DataPortabilityServersImplementation.js.map +1 -1
- package/dist/generated/abi/DataRefinerRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataRefinerRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/DataRegistryImplementation.cjs +0 -13
- package/dist/generated/abi/DataRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/DataRegistryImplementation.d.ts +0 -10
- package/dist/generated/abi/DataRegistryImplementation.js +0 -13
- package/dist/generated/abi/DataRegistryImplementation.js.map +1 -1
- package/dist/generated/abi/DatasetRegistryImplementation.cjs +751 -0
- package/dist/generated/abi/DatasetRegistryImplementation.cjs.map +1 -0
- package/dist/generated/abi/DatasetRegistryImplementation.d.ts +557 -0
- package/dist/generated/abi/DatasetRegistryImplementation.js +727 -0
- package/dist/generated/abi/DatasetRegistryImplementation.js.map +1 -0
- package/dist/generated/abi/ProtocolConfigImplementation.cjs +578 -0
- package/dist/generated/abi/ProtocolConfigImplementation.cjs.map +1 -0
- package/dist/generated/abi/ProtocolConfigImplementation.d.ts +423 -0
- package/dist/generated/abi/ProtocolConfigImplementation.js +554 -0
- package/dist/generated/abi/ProtocolConfigImplementation.js.map +1 -0
- package/dist/generated/abi/QueryEngineImplementation.cjs.map +1 -1
- package/dist/generated/abi/QueryEngineImplementation.js.map +1 -1
- package/dist/generated/abi/SwapHelperImplementation.cjs +0 -43
- package/dist/generated/abi/SwapHelperImplementation.cjs.map +1 -1
- package/dist/generated/abi/SwapHelperImplementation.d.ts +0 -35
- package/dist/generated/abi/SwapHelperImplementation.js +0 -43
- package/dist/generated/abi/SwapHelperImplementation.js.map +1 -1
- package/dist/generated/abi/TeePoolDedicatedGpuImplementation.cjs.map +1 -1
- package/dist/generated/abi/TeePoolDedicatedGpuImplementation.js.map +1 -1
- package/dist/generated/abi/TeePoolDedicatedStandardImplementation.cjs.map +1 -1
- package/dist/generated/abi/TeePoolDedicatedStandardImplementation.js.map +1 -1
- package/dist/generated/abi/TeePoolEphemeralStandardImplementation.cjs.map +1 -1
- package/dist/generated/abi/TeePoolEphemeralStandardImplementation.js.map +1 -1
- package/dist/generated/abi/TeePoolPersistentGpuImplementation.cjs.map +1 -1
- package/dist/generated/abi/TeePoolPersistentGpuImplementation.js.map +1 -1
- package/dist/generated/abi/TeePoolPersistentStandardImplementation.cjs.map +1 -1
- package/dist/generated/abi/TeePoolPersistentStandardImplementation.js.map +1 -1
- package/dist/generated/abi/TeePoolPhalaImplementation.cjs.map +1 -1
- package/dist/generated/abi/TeePoolPhalaImplementation.js.map +1 -1
- package/dist/generated/abi/UniswapV3NonfungiblePositionManagerImplementation.cjs +1251 -0
- package/dist/generated/abi/UniswapV3NonfungiblePositionManagerImplementation.cjs.map +1 -0
- package/dist/generated/abi/UniswapV3NonfungiblePositionManagerImplementation.d.ts +948 -0
- package/dist/generated/abi/UniswapV3NonfungiblePositionManagerImplementation.js +1227 -0
- package/dist/generated/abi/UniswapV3NonfungiblePositionManagerImplementation.js.map +1 -0
- package/dist/generated/abi/UniswapV3QuoterV2Implementation.cjs +297 -0
- package/dist/generated/abi/UniswapV3QuoterV2Implementation.cjs.map +1 -0
- package/dist/generated/abi/UniswapV3QuoterV2Implementation.d.ts +206 -0
- package/dist/generated/abi/UniswapV3QuoterV2Implementation.js +273 -0
- package/dist/generated/abi/UniswapV3QuoterV2Implementation.js.map +1 -0
- package/dist/generated/abi/VanaEpochImplementation.cjs +195 -0
- package/dist/generated/abi/VanaEpochImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaEpochImplementation.d.ts +151 -0
- package/dist/generated/abi/VanaEpochImplementation.js +195 -0
- package/dist/generated/abi/VanaEpochImplementation.js.map +1 -1
- package/dist/generated/abi/VanaPoolEntityImplementation.cjs +22 -65
- package/dist/generated/abi/VanaPoolEntityImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaPoolEntityImplementation.d.ts +17 -51
- package/dist/generated/abi/VanaPoolEntityImplementation.js +22 -65
- package/dist/generated/abi/VanaPoolEntityImplementation.js.map +1 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.cjs +113 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.d.ts +85 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.js +113 -1
- package/dist/generated/abi/VanaPoolStakingImplementation.js.map +1 -1
- package/dist/generated/abi/VanaPoolTreasuryImplementation.cjs.map +1 -1
- package/dist/generated/abi/VanaPoolTreasuryImplementation.js.map +1 -1
- package/dist/generated/abi/VanaRuntimePermissionsImplementation.cjs +759 -0
- package/dist/generated/abi/VanaRuntimePermissionsImplementation.cjs.map +1 -0
- package/dist/generated/abi/VanaRuntimePermissionsImplementation.d.ts +563 -0
- package/dist/generated/abi/VanaRuntimePermissionsImplementation.js +735 -0
- package/dist/generated/abi/VanaRuntimePermissionsImplementation.js.map +1 -0
- package/dist/generated/abi/VanaRuntimeServersImplementation.cjs +820 -0
- package/dist/generated/abi/VanaRuntimeServersImplementation.cjs.map +1 -0
- package/dist/generated/abi/VanaRuntimeServersImplementation.d.ts +609 -0
- package/dist/generated/abi/VanaRuntimeServersImplementation.js +796 -0
- package/dist/generated/abi/VanaRuntimeServersImplementation.js.map +1 -0
- package/dist/generated/abi/VanaTreasuryImplementation.cjs +536 -0
- package/dist/generated/abi/VanaTreasuryImplementation.cjs.map +1 -0
- package/dist/generated/abi/VanaTreasuryImplementation.d.ts +393 -0
- package/dist/generated/abi/VanaTreasuryImplementation.js +512 -0
- package/dist/generated/abi/VanaTreasuryImplementation.js.map +1 -0
- package/dist/generated/abi/WVANAImplementation.cjs +339 -0
- package/dist/generated/abi/WVANAImplementation.cjs.map +1 -0
- package/dist/generated/abi/WVANAImplementation.d.ts +244 -0
- package/dist/generated/abi/WVANAImplementation.js +315 -0
- package/dist/generated/abi/WVANAImplementation.js.map +1 -0
- package/dist/generated/abi/index.cjs +79 -47
- package/dist/generated/abi/index.cjs.map +1 -1
- package/dist/generated/abi/index.d.ts +15783 -10449
- package/dist/generated/abi/index.js +65 -43
- package/dist/generated/abi/index.js.map +1 -1
- package/dist/{config → generated}/addresses.cjs +174 -75
- package/dist/generated/addresses.cjs.map +1 -0
- package/dist/{config → generated}/addresses.d.ts +174 -165
- package/dist/{config → generated}/addresses.js +174 -75
- package/dist/generated/addresses.js.map +1 -0
- package/dist/generated/event-types.cjs.map +1 -1
- package/dist/generated/event-types.d.ts +482 -399
- package/dist/generated/eventRegistry.cjs +2601 -724
- package/dist/generated/eventRegistry.cjs.map +1 -1
- package/dist/generated/eventRegistry.d.ts +2 -2
- package/dist/generated/eventRegistry.js +2601 -724
- package/dist/generated/eventRegistry.js.map +1 -1
- package/dist/generated/server/server-exports.cjs +22 -0
- package/dist/generated/server/server-exports.cjs.map +1 -1
- package/dist/generated/server/server-exports.d.ts +31 -11
- package/dist/generated/server/server-exports.js +17 -0
- package/dist/generated/server/server-exports.js.map +1 -1
- package/dist/generated/server/server.cjs.map +1 -1
- package/dist/generated/server/server.d.ts +771 -402
- package/dist/generated/subgraph.cjs +797 -32
- package/dist/generated/subgraph.cjs.map +1 -1
- package/dist/generated/subgraph.d.ts +135 -0
- package/dist/generated/subgraph.js +792 -32
- package/dist/generated/subgraph.js.map +1 -1
- package/dist/index.browser.d.ts +6 -1
- package/dist/index.browser.js +26 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.node.cjs +47 -4
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.ts +60 -14
- package/dist/index.node.js +42 -3
- package/dist/index.node.js.map +1 -1
- package/dist/lib/__tests__/redisAtomicStore.test.d.ts +1 -0
- package/dist/lib/redisAtomicStore.cjs +201 -0
- package/dist/lib/redisAtomicStore.cjs.map +1 -0
- package/dist/lib/redisAtomicStore.d.ts +120 -0
- package/dist/lib/redisAtomicStore.js +177 -0
- package/dist/lib/redisAtomicStore.js.map +1 -0
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.ts +39 -1
- package/dist/node.js.map +1 -1
- package/dist/platform/browser.cjs +160 -2
- package/dist/platform/browser.cjs.map +1 -1
- package/dist/platform/browser.d.ts +232 -12
- package/dist/platform/browser.js +160 -2
- package/dist/platform/browser.js.map +1 -1
- package/dist/platform/interface.cjs.map +1 -1
- package/dist/platform/interface.d.ts +283 -90
- package/dist/platform/node.cjs +163 -2
- package/dist/platform/node.cjs.map +1 -1
- package/dist/platform/node.d.ts +69 -6
- package/dist/platform/node.js +163 -2
- package/dist/platform/node.js.map +1 -1
- package/dist/server/relayerHandler.cjs +452 -0
- package/dist/server/relayerHandler.cjs.map +1 -0
- package/dist/server/relayerHandler.d.ts +69 -0
- package/dist/server/relayerHandler.js +428 -0
- package/dist/server/relayerHandler.js.map +1 -0
- package/dist/storage/index.cjs +3 -0
- package/dist/storage/index.cjs.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/manager.cjs +108 -25
- package/dist/storage/manager.cjs.map +1 -1
- package/dist/storage/manager.d.ts +119 -25
- package/dist/storage/manager.js +108 -25
- package/dist/storage/manager.js.map +1 -1
- package/dist/storage/providers/callback-storage.cjs +86 -15
- package/dist/storage/providers/callback-storage.cjs.map +1 -1
- package/dist/storage/providers/callback-storage.d.ts +109 -20
- package/dist/storage/providers/callback-storage.js +86 -15
- package/dist/storage/providers/callback-storage.js.map +1 -1
- package/dist/storage/providers/dropbox.cjs +237 -0
- package/dist/storage/providers/dropbox.cjs.map +1 -0
- package/dist/storage/providers/dropbox.d.ts +39 -0
- package/dist/storage/providers/dropbox.js +215 -0
- package/dist/storage/providers/dropbox.js.map +1 -0
- package/dist/storage/providers/dropbox.test.d.ts +1 -0
- package/dist/storage/providers/pinata.cjs.map +1 -1
- package/dist/storage/providers/pinata.d.ts +12 -14
- package/dist/storage/providers/pinata.js.map +1 -1
- package/dist/tests/data-upload-owner-validation.test.d.ts +1 -0
- package/dist/tests/factories/mockFactory.d.ts +6 -6
- package/dist/tests/fakes/FakeWaitForTransactionEvents.d.ts +2 -2
- package/dist/tests/permissions-revoke-relayer.test.d.ts +1 -0
- package/dist/tests/permissions-transaction-options.test.d.ts +1 -0
- package/dist/tests/read-only-mode.test.d.ts +1 -0
- package/dist/tests/relayer-integration.test.d.ts +1 -0
- package/dist/tests/relayer-unified.test.d.ts +1 -0
- package/dist/tests/server-relayer-handler.test.d.ts +1 -0
- package/dist/types/accessSettlement.cjs +17 -0
- package/dist/types/accessSettlement.cjs.map +1 -0
- package/dist/types/accessSettlement.d.ts +66 -0
- package/dist/types/accessSettlement.js +1 -0
- package/dist/types/accessSettlement.js.map +1 -0
- package/dist/types/atomicStore.cjs +31 -0
- package/dist/types/atomicStore.cjs.map +1 -0
- package/dist/types/atomicStore.d.ts +236 -0
- package/dist/types/atomicStore.js +7 -0
- package/dist/types/atomicStore.js.map +1 -0
- package/dist/types/blockchain.cjs.map +1 -1
- package/dist/types/blockchain.d.ts +39 -11
- package/dist/types/chains.cjs.map +1 -1
- package/dist/types/chains.d.ts +74 -7
- package/dist/types/chains.js.map +1 -1
- package/dist/types/config.cjs +10 -0
- package/dist/types/config.cjs.map +1 -1
- package/dist/types/config.d.ts +217 -220
- package/dist/types/config.js +8 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/contracts.cjs.map +1 -1
- package/dist/types/contracts.d.ts +71 -7
- package/dist/types/controller-context.cjs.map +1 -1
- package/dist/types/controller-context.d.ts +12 -6
- package/dist/types/data.cjs.map +1 -1
- package/dist/types/data.d.ts +82 -10
- package/dist/types/generics.cjs.map +1 -1
- package/dist/types/generics.d.ts +81 -10
- package/dist/types/index.cjs +4 -0
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.ts +36 -6
- package/dist/types/index.js +9 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/operationStore.cjs +17 -0
- package/dist/types/operationStore.cjs.map +1 -0
- package/dist/types/operationStore.d.ts +171 -0
- package/dist/types/operationStore.js +1 -0
- package/dist/types/operationStore.js.map +1 -0
- package/dist/types/operations.cjs +3 -15
- package/dist/types/operations.cjs.map +1 -1
- package/dist/types/operations.d.ts +131 -39
- package/dist/types/operations.js +2 -13
- package/dist/types/operations.js.map +1 -1
- package/dist/types/options.cjs +17 -0
- package/dist/types/options.cjs.map +1 -0
- package/dist/types/options.d.ts +308 -0
- package/dist/types/options.js +1 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/permissions.cjs.map +1 -1
- package/dist/types/permissions.d.ts +19 -20
- package/dist/types/personal.cjs.map +1 -1
- package/dist/types/personal.d.ts +150 -14
- package/dist/types/relayer.cjs.map +1 -1
- package/dist/types/relayer.d.ts +307 -35
- package/dist/types/runtimePermissions.cjs +17 -0
- package/dist/types/runtimePermissions.cjs.map +1 -0
- package/dist/types/runtimePermissions.d.ts +122 -0
- package/dist/types/runtimePermissions.js +1 -0
- package/dist/types/runtimePermissions.js.map +1 -0
- package/dist/types/storage.cjs.map +1 -1
- package/dist/types/storage.d.ts +9 -21
- package/dist/types/storage.js.map +1 -1
- package/dist/types/utils.cjs.map +1 -1
- package/dist/types/utils.d.ts +0 -45
- package/dist/utils/__tests__/chainQuery.test.d.ts +1 -0
- package/dist/utils/__tests__/subgraphConsistency.test.d.ts +4 -0
- package/dist/utils/__tests__/subgraphPagination.test.d.ts +4 -0
- package/dist/utils/blockchain/registry.cjs +3 -3
- package/dist/utils/blockchain/registry.cjs.map +1 -1
- package/dist/utils/blockchain/registry.d.ts +1 -1
- package/dist/utils/blockchain/registry.js +3 -3
- package/dist/utils/blockchain/registry.js.map +1 -1
- package/dist/utils/chainQuery.cjs +107 -0
- package/dist/utils/chainQuery.cjs.map +1 -0
- package/dist/utils/chainQuery.d.ts +31 -0
- package/dist/utils/chainQuery.js +82 -0
- package/dist/utils/chainQuery.js.map +1 -0
- package/dist/utils/grantFiles.cjs +4 -1
- package/dist/utils/grantFiles.cjs.map +1 -1
- package/dist/utils/grantFiles.d.ts +10 -20
- package/dist/utils/grantFiles.js +4 -1
- package/dist/utils/grantFiles.js.map +1 -1
- package/dist/utils/grantValidation.cjs.map +1 -1
- package/dist/utils/grantValidation.d.ts +95 -16
- package/dist/utils/grantValidation.js.map +1 -1
- package/dist/utils/grants.cjs.map +1 -1
- package/dist/utils/grants.d.ts +93 -12
- package/dist/utils/grants.js.map +1 -1
- package/dist/utils/ipfs.cjs +2 -4
- package/dist/utils/ipfs.cjs.map +1 -1
- package/dist/utils/ipfs.d.ts +1 -1
- package/dist/utils/ipfs.js +2 -4
- package/dist/utils/ipfs.js.map +1 -1
- package/dist/utils/lazy-import.cjs.map +1 -1
- package/dist/utils/lazy-import.d.ts +32 -7
- package/dist/utils/lazy-import.js.map +1 -1
- package/dist/utils/multicall.cjs +1 -1
- package/dist/utils/multicall.cjs.map +1 -1
- package/dist/utils/multicall.js +1 -1
- package/dist/utils/multicall.js.map +1 -1
- package/dist/utils/runtimeGrantFiles.cjs +84 -0
- package/dist/utils/runtimeGrantFiles.cjs.map +1 -0
- package/dist/utils/runtimeGrantFiles.d.ts +66 -0
- package/dist/utils/runtimeGrantFiles.js +58 -0
- package/dist/utils/runtimeGrantFiles.js.map +1 -0
- package/dist/utils/signatureCache.cjs +8 -2
- package/dist/utils/signatureCache.cjs.map +1 -1
- package/dist/utils/signatureCache.d.ts +49 -8
- package/dist/utils/signatureCache.js +8 -2
- package/dist/utils/signatureCache.js.map +1 -1
- package/dist/utils/subgraphConsistency.cjs +184 -0
- package/dist/utils/subgraphConsistency.cjs.map +1 -0
- package/dist/utils/subgraphConsistency.d.ts +65 -0
- package/dist/utils/subgraphConsistency.js +155 -0
- package/dist/utils/subgraphConsistency.js.map +1 -0
- package/dist/utils/subgraphMetaCache.cjs +101 -0
- package/dist/utils/subgraphMetaCache.cjs.map +1 -0
- package/dist/utils/subgraphMetaCache.d.ts +56 -0
- package/dist/utils/subgraphMetaCache.js +76 -0
- package/dist/utils/subgraphMetaCache.js.map +1 -0
- package/dist/utils/subgraphPagination.cjs +104 -0
- package/dist/utils/subgraphPagination.cjs.map +1 -0
- package/dist/utils/subgraphPagination.d.ts +78 -0
- package/dist/utils/subgraphPagination.js +78 -0
- package/dist/utils/subgraphPagination.js.map +1 -0
- package/dist/utils/transactionHelpers.cjs.map +1 -1
- package/dist/utils/transactionHelpers.d.ts +12 -12
- package/dist/utils/transactionHelpers.js.map +1 -1
- package/dist/utils/typedDataConverter.cjs.map +1 -1
- package/dist/utils/typedDataConverter.d.ts +39 -3
- package/dist/utils/typedDataConverter.js.map +1 -1
- package/dist/utils/urlResolver.cjs +7 -0
- package/dist/utils/urlResolver.cjs.map +1 -1
- package/dist/utils/urlResolver.d.ts +22 -4
- package/dist/utils/urlResolver.js +7 -0
- package/dist/utils/urlResolver.js.map +1 -1
- package/dist/utils/wallet.cjs +63 -0
- package/dist/utils/wallet.cjs.map +1 -0
- package/dist/utils/wallet.d.ts +94 -0
- package/dist/utils/wallet.js +37 -0
- package/dist/utils/wallet.js.map +1 -0
- package/package.json +7 -2
- package/dist/config/addresses.cjs.map +0 -1
- package/dist/config/addresses.js.map +0 -1
- package/dist/generated/abi/DLPTreasuryImplementation.cjs.map +0 -1
- package/dist/generated/abi/DLPTreasuryImplementation.js.map +0 -1
- package/dist/server/handler.cjs +0 -101
- package/dist/server/handler.cjs.map +0 -1
- package/dist/server/handler.d.ts +0 -87
- package/dist/server/handler.js +0 -77
- package/dist/server/handler.js.map +0 -1
- /package/dist/{tests/server-handler.test.d.ts → client/__tests__/enhancedResponse.test.d.ts} +0 -0
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provides signature caching to improve UX by avoiding repeated wallet prompts.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module implements a secure signature cache that stores signed messages
|
|
6
|
+
* temporarily to avoid repeatedly prompting users for the same signature.
|
|
7
|
+
* It uses platform-appropriate storage (sessionStorage in browser, memory in Node.js)
|
|
8
|
+
* and includes automatic expiration and cleanup.
|
|
9
|
+
*
|
|
10
|
+
* @category Utilities
|
|
11
|
+
* @module utils/signatureCache
|
|
12
|
+
*/
|
|
1
13
|
import type { Hash } from "viem";
|
|
2
14
|
import type { VanaCacheAdapter } from "../platform/interface";
|
|
3
15
|
/**
|
|
@@ -109,23 +121,52 @@ export declare class SignatureCache {
|
|
|
109
121
|
*/
|
|
110
122
|
static hashMessage(message: object): string;
|
|
111
123
|
/**
|
|
112
|
-
* Deterministic JSON replacer
|
|
113
|
-
*
|
|
124
|
+
* Deterministic JSON replacer for consistent cache key generation.
|
|
125
|
+
*
|
|
126
|
+
* @remarks
|
|
127
|
+
* Handles BigInt serialization and sorts object keys to ensure
|
|
128
|
+
* identical objects always produce the same hash regardless of
|
|
129
|
+
* property order.
|
|
114
130
|
*
|
|
115
131
|
* @param _key - The object key being serialized (unused)
|
|
116
132
|
* @param value - The value to serialize
|
|
117
133
|
* @returns The serialized value with sorted keys for objects
|
|
134
|
+
*
|
|
135
|
+
* @internal
|
|
118
136
|
*/
|
|
119
137
|
private static deterministicReplacer;
|
|
120
138
|
}
|
|
121
139
|
/**
|
|
122
|
-
*
|
|
140
|
+
* Wraps signature operations with caching to avoid repeated prompts.
|
|
123
141
|
*
|
|
124
|
-
* @
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
142
|
+
* @remarks
|
|
143
|
+
* This helper function checks the cache before requesting a signature
|
|
144
|
+
* and stores new signatures for future use. It significantly improves
|
|
145
|
+
* UX for operations that may be retried or called multiple times.
|
|
146
|
+
*
|
|
147
|
+
* @param cache - The cache adapter to use for storage.
|
|
148
|
+
* Obtain from platform adapter.
|
|
149
|
+
* @param walletAddress - The wallet address signing the message.
|
|
150
|
+
* Obtain from wallet connection.
|
|
151
|
+
* @param typedData - The EIP-712 typed data being signed.
|
|
152
|
+
* Typically permission or grant data.
|
|
153
|
+
* @param signFn - Async function that performs the actual signing.
|
|
154
|
+
* Usually calls wallet.signTypedData().
|
|
155
|
+
* @param ttlHours - Cache TTL in hours.
|
|
156
|
+
* Defaults to 2 hours.
|
|
129
157
|
* @returns The signature (cached or newly generated)
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* const signature = await withSignatureCache(
|
|
162
|
+
* platformAdapter.cache,
|
|
163
|
+
* walletAddress,
|
|
164
|
+
* typedData,
|
|
165
|
+
* async () => wallet.signTypedData(typedData),
|
|
166
|
+
* 24 // Cache for 24 hours
|
|
167
|
+
* );
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @category Utilities
|
|
130
171
|
*/
|
|
131
172
|
export declare function withSignatureCache(cache: VanaCacheAdapter, walletAddress: string, typedData: Record<string, unknown>, signFn: () => Promise<Hash>, ttlHours?: number): Promise<Hash>;
|
|
@@ -121,12 +121,18 @@ class SignatureCache {
|
|
|
121
121
|
return toHex(hashBytes);
|
|
122
122
|
}
|
|
123
123
|
/**
|
|
124
|
-
* Deterministic JSON replacer
|
|
125
|
-
*
|
|
124
|
+
* Deterministic JSON replacer for consistent cache key generation.
|
|
125
|
+
*
|
|
126
|
+
* @remarks
|
|
127
|
+
* Handles BigInt serialization and sorts object keys to ensure
|
|
128
|
+
* identical objects always produce the same hash regardless of
|
|
129
|
+
* property order.
|
|
126
130
|
*
|
|
127
131
|
* @param _key - The object key being serialized (unused)
|
|
128
132
|
* @param value - The value to serialize
|
|
129
133
|
* @returns The serialized value with sorted keys for objects
|
|
134
|
+
*
|
|
135
|
+
* @internal
|
|
130
136
|
*/
|
|
131
137
|
static deterministicReplacer(_key, value) {
|
|
132
138
|
if (typeof value === "bigint") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/signatureCache.ts"],"sourcesContent":["import type { Hash } from \"viem\";\nimport { getAddress, toHex } from \"viem\";\nimport type { VanaCacheAdapter } from \"../platform/interface\";\nimport { sha256 } from \"@noble/hashes/sha256\";\n\ninterface CachedSignature {\n signature: Hash;\n expires: number;\n}\n\n/**\n * Simple signature cache using platform cache adapter to avoid repeated signing of identical messages.\n *\n * @remarks\n * This cache significantly improves UX by avoiding repeated wallet signature prompts\n * for identical operations. It's particularly useful for operations that may be\n * retried or called multiple times with the same parameters.\n *\n * Features:\n * - Platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * - Configurable TTL (default 2 hours)\n * - Automatic cleanup of expired entries\n * - Cache keys based on wallet address + message hash\n *\n * @example\n * ```typescript\n * // Check cache before requesting signature\n * const cached = SignatureCache.get(cache, walletAddress, messageHash);\n * if (cached) {\n * return cached;\n * }\n *\n * // Request signature and cache it\n * const signature = await wallet.signTypedData(typedData);\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n * ```\n * @category Utilities\n */\nexport class SignatureCache {\n private static readonly PREFIX = \"vana_sig_\";\n private static readonly DEFAULT_TTL_HOURS = 2;\n\n /**\n * Get a cached signature if it exists and hasn't expired\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @returns The cached signature if valid, null if expired or not found\n * @example\n * ```typescript\n * const messageHash = SignatureCache.hashMessage(typedData);\n * const cached = SignatureCache.get(cache, '0x123...', messageHash);\n * if (cached) {\n * console.log('Using cached signature:', cached);\n * }\n * ```\n */\n static get(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n ): Hash | null {\n const key = this.getCacheKey(walletAddress, messageHash);\n\n try {\n const stored = cache.get(key);\n if (!stored) return null;\n\n const cached: CachedSignature = JSON.parse(stored);\n\n // Check if expired\n if (Date.now() > cached.expires) {\n cache.delete(key);\n return null;\n }\n\n return cached.signature;\n } catch {\n // Invalid JSON or storage error, clean up\n try {\n cache.delete(key);\n } catch {\n // Ignore cache cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Store a signature in the cache with configurable TTL\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to cache\n * @param ttlHours - Time to live in hours (default: 2)\n * @example\n * ```typescript\n * const signature = await wallet.signTypedData(typedData);\n * const messageHash = SignatureCache.hashMessage(typedData);\n *\n * // Cache for default 2 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n *\n * // Cache for 24 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);\n * ```\n */\n static set(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n signature: Hash,\n ttlHours: number = this.DEFAULT_TTL_HOURS,\n ): void {\n const key = this.getCacheKey(walletAddress, messageHash);\n const cached: CachedSignature = {\n signature,\n expires: Date.now() + ttlHours * 3600000, // Convert hours to milliseconds\n };\n\n try {\n cache.set(key, JSON.stringify(cached));\n } catch {\n // Storage quota exceeded or other error, ignore silently\n // Better to continue without caching than to fail\n }\n }\n\n /**\n * Clear all cached signatures (useful for testing or explicit cleanup)\n *\n * @param cache - Platform cache adapter instance\n * @example\n * ```typescript\n * // Clear all signatures when user logs out\n * SignatureCache.clear(cache);\n *\n * // Clear before running tests\n * beforeEach(() => {\n * SignatureCache.clear(cache);\n * });\n * ```\n */\n static clear(cache: VanaCacheAdapter): void {\n try {\n cache.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n private static getCacheKey(\n walletAddress: string,\n messageHash: string,\n ): string {\n return `${this.PREFIX}${getAddress(walletAddress)}:${messageHash}`;\n }\n\n /**\n * Generate a deterministic hash of a message object for cache key generation\n *\n * @remarks\n * Creates a cryptographically secure hash from complex objects including EIP-712 typed data.\n * Uses SHA-256 for collision resistance and deterministic key generation.\n * Handles BigInt serialization and sorts object keys for consistency.\n *\n * @param message - The message object to hash (typically EIP-712 typed data)\n * @returns A hex string hash (SHA-256) suitable for cache keys\n * @example\n * ```typescript\n * const typedData = {\n * domain: { name: 'Vana', version: '1' },\n * message: { nonce: 123n, grant: '...' }\n * };\n *\n * const hash = SignatureCache.hashMessage(typedData);\n * // Returns SHA-256 hash like: \"a1b2c3d4e5f6...\"\n * ```\n */\n static hashMessage(message: object): string {\n // Deterministically stringify the object with sorted keys\n const jsonString = JSON.stringify(message, this.deterministicReplacer);\n\n // Use SHA-256 for cryptographic hashing\n const hashBytes = sha256(new TextEncoder().encode(jsonString));\n return toHex(hashBytes);\n }\n\n /**\n * Deterministic JSON replacer that handles BigInt values and sorts object keys\n * This ensures consistent cache key generation for EIP-712 typed data\n *\n * @param _key - The object key being serialized (unused)\n * @param value - The value to serialize\n * @returns The serialized value with sorted keys for objects\n */\n private static deterministicReplacer(_key: string, value: unknown): unknown {\n if (typeof value === \"bigint\") {\n return `__BIGINT__${value.toString()}`;\n }\n // Sort object keys for deterministic serialization\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, key) => {\n sorted[key] = (value as Record<string, unknown>)[key];\n return sorted;\n },\n {} as Record<string, unknown>,\n );\n }\n return value;\n }\n}\n\n/**\n * Wrapper function to cache signature operations\n *\n * @param cache - The cache adapter to use for storage\n * @param walletAddress - The wallet address signing the message\n * @param typedData - The EIP-712 typed data being signed\n * @param signFn - Function that performs the actual signing\n * @param ttlHours - Cache TTL in hours (default 2)\n * @returns The signature (cached or newly generated)\n */\nexport async function withSignatureCache(\n cache: VanaCacheAdapter,\n walletAddress: string,\n typedData: Record<string, unknown>,\n signFn: () => Promise<Hash>,\n ttlHours?: number,\n): Promise<Hash> {\n // Create a hash of the typed data for the cache key\n const messageHash = SignatureCache.hashMessage(typedData);\n\n // Try to get from cache first\n const cached = SignatureCache.get(cache, walletAddress, messageHash);\n if (cached) {\n return cached;\n }\n\n // Not in cache, sign and store\n const signature = await signFn();\n SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);\n\n return signature;\n}\n"],"mappings":"AACA,SAAS,YAAY,aAAa;AAElC,SAAS,cAAc;AAmChB,MAAM,eAAe;AAAA,EAC1B,OAAwB,SAAS;AAAA,EACjC,OAAwB,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkB5C,OAAO,IACL,OACA,eACA,aACa;AACb,UAAM,MAAM,KAAK,YAAY,eAAe,WAAW;AAEvD,QAAI;AACF,YAAM,SAAS,MAAM,IAAI,GAAG;AAC5B,UAAI,CAAC,OAAQ,QAAO;AAEpB,YAAM,SAA0B,KAAK,MAAM,MAAM;AAGjD,UAAI,KAAK,IAAI,IAAI,OAAO,SAAS;AAC/B,cAAM,OAAO,GAAG;AAChB,eAAO;AAAA,MACT;AAEA,aAAO,OAAO;AAAA,IAChB,QAAQ;AAEN,UAAI;AACF,cAAM,OAAO,GAAG;AAAA,MAClB,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,OAAO,IACL,OACA,eACA,aACA,WACA,WAAmB,KAAK,mBAClB;AACN,UAAM,MAAM,KAAK,YAAY,eAAe,WAAW;AACvD,UAAM,SAA0B;AAAA,MAC9B;AAAA,MACA,SAAS,KAAK,IAAI,IAAI,WAAW;AAAA;AAAA,IACnC;AAEA,QAAI;AACF,YAAM,IAAI,KAAK,KAAK,UAAU,MAAM,CAAC;AAAA,IACvC,QAAQ;AAAA,IAGR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,OAAO,MAAM,OAA+B;AAC1C,QAAI;AACF,YAAM,MAAM;AAAA,IACd,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,OAAe,YACb,eACA,aACQ;AACR,WAAO,GAAG,KAAK,MAAM,GAAG,WAAW,aAAa,CAAC,IAAI,WAAW;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,OAAO,YAAY,SAAyB;AAE1C,UAAM,aAAa,KAAK,UAAU,SAAS,KAAK,qBAAqB;AAGrE,UAAM,YAAY,OAAO,IAAI,YAAY,EAAE,OAAO,UAAU,CAAC;AAC7D,WAAO,MAAM,SAAS;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAe,sBAAsB,MAAc,OAAyB;AAC1E,QAAI,OAAO,UAAU,UAAU;AAC7B,aAAO,aAAa,MAAM,SAAS,CAAC;AAAA,IACtC;AAEA,QAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AACxE,aAAO,OAAO,KAAK,KAAgC,EAChD,KAAK,EACL;AAAA,QACC,CAAC,QAAQ,QAAQ;AACf,iBAAO,GAAG,IAAK,MAAkC,GAAG;AACpD,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MACH;AAAA,IACJ;AACA,WAAO;AAAA,EACT;AACF;AAYA,eAAsB,mBACpB,OACA,eACA,WACA,QACA,UACe;AAEf,QAAM,cAAc,eAAe,YAAY,SAAS;AAGxD,QAAM,SAAS,eAAe,IAAI,OAAO,eAAe,WAAW;AACnE,MAAI,QAAQ;AACV,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,MAAM,OAAO;AAC/B,iBAAe,IAAI,OAAO,eAAe,aAAa,WAAW,QAAQ;AAEzE,SAAO;AACT;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/signatureCache.ts"],"sourcesContent":["/**\n * Provides signature caching to improve UX by avoiding repeated wallet prompts.\n *\n * @remarks\n * This module implements a secure signature cache that stores signed messages\n * temporarily to avoid repeatedly prompting users for the same signature.\n * It uses platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * and includes automatic expiration and cleanup.\n *\n * @category Utilities\n * @module utils/signatureCache\n */\n\nimport type { Hash } from \"viem\";\nimport { getAddress, toHex } from \"viem\";\nimport type { VanaCacheAdapter } from \"../platform/interface\";\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n/**\n * Represents a cached signature with expiration metadata.\n *\n * @internal\n */\ninterface CachedSignature {\n /** The cached signature hash */\n signature: Hash;\n /** Unix timestamp when this cache entry expires */\n expires: number;\n}\n\n/**\n * Simple signature cache using platform cache adapter to avoid repeated signing of identical messages.\n *\n * @remarks\n * This cache significantly improves UX by avoiding repeated wallet signature prompts\n * for identical operations. It's particularly useful for operations that may be\n * retried or called multiple times with the same parameters.\n *\n * Features:\n * - Platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * - Configurable TTL (default 2 hours)\n * - Automatic cleanup of expired entries\n * - Cache keys based on wallet address + message hash\n *\n * @example\n * ```typescript\n * // Check cache before requesting signature\n * const cached = SignatureCache.get(cache, walletAddress, messageHash);\n * if (cached) {\n * return cached;\n * }\n *\n * // Request signature and cache it\n * const signature = await wallet.signTypedData(typedData);\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n * ```\n * @category Utilities\n */\nexport class SignatureCache {\n private static readonly PREFIX = \"vana_sig_\";\n private static readonly DEFAULT_TTL_HOURS = 2;\n\n /**\n * Get a cached signature if it exists and hasn't expired\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @returns The cached signature if valid, null if expired or not found\n * @example\n * ```typescript\n * const messageHash = SignatureCache.hashMessage(typedData);\n * const cached = SignatureCache.get(cache, '0x123...', messageHash);\n * if (cached) {\n * console.log('Using cached signature:', cached);\n * }\n * ```\n */\n static get(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n ): Hash | null {\n const key = this.getCacheKey(walletAddress, messageHash);\n\n try {\n const stored = cache.get(key);\n if (!stored) return null;\n\n const cached: CachedSignature = JSON.parse(stored);\n\n // Check if expired\n if (Date.now() > cached.expires) {\n cache.delete(key);\n return null;\n }\n\n return cached.signature;\n } catch {\n // Invalid JSON or storage error, clean up\n try {\n cache.delete(key);\n } catch {\n // Ignore cache cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Store a signature in the cache with configurable TTL\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to cache\n * @param ttlHours - Time to live in hours (default: 2)\n * @example\n * ```typescript\n * const signature = await wallet.signTypedData(typedData);\n * const messageHash = SignatureCache.hashMessage(typedData);\n *\n * // Cache for default 2 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n *\n * // Cache for 24 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);\n * ```\n */\n static set(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n signature: Hash,\n ttlHours: number = this.DEFAULT_TTL_HOURS,\n ): void {\n const key = this.getCacheKey(walletAddress, messageHash);\n const cached: CachedSignature = {\n signature,\n expires: Date.now() + ttlHours * 3600000, // Convert hours to milliseconds\n };\n\n try {\n cache.set(key, JSON.stringify(cached));\n } catch {\n // Storage quota exceeded or other error, ignore silently\n // Better to continue without caching than to fail\n }\n }\n\n /**\n * Clear all cached signatures (useful for testing or explicit cleanup)\n *\n * @param cache - Platform cache adapter instance\n * @example\n * ```typescript\n * // Clear all signatures when user logs out\n * SignatureCache.clear(cache);\n *\n * // Clear before running tests\n * beforeEach(() => {\n * SignatureCache.clear(cache);\n * });\n * ```\n */\n static clear(cache: VanaCacheAdapter): void {\n try {\n cache.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n private static getCacheKey(\n walletAddress: string,\n messageHash: string,\n ): string {\n return `${this.PREFIX}${getAddress(walletAddress)}:${messageHash}`;\n }\n\n /**\n * Generate a deterministic hash of a message object for cache key generation\n *\n * @remarks\n * Creates a cryptographically secure hash from complex objects including EIP-712 typed data.\n * Uses SHA-256 for collision resistance and deterministic key generation.\n * Handles BigInt serialization and sorts object keys for consistency.\n *\n * @param message - The message object to hash (typically EIP-712 typed data)\n * @returns A hex string hash (SHA-256) suitable for cache keys\n * @example\n * ```typescript\n * const typedData = {\n * domain: { name: 'Vana', version: '1' },\n * message: { nonce: 123n, grant: '...' }\n * };\n *\n * const hash = SignatureCache.hashMessage(typedData);\n * // Returns SHA-256 hash like: \"a1b2c3d4e5f6...\"\n * ```\n */\n static hashMessage(message: object): string {\n // Deterministically stringify the object with sorted keys\n const jsonString = JSON.stringify(message, this.deterministicReplacer);\n\n // Use SHA-256 for cryptographic hashing\n const hashBytes = sha256(new TextEncoder().encode(jsonString));\n return toHex(hashBytes);\n }\n\n /**\n * Deterministic JSON replacer for consistent cache key generation.\n *\n * @remarks\n * Handles BigInt serialization and sorts object keys to ensure\n * identical objects always produce the same hash regardless of\n * property order.\n *\n * @param _key - The object key being serialized (unused)\n * @param value - The value to serialize\n * @returns The serialized value with sorted keys for objects\n *\n * @internal\n */\n private static deterministicReplacer(_key: string, value: unknown): unknown {\n if (typeof value === \"bigint\") {\n return `__BIGINT__${value.toString()}`;\n }\n // Sort object keys for deterministic serialization\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, key) => {\n sorted[key] = (value as Record<string, unknown>)[key];\n return sorted;\n },\n {} as Record<string, unknown>,\n );\n }\n return value;\n }\n}\n\n/**\n * Wraps signature operations with caching to avoid repeated prompts.\n *\n * @remarks\n * This helper function checks the cache before requesting a signature\n * and stores new signatures for future use. It significantly improves\n * UX for operations that may be retried or called multiple times.\n *\n * @param cache - The cache adapter to use for storage.\n * Obtain from platform adapter.\n * @param walletAddress - The wallet address signing the message.\n * Obtain from wallet connection.\n * @param typedData - The EIP-712 typed data being signed.\n * Typically permission or grant data.\n * @param signFn - Async function that performs the actual signing.\n * Usually calls wallet.signTypedData().\n * @param ttlHours - Cache TTL in hours.\n * Defaults to 2 hours.\n * @returns The signature (cached or newly generated)\n *\n * @example\n * ```typescript\n * const signature = await withSignatureCache(\n * platformAdapter.cache,\n * walletAddress,\n * typedData,\n * async () => wallet.signTypedData(typedData),\n * 24 // Cache for 24 hours\n * );\n * ```\n *\n * @category Utilities\n */\nexport async function withSignatureCache(\n cache: VanaCacheAdapter,\n walletAddress: string,\n typedData: Record<string, unknown>,\n signFn: () => Promise<Hash>,\n ttlHours?: number,\n): Promise<Hash> {\n // Create a hash of the typed data for the cache key\n const messageHash = SignatureCache.hashMessage(typedData);\n\n // Try to get from cache first\n const cached = SignatureCache.get(cache, walletAddress, messageHash);\n if (cached) {\n return cached;\n }\n\n // Not in cache, sign and store\n const signature = await signFn();\n SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);\n\n return signature;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var subgraphConsistency_exports = {};
|
|
20
|
+
__export(subgraphConsistency_exports, {
|
|
21
|
+
StaleDataError: () => StaleDataError,
|
|
22
|
+
addMetaToQuery: () => addMetaToQuery,
|
|
23
|
+
calculateStaleness: () => calculateStaleness,
|
|
24
|
+
checkSubgraphConsistency: () => checkSubgraphConsistency,
|
|
25
|
+
fetchSubgraphMeta: () => fetchSubgraphMeta,
|
|
26
|
+
waitForSubgraphSync: () => waitForSubgraphSync
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(subgraphConsistency_exports);
|
|
29
|
+
var import_graphql = require("graphql");
|
|
30
|
+
var import_subgraph = require("../generated/subgraph");
|
|
31
|
+
var import_subgraphMetaCache = require("./subgraphMetaCache");
|
|
32
|
+
class StaleDataError extends Error {
|
|
33
|
+
constructor(requiredBlock, currentBlock, message) {
|
|
34
|
+
super(
|
|
35
|
+
message ?? `Subgraph data is stale. Required block: ${requiredBlock}, Current block: ${currentBlock}`
|
|
36
|
+
);
|
|
37
|
+
this.requiredBlock = requiredBlock;
|
|
38
|
+
this.currentBlock = currentBlock;
|
|
39
|
+
this.name = "StaleDataError";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function fetchSubgraphMeta(subgraphUrl, useCache = true) {
|
|
43
|
+
if (useCache) {
|
|
44
|
+
const cached = import_subgraphMetaCache.globalMetaCache.get(subgraphUrl);
|
|
45
|
+
if (cached) {
|
|
46
|
+
return cached;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const response = await fetch(subgraphUrl, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json"
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify({
|
|
55
|
+
query: (0, import_graphql.print)(import_subgraph.GetSubgraphMetaDocument)
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
if (!response.ok) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Failed to fetch subgraph metadata: ${response.status} ${response.statusText}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const result = await response.json();
|
|
64
|
+
if (result.errors) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (!result.data?._meta) {
|
|
70
|
+
throw new Error("No metadata returned from subgraph");
|
|
71
|
+
}
|
|
72
|
+
const meta = result.data._meta;
|
|
73
|
+
const subgraphMeta = {
|
|
74
|
+
blockNumber: meta.block.number,
|
|
75
|
+
blockTimestamp: meta.block.timestamp ?? void 0,
|
|
76
|
+
blockHash: meta.block.hash ?? void 0,
|
|
77
|
+
deployment: meta.deployment,
|
|
78
|
+
hasIndexingErrors: meta.hasIndexingErrors
|
|
79
|
+
};
|
|
80
|
+
if (useCache) {
|
|
81
|
+
import_subgraphMetaCache.globalMetaCache.set(subgraphUrl, subgraphMeta);
|
|
82
|
+
}
|
|
83
|
+
return subgraphMeta;
|
|
84
|
+
}
|
|
85
|
+
async function checkSubgraphConsistency(subgraphUrl, options) {
|
|
86
|
+
if (options?.signal?.aborted) {
|
|
87
|
+
throw new Error("Operation aborted");
|
|
88
|
+
}
|
|
89
|
+
if (!options?.minBlock) {
|
|
90
|
+
return fetchSubgraphMeta(subgraphUrl);
|
|
91
|
+
}
|
|
92
|
+
const meta = await fetchSubgraphMeta(subgraphUrl);
|
|
93
|
+
if (meta.blockNumber < options.minBlock) {
|
|
94
|
+
if (options.waitForSync && options.waitForSync > 0) {
|
|
95
|
+
return waitForSubgraphSync(
|
|
96
|
+
subgraphUrl,
|
|
97
|
+
options.minBlock,
|
|
98
|
+
options.waitForSync,
|
|
99
|
+
2e3,
|
|
100
|
+
// pollInterval
|
|
101
|
+
options.signal
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
throw new StaleDataError(options.minBlock, meta.blockNumber);
|
|
105
|
+
}
|
|
106
|
+
return meta;
|
|
107
|
+
}
|
|
108
|
+
async function waitForSubgraphSync(subgraphUrl, targetBlock, maxWait, pollInterval = 2e3, signal) {
|
|
109
|
+
const startTime = Date.now();
|
|
110
|
+
if (signal?.aborted) {
|
|
111
|
+
throw new Error("Operation aborted");
|
|
112
|
+
}
|
|
113
|
+
const checkAbort = () => {
|
|
114
|
+
if (signal?.aborted) {
|
|
115
|
+
throw new Error("Operation aborted");
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
while (Date.now() - startTime < maxWait) {
|
|
119
|
+
checkAbort();
|
|
120
|
+
const meta = await fetchSubgraphMeta(subgraphUrl);
|
|
121
|
+
if (meta.blockNumber >= targetBlock) {
|
|
122
|
+
return meta;
|
|
123
|
+
}
|
|
124
|
+
await new Promise((resolve, reject) => {
|
|
125
|
+
const timer = setTimeout(resolve, pollInterval);
|
|
126
|
+
if (signal) {
|
|
127
|
+
const abortHandler = () => {
|
|
128
|
+
clearTimeout(timer);
|
|
129
|
+
reject(new Error("Operation aborted"));
|
|
130
|
+
};
|
|
131
|
+
if (signal.aborted) {
|
|
132
|
+
abortHandler();
|
|
133
|
+
} else {
|
|
134
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
checkAbort();
|
|
140
|
+
const finalMeta = await fetchSubgraphMeta(subgraphUrl);
|
|
141
|
+
if (finalMeta.blockNumber >= targetBlock) {
|
|
142
|
+
return finalMeta;
|
|
143
|
+
}
|
|
144
|
+
throw new StaleDataError(
|
|
145
|
+
targetBlock,
|
|
146
|
+
finalMeta.blockNumber,
|
|
147
|
+
`Subgraph did not sync to block ${targetBlock} within ${maxWait}ms. Current block: ${finalMeta.blockNumber}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
function calculateStaleness(meta, currentTimestamp) {
|
|
151
|
+
if (!meta.blockTimestamp) {
|
|
152
|
+
return void 0;
|
|
153
|
+
}
|
|
154
|
+
return Math.max(0, currentTimestamp - meta.blockTimestamp);
|
|
155
|
+
}
|
|
156
|
+
function addMetaToQuery(baseQuery) {
|
|
157
|
+
if (baseQuery.includes("_meta")) {
|
|
158
|
+
return baseQuery;
|
|
159
|
+
}
|
|
160
|
+
const queryMatch = baseQuery.match(/query\s+\w+[^{]*\{/);
|
|
161
|
+
if (!queryMatch) {
|
|
162
|
+
return baseQuery;
|
|
163
|
+
}
|
|
164
|
+
const insertPoint = queryMatch.index + queryMatch[0].length;
|
|
165
|
+
return baseQuery.slice(0, insertPoint) + `
|
|
166
|
+
_meta {
|
|
167
|
+
block {
|
|
168
|
+
number
|
|
169
|
+
timestamp
|
|
170
|
+
}
|
|
171
|
+
hasIndexingErrors
|
|
172
|
+
}
|
|
173
|
+
` + baseQuery.slice(insertPoint);
|
|
174
|
+
}
|
|
175
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
176
|
+
0 && (module.exports = {
|
|
177
|
+
StaleDataError,
|
|
178
|
+
addMetaToQuery,
|
|
179
|
+
calculateStaleness,
|
|
180
|
+
checkSubgraphConsistency,
|
|
181
|
+
fetchSubgraphMeta,
|
|
182
|
+
waitForSubgraphSync
|
|
183
|
+
});
|
|
184
|
+
//# sourceMappingURL=subgraphConsistency.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/subgraphConsistency.ts"],"sourcesContent":["/**\n * @file Utilities for handling subgraph data consistency\n * @module vana-sdk/utils/subgraphConsistency\n */\n\nimport { print } from \"graphql\";\nimport type { ConsistencyOptions } from \"../types/options\";\nimport type { GetSubgraphMetaQuery } from \"../generated/subgraph\";\nimport { GetSubgraphMetaDocument } from \"../generated/subgraph\";\nimport { globalMetaCache } from \"./subgraphMetaCache\";\n\n/**\n * Error thrown when subgraph data is stale relative to consistency requirements\n */\nexport class StaleDataError extends Error {\n constructor(\n public readonly requiredBlock: number,\n public readonly currentBlock: number,\n message?: string,\n ) {\n super(\n message ??\n `Subgraph data is stale. Required block: ${requiredBlock}, Current block: ${currentBlock}`,\n );\n this.name = \"StaleDataError\";\n }\n}\n\n/**\n * Subgraph metadata response structure\n */\nexport interface SubgraphMeta {\n blockNumber: number;\n blockTimestamp?: number;\n blockHash?: string;\n deployment: string;\n hasIndexingErrors: boolean;\n}\n\n/**\n * Response structure from subgraph queries\n */\ninterface SubgraphResponse<T> {\n data?: T;\n errors?: Array<{ message: string }>;\n}\n\n/**\n * Fetches the current metadata from a subgraph\n *\n * @param subgraphUrl - The GraphQL endpoint URL\n * @returns Current block information and indexing status\n */\nexport async function fetchSubgraphMeta(\n subgraphUrl: string,\n useCache = true,\n): Promise<SubgraphMeta> {\n // Check cache first\n if (useCache) {\n const cached = globalMetaCache.get(subgraphUrl);\n if (cached) {\n return cached;\n }\n }\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query: print(GetSubgraphMetaDocument),\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch subgraph metadata: ${response.status} ${response.statusText}`,\n );\n }\n\n const result =\n (await response.json()) as SubgraphResponse<GetSubgraphMetaQuery>;\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n if (!result.data?._meta) {\n throw new Error(\"No metadata returned from subgraph\");\n }\n\n const meta = result.data._meta;\n const subgraphMeta: SubgraphMeta = {\n blockNumber: meta.block.number,\n blockTimestamp: meta.block.timestamp ?? undefined,\n blockHash: meta.block.hash ?? undefined,\n deployment: meta.deployment,\n hasIndexingErrors: meta.hasIndexingErrors,\n };\n\n // Cache the result\n if (useCache) {\n globalMetaCache.set(subgraphUrl, subgraphMeta);\n }\n\n return subgraphMeta;\n}\n\n/**\n * Checks if subgraph meets consistency requirements\n *\n * @param subgraphUrl - The GraphQL endpoint URL\n * @param options - Consistency requirements\n * @returns The subgraph metadata if requirements are met\n * @throws {StaleDataError} If subgraph is behind required block\n */\nexport async function checkSubgraphConsistency(\n subgraphUrl: string,\n options?: ConsistencyOptions,\n): Promise<SubgraphMeta> {\n // Check if already aborted\n if (options?.signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n // If no consistency requirements, just return current metadata\n if (!options?.minBlock) {\n return fetchSubgraphMeta(subgraphUrl);\n }\n\n const meta = await fetchSubgraphMeta(subgraphUrl);\n\n // Check if subgraph has reached required block\n if (meta.blockNumber < options.minBlock) {\n // If waitForSync is specified, poll until caught up\n if (options.waitForSync && options.waitForSync > 0) {\n return waitForSubgraphSync(\n subgraphUrl,\n options.minBlock,\n options.waitForSync,\n 2000, // pollInterval\n options.signal,\n );\n }\n\n // Otherwise throw immediately\n throw new StaleDataError(options.minBlock, meta.blockNumber);\n }\n\n return meta;\n}\n\n/**\n * Waits for subgraph to sync to a specific block\n *\n * @param subgraphUrl - The GraphQL endpoint URL\n * @param targetBlock - Block number to wait for\n * @param maxWait - Maximum milliseconds to wait\n * @param pollInterval - How often to check (default: 2000ms)\n * @returns The subgraph metadata when target is reached\n * @throws {StaleDataError} If timeout is reached before sync\n */\nexport async function waitForSubgraphSync(\n subgraphUrl: string,\n targetBlock: number,\n maxWait: number,\n pollInterval = 2000,\n signal?: AbortSignal,\n): Promise<SubgraphMeta> {\n const startTime = Date.now();\n\n // Check if already aborted\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n // Set up abort handling\n const checkAbort = () => {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n };\n\n while (Date.now() - startTime < maxWait) {\n checkAbort();\n const meta = await fetchSubgraphMeta(subgraphUrl);\n\n // Check if we've reached the target\n if (meta.blockNumber >= targetBlock) {\n return meta;\n }\n\n // Wait before next check with abort support\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, pollInterval);\n\n if (signal) {\n const abortHandler = () => {\n clearTimeout(timer);\n reject(new Error(\"Operation aborted\"));\n };\n\n if (signal.aborted) {\n abortHandler();\n } else {\n signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n }\n });\n }\n\n // Timeout reached, check one more time\n checkAbort();\n const finalMeta = await fetchSubgraphMeta(subgraphUrl);\n if (finalMeta.blockNumber >= targetBlock) {\n return finalMeta;\n }\n\n throw new StaleDataError(\n targetBlock,\n finalMeta.blockNumber,\n `Subgraph did not sync to block ${targetBlock} within ${maxWait}ms. Current block: ${finalMeta.blockNumber}`,\n );\n}\n\n/**\n * Calculates staleness in seconds based on block timestamps\n *\n * @param meta - Subgraph metadata\n * @param currentTimestamp - Current chain timestamp\n * @returns Seconds behind the chain, or undefined if timestamps unavailable\n */\nexport function calculateStaleness(\n meta: SubgraphMeta,\n currentTimestamp: number,\n): number | undefined {\n if (!meta.blockTimestamp) {\n return undefined;\n }\n\n return Math.max(0, currentTimestamp - meta.blockTimestamp);\n}\n\n/**\n * Builds a GraphQL query with _meta field included\n *\n * @param baseQuery - The original query string\n * @returns Query with _meta field added\n */\nexport function addMetaToQuery(baseQuery: string): string {\n // Simple approach: inject _meta at the root level\n // This is a basic implementation - could be enhanced with proper AST manipulation\n if (baseQuery.includes(\"_meta\")) {\n return baseQuery; // Already has meta\n }\n\n // Find the first { after query name and inject _meta\n const queryMatch = baseQuery.match(/query\\s+\\w+[^{]*\\{/);\n if (!queryMatch) {\n return baseQuery; // Can't parse, return as-is\n }\n\n const insertPoint = queryMatch.index! + queryMatch[0].length;\n return (\n baseQuery.slice(0, insertPoint) +\n `\n _meta {\n block {\n number\n timestamp\n }\n hasIndexingErrors\n }\n ` +\n baseQuery.slice(insertPoint)\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Utilities for handling subgraph data consistency
|
|
3
|
+
* @module vana-sdk/utils/subgraphConsistency
|
|
4
|
+
*/
|
|
5
|
+
import type { ConsistencyOptions } from "../types/options";
|
|
6
|
+
/**
|
|
7
|
+
* Error thrown when subgraph data is stale relative to consistency requirements
|
|
8
|
+
*/
|
|
9
|
+
export declare class StaleDataError extends Error {
|
|
10
|
+
readonly requiredBlock: number;
|
|
11
|
+
readonly currentBlock: number;
|
|
12
|
+
constructor(requiredBlock: number, currentBlock: number, message?: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Subgraph metadata response structure
|
|
16
|
+
*/
|
|
17
|
+
export interface SubgraphMeta {
|
|
18
|
+
blockNumber: number;
|
|
19
|
+
blockTimestamp?: number;
|
|
20
|
+
blockHash?: string;
|
|
21
|
+
deployment: string;
|
|
22
|
+
hasIndexingErrors: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Fetches the current metadata from a subgraph
|
|
26
|
+
*
|
|
27
|
+
* @param subgraphUrl - The GraphQL endpoint URL
|
|
28
|
+
* @returns Current block information and indexing status
|
|
29
|
+
*/
|
|
30
|
+
export declare function fetchSubgraphMeta(subgraphUrl: string, useCache?: boolean): Promise<SubgraphMeta>;
|
|
31
|
+
/**
|
|
32
|
+
* Checks if subgraph meets consistency requirements
|
|
33
|
+
*
|
|
34
|
+
* @param subgraphUrl - The GraphQL endpoint URL
|
|
35
|
+
* @param options - Consistency requirements
|
|
36
|
+
* @returns The subgraph metadata if requirements are met
|
|
37
|
+
* @throws {StaleDataError} If subgraph is behind required block
|
|
38
|
+
*/
|
|
39
|
+
export declare function checkSubgraphConsistency(subgraphUrl: string, options?: ConsistencyOptions): Promise<SubgraphMeta>;
|
|
40
|
+
/**
|
|
41
|
+
* Waits for subgraph to sync to a specific block
|
|
42
|
+
*
|
|
43
|
+
* @param subgraphUrl - The GraphQL endpoint URL
|
|
44
|
+
* @param targetBlock - Block number to wait for
|
|
45
|
+
* @param maxWait - Maximum milliseconds to wait
|
|
46
|
+
* @param pollInterval - How often to check (default: 2000ms)
|
|
47
|
+
* @returns The subgraph metadata when target is reached
|
|
48
|
+
* @throws {StaleDataError} If timeout is reached before sync
|
|
49
|
+
*/
|
|
50
|
+
export declare function waitForSubgraphSync(subgraphUrl: string, targetBlock: number, maxWait: number, pollInterval?: number, signal?: AbortSignal): Promise<SubgraphMeta>;
|
|
51
|
+
/**
|
|
52
|
+
* Calculates staleness in seconds based on block timestamps
|
|
53
|
+
*
|
|
54
|
+
* @param meta - Subgraph metadata
|
|
55
|
+
* @param currentTimestamp - Current chain timestamp
|
|
56
|
+
* @returns Seconds behind the chain, or undefined if timestamps unavailable
|
|
57
|
+
*/
|
|
58
|
+
export declare function calculateStaleness(meta: SubgraphMeta, currentTimestamp: number): number | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Builds a GraphQL query with _meta field included
|
|
61
|
+
*
|
|
62
|
+
* @param baseQuery - The original query string
|
|
63
|
+
* @returns Query with _meta field added
|
|
64
|
+
*/
|
|
65
|
+
export declare function addMetaToQuery(baseQuery: string): string;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { print } from "graphql";
|
|
2
|
+
import { GetSubgraphMetaDocument } from "../generated/subgraph";
|
|
3
|
+
import { globalMetaCache } from "./subgraphMetaCache";
|
|
4
|
+
class StaleDataError extends Error {
|
|
5
|
+
constructor(requiredBlock, currentBlock, message) {
|
|
6
|
+
super(
|
|
7
|
+
message ?? `Subgraph data is stale. Required block: ${requiredBlock}, Current block: ${currentBlock}`
|
|
8
|
+
);
|
|
9
|
+
this.requiredBlock = requiredBlock;
|
|
10
|
+
this.currentBlock = currentBlock;
|
|
11
|
+
this.name = "StaleDataError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async function fetchSubgraphMeta(subgraphUrl, useCache = true) {
|
|
15
|
+
if (useCache) {
|
|
16
|
+
const cached = globalMetaCache.get(subgraphUrl);
|
|
17
|
+
if (cached) {
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const response = await fetch(subgraphUrl, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json"
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify({
|
|
27
|
+
query: print(GetSubgraphMetaDocument)
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Failed to fetch subgraph metadata: ${response.status} ${response.statusText}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const result = await response.json();
|
|
36
|
+
if (result.errors) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Subgraph query errors: ${result.errors.map((e) => e.message).join(", ")}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
if (!result.data?._meta) {
|
|
42
|
+
throw new Error("No metadata returned from subgraph");
|
|
43
|
+
}
|
|
44
|
+
const meta = result.data._meta;
|
|
45
|
+
const subgraphMeta = {
|
|
46
|
+
blockNumber: meta.block.number,
|
|
47
|
+
blockTimestamp: meta.block.timestamp ?? void 0,
|
|
48
|
+
blockHash: meta.block.hash ?? void 0,
|
|
49
|
+
deployment: meta.deployment,
|
|
50
|
+
hasIndexingErrors: meta.hasIndexingErrors
|
|
51
|
+
};
|
|
52
|
+
if (useCache) {
|
|
53
|
+
globalMetaCache.set(subgraphUrl, subgraphMeta);
|
|
54
|
+
}
|
|
55
|
+
return subgraphMeta;
|
|
56
|
+
}
|
|
57
|
+
async function checkSubgraphConsistency(subgraphUrl, options) {
|
|
58
|
+
if (options?.signal?.aborted) {
|
|
59
|
+
throw new Error("Operation aborted");
|
|
60
|
+
}
|
|
61
|
+
if (!options?.minBlock) {
|
|
62
|
+
return fetchSubgraphMeta(subgraphUrl);
|
|
63
|
+
}
|
|
64
|
+
const meta = await fetchSubgraphMeta(subgraphUrl);
|
|
65
|
+
if (meta.blockNumber < options.minBlock) {
|
|
66
|
+
if (options.waitForSync && options.waitForSync > 0) {
|
|
67
|
+
return waitForSubgraphSync(
|
|
68
|
+
subgraphUrl,
|
|
69
|
+
options.minBlock,
|
|
70
|
+
options.waitForSync,
|
|
71
|
+
2e3,
|
|
72
|
+
// pollInterval
|
|
73
|
+
options.signal
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
throw new StaleDataError(options.minBlock, meta.blockNumber);
|
|
77
|
+
}
|
|
78
|
+
return meta;
|
|
79
|
+
}
|
|
80
|
+
async function waitForSubgraphSync(subgraphUrl, targetBlock, maxWait, pollInterval = 2e3, signal) {
|
|
81
|
+
const startTime = Date.now();
|
|
82
|
+
if (signal?.aborted) {
|
|
83
|
+
throw new Error("Operation aborted");
|
|
84
|
+
}
|
|
85
|
+
const checkAbort = () => {
|
|
86
|
+
if (signal?.aborted) {
|
|
87
|
+
throw new Error("Operation aborted");
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
while (Date.now() - startTime < maxWait) {
|
|
91
|
+
checkAbort();
|
|
92
|
+
const meta = await fetchSubgraphMeta(subgraphUrl);
|
|
93
|
+
if (meta.blockNumber >= targetBlock) {
|
|
94
|
+
return meta;
|
|
95
|
+
}
|
|
96
|
+
await new Promise((resolve, reject) => {
|
|
97
|
+
const timer = setTimeout(resolve, pollInterval);
|
|
98
|
+
if (signal) {
|
|
99
|
+
const abortHandler = () => {
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
reject(new Error("Operation aborted"));
|
|
102
|
+
};
|
|
103
|
+
if (signal.aborted) {
|
|
104
|
+
abortHandler();
|
|
105
|
+
} else {
|
|
106
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
checkAbort();
|
|
112
|
+
const finalMeta = await fetchSubgraphMeta(subgraphUrl);
|
|
113
|
+
if (finalMeta.blockNumber >= targetBlock) {
|
|
114
|
+
return finalMeta;
|
|
115
|
+
}
|
|
116
|
+
throw new StaleDataError(
|
|
117
|
+
targetBlock,
|
|
118
|
+
finalMeta.blockNumber,
|
|
119
|
+
`Subgraph did not sync to block ${targetBlock} within ${maxWait}ms. Current block: ${finalMeta.blockNumber}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
function calculateStaleness(meta, currentTimestamp) {
|
|
123
|
+
if (!meta.blockTimestamp) {
|
|
124
|
+
return void 0;
|
|
125
|
+
}
|
|
126
|
+
return Math.max(0, currentTimestamp - meta.blockTimestamp);
|
|
127
|
+
}
|
|
128
|
+
function addMetaToQuery(baseQuery) {
|
|
129
|
+
if (baseQuery.includes("_meta")) {
|
|
130
|
+
return baseQuery;
|
|
131
|
+
}
|
|
132
|
+
const queryMatch = baseQuery.match(/query\s+\w+[^{]*\{/);
|
|
133
|
+
if (!queryMatch) {
|
|
134
|
+
return baseQuery;
|
|
135
|
+
}
|
|
136
|
+
const insertPoint = queryMatch.index + queryMatch[0].length;
|
|
137
|
+
return baseQuery.slice(0, insertPoint) + `
|
|
138
|
+
_meta {
|
|
139
|
+
block {
|
|
140
|
+
number
|
|
141
|
+
timestamp
|
|
142
|
+
}
|
|
143
|
+
hasIndexingErrors
|
|
144
|
+
}
|
|
145
|
+
` + baseQuery.slice(insertPoint);
|
|
146
|
+
}
|
|
147
|
+
export {
|
|
148
|
+
StaleDataError,
|
|
149
|
+
addMetaToQuery,
|
|
150
|
+
calculateStaleness,
|
|
151
|
+
checkSubgraphConsistency,
|
|
152
|
+
fetchSubgraphMeta,
|
|
153
|
+
waitForSubgraphSync
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=subgraphConsistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/subgraphConsistency.ts"],"sourcesContent":["/**\n * @file Utilities for handling subgraph data consistency\n * @module vana-sdk/utils/subgraphConsistency\n */\n\nimport { print } from \"graphql\";\nimport type { ConsistencyOptions } from \"../types/options\";\nimport type { GetSubgraphMetaQuery } from \"../generated/subgraph\";\nimport { GetSubgraphMetaDocument } from \"../generated/subgraph\";\nimport { globalMetaCache } from \"./subgraphMetaCache\";\n\n/**\n * Error thrown when subgraph data is stale relative to consistency requirements\n */\nexport class StaleDataError extends Error {\n constructor(\n public readonly requiredBlock: number,\n public readonly currentBlock: number,\n message?: string,\n ) {\n super(\n message ??\n `Subgraph data is stale. Required block: ${requiredBlock}, Current block: ${currentBlock}`,\n );\n this.name = \"StaleDataError\";\n }\n}\n\n/**\n * Subgraph metadata response structure\n */\nexport interface SubgraphMeta {\n blockNumber: number;\n blockTimestamp?: number;\n blockHash?: string;\n deployment: string;\n hasIndexingErrors: boolean;\n}\n\n/**\n * Response structure from subgraph queries\n */\ninterface SubgraphResponse<T> {\n data?: T;\n errors?: Array<{ message: string }>;\n}\n\n/**\n * Fetches the current metadata from a subgraph\n *\n * @param subgraphUrl - The GraphQL endpoint URL\n * @returns Current block information and indexing status\n */\nexport async function fetchSubgraphMeta(\n subgraphUrl: string,\n useCache = true,\n): Promise<SubgraphMeta> {\n // Check cache first\n if (useCache) {\n const cached = globalMetaCache.get(subgraphUrl);\n if (cached) {\n return cached;\n }\n }\n\n const response = await fetch(subgraphUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query: print(GetSubgraphMetaDocument),\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch subgraph metadata: ${response.status} ${response.statusText}`,\n );\n }\n\n const result =\n (await response.json()) as SubgraphResponse<GetSubgraphMetaQuery>;\n\n if (result.errors) {\n throw new Error(\n `Subgraph query errors: ${result.errors.map((e) => e.message).join(\", \")}`,\n );\n }\n\n if (!result.data?._meta) {\n throw new Error(\"No metadata returned from subgraph\");\n }\n\n const meta = result.data._meta;\n const subgraphMeta: SubgraphMeta = {\n blockNumber: meta.block.number,\n blockTimestamp: meta.block.timestamp ?? undefined,\n blockHash: meta.block.hash ?? undefined,\n deployment: meta.deployment,\n hasIndexingErrors: meta.hasIndexingErrors,\n };\n\n // Cache the result\n if (useCache) {\n globalMetaCache.set(subgraphUrl, subgraphMeta);\n }\n\n return subgraphMeta;\n}\n\n/**\n * Checks if subgraph meets consistency requirements\n *\n * @param subgraphUrl - The GraphQL endpoint URL\n * @param options - Consistency requirements\n * @returns The subgraph metadata if requirements are met\n * @throws {StaleDataError} If subgraph is behind required block\n */\nexport async function checkSubgraphConsistency(\n subgraphUrl: string,\n options?: ConsistencyOptions,\n): Promise<SubgraphMeta> {\n // Check if already aborted\n if (options?.signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n // If no consistency requirements, just return current metadata\n if (!options?.minBlock) {\n return fetchSubgraphMeta(subgraphUrl);\n }\n\n const meta = await fetchSubgraphMeta(subgraphUrl);\n\n // Check if subgraph has reached required block\n if (meta.blockNumber < options.minBlock) {\n // If waitForSync is specified, poll until caught up\n if (options.waitForSync && options.waitForSync > 0) {\n return waitForSubgraphSync(\n subgraphUrl,\n options.minBlock,\n options.waitForSync,\n 2000, // pollInterval\n options.signal,\n );\n }\n\n // Otherwise throw immediately\n throw new StaleDataError(options.minBlock, meta.blockNumber);\n }\n\n return meta;\n}\n\n/**\n * Waits for subgraph to sync to a specific block\n *\n * @param subgraphUrl - The GraphQL endpoint URL\n * @param targetBlock - Block number to wait for\n * @param maxWait - Maximum milliseconds to wait\n * @param pollInterval - How often to check (default: 2000ms)\n * @returns The subgraph metadata when target is reached\n * @throws {StaleDataError} If timeout is reached before sync\n */\nexport async function waitForSubgraphSync(\n subgraphUrl: string,\n targetBlock: number,\n maxWait: number,\n pollInterval = 2000,\n signal?: AbortSignal,\n): Promise<SubgraphMeta> {\n const startTime = Date.now();\n\n // Check if already aborted\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n\n // Set up abort handling\n const checkAbort = () => {\n if (signal?.aborted) {\n throw new Error(\"Operation aborted\");\n }\n };\n\n while (Date.now() - startTime < maxWait) {\n checkAbort();\n const meta = await fetchSubgraphMeta(subgraphUrl);\n\n // Check if we've reached the target\n if (meta.blockNumber >= targetBlock) {\n return meta;\n }\n\n // Wait before next check with abort support\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(resolve, pollInterval);\n\n if (signal) {\n const abortHandler = () => {\n clearTimeout(timer);\n reject(new Error(\"Operation aborted\"));\n };\n\n if (signal.aborted) {\n abortHandler();\n } else {\n signal.addEventListener(\"abort\", abortHandler, { once: true });\n }\n }\n });\n }\n\n // Timeout reached, check one more time\n checkAbort();\n const finalMeta = await fetchSubgraphMeta(subgraphUrl);\n if (finalMeta.blockNumber >= targetBlock) {\n return finalMeta;\n }\n\n throw new StaleDataError(\n targetBlock,\n finalMeta.blockNumber,\n `Subgraph did not sync to block ${targetBlock} within ${maxWait}ms. Current block: ${finalMeta.blockNumber}`,\n );\n}\n\n/**\n * Calculates staleness in seconds based on block timestamps\n *\n * @param meta - Subgraph metadata\n * @param currentTimestamp - Current chain timestamp\n * @returns Seconds behind the chain, or undefined if timestamps unavailable\n */\nexport function calculateStaleness(\n meta: SubgraphMeta,\n currentTimestamp: number,\n): number | undefined {\n if (!meta.blockTimestamp) {\n return undefined;\n }\n\n return Math.max(0, currentTimestamp - meta.blockTimestamp);\n}\n\n/**\n * Builds a GraphQL query with _meta field included\n *\n * @param baseQuery - The original query string\n * @returns Query with _meta field added\n */\nexport function addMetaToQuery(baseQuery: string): string {\n // Simple approach: inject _meta at the root level\n // This is a basic implementation - could be enhanced with proper AST manipulation\n if (baseQuery.includes(\"_meta\")) {\n return baseQuery; // Already has meta\n }\n\n // Find the first { after query name and inject _meta\n const queryMatch = baseQuery.match(/query\\s+\\w+[^{]*\\{/);\n if (!queryMatch) {\n return baseQuery; // Can't parse, return as-is\n }\n\n const insertPoint = queryMatch.index! + queryMatch[0].length;\n return (\n baseQuery.slice(0, insertPoint) +\n `\n _meta {\n block {\n number\n timestamp\n }\n hasIndexingErrors\n }\n ` +\n baseQuery.slice(insertPoint)\n );\n}\n"],"mappings":"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","names":[]}
|