@opendatalabs/vana-sdk 0.1.0-alpha.fd33fc9 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.ts +33 -1
- package/dist/browser.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/__tests__/enhancedResponse.test.d.ts +1 -0
- 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/contracts/contractController.cjs.map +1 -1
- package/dist/contracts/contractController.d.ts +66 -10
- 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/base.cjs +33 -0
- package/dist/controllers/base.cjs.map +1 -1
- package/dist/controllers/base.d.ts +10 -0
- package/dist/controllers/base.js +33 -0
- package/dist/controllers/base.js.map +1 -1
- package/dist/controllers/data.cjs +417 -276
- package/dist/controllers/data.cjs.map +1 -1
- package/dist/controllers/data.d.ts +246 -193
- package/dist/controllers/data.js +430 -279
- 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 +690 -209
- package/dist/controllers/permissions.cjs.map +1 -1
- package/dist/controllers/permissions.d.ts +196 -68
- package/dist/controllers/permissions.js +690 -209
- package/dist/controllers/permissions.js.map +1 -1
- package/dist/controllers/protocol.cjs.map +1 -1
- package/dist/controllers/protocol.d.ts +27 -28
- package/dist/controllers/protocol.js.map +1 -1
- package/dist/controllers/schemas.cjs +104 -25
- package/dist/controllers/schemas.cjs.map +1 -1
- package/dist/controllers/schemas.d.ts +88 -40
- package/dist/controllers/schemas.js +104 -25
- package/dist/controllers/schemas.js.map +1 -1
- package/dist/controllers/server.cjs +269 -58
- package/dist/controllers/server.cjs.map +1 -1
- package/dist/controllers/server.d.ts +157 -52
- package/dist/controllers/server.js +269 -58
- 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 +55 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.ts +54 -3
- package/dist/core.js +55 -1
- package/dist/core.js.map +1 -1
- package/dist/crypto/ecies/base.cjs +16 -3
- package/dist/crypto/ecies/base.cjs.map +1 -1
- package/dist/crypto/ecies/base.js +16 -3
- package/dist/crypto/ecies/base.js.map +1 -1
- package/dist/errors.cjs +29 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +64 -0
- package/dist/errors.js +28 -0
- package/dist/errors.js.map +1 -1
- package/dist/generated/abi/ComputeInstructionRegistryImplementation.cjs.map +1 -1
- package/dist/generated/abi/ComputeInstructionRegistryImplementation.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/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/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/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/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/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/index.d.ts +546 -146
- package/dist/generated/event-types.cjs.map +1 -1
- package/dist/generated/event-types.d.ts +14 -8
- package/dist/generated/eventRegistry.cjs +42 -18
- package/dist/generated/eventRegistry.cjs.map +1 -1
- package/dist/generated/eventRegistry.js +42 -18
- 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 +27 -10
- 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 +2 -0
- package/dist/index.browser.js +10 -0
- 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 +26 -0
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.ts +49 -5
- package/dist/index.node.js +25 -1
- 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 +315 -81
- package/dist/server/relayerHandler.cjs.map +1 -1
- package/dist/server/relayerHandler.d.ts +35 -2
- package/dist/server/relayerHandler.js +315 -81
- package/dist/server/relayerHandler.js.map +1 -1
- 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/permissions-transaction-options.test.d.ts +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.map +1 -1
- package/dist/types/config.d.ts +38 -4
- 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 +4 -1
- package/dist/types/data.cjs.map +1 -1
- package/dist/types/data.d.ts +11 -10
- package/dist/types/generics.cjs.map +1 -1
- package/dist/types/generics.d.ts +81 -10
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.ts +31 -3
- 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 +145 -24
- 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/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/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.map +1 -1
- package/dist/utils/wallet.d.ts +78 -16
- package/dist/utils/wallet.js.map +1 -1
- package/package.json +3 -1
|
@@ -28,30 +28,28 @@ export interface PinataFile {
|
|
|
28
28
|
metadata?: object;
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
|
-
*
|
|
31
|
+
* Manages IPFS storage through Pinata's enhanced API.
|
|
32
32
|
*
|
|
33
33
|
* @remarks
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* on IPFS without
|
|
34
|
+
* Extends standard IPFS with additional features like file listing,
|
|
35
|
+
* deletion (unpinning), and rich metadata. Production-ready managed
|
|
36
|
+
* service with guaranteed availability. The "it just works" solution
|
|
37
|
+
* for developers who want full CRUD operations on IPFS without
|
|
38
|
+
* managing infrastructure.
|
|
38
39
|
*
|
|
39
40
|
* @category Storage
|
|
40
|
-
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```typescript
|
|
43
|
-
* const
|
|
44
|
-
* jwt: "your-
|
|
43
|
+
* const storage = new PinataStorage({
|
|
44
|
+
* jwt: "your-jwt-token"
|
|
45
45
|
* });
|
|
46
46
|
*
|
|
47
47
|
* // Upload with metadata
|
|
48
|
-
* const
|
|
49
|
-
*
|
|
50
|
-
* metadata: { userId: "123", category: "avatar" }
|
|
51
|
-
* });
|
|
48
|
+
* const result = await storage.upload(blob, "file.json");
|
|
49
|
+
* console.log(`Pinned at: ${result.url}`);
|
|
52
50
|
*
|
|
53
|
-
* // List
|
|
54
|
-
* const files = await
|
|
51
|
+
* // List and manage files
|
|
52
|
+
* const files = await storage.list({ limit: 10 });
|
|
55
53
|
*
|
|
56
54
|
* // Delete file
|
|
57
55
|
* await pinataStorage.delete(cid);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/storage/providers/pinata.ts"],"sourcesContent":["import {\n StorageError,\n type StorageProvider,\n type StorageUploadResult,\n type StorageFile,\n type StorageListOptions,\n type StorageProviderConfig,\n} from \"../index\";\n\nexport interface PinataConfig {\n /** Pinata JWT token for authentication */\n jwt: string;\n /** Optional custom gateway URL (defaults to https://gateway.pinata.cloud) */\n gatewayUrl?: string;\n}\n\nexport interface PinataListQuery {\n /** Maximum number of results to return */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n /** Filter by name pattern */\n namePattern?: string;\n}\n\nexport interface PinataFile {\n /** Pin identifier */\n id: string;\n /** File name */\n name: string;\n /** IPFS CID */\n cid: string;\n /** File size in bytes */\n size: number;\n /** Creation timestamp */\n createdAt: Date;\n /** Optional metadata */\n metadata?: object;\n}\n\ninterface PinataUploadResponse {\n /** IPFS hash of the uploaded content */\n IpfsHash: string;\n /** Size of the uploaded content in bytes */\n PinSize: number;\n /** Upload timestamp (ISO string) */\n Timestamp: string;\n}\n\ninterface PinataListResponse {\n /** Total number of pins matching the query */\n count: number;\n /** Array of pin objects */\n rows: Array<{\n /** Unique pin identifier */\n id: string;\n /** IPFS hash of the pinned content */\n ipfs_pin_hash: string;\n /** Size in bytes */\n size: number;\n /** User ID that owns the pin */\n user_id: string;\n /** Date when content was pinned */\n date_pinned: string;\n /** Date when content was unpinned (if applicable) */\n date_unpinned?: string;\n /** Pin metadata */\n metadata: {\n /** Optional name for the pin */\n name?: string;\n /** Additional key-value metadata */\n keyvalues?: Record<string, unknown>;\n };\n }>;\n}\n\n/**\n * Provides managed IPFS storage with full-featured API via Pinata\n *\n * @remarks\n * This provider uses Pinata's enhanced IPFS service, which extends standard IPFS\n * with additional features like file listing, deletion (unpinning), and rich metadata.\n * It's the \"it just works\" solution for developers who want full CRUD operations\n * on IPFS without managing infrastructure.\n *\n * @category Storage\n *\n * @example\n * ```typescript\n * const pinataStorage = new PinataStorage({\n * jwt: \"your-pinata-jwt-token\"\n * });\n *\n * // Upload with metadata\n * const cid = await pinataStorage.upload(fileBlob, {\n * name: \"user-avatar.png\",\n * metadata: { userId: \"123\", category: \"avatar\" }\n * });\n *\n * // List files with query\n * const files = await pinataStorage.list({ limit: 10 });\n *\n * // Delete file\n * await pinataStorage.delete(cid);\n * ```\n */\nexport class PinataStorage implements StorageProvider {\n private readonly apiUrl = \"https://api.pinata.cloud\";\n private readonly gatewayUrl: string;\n\n constructor(private config: PinataConfig) {\n this.gatewayUrl = config.gatewayUrl ?? \"https://gateway.pinata.cloud\";\n if (!config.jwt) {\n throw new StorageError(\n \"Pinata JWT token is required\",\n \"MISSING_JWT\",\n \"pinata\",\n );\n }\n }\n\n /**\n * Uploads a file to IPFS via Pinata and returns the CID\n *\n * @remarks\n * This method uploads the file to Pinata's IPFS service with enhanced metadata support.\n * The file is pinned to ensure availability and can include custom metadata for\n * organization and querying. The metadata is stored alongside the file for later retrieval.\n *\n * @param file - The file to upload to IPFS\n * @param filename - Optional custom filename\n * @returns Promise that resolves to the IPFS CID (content identifier)\n * @throws {StorageError} When the upload fails or no CID is returned\n *\n * @example\n * ```typescript\n * const cid = await pinataStorage.upload(fileBlob, {\n * name: \"user-document.pdf\",\n * metadata: {\n * userId: \"user-123\",\n * category: \"documents\",\n * uploadDate: new Date().toISOString()\n * }\n * });\n * console.log(\"File pinned to IPFS:\", cid);\n * ```\n */\n async upload(file: Blob, filename?: string): Promise<StorageUploadResult> {\n try {\n const fileName = filename ?? `vana-file-${Date.now()}.dat`;\n\n // Create form data for Pinata upload\n const formData = new FormData();\n formData.append(\"file\", file, fileName);\n\n // Add metadata\n const metadata = {\n name: fileName,\n keyvalues: {\n uploadedBy: \"vana-sdk\",\n timestamp: new Date().toISOString(),\n },\n };\n formData.append(\"pinataMetadata\", JSON.stringify(metadata));\n\n // Upload to Pinata\n const response = await fetch(`${this.apiUrl}/pinning/pinFileToIPFS`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new StorageError(\n `Pinata upload failed: ${errorText}`,\n \"UPLOAD_FAILED\",\n \"pinata\",\n );\n }\n\n const result = (await response.json()) as PinataUploadResponse;\n const ipfsHash = result.IpfsHash;\n\n if (!ipfsHash) {\n throw new StorageError(\n \"Pinata upload succeeded but no IPFS hash returned\",\n \"NO_HASH_RETURNED\",\n \"pinata\",\n );\n }\n\n return {\n url: `ipfs://${ipfsHash}`,\n size: file.size,\n contentType: file.type ?? \"application/octet-stream\",\n };\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata upload error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"UPLOAD_ERROR\",\n \"pinata\",\n );\n }\n }\n\n async download(cid: string): Promise<Blob> {\n try {\n // Validate CID format\n if (!this.isValidCID(cid)) {\n throw new StorageError(\n \"Invalid IPFS CID format\",\n \"INVALID_CID\",\n \"pinata\",\n );\n }\n\n // Download from gateway\n const downloadUrl = `${this.gatewayUrl}/ipfs/${cid}`;\n const response = await fetch(downloadUrl);\n\n if (!response.ok) {\n throw new StorageError(\n `Failed to download from IPFS: ${response.statusText}`,\n \"DOWNLOAD_FAILED\",\n \"pinata\",\n );\n }\n\n return await response.blob();\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata download error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DOWNLOAD_ERROR\",\n \"pinata\",\n );\n }\n }\n\n /**\n * Lists files uploaded to Pinata with optional filtering\n *\n * @remarks\n * This method retrieves a list of files that have been uploaded to Pinata,\n * filtered to only include files uploaded by the Vana SDK. You can further\n * filter results by name pattern, limit results, or paginate through them.\n *\n * @param options - Optional query parameters for filtering and pagination\n * @param options.limit - Maximum number of results to return (default: 10)\n * @param options.offset - Number of results to skip for pagination\n * @param options.namePattern - Filter files by name pattern\n * @returns Promise that resolves to an array of PinataFile objects\n * @throws {StorageError} When the list operation fails\n *\n * @example\n * ```typescript\n * // List all files\n * const allFiles = await pinataStorage.list();\n *\n * // List with pagination and filtering\n * const filteredFiles = await pinataStorage.list({\n * limit: 20,\n * offset: 10,\n * namePattern: \"document\"\n * });\n *\n * filteredFiles.forEach(file => {\n * console.log(`${file.name} (${file.size} bytes): ${file.cid}`);\n * });\n * ```\n */\n async list(options?: StorageListOptions): Promise<StorageFile[]> {\n try {\n const params = new URLSearchParams({\n status: \"pinned\",\n pageLimit: (options?.limit ?? 10).toString(),\n metadata: JSON.stringify({\n keyvalues: {\n uploadedBy: \"vana-sdk\",\n },\n }),\n });\n\n if (options?.offset) {\n params.set(\"pageOffset\", options.offset.toString());\n }\n\n if (options?.namePattern) {\n params.set(\"metadata[name]\", options.namePattern);\n }\n\n const response = await fetch(`${this.apiUrl}/data/pinList?${params}`, {\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new StorageError(\n `Failed to list Pinata files: ${errorText}`,\n \"LIST_FAILED\",\n \"pinata\",\n );\n }\n\n const result = (await response.json()) as PinataListResponse;\n\n return result.rows.map((pin) => ({\n id: pin.id,\n name: pin.metadata?.name ?? \"Unnamed\",\n url: `ipfs://${pin.ipfs_pin_hash}`,\n size: parseInt(String(pin.size), 10) || 0,\n contentType: \"application/octet-stream\", // Pinata doesn't store content type\n createdAt: new Date(pin.date_pinned),\n metadata: pin.metadata?.keyvalues ?? {},\n }));\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata list error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"LIST_ERROR\",\n \"pinata\",\n );\n }\n }\n\n /**\n * Deletes a file from Pinata by unpinning it from IPFS\n *\n * @remarks\n * This method removes the file from your Pinata account by unpinning it,\n * which means it will no longer be guaranteed to be available on the IPFS network.\n * Note that if the file is pinned elsewhere or cached by other nodes, it may still\n * be accessible for some time.\n *\n * @param url - The IPFS URL or content identifier of the file to delete\n * @returns Promise that resolves when the file is successfully unpinned\n * @throws {StorageError} When the deletion fails or CID format is invalid\n *\n * @example\n * ```typescript\n * // Delete a file by CID\n * await pinataStorage.delete(\"QmTzQ1JRkWErjk39mryYw2WVrgBMe2B36gRq8GCL8qCACj\");\n * console.log(\"File unpinned from Pinata\");\n *\n * // Delete after listing\n * const files = await pinataStorage.list();\n * for (const file of files) {\n * if (file.name.includes(\"temp\")) {\n * await pinataStorage.delete(file.cid);\n * }\n * }\n * ```\n */\n async delete(url: string): Promise<boolean> {\n try {\n // Extract CID from URL or use as-is\n const cid = this.extractCidFromUrl(url);\n\n // Validate CID format\n if (!this.isValidCID(cid)) {\n throw new StorageError(\n \"Invalid IPFS CID format\",\n \"INVALID_CID\",\n \"pinata\",\n );\n }\n\n const response = await fetch(`${this.apiUrl}/pinning/unpin/${cid}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new StorageError(\n `Failed to delete from Pinata: ${errorText}`,\n \"DELETE_FAILED\",\n \"pinata\",\n );\n }\n\n return true;\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata delete error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DELETE_ERROR\",\n \"pinata\",\n );\n }\n }\n\n getConfig(): StorageProviderConfig {\n return {\n name: \"Pinata IPFS\",\n type: \"pinata\",\n requiresAuth: true,\n features: {\n upload: true,\n download: true,\n list: true,\n delete: true,\n },\n };\n }\n\n /**\n * Extract CID from URL or return as-is\n *\n * @param url - URL or CID string\n * @returns CID string\n */\n private extractCidFromUrl(url: string): string {\n // If it's already a CID (not a URL), return as-is\n if (!url.includes(\"/\")) {\n return url;\n }\n\n // Extract CID from gateway URL\n const cidMatch = url.match(/\\/ipfs\\/([a-zA-Z0-9]+)/);\n if (cidMatch) {\n return cidMatch[1];\n }\n\n // If no match, assume it's a CID\n return url;\n }\n\n /**\n * Basic CID validation\n *\n * @param cid - Content identifier to validate\n * @returns True if CID appears valid\n */\n private isValidCID(cid: string): boolean {\n // Basic validation: CIDs typically start with 'Qm' or 'ba' and contain alphanumeric characters\n return (\n /^[a-zA-Z0-9]{10,}$/.test(cid) &&\n (cid.startsWith(\"Qm\") || cid.startsWith(\"ba\") || cid.includes(\"Test\"))\n );\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/providers/pinata.ts"],"sourcesContent":["import {\n StorageError,\n type StorageProvider,\n type StorageUploadResult,\n type StorageFile,\n type StorageListOptions,\n type StorageProviderConfig,\n} from \"../index\";\n\nexport interface PinataConfig {\n /** Pinata JWT token for authentication */\n jwt: string;\n /** Optional custom gateway URL (defaults to https://gateway.pinata.cloud) */\n gatewayUrl?: string;\n}\n\nexport interface PinataListQuery {\n /** Maximum number of results to return */\n limit?: number;\n /** Offset for pagination */\n offset?: number;\n /** Filter by name pattern */\n namePattern?: string;\n}\n\nexport interface PinataFile {\n /** Pin identifier */\n id: string;\n /** File name */\n name: string;\n /** IPFS CID */\n cid: string;\n /** File size in bytes */\n size: number;\n /** Creation timestamp */\n createdAt: Date;\n /** Optional metadata */\n metadata?: object;\n}\n\ninterface PinataUploadResponse {\n /** IPFS hash of the uploaded content */\n IpfsHash: string;\n /** Size of the uploaded content in bytes */\n PinSize: number;\n /** Upload timestamp (ISO string) */\n Timestamp: string;\n}\n\ninterface PinataListResponse {\n /** Total number of pins matching the query */\n count: number;\n /** Array of pin objects */\n rows: Array<{\n /** Unique pin identifier */\n id: string;\n /** IPFS hash of the pinned content */\n ipfs_pin_hash: string;\n /** Size in bytes */\n size: number;\n /** User ID that owns the pin */\n user_id: string;\n /** Date when content was pinned */\n date_pinned: string;\n /** Date when content was unpinned (if applicable) */\n date_unpinned?: string;\n /** Pin metadata */\n metadata: {\n /** Optional name for the pin */\n name?: string;\n /** Additional key-value metadata */\n keyvalues?: Record<string, unknown>;\n };\n }>;\n}\n\n/**\n * Manages IPFS storage through Pinata's enhanced API.\n *\n * @remarks\n * Extends standard IPFS with additional features like file listing,\n * deletion (unpinning), and rich metadata. Production-ready managed\n * service with guaranteed availability. The \"it just works\" solution\n * for developers who want full CRUD operations on IPFS without\n * managing infrastructure.\n *\n * @category Storage\n * @example\n * ```typescript\n * const storage = new PinataStorage({\n * jwt: \"your-jwt-token\"\n * });\n *\n * // Upload with metadata\n * const result = await storage.upload(blob, \"file.json\");\n * console.log(`Pinned at: ${result.url}`);\n *\n * // List and manage files\n * const files = await storage.list({ limit: 10 });\n *\n * // Delete file\n * await pinataStorage.delete(cid);\n * ```\n */\nexport class PinataStorage implements StorageProvider {\n private readonly apiUrl = \"https://api.pinata.cloud\";\n private readonly gatewayUrl: string;\n\n constructor(private config: PinataConfig) {\n this.gatewayUrl = config.gatewayUrl ?? \"https://gateway.pinata.cloud\";\n if (!config.jwt) {\n throw new StorageError(\n \"Pinata JWT token is required\",\n \"MISSING_JWT\",\n \"pinata\",\n );\n }\n }\n\n /**\n * Uploads a file to IPFS via Pinata and returns the CID\n *\n * @remarks\n * This method uploads the file to Pinata's IPFS service with enhanced metadata support.\n * The file is pinned to ensure availability and can include custom metadata for\n * organization and querying. The metadata is stored alongside the file for later retrieval.\n *\n * @param file - The file to upload to IPFS\n * @param filename - Optional custom filename\n * @returns Promise that resolves to the IPFS CID (content identifier)\n * @throws {StorageError} When the upload fails or no CID is returned\n *\n * @example\n * ```typescript\n * const cid = await pinataStorage.upload(fileBlob, {\n * name: \"user-document.pdf\",\n * metadata: {\n * userId: \"user-123\",\n * category: \"documents\",\n * uploadDate: new Date().toISOString()\n * }\n * });\n * console.log(\"File pinned to IPFS:\", cid);\n * ```\n */\n async upload(file: Blob, filename?: string): Promise<StorageUploadResult> {\n try {\n const fileName = filename ?? `vana-file-${Date.now()}.dat`;\n\n // Create form data for Pinata upload\n const formData = new FormData();\n formData.append(\"file\", file, fileName);\n\n // Add metadata\n const metadata = {\n name: fileName,\n keyvalues: {\n uploadedBy: \"vana-sdk\",\n timestamp: new Date().toISOString(),\n },\n };\n formData.append(\"pinataMetadata\", JSON.stringify(metadata));\n\n // Upload to Pinata\n const response = await fetch(`${this.apiUrl}/pinning/pinFileToIPFS`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n },\n body: formData,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new StorageError(\n `Pinata upload failed: ${errorText}`,\n \"UPLOAD_FAILED\",\n \"pinata\",\n );\n }\n\n const result = (await response.json()) as PinataUploadResponse;\n const ipfsHash = result.IpfsHash;\n\n if (!ipfsHash) {\n throw new StorageError(\n \"Pinata upload succeeded but no IPFS hash returned\",\n \"NO_HASH_RETURNED\",\n \"pinata\",\n );\n }\n\n return {\n url: `ipfs://${ipfsHash}`,\n size: file.size,\n contentType: file.type ?? \"application/octet-stream\",\n };\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata upload error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"UPLOAD_ERROR\",\n \"pinata\",\n );\n }\n }\n\n async download(cid: string): Promise<Blob> {\n try {\n // Validate CID format\n if (!this.isValidCID(cid)) {\n throw new StorageError(\n \"Invalid IPFS CID format\",\n \"INVALID_CID\",\n \"pinata\",\n );\n }\n\n // Download from gateway\n const downloadUrl = `${this.gatewayUrl}/ipfs/${cid}`;\n const response = await fetch(downloadUrl);\n\n if (!response.ok) {\n throw new StorageError(\n `Failed to download from IPFS: ${response.statusText}`,\n \"DOWNLOAD_FAILED\",\n \"pinata\",\n );\n }\n\n return await response.blob();\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata download error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DOWNLOAD_ERROR\",\n \"pinata\",\n );\n }\n }\n\n /**\n * Lists files uploaded to Pinata with optional filtering\n *\n * @remarks\n * This method retrieves a list of files that have been uploaded to Pinata,\n * filtered to only include files uploaded by the Vana SDK. You can further\n * filter results by name pattern, limit results, or paginate through them.\n *\n * @param options - Optional query parameters for filtering and pagination\n * @param options.limit - Maximum number of results to return (default: 10)\n * @param options.offset - Number of results to skip for pagination\n * @param options.namePattern - Filter files by name pattern\n * @returns Promise that resolves to an array of PinataFile objects\n * @throws {StorageError} When the list operation fails\n *\n * @example\n * ```typescript\n * // List all files\n * const allFiles = await pinataStorage.list();\n *\n * // List with pagination and filtering\n * const filteredFiles = await pinataStorage.list({\n * limit: 20,\n * offset: 10,\n * namePattern: \"document\"\n * });\n *\n * filteredFiles.forEach(file => {\n * console.log(`${file.name} (${file.size} bytes): ${file.cid}`);\n * });\n * ```\n */\n async list(options?: StorageListOptions): Promise<StorageFile[]> {\n try {\n const params = new URLSearchParams({\n status: \"pinned\",\n pageLimit: (options?.limit ?? 10).toString(),\n metadata: JSON.stringify({\n keyvalues: {\n uploadedBy: \"vana-sdk\",\n },\n }),\n });\n\n if (options?.offset) {\n params.set(\"pageOffset\", options.offset.toString());\n }\n\n if (options?.namePattern) {\n params.set(\"metadata[name]\", options.namePattern);\n }\n\n const response = await fetch(`${this.apiUrl}/data/pinList?${params}`, {\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new StorageError(\n `Failed to list Pinata files: ${errorText}`,\n \"LIST_FAILED\",\n \"pinata\",\n );\n }\n\n const result = (await response.json()) as PinataListResponse;\n\n return result.rows.map((pin) => ({\n id: pin.id,\n name: pin.metadata?.name ?? \"Unnamed\",\n url: `ipfs://${pin.ipfs_pin_hash}`,\n size: parseInt(String(pin.size), 10) || 0,\n contentType: \"application/octet-stream\", // Pinata doesn't store content type\n createdAt: new Date(pin.date_pinned),\n metadata: pin.metadata?.keyvalues ?? {},\n }));\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata list error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"LIST_ERROR\",\n \"pinata\",\n );\n }\n }\n\n /**\n * Deletes a file from Pinata by unpinning it from IPFS\n *\n * @remarks\n * This method removes the file from your Pinata account by unpinning it,\n * which means it will no longer be guaranteed to be available on the IPFS network.\n * Note that if the file is pinned elsewhere or cached by other nodes, it may still\n * be accessible for some time.\n *\n * @param url - The IPFS URL or content identifier of the file to delete\n * @returns Promise that resolves when the file is successfully unpinned\n * @throws {StorageError} When the deletion fails or CID format is invalid\n *\n * @example\n * ```typescript\n * // Delete a file by CID\n * await pinataStorage.delete(\"QmTzQ1JRkWErjk39mryYw2WVrgBMe2B36gRq8GCL8qCACj\");\n * console.log(\"File unpinned from Pinata\");\n *\n * // Delete after listing\n * const files = await pinataStorage.list();\n * for (const file of files) {\n * if (file.name.includes(\"temp\")) {\n * await pinataStorage.delete(file.cid);\n * }\n * }\n * ```\n */\n async delete(url: string): Promise<boolean> {\n try {\n // Extract CID from URL or use as-is\n const cid = this.extractCidFromUrl(url);\n\n // Validate CID format\n if (!this.isValidCID(cid)) {\n throw new StorageError(\n \"Invalid IPFS CID format\",\n \"INVALID_CID\",\n \"pinata\",\n );\n }\n\n const response = await fetch(`${this.apiUrl}/pinning/unpin/${cid}`, {\n method: \"DELETE\",\n headers: {\n Authorization: `Bearer ${this.config.jwt}`,\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new StorageError(\n `Failed to delete from Pinata: ${errorText}`,\n \"DELETE_FAILED\",\n \"pinata\",\n );\n }\n\n return true;\n } catch (error) {\n if (error instanceof StorageError) {\n throw error;\n }\n throw new StorageError(\n `Pinata delete error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n \"DELETE_ERROR\",\n \"pinata\",\n );\n }\n }\n\n getConfig(): StorageProviderConfig {\n return {\n name: \"Pinata IPFS\",\n type: \"pinata\",\n requiresAuth: true,\n features: {\n upload: true,\n download: true,\n list: true,\n delete: true,\n },\n };\n }\n\n /**\n * Extract CID from URL or return as-is\n *\n * @param url - URL or CID string\n * @returns CID string\n */\n private extractCidFromUrl(url: string): string {\n // If it's already a CID (not a URL), return as-is\n if (!url.includes(\"/\")) {\n return url;\n }\n\n // Extract CID from gateway URL\n const cidMatch = url.match(/\\/ipfs\\/([a-zA-Z0-9]+)/);\n if (cidMatch) {\n return cidMatch[1];\n }\n\n // If no match, assume it's a CID\n return url;\n }\n\n /**\n * Basic CID validation\n *\n * @param cid - Content identifier to validate\n * @returns True if CID appears valid\n */\n private isValidCID(cid: string): boolean {\n // Basic validation: CIDs typically start with 'Qm' or 'ba' and contain alphanumeric characters\n return (\n /^[a-zA-Z0-9]{10,}$/.test(cid) &&\n (cid.startsWith(\"Qm\") || cid.startsWith(\"ba\") || cid.includes(\"Test\"))\n );\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
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 atomicStore_exports = {};
|
|
20
|
+
__export(atomicStore_exports, {
|
|
21
|
+
hasNonceSupport: () => hasNonceSupport
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(atomicStore_exports);
|
|
24
|
+
function hasNonceSupport(store) {
|
|
25
|
+
return "atomicAssignNonce" in store && typeof store.atomicAssignNonce === "function";
|
|
26
|
+
}
|
|
27
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
+
0 && (module.exports = {
|
|
29
|
+
hasNonceSupport
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=atomicStore.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/atomicStore.ts"],"sourcesContent":["/**\n * Atomic storage primitives for distributed state management.\n *\n * @module\n */\n\n/**\n * Interface for atomic storage operations required by the SDK's distributed components.\n *\n * @remarks\n * Implementations of this interface MUST guarantee atomicity for all operations.\n * These primitives are used by the SDK's internal components to coordinate\n * distributed state in multi-instance deployments (e.g., serverless functions).\n *\n * The SDK provides a reference Redis implementation, but you can implement\n * this interface using any storage backend that supports atomic operations:\n * - PostgreSQL with advisory locks\n * - DynamoDB with conditional writes\n * - MongoDB with findAndModify\n * - Zookeeper or etcd for coordination\n *\n * @example\n * ```typescript\n * // Using the Redis reference implementation\n * import { RedisAtomicStore } from './lib/redisAtomicStore';\n *\n * const atomicStore = new RedisAtomicStore({\n * redis: process.env.REDIS_URL\n * });\n *\n * const vana = Vana({\n * privateKey: process.env.RELAYER_PRIVATE_KEY,\n * atomicStore\n * });\n * ```\n *\n * @category Storage\n */\nexport interface IAtomicStore {\n /**\n * Atomically increments a counter and returns the new value.\n *\n * @remarks\n * This operation MUST be atomic. If the key doesn't exist, it should be\n * initialized to 0 before incrementing. The operation must return the\n * value after incrementing.\n *\n * This is used primarily for nonce assignment where atomicity is critical\n * to prevent conflicts under concurrent load.\n *\n * @param key - The key to increment\n * @returns The new value after incrementing\n *\n * @example\n * ```typescript\n * // First call returns 1\n * const nonce1 = await store.incr('nonce:0x123:1480');\n * // Second call returns 2\n * const nonce2 = await store.incr('nonce:0x123:1480');\n * ```\n */\n incr(key: string): Promise<number>;\n\n /**\n * Attempts to acquire a distributed lock with automatic expiration.\n *\n * @remarks\n * This operation MUST be atomic and follow the \"SET NX EX\" semantics:\n * - Only succeeds if the lock doesn't exist (NX - \"Not eXists\")\n * - Automatically expires after the specified TTL (EX - \"EXpire\")\n * - Returns a unique lock ID on success for safe release\n *\n * The lock ID should be a unique value (e.g., UUID or timestamp+random)\n * that prevents accidental release by other processes.\n *\n * @param key - The lock key\n * @param ttlSeconds - Time-to-live in seconds (automatic expiration)\n * @returns A unique lock ID if acquired, null if lock is already held\n *\n * @example\n * ```typescript\n * const lockId = await store.acquireLock('nonce:lock:0x123', 5);\n * if (lockId) {\n * try {\n * // Critical section - only one process can be here\n * await performCriticalOperation();\n * } finally {\n * await store.releaseLock('nonce:lock:0x123', lockId);\n * }\n * }\n * ```\n */\n acquireLock(key: string, ttlSeconds: number): Promise<string | null>;\n\n /**\n * Releases a previously acquired lock.\n *\n * @remarks\n * This operation MUST be atomic and safe. It should only succeed if the\n * provided lockId matches the current lock value. This prevents accidental\n * release of locks acquired by other processes.\n *\n * Implementations should use compare-and-delete semantics or a Lua script\n * (in Redis) to ensure atomicity.\n *\n * @param key - The lock key\n * @param lockId - The unique ID returned by acquireLock\n *\n * @example\n * ```typescript\n * const lockId = await store.acquireLock('lock:key', 5);\n * if (lockId) {\n * // ... do work ...\n * await store.releaseLock('lock:key', lockId);\n * }\n * ```\n */\n releaseLock(key: string, lockId: string): Promise<void>;\n\n /**\n * Gets the value associated with a key.\n *\n * @remarks\n * This is a simple read operation. It should return null if the key\n * doesn't exist.\n *\n * @param key - The key to retrieve\n * @returns The stored value, or null if not found\n *\n * @example\n * ```typescript\n * const lastUsedNonce = await store.get('lastNonce:0x123:1480');\n * ```\n */\n get(key: string): Promise<string | null>;\n\n /**\n * Sets a key-value pair.\n *\n * @remarks\n * This is a simple write operation. It should overwrite any existing value.\n *\n * @param key - The key to set\n * @param value - The value to store\n *\n * @example\n * ```typescript\n * await store.set('lastNonce:0x123:1480', '42');\n * ```\n */\n set(key: string, value: string): Promise<void>;\n\n /**\n * Sets a key-value pair with expiration.\n *\n * @remarks\n * This operation sets a value with automatic expiration after the specified TTL.\n * Useful for temporary state that should be automatically cleaned up.\n *\n * @param key - The key to set\n * @param value - The value to store\n * @param ttlSeconds - Time-to-live in seconds\n *\n * @example\n * ```typescript\n * // Store operation state for 24 hours\n * await store.setWithTTL('operation:123', JSON.stringify(state), 86400);\n * ```\n */\n setWithTTL?(key: string, value: string, ttlSeconds: number): Promise<void>;\n\n /**\n * Deletes a key.\n *\n * @remarks\n * This operation removes a key from storage. Should be idempotent\n * (no error if key doesn't exist).\n *\n * @param key - The key to delete\n *\n * @example\n * ```typescript\n * await store.delete('temp:data:123');\n * ```\n */\n delete?(key: string): Promise<void>;\n\n /**\n * Executes an atomic script (e.g., Lua in Redis, stored procedure in SQL).\n *\n * @remarks\n * This is an optional method that allows execution of atomic scripts\n * for complex operations that require multiple steps to be atomic.\n * Not all stores support this - simple stores may omit it.\n *\n * For Redis: executes a Lua script\n * For PostgreSQL: executes a stored procedure or CTE\n * For DynamoDB: might use TransactWrite\n *\n * @param script - The script to execute\n * @param keys - Array of keys the script will operate on\n * @param args - Array of arguments to pass to the script\n * @returns The script's return value\n *\n * @example\n * ```typescript\n * const result = await store.eval(\n * 'return redis.call(\"INCR\", KEYS[1])',\n * ['counter:users'],\n * []\n * );\n * ```\n */\n eval?(script: string, keys: string[], args: string[]): Promise<any>;\n}\n\n/**\n * Extended atomic store interface with nonce support.\n *\n * @remarks\n * Some atomic stores (like Redis) provide optimized atomic nonce assignment\n * through native scripting capabilities. This interface extends the base\n * IAtomicStore with this optional optimization.\n *\n * @internal\n */\nexport interface IAtomicStoreWithNonceSupport extends IAtomicStore {\n /**\n * Atomically assigns a nonce with gap prevention.\n *\n * @param key - The storage key for the last used nonce\n * @param pendingCount - The current pending transaction count from blockchain\n * @returns The assigned nonce\n */\n atomicAssignNonce(key: string, pendingCount: number): Promise<number>;\n}\n\n/**\n * Type guard to check if an atomic store supports optimized nonce assignment.\n *\n * @param store - The atomic store to check\n * @returns True if the store supports atomicAssignNonce\n *\n * @internal\n */\nexport function hasNonceSupport(\n store: IAtomicStore,\n): store is IAtomicStoreWithNonceSupport {\n return (\n \"atomicAssignNonce\" in store &&\n typeof (store as IAtomicStoreWithNonceSupport).atomicAssignNonce ===\n \"function\"\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqPO,SAAS,gBACd,OACuC;AACvC,SACE,uBAAuB,SACvB,OAAQ,MAAuC,sBAC7C;AAEN;","names":[]}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic storage primitives for distributed state management.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Interface for atomic storage operations required by the SDK's distributed components.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Implementations of this interface MUST guarantee atomicity for all operations.
|
|
11
|
+
* These primitives are used by the SDK's internal components to coordinate
|
|
12
|
+
* distributed state in multi-instance deployments (e.g., serverless functions).
|
|
13
|
+
*
|
|
14
|
+
* The SDK provides a reference Redis implementation, but you can implement
|
|
15
|
+
* this interface using any storage backend that supports atomic operations:
|
|
16
|
+
* - PostgreSQL with advisory locks
|
|
17
|
+
* - DynamoDB with conditional writes
|
|
18
|
+
* - MongoDB with findAndModify
|
|
19
|
+
* - Zookeeper or etcd for coordination
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Using the Redis reference implementation
|
|
24
|
+
* import { RedisAtomicStore } from './lib/redisAtomicStore';
|
|
25
|
+
*
|
|
26
|
+
* const atomicStore = new RedisAtomicStore({
|
|
27
|
+
* redis: process.env.REDIS_URL
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* const vana = Vana({
|
|
31
|
+
* privateKey: process.env.RELAYER_PRIVATE_KEY,
|
|
32
|
+
* atomicStore
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @category Storage
|
|
37
|
+
*/
|
|
38
|
+
export interface IAtomicStore {
|
|
39
|
+
/**
|
|
40
|
+
* Atomically increments a counter and returns the new value.
|
|
41
|
+
*
|
|
42
|
+
* @remarks
|
|
43
|
+
* This operation MUST be atomic. If the key doesn't exist, it should be
|
|
44
|
+
* initialized to 0 before incrementing. The operation must return the
|
|
45
|
+
* value after incrementing.
|
|
46
|
+
*
|
|
47
|
+
* This is used primarily for nonce assignment where atomicity is critical
|
|
48
|
+
* to prevent conflicts under concurrent load.
|
|
49
|
+
*
|
|
50
|
+
* @param key - The key to increment
|
|
51
|
+
* @returns The new value after incrementing
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* // First call returns 1
|
|
56
|
+
* const nonce1 = await store.incr('nonce:0x123:1480');
|
|
57
|
+
* // Second call returns 2
|
|
58
|
+
* const nonce2 = await store.incr('nonce:0x123:1480');
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
incr(key: string): Promise<number>;
|
|
62
|
+
/**
|
|
63
|
+
* Attempts to acquire a distributed lock with automatic expiration.
|
|
64
|
+
*
|
|
65
|
+
* @remarks
|
|
66
|
+
* This operation MUST be atomic and follow the "SET NX EX" semantics:
|
|
67
|
+
* - Only succeeds if the lock doesn't exist (NX - "Not eXists")
|
|
68
|
+
* - Automatically expires after the specified TTL (EX - "EXpire")
|
|
69
|
+
* - Returns a unique lock ID on success for safe release
|
|
70
|
+
*
|
|
71
|
+
* The lock ID should be a unique value (e.g., UUID or timestamp+random)
|
|
72
|
+
* that prevents accidental release by other processes.
|
|
73
|
+
*
|
|
74
|
+
* @param key - The lock key
|
|
75
|
+
* @param ttlSeconds - Time-to-live in seconds (automatic expiration)
|
|
76
|
+
* @returns A unique lock ID if acquired, null if lock is already held
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const lockId = await store.acquireLock('nonce:lock:0x123', 5);
|
|
81
|
+
* if (lockId) {
|
|
82
|
+
* try {
|
|
83
|
+
* // Critical section - only one process can be here
|
|
84
|
+
* await performCriticalOperation();
|
|
85
|
+
* } finally {
|
|
86
|
+
* await store.releaseLock('nonce:lock:0x123', lockId);
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
acquireLock(key: string, ttlSeconds: number): Promise<string | null>;
|
|
92
|
+
/**
|
|
93
|
+
* Releases a previously acquired lock.
|
|
94
|
+
*
|
|
95
|
+
* @remarks
|
|
96
|
+
* This operation MUST be atomic and safe. It should only succeed if the
|
|
97
|
+
* provided lockId matches the current lock value. This prevents accidental
|
|
98
|
+
* release of locks acquired by other processes.
|
|
99
|
+
*
|
|
100
|
+
* Implementations should use compare-and-delete semantics or a Lua script
|
|
101
|
+
* (in Redis) to ensure atomicity.
|
|
102
|
+
*
|
|
103
|
+
* @param key - The lock key
|
|
104
|
+
* @param lockId - The unique ID returned by acquireLock
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* const lockId = await store.acquireLock('lock:key', 5);
|
|
109
|
+
* if (lockId) {
|
|
110
|
+
* // ... do work ...
|
|
111
|
+
* await store.releaseLock('lock:key', lockId);
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
releaseLock(key: string, lockId: string): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Gets the value associated with a key.
|
|
118
|
+
*
|
|
119
|
+
* @remarks
|
|
120
|
+
* This is a simple read operation. It should return null if the key
|
|
121
|
+
* doesn't exist.
|
|
122
|
+
*
|
|
123
|
+
* @param key - The key to retrieve
|
|
124
|
+
* @returns The stored value, or null if not found
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const lastUsedNonce = await store.get('lastNonce:0x123:1480');
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
get(key: string): Promise<string | null>;
|
|
132
|
+
/**
|
|
133
|
+
* Sets a key-value pair.
|
|
134
|
+
*
|
|
135
|
+
* @remarks
|
|
136
|
+
* This is a simple write operation. It should overwrite any existing value.
|
|
137
|
+
*
|
|
138
|
+
* @param key - The key to set
|
|
139
|
+
* @param value - The value to store
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* await store.set('lastNonce:0x123:1480', '42');
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
set(key: string, value: string): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Sets a key-value pair with expiration.
|
|
149
|
+
*
|
|
150
|
+
* @remarks
|
|
151
|
+
* This operation sets a value with automatic expiration after the specified TTL.
|
|
152
|
+
* Useful for temporary state that should be automatically cleaned up.
|
|
153
|
+
*
|
|
154
|
+
* @param key - The key to set
|
|
155
|
+
* @param value - The value to store
|
|
156
|
+
* @param ttlSeconds - Time-to-live in seconds
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // Store operation state for 24 hours
|
|
161
|
+
* await store.setWithTTL('operation:123', JSON.stringify(state), 86400);
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
setWithTTL?(key: string, value: string, ttlSeconds: number): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Deletes a key.
|
|
167
|
+
*
|
|
168
|
+
* @remarks
|
|
169
|
+
* This operation removes a key from storage. Should be idempotent
|
|
170
|
+
* (no error if key doesn't exist).
|
|
171
|
+
*
|
|
172
|
+
* @param key - The key to delete
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* await store.delete('temp:data:123');
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
delete?(key: string): Promise<void>;
|
|
180
|
+
/**
|
|
181
|
+
* Executes an atomic script (e.g., Lua in Redis, stored procedure in SQL).
|
|
182
|
+
*
|
|
183
|
+
* @remarks
|
|
184
|
+
* This is an optional method that allows execution of atomic scripts
|
|
185
|
+
* for complex operations that require multiple steps to be atomic.
|
|
186
|
+
* Not all stores support this - simple stores may omit it.
|
|
187
|
+
*
|
|
188
|
+
* For Redis: executes a Lua script
|
|
189
|
+
* For PostgreSQL: executes a stored procedure or CTE
|
|
190
|
+
* For DynamoDB: might use TransactWrite
|
|
191
|
+
*
|
|
192
|
+
* @param script - The script to execute
|
|
193
|
+
* @param keys - Array of keys the script will operate on
|
|
194
|
+
* @param args - Array of arguments to pass to the script
|
|
195
|
+
* @returns The script's return value
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* const result = await store.eval(
|
|
200
|
+
* 'return redis.call("INCR", KEYS[1])',
|
|
201
|
+
* ['counter:users'],
|
|
202
|
+
* []
|
|
203
|
+
* );
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
eval?(script: string, keys: string[], args: string[]): Promise<any>;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Extended atomic store interface with nonce support.
|
|
210
|
+
*
|
|
211
|
+
* @remarks
|
|
212
|
+
* Some atomic stores (like Redis) provide optimized atomic nonce assignment
|
|
213
|
+
* through native scripting capabilities. This interface extends the base
|
|
214
|
+
* IAtomicStore with this optional optimization.
|
|
215
|
+
*
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
export interface IAtomicStoreWithNonceSupport extends IAtomicStore {
|
|
219
|
+
/**
|
|
220
|
+
* Atomically assigns a nonce with gap prevention.
|
|
221
|
+
*
|
|
222
|
+
* @param key - The storage key for the last used nonce
|
|
223
|
+
* @param pendingCount - The current pending transaction count from blockchain
|
|
224
|
+
* @returns The assigned nonce
|
|
225
|
+
*/
|
|
226
|
+
atomicAssignNonce(key: string, pendingCount: number): Promise<number>;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Type guard to check if an atomic store supports optimized nonce assignment.
|
|
230
|
+
*
|
|
231
|
+
* @param store - The atomic store to check
|
|
232
|
+
* @returns True if the store supports atomicAssignNonce
|
|
233
|
+
*
|
|
234
|
+
* @internal
|
|
235
|
+
*/
|
|
236
|
+
export declare function hasNonceSupport(store: IAtomicStore): store is IAtomicStoreWithNonceSupport;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/atomicStore.ts"],"sourcesContent":["/**\n * Atomic storage primitives for distributed state management.\n *\n * @module\n */\n\n/**\n * Interface for atomic storage operations required by the SDK's distributed components.\n *\n * @remarks\n * Implementations of this interface MUST guarantee atomicity for all operations.\n * These primitives are used by the SDK's internal components to coordinate\n * distributed state in multi-instance deployments (e.g., serverless functions).\n *\n * The SDK provides a reference Redis implementation, but you can implement\n * this interface using any storage backend that supports atomic operations:\n * - PostgreSQL with advisory locks\n * - DynamoDB with conditional writes\n * - MongoDB with findAndModify\n * - Zookeeper or etcd for coordination\n *\n * @example\n * ```typescript\n * // Using the Redis reference implementation\n * import { RedisAtomicStore } from './lib/redisAtomicStore';\n *\n * const atomicStore = new RedisAtomicStore({\n * redis: process.env.REDIS_URL\n * });\n *\n * const vana = Vana({\n * privateKey: process.env.RELAYER_PRIVATE_KEY,\n * atomicStore\n * });\n * ```\n *\n * @category Storage\n */\nexport interface IAtomicStore {\n /**\n * Atomically increments a counter and returns the new value.\n *\n * @remarks\n * This operation MUST be atomic. If the key doesn't exist, it should be\n * initialized to 0 before incrementing. The operation must return the\n * value after incrementing.\n *\n * This is used primarily for nonce assignment where atomicity is critical\n * to prevent conflicts under concurrent load.\n *\n * @param key - The key to increment\n * @returns The new value after incrementing\n *\n * @example\n * ```typescript\n * // First call returns 1\n * const nonce1 = await store.incr('nonce:0x123:1480');\n * // Second call returns 2\n * const nonce2 = await store.incr('nonce:0x123:1480');\n * ```\n */\n incr(key: string): Promise<number>;\n\n /**\n * Attempts to acquire a distributed lock with automatic expiration.\n *\n * @remarks\n * This operation MUST be atomic and follow the \"SET NX EX\" semantics:\n * - Only succeeds if the lock doesn't exist (NX - \"Not eXists\")\n * - Automatically expires after the specified TTL (EX - \"EXpire\")\n * - Returns a unique lock ID on success for safe release\n *\n * The lock ID should be a unique value (e.g., UUID or timestamp+random)\n * that prevents accidental release by other processes.\n *\n * @param key - The lock key\n * @param ttlSeconds - Time-to-live in seconds (automatic expiration)\n * @returns A unique lock ID if acquired, null if lock is already held\n *\n * @example\n * ```typescript\n * const lockId = await store.acquireLock('nonce:lock:0x123', 5);\n * if (lockId) {\n * try {\n * // Critical section - only one process can be here\n * await performCriticalOperation();\n * } finally {\n * await store.releaseLock('nonce:lock:0x123', lockId);\n * }\n * }\n * ```\n */\n acquireLock(key: string, ttlSeconds: number): Promise<string | null>;\n\n /**\n * Releases a previously acquired lock.\n *\n * @remarks\n * This operation MUST be atomic and safe. It should only succeed if the\n * provided lockId matches the current lock value. This prevents accidental\n * release of locks acquired by other processes.\n *\n * Implementations should use compare-and-delete semantics or a Lua script\n * (in Redis) to ensure atomicity.\n *\n * @param key - The lock key\n * @param lockId - The unique ID returned by acquireLock\n *\n * @example\n * ```typescript\n * const lockId = await store.acquireLock('lock:key', 5);\n * if (lockId) {\n * // ... do work ...\n * await store.releaseLock('lock:key', lockId);\n * }\n * ```\n */\n releaseLock(key: string, lockId: string): Promise<void>;\n\n /**\n * Gets the value associated with a key.\n *\n * @remarks\n * This is a simple read operation. It should return null if the key\n * doesn't exist.\n *\n * @param key - The key to retrieve\n * @returns The stored value, or null if not found\n *\n * @example\n * ```typescript\n * const lastUsedNonce = await store.get('lastNonce:0x123:1480');\n * ```\n */\n get(key: string): Promise<string | null>;\n\n /**\n * Sets a key-value pair.\n *\n * @remarks\n * This is a simple write operation. It should overwrite any existing value.\n *\n * @param key - The key to set\n * @param value - The value to store\n *\n * @example\n * ```typescript\n * await store.set('lastNonce:0x123:1480', '42');\n * ```\n */\n set(key: string, value: string): Promise<void>;\n\n /**\n * Sets a key-value pair with expiration.\n *\n * @remarks\n * This operation sets a value with automatic expiration after the specified TTL.\n * Useful for temporary state that should be automatically cleaned up.\n *\n * @param key - The key to set\n * @param value - The value to store\n * @param ttlSeconds - Time-to-live in seconds\n *\n * @example\n * ```typescript\n * // Store operation state for 24 hours\n * await store.setWithTTL('operation:123', JSON.stringify(state), 86400);\n * ```\n */\n setWithTTL?(key: string, value: string, ttlSeconds: number): Promise<void>;\n\n /**\n * Deletes a key.\n *\n * @remarks\n * This operation removes a key from storage. Should be idempotent\n * (no error if key doesn't exist).\n *\n * @param key - The key to delete\n *\n * @example\n * ```typescript\n * await store.delete('temp:data:123');\n * ```\n */\n delete?(key: string): Promise<void>;\n\n /**\n * Executes an atomic script (e.g., Lua in Redis, stored procedure in SQL).\n *\n * @remarks\n * This is an optional method that allows execution of atomic scripts\n * for complex operations that require multiple steps to be atomic.\n * Not all stores support this - simple stores may omit it.\n *\n * For Redis: executes a Lua script\n * For PostgreSQL: executes a stored procedure or CTE\n * For DynamoDB: might use TransactWrite\n *\n * @param script - The script to execute\n * @param keys - Array of keys the script will operate on\n * @param args - Array of arguments to pass to the script\n * @returns The script's return value\n *\n * @example\n * ```typescript\n * const result = await store.eval(\n * 'return redis.call(\"INCR\", KEYS[1])',\n * ['counter:users'],\n * []\n * );\n * ```\n */\n eval?(script: string, keys: string[], args: string[]): Promise<any>;\n}\n\n/**\n * Extended atomic store interface with nonce support.\n *\n * @remarks\n * Some atomic stores (like Redis) provide optimized atomic nonce assignment\n * through native scripting capabilities. This interface extends the base\n * IAtomicStore with this optional optimization.\n *\n * @internal\n */\nexport interface IAtomicStoreWithNonceSupport extends IAtomicStore {\n /**\n * Atomically assigns a nonce with gap prevention.\n *\n * @param key - The storage key for the last used nonce\n * @param pendingCount - The current pending transaction count from blockchain\n * @returns The assigned nonce\n */\n atomicAssignNonce(key: string, pendingCount: number): Promise<number>;\n}\n\n/**\n * Type guard to check if an atomic store supports optimized nonce assignment.\n *\n * @param store - The atomic store to check\n * @returns True if the store supports atomicAssignNonce\n *\n * @internal\n */\nexport function hasNonceSupport(\n store: IAtomicStore,\n): store is IAtomicStoreWithNonceSupport {\n return (\n \"atomicAssignNonce\" in store &&\n typeof (store as IAtomicStoreWithNonceSupport).atomicAssignNonce ===\n \"function\"\n );\n}\n"],"mappings":"AAqPO,SAAS,gBACd,OACuC;AACvC,SACE,uBAAuB,SACvB,OAAQ,MAAuC,sBAC7C;AAEN;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/blockchain.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../../src/types/blockchain.ts"],"sourcesContent":["/**\n * Defines core blockchain interaction types.\n *\n * @remarks\n * This module provides fundamental types for blockchain transactions,\n * including transaction requests, confirmation options, and results.\n * These types form the basis for all blockchain interactions in the SDK.\n *\n * @category Types\n * @module types/blockchain\n */\n\nimport type { Hash, Address } from \"viem\";\n\n/**\n * Represents a submitted blockchain transaction awaiting confirmation.\n *\n * @remarks\n * Returned immediately after transaction submission, before confirmation.\n * Use `waitForTransactionEvents` to wait for confirmation and retrieve events.\n *\n * @category Blockchain\n */\nexport interface TransactionRequest {\n /** Transaction hash */\n hash: Hash;\n /** Account that initiated the transaction */\n from: Address;\n /** Contract that was called */\n contractName: string;\n /** Function that was called */\n functionName: string;\n /** Function arguments (for debugging/logging) */\n args?: readonly unknown[];\n}\n\n/**\n * Configures transaction confirmation waiting behavior.\n *\n * @remarks\n * Controls how long and how often to check for transaction confirmation.\n * Adjust based on network congestion and application requirements.\n *\n * @category Blockchain\n */\nexport interface TransactionWaitOptions {\n /** Number of confirmations to wait for (default: 1) */\n confirmations?: number;\n /** Timeout in milliseconds (default: 30000) */\n timeout?: number;\n /** Polling interval in milliseconds (default: 4000) */\n pollingInterval?: number;\n}\n\n/**\n * Represents a confirmed blockchain transaction with metadata.\n *\n * @remarks\n * Contains essential transaction information after confirmation including\n * gas usage, block number, and function details. Extended by specific\n * result types with parsed events.\n *\n * @category Blockchain\n */\nexport interface TransactionResult {\n /** Transaction hash */\n transactionHash: Hash;\n /** Block number where transaction was included */\n blockNumber: bigint;\n /** Gas used by the transaction */\n gasUsed: bigint;\n /** Account that initiated the transaction */\n from: Address;\n /** Contract that was called */\n contractName: string;\n /** Function that was called */\n functionName: string;\n}\n\n/**\n * @remarks\n * Event typing strategy:\n * - Event arguments are dynamically typed based on contract mappings\n * - `parseTransaction` returns `expectedEvents` with typed args for mapped functions\n * - `allEvents` contains all parsed events from the transaction\n * - This approach lets the mapping file drive types rather than requiring\n * specific result interfaces per event type\n *\n * @internal\n */\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -1,10 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Defines core blockchain interaction types.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module provides fundamental types for blockchain transactions,
|
|
6
|
+
* including transaction requests, confirmation options, and results.
|
|
7
|
+
* These types form the basis for all blockchain interactions in the SDK.
|
|
8
|
+
*
|
|
9
|
+
* @category Types
|
|
10
|
+
* @module types/blockchain
|
|
3
11
|
*/
|
|
4
12
|
import type { Hash, Address } from "viem";
|
|
5
13
|
/**
|
|
6
|
-
* Represents a
|
|
7
|
-
*
|
|
14
|
+
* Represents a submitted blockchain transaction awaiting confirmation.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Returned immediately after transaction submission, before confirmation.
|
|
18
|
+
* Use `waitForTransactionEvents` to wait for confirmation and retrieve events.
|
|
19
|
+
*
|
|
20
|
+
* @category Blockchain
|
|
8
21
|
*/
|
|
9
22
|
export interface TransactionRequest {
|
|
10
23
|
/** Transaction hash */
|
|
@@ -19,7 +32,13 @@ export interface TransactionRequest {
|
|
|
19
32
|
args?: readonly unknown[];
|
|
20
33
|
}
|
|
21
34
|
/**
|
|
22
|
-
*
|
|
35
|
+
* Configures transaction confirmation waiting behavior.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* Controls how long and how often to check for transaction confirmation.
|
|
39
|
+
* Adjust based on network congestion and application requirements.
|
|
40
|
+
*
|
|
41
|
+
* @category Blockchain
|
|
23
42
|
*/
|
|
24
43
|
export interface TransactionWaitOptions {
|
|
25
44
|
/** Number of confirmations to wait for (default: 1) */
|
|
@@ -30,7 +49,14 @@ export interface TransactionWaitOptions {
|
|
|
30
49
|
pollingInterval?: number;
|
|
31
50
|
}
|
|
32
51
|
/**
|
|
33
|
-
*
|
|
52
|
+
* Represents a confirmed blockchain transaction with metadata.
|
|
53
|
+
*
|
|
54
|
+
* @remarks
|
|
55
|
+
* Contains essential transaction information after confirmation including
|
|
56
|
+
* gas usage, block number, and function details. Extended by specific
|
|
57
|
+
* result types with parsed events.
|
|
58
|
+
*
|
|
59
|
+
* @category Blockchain
|
|
34
60
|
*/
|
|
35
61
|
export interface TransactionResult {
|
|
36
62
|
/** Transaction hash */
|
|
@@ -47,11 +73,13 @@ export interface TransactionResult {
|
|
|
47
73
|
functionName: string;
|
|
48
74
|
}
|
|
49
75
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* Event typing strategy:
|
|
78
|
+
* - Event arguments are dynamically typed based on contract mappings
|
|
79
|
+
* - `parseTransaction` returns `expectedEvents` with typed args for mapped functions
|
|
80
|
+
* - `allEvents` contains all parsed events from the transaction
|
|
81
|
+
* - This approach lets the mapping file drive types rather than requiring
|
|
82
|
+
* specific result interfaces per event type
|
|
54
83
|
*
|
|
55
|
-
*
|
|
56
|
-
* letting the mapping file drive the types instead.
|
|
84
|
+
* @internal
|
|
57
85
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types/chains.ts"],"sourcesContent":["import type { Chain } from \"viem\";\n\n/**\n *
|
|
1
|
+
{"version":3,"sources":["../../src/types/chains.ts"],"sourcesContent":["import type { Chain } from \"viem\";\n\n/**\n * Represents the supported Vana network chain identifiers.\n *\n * @remarks\n * The Vana protocol operates on two primary networks:\n * - `14800`: Moksha testnet for development and testing\n * - `1480`: Vana mainnet for production deployment\n *\n * Use these chain IDs when configuring the SDK or checking network compatibility.\n *\n * @category Blockchain\n * @see {@link https://docs.vana.org/docs/networks | Network Documentation}\n */\nexport type VanaChainId = 14800 | 1480;\n\n/**\n * Extends viem's Chain type with Vana-specific chain constraints.\n *\n * @remarks\n * Ensures type safety for Vana-specific chains by restricting the chain ID\n * to supported networks. This type provides full viem Chain compatibility\n * while guaranteeing the chain is a valid Vana network.\n *\n * @category Blockchain\n */\nexport type VanaChain = Chain & {\n id: VanaChainId;\n};\n\n/**\n * Maps Vana chain IDs to their complete chain configurations.\n *\n * @remarks\n * Provides type-safe access to chain configurations indexed by chain ID.\n * Use this for dynamic chain selection based on runtime chain ID values.\n *\n * @category Blockchain\n * @example\n * ```typescript\n * const configs: ChainConfig = {\n * 14800: mokshaTestnet,\n * 1480: vanaMainnet\n * };\n * const chain = configs[chainId];\n * ```\n */\nexport type ChainConfig = {\n [K in VanaChainId]: VanaChain;\n};\n\n/**\n * Validates whether a chain ID represents a supported Vana network.\n *\n * @remarks\n * Type guard for runtime validation of chain IDs from external sources.\n * Use when accepting user input or processing network configurations.\n *\n * @param chainId - The chain ID to validate\n * @returns `true` if the chain ID is a supported Vana network, `false` otherwise\n *\n * @example\n * ```typescript\n * const chainId = parseInt(process.env.CHAIN_ID);\n *\n * if (!isVanaChainId(chainId)) {\n * throw new Error(`Unsupported chain ID: ${chainId}`);\n * }\n *\n * // TypeScript now knows chainId is VanaChainId\n * const config = getChainConfig(chainId);\n * ```\n *\n * @category Blockchain\n */\nexport function isVanaChainId(chainId: number): chainId is VanaChainId {\n return chainId === 14800 || chainId === 1480;\n}\n\n/**\n * Validates whether a Chain object represents a supported Vana network.\n *\n * @remarks\n * Type guard for validating viem Chain objects as Vana chains.\n * Ensures both type safety and runtime validation for chain compatibility.\n *\n * @param chain - The chain object to validate\n * @returns `true` if the chain is a supported Vana network, `false` otherwise\n *\n * @example\n * ```typescript\n * import { mainnet, mokshaTestnet } from 'viem/chains';\n *\n * if (isVanaChain(chain)) {\n * // TypeScript knows this is a VanaChain\n * console.log(`Connected to Vana network: ${chain.id}`);\n * } else {\n * console.error('Please connect to a Vana network');\n * }\n * ```\n *\n * @category Blockchain\n */\nexport function isVanaChain(chain: Chain): chain is VanaChain {\n return isVanaChainId(chain.id);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4EO,SAAS,cAAc,SAAyC;AACrE,SAAO,YAAY,SAAS,YAAY;AAC1C;AA0BO,SAAS,YAAY,OAAkC;AAC5D,SAAO,cAAc,MAAM,EAAE;AAC/B;","names":[]}
|