@opendatalabs/vana-sdk 0.1.0-alpha.f2de4f7 → 0.1.0-alpha.f35bb9c

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.
Files changed (165) hide show
  1. package/dist/browser.cjs.map +1 -1
  2. package/dist/browser.d.ts +33 -1
  3. package/dist/browser.js.map +1 -1
  4. package/dist/chains/index.cjs.map +1 -1
  5. package/dist/chains/index.d.ts +30 -1
  6. package/dist/chains/index.js.map +1 -1
  7. package/dist/config/chains.cjs.map +1 -1
  8. package/dist/config/chains.d.ts +99 -0
  9. package/dist/config/chains.js.map +1 -1
  10. package/dist/contracts/contractController.cjs.map +1 -1
  11. package/dist/contracts/contractController.d.ts +66 -10
  12. package/dist/contracts/contractController.js.map +1 -1
  13. package/dist/controllers/data.cjs +173 -141
  14. package/dist/controllers/data.cjs.map +1 -1
  15. package/dist/controllers/data.d.ts +213 -175
  16. package/dist/controllers/data.js +173 -141
  17. package/dist/controllers/data.js.map +1 -1
  18. package/dist/controllers/permissions.cjs +185 -191
  19. package/dist/controllers/permissions.cjs.map +1 -1
  20. package/dist/controllers/permissions.d.ts +29 -73
  21. package/dist/controllers/permissions.js +185 -191
  22. package/dist/controllers/permissions.js.map +1 -1
  23. package/dist/controllers/protocol.cjs.map +1 -1
  24. package/dist/controllers/protocol.d.ts +27 -28
  25. package/dist/controllers/protocol.js.map +1 -1
  26. package/dist/controllers/schemas.cjs +23 -21
  27. package/dist/controllers/schemas.cjs.map +1 -1
  28. package/dist/controllers/schemas.d.ts +47 -40
  29. package/dist/controllers/schemas.js +23 -21
  30. package/dist/controllers/schemas.js.map +1 -1
  31. package/dist/controllers/server.cjs +17 -15
  32. package/dist/controllers/server.cjs.map +1 -1
  33. package/dist/controllers/server.d.ts +46 -38
  34. package/dist/controllers/server.js +17 -15
  35. package/dist/controllers/server.js.map +1 -1
  36. package/dist/core/apiClient.cjs +53 -3
  37. package/dist/core/apiClient.cjs.map +1 -1
  38. package/dist/core/apiClient.d.ts +132 -7
  39. package/dist/core/apiClient.js +53 -3
  40. package/dist/core/apiClient.js.map +1 -1
  41. package/dist/core/generics.cjs +30 -3
  42. package/dist/core/generics.cjs.map +1 -1
  43. package/dist/core/generics.d.ts +95 -6
  44. package/dist/core/generics.js +30 -3
  45. package/dist/core/generics.js.map +1 -1
  46. package/dist/core.cjs +29 -12
  47. package/dist/core.cjs.map +1 -1
  48. package/dist/core.d.ts +2 -1
  49. package/dist/core.js +29 -12
  50. package/dist/core.js.map +1 -1
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/index.node.cjs +3 -3
  54. package/dist/index.node.cjs.map +1 -1
  55. package/dist/index.node.d.ts +8 -9
  56. package/dist/index.node.js +2 -2
  57. package/dist/index.node.js.map +1 -1
  58. package/dist/node.cjs.map +1 -1
  59. package/dist/node.d.ts +39 -1
  60. package/dist/node.js.map +1 -1
  61. package/dist/platform/browser.cjs +160 -2
  62. package/dist/platform/browser.cjs.map +1 -1
  63. package/dist/platform/browser.d.ts +232 -12
  64. package/dist/platform/browser.js +160 -2
  65. package/dist/platform/browser.js.map +1 -1
  66. package/dist/platform/interface.cjs.map +1 -1
  67. package/dist/platform/interface.d.ts +283 -90
  68. package/dist/platform/node.cjs +163 -2
  69. package/dist/platform/node.cjs.map +1 -1
  70. package/dist/platform/node.d.ts +69 -6
  71. package/dist/platform/node.js +163 -2
  72. package/dist/platform/node.js.map +1 -1
  73. package/dist/server/relayerHandler.cjs +214 -0
  74. package/dist/server/relayerHandler.cjs.map +1 -0
  75. package/dist/server/relayerHandler.d.ts +36 -0
  76. package/dist/server/relayerHandler.js +190 -0
  77. package/dist/server/relayerHandler.js.map +1 -0
  78. package/dist/storage/manager.cjs +108 -25
  79. package/dist/storage/manager.cjs.map +1 -1
  80. package/dist/storage/manager.d.ts +119 -25
  81. package/dist/storage/manager.js +108 -25
  82. package/dist/storage/manager.js.map +1 -1
  83. package/dist/storage/providers/callback-storage.cjs +86 -15
  84. package/dist/storage/providers/callback-storage.cjs.map +1 -1
  85. package/dist/storage/providers/callback-storage.d.ts +109 -20
  86. package/dist/storage/providers/callback-storage.js +86 -15
  87. package/dist/storage/providers/callback-storage.js.map +1 -1
  88. package/dist/storage/providers/pinata.cjs.map +1 -1
  89. package/dist/storage/providers/pinata.d.ts +12 -14
  90. package/dist/storage/providers/pinata.js.map +1 -1
  91. package/dist/tests/factories/mockFactory.d.ts +2 -2
  92. package/dist/tests/relayer-integration.test.d.ts +1 -0
  93. package/dist/tests/relayer-unified.test.d.ts +1 -0
  94. package/dist/tests/server-relayer-handler.test.d.ts +1 -0
  95. package/dist/types/blockchain.cjs.map +1 -1
  96. package/dist/types/blockchain.d.ts +39 -11
  97. package/dist/types/chains.cjs.map +1 -1
  98. package/dist/types/chains.d.ts +74 -7
  99. package/dist/types/chains.js.map +1 -1
  100. package/dist/types/config.cjs.map +1 -1
  101. package/dist/types/config.d.ts +46 -191
  102. package/dist/types/config.js.map +1 -1
  103. package/dist/types/contracts.cjs.map +1 -1
  104. package/dist/types/contracts.d.ts +71 -7
  105. package/dist/types/controller-context.cjs.map +1 -1
  106. package/dist/types/controller-context.d.ts +3 -2
  107. package/dist/types/data.cjs.map +1 -1
  108. package/dist/types/data.d.ts +4 -6
  109. package/dist/types/generics.cjs.map +1 -1
  110. package/dist/types/generics.d.ts +80 -9
  111. package/dist/types/index.cjs.map +1 -1
  112. package/dist/types/index.d.ts +27 -2
  113. package/dist/types/index.js.map +1 -1
  114. package/dist/types/operations.cjs.map +1 -1
  115. package/dist/types/operations.d.ts +132 -15
  116. package/dist/types/operations.js.map +1 -1
  117. package/dist/types/permissions.cjs.map +1 -1
  118. package/dist/types/permissions.d.ts +15 -20
  119. package/dist/types/personal.cjs.map +1 -1
  120. package/dist/types/personal.d.ts +131 -14
  121. package/dist/types/relayer.cjs.map +1 -1
  122. package/dist/types/relayer.d.ts +262 -35
  123. package/dist/types/storage.cjs.map +1 -1
  124. package/dist/types/storage.d.ts +9 -21
  125. package/dist/types/storage.js.map +1 -1
  126. package/dist/utils/grantFiles.cjs.map +1 -1
  127. package/dist/utils/grantFiles.d.ts +10 -20
  128. package/dist/utils/grantFiles.js.map +1 -1
  129. package/dist/utils/grantValidation.cjs.map +1 -1
  130. package/dist/utils/grantValidation.d.ts +95 -16
  131. package/dist/utils/grantValidation.js.map +1 -1
  132. package/dist/utils/grants.cjs.map +1 -1
  133. package/dist/utils/grants.d.ts +93 -12
  134. package/dist/utils/grants.js.map +1 -1
  135. package/dist/utils/lazy-import.cjs.map +1 -1
  136. package/dist/utils/lazy-import.d.ts +32 -7
  137. package/dist/utils/lazy-import.js.map +1 -1
  138. package/dist/utils/signatureCache.cjs +8 -2
  139. package/dist/utils/signatureCache.cjs.map +1 -1
  140. package/dist/utils/signatureCache.d.ts +49 -8
  141. package/dist/utils/signatureCache.js +8 -2
  142. package/dist/utils/signatureCache.js.map +1 -1
  143. package/dist/utils/transactionHelpers.cjs.map +1 -1
  144. package/dist/utils/transactionHelpers.d.ts +12 -12
  145. package/dist/utils/transactionHelpers.js.map +1 -1
  146. package/dist/utils/typedDataConverter.cjs.map +1 -1
  147. package/dist/utils/typedDataConverter.d.ts +39 -3
  148. package/dist/utils/typedDataConverter.js.map +1 -1
  149. package/dist/utils/urlResolver.cjs +7 -0
  150. package/dist/utils/urlResolver.cjs.map +1 -1
  151. package/dist/utils/urlResolver.d.ts +22 -4
  152. package/dist/utils/urlResolver.js +7 -0
  153. package/dist/utils/urlResolver.js.map +1 -1
  154. package/dist/utils/wallet.cjs +2 -1
  155. package/dist/utils/wallet.cjs.map +1 -1
  156. package/dist/utils/wallet.d.ts +78 -16
  157. package/dist/utils/wallet.js +2 -1
  158. package/dist/utils/wallet.js.map +1 -1
  159. package/package.json +1 -1
  160. package/dist/server/handler.cjs +0 -101
  161. package/dist/server/handler.cjs.map +0 -1
  162. package/dist/server/handler.d.ts +0 -87
  163. package/dist/server/handler.js +0 -77
  164. package/dist/server/handler.js.map +0 -1
  165. /package/dist/tests/{server-handler.test.d.ts → permissions-revoke-relayer.test.d.ts} +0 -0
@@ -0,0 +1,36 @@
1
+ import type { VanaInstance } from "../index.node";
2
+ import type { UnifiedRelayerRequest, UnifiedRelayerResponse } from "../types/relayer";
3
+ /**
4
+ * Universal handler for all relayer operations.
5
+ *
6
+ * This function processes both EIP-712 signed operations and direct operations,
7
+ * automatically routing to the appropriate SDK methods.
8
+ *
9
+ * @param sdk - Initialized Vana SDK instance
10
+ * @param request - The unified relayer request
11
+ * @returns Promise resolving to operation-specific response
12
+ *
13
+ * @category Server
14
+ * @example
15
+ * ```typescript
16
+ * // In your server endpoint (Next.js example):
17
+ * import { handleRelayerOperation } from '@opendatalabs/vana-sdk/node';
18
+ *
19
+ * export async function POST(request: NextRequest) {
20
+ * try {
21
+ * const body = await request.json();
22
+ * const vana = getServerVanaInstance(); // Your server SDK instance
23
+ *
24
+ * const result = await handleRelayerOperation(vana, body);
25
+ *
26
+ * return NextResponse.json(result);
27
+ * } catch (error) {
28
+ * return NextResponse.json(
29
+ * { error: error.message },
30
+ * { status: 500 }
31
+ * );
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function handleRelayerOperation(sdk: VanaInstance, request: UnifiedRelayerRequest): Promise<UnifiedRelayerResponse>;
@@ -0,0 +1,190 @@
1
+ import { SignatureError } from "../errors";
2
+ import { recoverTypedDataAddress, getAddress } from "viem";
3
+ async function handleRelayerOperation(sdk, request) {
4
+ if (request.type === "signed") {
5
+ return handleSignedOperation(sdk, request);
6
+ }
7
+ return handleDirectOperation(sdk, request);
8
+ }
9
+ async function handleSignedOperation(sdk, request) {
10
+ const { typedData, signature, expectedUserAddress } = request;
11
+ let recoveredAddress;
12
+ try {
13
+ recoveredAddress = await recoverTypedDataAddress({
14
+ domain: {
15
+ ...typedData.domain,
16
+ chainId: typedData.domain.chainId ? BigInt(typedData.domain.chainId) : void 0
17
+ },
18
+ types: typedData.types,
19
+ primaryType: typedData.primaryType,
20
+ message: typedData.message,
21
+ signature
22
+ });
23
+ } catch (error) {
24
+ throw new SignatureError(
25
+ `Signature verification failed: ${error instanceof Error ? error.message : "Unknown error"}`
26
+ );
27
+ }
28
+ if (expectedUserAddress) {
29
+ const normalizedExpected = getAddress(expectedUserAddress);
30
+ const normalizedSigner = getAddress(recoveredAddress);
31
+ if (normalizedSigner !== normalizedExpected) {
32
+ throw new SignatureError(
33
+ `Security verification failed: Recovered signer address (${normalizedSigner}) does not match expected user address (${normalizedExpected})`
34
+ );
35
+ }
36
+ }
37
+ const result = await routeSignedOperation(sdk, typedData, signature);
38
+ return {
39
+ type: "signed",
40
+ hash: result.hash
41
+ };
42
+ }
43
+ async function routeSignedOperation(sdk, typedData, signature) {
44
+ const primaryType = typedData.primaryType;
45
+ switch (primaryType) {
46
+ case "Permission":
47
+ return sdk.permissions.submitSignedGrant(
48
+ {
49
+ ...typedData,
50
+ primaryType: "Permission"
51
+ },
52
+ signature
53
+ );
54
+ case "RevokePermission":
55
+ return sdk.permissions.submitSignedRevoke(
56
+ {
57
+ ...typedData,
58
+ primaryType: "RevokePermission"
59
+ },
60
+ signature
61
+ );
62
+ case "TrustServer":
63
+ return sdk.permissions.submitSignedTrustServer(
64
+ {
65
+ ...typedData,
66
+ primaryType: "TrustServer"
67
+ },
68
+ signature
69
+ );
70
+ case "AddServer":
71
+ return sdk.permissions.submitSignedAddAndTrustServer(
72
+ {
73
+ ...typedData,
74
+ primaryType: "AddServer"
75
+ },
76
+ signature
77
+ );
78
+ case "UntrustServer":
79
+ return sdk.permissions.submitSignedUntrustServer(
80
+ {
81
+ ...typedData,
82
+ primaryType: "UntrustServer"
83
+ },
84
+ signature
85
+ );
86
+ case "ServerFilesAndPermission":
87
+ return sdk.permissions.submitSignedAddServerFilesAndPermissions(
88
+ {
89
+ ...typedData,
90
+ primaryType: "ServerFilesAndPermission"
91
+ },
92
+ signature
93
+ );
94
+ // TODO: RegisterGrantee with signature is not supported until
95
+ // DataPortabilityGrantees contract adds registerGranteeWithSignature function
96
+ // case "RegisterGrantee":
97
+ // return sdk.permissions.submitSignedRegisterGrantee(...);
98
+ default:
99
+ throw new Error(`Unsupported operation type: ${typedData.primaryType}`);
100
+ }
101
+ }
102
+ async function handleDirectOperation(sdk, request) {
103
+ switch (request.operation) {
104
+ case "submitFileAddition": {
105
+ const { url, userAddress } = request.params;
106
+ const result = await sdk.data.addFileWithPermissions(
107
+ url,
108
+ userAddress,
109
+ []
110
+ // No permissions
111
+ );
112
+ const eventData = await sdk.waitForTransactionEvents(result);
113
+ const fileId = eventData.expectedEvents?.FileAdded?.fileId;
114
+ if (!fileId) {
115
+ throw new Error("Failed to get fileId from transaction events");
116
+ }
117
+ return {
118
+ type: "direct",
119
+ result: {
120
+ fileId: Number(fileId),
121
+ transactionHash: result.hash
122
+ }
123
+ };
124
+ }
125
+ case "submitFileAdditionWithPermissions": {
126
+ const { url, userAddress, permissions } = request.params;
127
+ const result = await sdk.data.addFileWithPermissions(
128
+ url,
129
+ userAddress,
130
+ permissions
131
+ );
132
+ const eventData = await sdk.waitForTransactionEvents(result);
133
+ const fileId = eventData.expectedEvents?.FileAdded?.fileId;
134
+ if (!fileId) {
135
+ throw new Error("Failed to get fileId from transaction events");
136
+ }
137
+ return {
138
+ type: "direct",
139
+ result: {
140
+ fileId: Number(fileId),
141
+ transactionHash: result.hash
142
+ }
143
+ };
144
+ }
145
+ case "submitFileAdditionComplete": {
146
+ const { url, userAddress, permissions, schemaId, ownerAddress } = request.params;
147
+ const result = await sdk.data.addFileWithEncryptedPermissionsAndSchema(
148
+ url,
149
+ ownerAddress ?? userAddress,
150
+ permissions,
151
+ // Already in correct format with encrypted 'key' field
152
+ schemaId
153
+ );
154
+ const eventData = await sdk.waitForTransactionEvents(result);
155
+ const fileId = eventData.expectedEvents?.FileAdded?.fileId;
156
+ if (!fileId) {
157
+ throw new Error("Failed to get fileId from transaction events");
158
+ }
159
+ return {
160
+ type: "direct",
161
+ result: {
162
+ fileId: Number(fileId),
163
+ transactionHash: result.hash
164
+ }
165
+ };
166
+ }
167
+ case "storeGrantFile": {
168
+ const grantFile = request.params;
169
+ const blob = new Blob([JSON.stringify(grantFile)], {
170
+ type: "application/json"
171
+ });
172
+ const result = await sdk.data.upload({
173
+ content: blob,
174
+ filename: `grant-${Date.now()}.json`
175
+ });
176
+ return {
177
+ type: "direct",
178
+ result: { url: result.url }
179
+ };
180
+ }
181
+ default: {
182
+ const exhaustiveCheck = request;
183
+ return exhaustiveCheck;
184
+ }
185
+ }
186
+ }
187
+ export {
188
+ handleRelayerOperation
189
+ };
190
+ //# sourceMappingURL=relayerHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/relayerHandler.ts"],"sourcesContent":["import type { VanaInstance } from \"../index.node\";\nimport type {\n UnifiedRelayerRequest,\n UnifiedRelayerResponse,\n SignedRelayerRequest,\n DirectRelayerRequest,\n} from \"../types/relayer\";\nimport type {\n GenericTypedData,\n PermissionGrantTypedData,\n RevokePermissionTypedData,\n TrustServerTypedData,\n AddAndTrustServerTypedData,\n ServerFilesAndPermissionTypedData,\n TypedDataPrimaryType,\n} from \"../types/permissions\";\nimport { SignatureError } from \"../errors\";\nimport { recoverTypedDataAddress, getAddress, type Hash } from \"viem\";\n\n/**\n * Universal handler for all relayer operations.\n *\n * This function processes both EIP-712 signed operations and direct operations,\n * automatically routing to the appropriate SDK methods.\n *\n * @param sdk - Initialized Vana SDK instance\n * @param request - The unified relayer request\n * @returns Promise resolving to operation-specific response\n *\n * @category Server\n * @example\n * ```typescript\n * // In your server endpoint (Next.js example):\n * import { handleRelayerOperation } from '@opendatalabs/vana-sdk/node';\n *\n * export async function POST(request: NextRequest) {\n * try {\n * const body = await request.json();\n * const vana = getServerVanaInstance(); // Your server SDK instance\n *\n * const result = await handleRelayerOperation(vana, body);\n *\n * return NextResponse.json(result);\n * } catch (error) {\n * return NextResponse.json(\n * { error: error.message },\n * { status: 500 }\n * );\n * }\n * }\n * ```\n */\nexport async function handleRelayerOperation(\n sdk: VanaInstance,\n request: UnifiedRelayerRequest,\n): Promise<UnifiedRelayerResponse> {\n // Handle signed operations (EIP-712)\n if (request.type === \"signed\") {\n return handleSignedOperation(sdk, request);\n }\n\n // Handle direct operations (non-signed)\n return handleDirectOperation(sdk, request);\n}\n\n/**\n * Handle EIP-712 signed operations with full type safety\n */\nasync function handleSignedOperation(\n sdk: VanaInstance,\n request: SignedRelayerRequest,\n): Promise<UnifiedRelayerResponse> {\n const { typedData, signature, expectedUserAddress } = request;\n\n // Step 1: Verify the signature (security check)\n let recoveredAddress: `0x${string}`;\n try {\n recoveredAddress = await recoverTypedDataAddress({\n domain: {\n ...typedData.domain,\n chainId: typedData.domain.chainId\n ? BigInt(typedData.domain.chainId)\n : undefined,\n },\n types: typedData.types,\n primaryType: typedData.primaryType,\n message: typedData.message as unknown as Record<string, unknown>,\n signature,\n });\n } catch (error) {\n // Handle signature verification errors\n throw new SignatureError(\n `Signature verification failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n\n // Optional security check: Verify the signer matches expected address\n if (expectedUserAddress) {\n const normalizedExpected = getAddress(expectedUserAddress);\n const normalizedSigner = getAddress(recoveredAddress);\n\n if (normalizedSigner !== normalizedExpected) {\n throw new SignatureError(\n `Security verification failed: Recovered signer address (${normalizedSigner}) does not match expected user address (${normalizedExpected})`,\n );\n }\n }\n\n // Step 2: Route to appropriate SDK method based on primaryType\n // Using proper type narrowing instead of unsafe casts\n const result = await routeSignedOperation(sdk, typedData, signature);\n\n // Return the transaction hash with type\n return {\n type: \"signed\",\n hash: result.hash,\n };\n}\n\n/**\n * Route signed operations to the appropriate SDK method with type safety\n */\nasync function routeSignedOperation(\n sdk: VanaInstance,\n typedData: GenericTypedData,\n signature: Hash,\n) {\n const primaryType = typedData.primaryType as TypedDataPrimaryType;\n\n // Type-safe routing based on primaryType\n switch (primaryType) {\n case \"Permission\":\n // TypeScript knows this is a Permission operation\n return sdk.permissions.submitSignedGrant(\n {\n ...typedData,\n primaryType: \"Permission\",\n } as PermissionGrantTypedData,\n signature,\n );\n\n case \"RevokePermission\":\n return sdk.permissions.submitSignedRevoke(\n {\n ...typedData,\n primaryType: \"RevokePermission\",\n } as RevokePermissionTypedData,\n signature,\n );\n\n case \"TrustServer\":\n return sdk.permissions.submitSignedTrustServer(\n {\n ...typedData,\n primaryType: \"TrustServer\",\n } as TrustServerTypedData,\n signature,\n );\n\n case \"AddServer\":\n return sdk.permissions.submitSignedAddAndTrustServer(\n {\n ...typedData,\n primaryType: \"AddServer\",\n } as AddAndTrustServerTypedData,\n signature,\n );\n\n case \"UntrustServer\":\n return sdk.permissions.submitSignedUntrustServer(\n {\n ...typedData,\n primaryType: \"UntrustServer\",\n } as GenericTypedData,\n signature,\n );\n\n case \"ServerFilesAndPermission\":\n return sdk.permissions.submitSignedAddServerFilesAndPermissions(\n {\n ...typedData,\n primaryType: \"ServerFilesAndPermission\",\n } as ServerFilesAndPermissionTypedData,\n signature,\n );\n\n // TODO: RegisterGrantee with signature is not supported until\n // DataPortabilityGrantees contract adds registerGranteeWithSignature function\n // case \"RegisterGrantee\":\n // return sdk.permissions.submitSignedRegisterGrantee(...);\n\n default:\n throw new Error(`Unsupported operation type: ${typedData.primaryType}`);\n }\n}\n\n/**\n * Handle direct (non-signed) operations\n */\nasync function handleDirectOperation(\n sdk: VanaInstance,\n request: DirectRelayerRequest,\n): Promise<UnifiedRelayerResponse> {\n switch (request.operation) {\n case \"submitFileAddition\": {\n const { url, userAddress } = request.params;\n\n // Use SDK to add file with no permissions\n const result = await sdk.data.addFileWithPermissions(\n url,\n userAddress,\n [], // No permissions\n );\n\n // Wait for transaction events to get fileId\n const eventData = await sdk.waitForTransactionEvents(result);\n const fileId = eventData.expectedEvents?.FileAdded?.fileId;\n\n if (!fileId) {\n throw new Error(\"Failed to get fileId from transaction events\");\n }\n\n return {\n type: \"direct\",\n result: {\n fileId: Number(fileId),\n transactionHash: result.hash,\n },\n };\n }\n\n case \"submitFileAdditionWithPermissions\": {\n const { url, userAddress, permissions } = request.params;\n\n // Use SDK to add file with permissions\n const result = await sdk.data.addFileWithPermissions(\n url,\n userAddress,\n permissions,\n );\n\n // Wait for transaction events to get fileId\n const eventData = await sdk.waitForTransactionEvents(result);\n const fileId = eventData.expectedEvents?.FileAdded?.fileId;\n\n if (!fileId) {\n throw new Error(\"Failed to get fileId from transaction events\");\n }\n\n return {\n type: \"direct\",\n result: {\n fileId: Number(fileId),\n transactionHash: result.hash,\n },\n };\n }\n\n case \"submitFileAdditionComplete\": {\n const { url, userAddress, permissions, schemaId, ownerAddress } =\n request.params;\n\n // Permissions are already encrypted, use the appropriate method\n // No mapping needed - permissions already have { account, key } format\n const result = await sdk.data.addFileWithEncryptedPermissionsAndSchema(\n url,\n ownerAddress ?? userAddress,\n permissions, // Already in correct format with encrypted 'key' field\n schemaId,\n );\n\n // Wait for transaction events to get fileId\n const eventData = await sdk.waitForTransactionEvents(result);\n const fileId = eventData.expectedEvents?.FileAdded?.fileId;\n\n if (!fileId) {\n throw new Error(\"Failed to get fileId from transaction events\");\n }\n\n return {\n type: \"direct\",\n result: {\n fileId: Number(fileId),\n transactionHash: result.hash,\n },\n };\n }\n\n case \"storeGrantFile\": {\n const grantFile = request.params;\n\n // Store grant file using SDK's data controller\n // Convert grant file to blob for storage\n const blob = new Blob([JSON.stringify(grantFile)], {\n type: \"application/json\",\n });\n\n // Upload using the data controller\n const result = await sdk.data.upload({\n content: blob,\n filename: `grant-${Date.now()}.json`,\n });\n\n return {\n type: \"direct\",\n result: { url: result.url },\n };\n }\n\n default: {\n // TypeScript exhaustiveness check - ensures all cases are handled at compile time\n const exhaustiveCheck: never = request;\n // Return exhaustiveCheck to satisfy TypeScript while throwing an error\n // This should never be reached if all cases are handled\n return exhaustiveCheck;\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -51,10 +51,20 @@ class StorageManager {
51
51
  }
52
52
  }
53
53
  /**
54
- * Get a registered storage provider
54
+ * Retrieves a registered storage provider.
55
55
  *
56
- * @param name - Provider identifier, uses default if not specified
57
- * @returns Storage provider instance
56
+ * @param name - Provider identifier.
57
+ * If not specified, returns the default provider.
58
+ * @returns The requested storage provider instance
59
+ *
60
+ * @throws {StorageError} With code 'NO_PROVIDER' if no provider available
61
+ * @throws {StorageError} With code 'PROVIDER_NOT_FOUND' if named provider doesn't exist
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const provider = storage.getProvider('pinata');
66
+ * const config = provider.getConfig();
67
+ * ```
58
68
  */
59
69
  getProvider(name) {
60
70
  const providerName = name ?? this.defaultProvider;
@@ -76,25 +86,49 @@ class StorageManager {
76
86
  return provider;
77
87
  }
78
88
  /**
79
- * List all registered providers
89
+ * Lists all registered provider names.
90
+ *
91
+ * @returns Array of registered provider identifiers
80
92
  *
81
- * @returns Array of provider names
93
+ * @example
94
+ * ```typescript
95
+ * const providers = storage.listProviders();
96
+ * console.log('Available providers:', providers);
97
+ * // Output: ['ipfs', 'pinata', 'google-drive']
98
+ * ```
82
99
  */
83
100
  listProviders() {
84
101
  return Array.from(this.providers.keys());
85
102
  }
86
103
  /**
87
- * Get the default provider name
104
+ * Gets the current default provider name.
88
105
  *
89
- * @returns Default provider name or null
106
+ * @returns Default provider identifier or null if none set
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const defaultName = storage.getDefaultProvider();
111
+ * if (defaultName) {
112
+ * console.log(`Using ${defaultName} by default`);
113
+ * }
114
+ * ```
90
115
  */
91
116
  getDefaultProvider() {
92
117
  return this.defaultProvider;
93
118
  }
94
119
  /**
95
- * Set the default provider
120
+ * Sets the default storage provider.
121
+ *
122
+ * @param name - Provider identifier to set as default.
123
+ * Must be a registered provider name.
96
124
  *
97
- * @param name - Provider identifier
125
+ * @throws {StorageError} With code 'PROVIDER_NOT_FOUND' if provider not registered
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * storage.setDefaultProvider('pinata');
130
+ * // Now all operations without provider name will use Pinata
131
+ * ```
98
132
  */
99
133
  setDefaultProvider(name) {
100
134
  if (!this.providers.has(name)) {
@@ -133,50 +167,99 @@ class StorageManager {
133
167
  return provider.upload(file, filename);
134
168
  }
135
169
  /**
136
- * Download a file using the specified or default provider
170
+ * Downloads a file from storage.
171
+ *
172
+ * @param url - The storage URL to download from.
173
+ * Format depends on the storage provider.
174
+ * @param providerName - Optional provider identifier.
175
+ * Uses default provider if not specified.
176
+ * @returns The downloaded file as a Blob
177
+ *
178
+ * @throws {StorageError} If download fails or provider unavailable
137
179
  *
138
- * @param url - The storage URL
139
- * @param providerName - Optional provider to use
140
- * @returns Promise with file blob
180
+ * @example
181
+ * ```typescript
182
+ * const blob = await storage.download('ipfs://QmXxx...');
183
+ * const text = await blob.text();
184
+ * ```
141
185
  */
142
186
  async download(url, providerName) {
143
187
  const provider = this.getProvider(providerName);
144
188
  return provider.download(url);
145
189
  }
146
190
  /**
147
- * List files using the specified or default provider
191
+ * Lists files in storage.
192
+ *
193
+ * @param options - Optional filtering and pagination.
194
+ * @param options.namePattern - Pattern to filter files.
195
+ * @param options.limit - Maximum files to return.
196
+ * @param providerName - Optional provider identifier.
197
+ * Uses default provider if not specified.
198
+ * @returns Array of file metadata
199
+ *
200
+ * @throws {StorageError} If listing fails or not supported by provider
148
201
  *
149
- * @param options - Optional filtering and pagination
150
- * @param providerName - Optional provider to use
151
- * @returns Promise with file list
202
+ * @example
203
+ * ```typescript
204
+ * const files = await storage.list(
205
+ * { namePattern: '*.json', limit: 10 },
206
+ * 'google-drive'
207
+ * );
208
+ * ```
152
209
  */
153
210
  async list(options, providerName) {
154
211
  const provider = this.getProvider(providerName);
155
212
  return provider.list(options);
156
213
  }
157
214
  /**
158
- * Delete a file using the specified or default provider
215
+ * Deletes a file from storage.
159
216
  *
160
- * @param url - The storage URL
161
- * @param providerName - Optional provider to use
162
- * @returns Promise with success status
217
+ * @param url - The storage URL to delete.
218
+ * Must be a valid URL for the provider.
219
+ * @param providerName - Optional provider identifier.
220
+ * Uses default provider if not specified.
221
+ * @returns True if deletion succeeded, false otherwise
222
+ *
223
+ * @throws {StorageError} If deletion fails or not supported by provider
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * const success = await storage.delete('ipfs://QmXxx...');
228
+ * if (success) {
229
+ * console.log('File deleted successfully');
230
+ * }
231
+ * ```
163
232
  */
164
233
  async delete(url, providerName) {
165
234
  const provider = this.getProvider(providerName);
166
235
  return provider.delete(url);
167
236
  }
168
237
  /**
169
- * Get list of registered storage provider names
238
+ * Gets all registered storage provider names.
170
239
  *
171
- * @returns Array of provider names
240
+ * @returns Array of provider identifiers
241
+ *
242
+ * @deprecated Use `listProviders()` instead
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * const providers = storage.getStorageProviders();
247
+ * ```
172
248
  */
173
249
  getStorageProviders() {
174
250
  return Array.from(this.providers.keys());
175
251
  }
176
252
  /**
177
- * Get the default storage provider name
253
+ * Gets the default storage provider name.
178
254
  *
179
- * @returns Default provider name or undefined
255
+ * @returns Default provider identifier or undefined if none set
256
+ *
257
+ * @deprecated Use `getDefaultProvider()` instead
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const defaultProvider = storage.getDefaultStorageProvider();
262
+ * ```
180
263
  */
181
264
  getDefaultStorageProvider() {
182
265
  return this.defaultProvider ?? void 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/storage/manager.ts"],"sourcesContent":["import type {\n StorageProvider,\n StorageUploadResult,\n StorageFile,\n StorageListOptions,\n} from \"../types/storage\";\nimport { StorageError } from \"../types/storage\";\n\n/**\n * Manages multiple storage providers with a unified interface for file operations.\n *\n * @remarks\n * The StorageManager provides a consistent API for uploading, downloading, and managing\n * files across different storage backends including IPFS, Pinata, Google Drive, and\n * server-managed storage. It handles provider registration, default provider selection,\n * and automatic fallback scenarios for robust file operations.\n *\n * Used internally by DataController for encrypted file storage, but can also be used\n * directly for custom storage workflows. Each provider implements the `StorageProvider`\n * interface to ensure consistent behavior across different storage backends.\n *\n * The manager supports provider-specific configurations and features while maintaining\n * a uniform API surface for applications.\n * @example\n * ```typescript\n * import { StorageManager, IPFSStorage, PinataStorage } from '@opendatalabs/vana-sdk';\n *\n * const storage = new StorageManager();\n *\n * // Register multiple providers\n * storage.register('ipfs', new IPFSStorage({\n * apiEndpoint: 'https://api.pinata.cloud/pinning/pinFileToIPFS'\n * }), true);\n * storage.register('pinata', new PinataStorage({\n * jwt: 'your-pinata-jwt-token'\n * }));\n *\n * // Upload to default provider\n * const result = await storage.upload(fileBlob, 'myfile.json');\n *\n * // Upload to specific provider\n * const result2 = await storage.upload(fileBlob, 'myfile.json', 'pinata');\n * ```\n * @category Storage\n * @see {@link https://docs.vana.com/developer/vana-sdk-documentation/core-modules/storage-providers | Storage Providers Guide} for configuration details\n */\nexport class StorageManager {\n private providers: Map<string, StorageProvider> = new Map();\n private defaultProvider: string | null = null;\n\n /**\n * Registers a storage provider with the manager.\n *\n * @remarks\n * This method adds a new storage provider to the manager's registry and optionally\n * sets it as the default provider for subsequent operations. If no default provider\n * is currently set, the first registered provider automatically becomes the default.\n * @param name - Unique identifier for the provider\n * @param provider - The storage provider instance implementing the `StorageProvider` interface\n * @param isDefault - Whether this provider should be set as the default (defaults to `false`)\n * @example\n * ```typescript\n * const pinata = new PinataStorage({ jwt: 'your-jwt-token' });\n * storage.register('pinata', pinata, true); // Set as default\n *\n * const ipfs = new IPFSStorage({ apiEndpoint: 'https://...' });\n * storage.register('ipfs', ipfs); // Not default\n * ```\n */\n register(name: string, provider: StorageProvider, isDefault = false): void {\n this.providers.set(name, provider);\n\n if (isDefault || this.defaultProvider === null) {\n this.defaultProvider = name;\n }\n }\n\n /**\n * Get a registered storage provider\n *\n * @param name - Provider identifier, uses default if not specified\n * @returns Storage provider instance\n */\n getProvider(name?: string): StorageProvider {\n const providerName = name ?? this.defaultProvider;\n\n if (!providerName) {\n throw new StorageError(\n \"No storage provider specified and no default provider set\",\n \"NO_PROVIDER\",\n \"manager\",\n );\n }\n\n const provider = this.providers.get(providerName);\n if (!provider) {\n throw new StorageError(\n `Storage provider '${providerName}' not found`,\n \"PROVIDER_NOT_FOUND\",\n \"manager\",\n );\n }\n\n return provider;\n }\n\n /**\n * List all registered providers\n *\n * @returns Array of provider names\n */\n listProviders(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Get the default provider name\n *\n * @returns Default provider name or null\n */\n getDefaultProvider(): string | null {\n return this.defaultProvider;\n }\n\n /**\n * Set the default provider\n *\n * @param name - Provider identifier\n */\n setDefaultProvider(name: string): void {\n if (!this.providers.has(name)) {\n throw new StorageError(\n `Cannot set default provider '${name}': provider not registered`,\n \"PROVIDER_NOT_FOUND\",\n \"manager\",\n );\n }\n this.defaultProvider = name;\n }\n\n /**\n * Uploads a file using the specified or default storage provider.\n *\n * @remarks\n * This method uploads a file to the specified provider or falls back to the default\n * provider if none is specified. The upload result includes the storage URL, file size,\n * content type, and provider-specific metadata that can be used for subsequent operations.\n * @param file - The file blob to upload\n * @param filename - Optional custom filename (defaults to auto-generated name)\n * @param providerName - Optional provider identifier (uses default if not specified)\n * @returns A Promise that resolves to the storage upload result with URL and metadata\n * @throws {StorageError} When no provider is available or upload fails\n * @example\n * ```typescript\n * // Upload to default provider\n * const result = await storage.upload(fileBlob, 'data.json');\n * console.log(`Uploaded to: ${result.url}`);\n *\n * // Upload to specific provider\n * const result2 = await storage.upload(fileBlob, 'data.json', 'pinata');\n * ```\n */\n async upload(\n file: Blob,\n filename?: string,\n providerName?: string,\n ): Promise<StorageUploadResult> {\n const provider = this.getProvider(providerName);\n return provider.upload(file, filename);\n }\n\n /**\n * Download a file using the specified or default provider\n *\n * @param url - The storage URL\n * @param providerName - Optional provider to use\n * @returns Promise with file blob\n */\n async download(url: string, providerName?: string): Promise<Blob> {\n const provider = this.getProvider(providerName);\n return provider.download(url);\n }\n\n /**\n * List files using the specified or default provider\n *\n * @param options - Optional filtering and pagination\n * @param providerName - Optional provider to use\n * @returns Promise with file list\n */\n async list(\n options?: StorageListOptions,\n providerName?: string,\n ): Promise<StorageFile[]> {\n const provider = this.getProvider(providerName);\n return provider.list(options);\n }\n\n /**\n * Delete a file using the specified or default provider\n *\n * @param url - The storage URL\n * @param providerName - Optional provider to use\n * @returns Promise with success status\n */\n async delete(url: string, providerName?: string): Promise<boolean> {\n const provider = this.getProvider(providerName);\n return provider.delete(url);\n }\n\n /**\n * Get list of registered storage provider names\n *\n * @returns Array of provider names\n */\n getStorageProviders(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Get the default storage provider name\n *\n * @returns Default provider name or undefined\n */\n getDefaultStorageProvider(): string | undefined {\n return this.defaultProvider ?? undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,qBAA6B;AAwCtB,MAAM,eAAe;AAAA,EAClB,YAA0C,oBAAI,IAAI;AAAA,EAClD,kBAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBzC,SAAS,MAAc,UAA2B,YAAY,OAAa;AACzE,SAAK,UAAU,IAAI,MAAM,QAAQ;AAEjC,QAAI,aAAa,KAAK,oBAAoB,MAAM;AAC9C,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAY,MAAgC;AAC1C,UAAM,eAAe,QAAQ,KAAK;AAElC,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,UAAU,IAAI,YAAY;AAChD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,qBAAqB,YAAY;AAAA,QACjC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,qBAAoC;AAClC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,MAAoB;AACrC,QAAI,CAAC,KAAK,UAAU,IAAI,IAAI,GAAG;AAC7B,YAAM,IAAI;AAAA,QACR,gCAAgC,IAAI;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBA,MAAM,OACJ,MACA,UACA,cAC8B;AAC9B,UAAM,WAAW,KAAK,YAAY,YAAY;AAC9C,WAAO,SAAS,OAAO,MAAM,QAAQ;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SAAS,KAAa,cAAsC;AAChE,UAAM,WAAW,KAAK,YAAY,YAAY;AAC9C,WAAO,SAAS,SAAS,GAAG;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,KACJ,SACA,cACwB;AACxB,UAAM,WAAW,KAAK,YAAY,YAAY;AAC9C,WAAO,SAAS,KAAK,OAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,OAAO,KAAa,cAAyC;AACjE,UAAM,WAAW,KAAK,YAAY,YAAY;AAC9C,WAAO,SAAS,OAAO,GAAG;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,sBAAgC;AAC9B,WAAO,MAAM,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,4BAAgD;AAC9C,WAAO,KAAK,mBAAmB;AAAA,EACjC;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/storage/manager.ts"],"sourcesContent":["/**\n * Manages multiple storage providers with a unified interface.\n *\n * @remarks\n * This module provides centralized management of storage providers, enabling\n * applications to work with multiple storage backends through a single API.\n * It handles provider registration, default selection, and operation routing.\n *\n * @category Storage\n * @module storage/manager\n */\n\nimport type {\n StorageProvider,\n StorageUploadResult,\n StorageFile,\n StorageListOptions,\n} from \"../types/storage\";\nimport { StorageError } from \"../types/storage\";\n\n/**\n * Manages multiple storage providers with a unified interface for file operations.\n *\n * @remarks\n * The StorageManager provides a consistent API for uploading, downloading, and managing\n * files across different storage backends including IPFS, Pinata, Google Drive, and\n * server-managed storage. It handles provider registration, default provider selection,\n * and automatic fallback scenarios for robust file operations.\n *\n * Used internally by DataController for encrypted file storage, but can also be used\n * directly for custom storage workflows. Each provider implements the `StorageProvider`\n * interface to ensure consistent behavior across different storage backends.\n *\n * The manager supports provider-specific configurations and features while maintaining\n * a uniform API surface for applications.\n * @example\n * ```typescript\n * import { StorageManager, IPFSStorage, PinataStorage } from '@opendatalabs/vana-sdk';\n *\n * const storage = new StorageManager();\n *\n * // Register multiple providers\n * storage.register('ipfs', new IPFSStorage({\n * apiEndpoint: 'https://api.pinata.cloud/pinning/pinFileToIPFS'\n * }), true);\n * storage.register('pinata', new PinataStorage({\n * jwt: 'your-pinata-jwt-token'\n * }));\n *\n * // Upload to default provider\n * const result = await storage.upload(fileBlob, 'myfile.json');\n *\n * // Upload to specific provider\n * const result2 = await storage.upload(fileBlob, 'myfile.json', 'pinata');\n * ```\n * @category Storage\n * @see {@link https://docs.vana.com/developer/vana-sdk-documentation/core-modules/storage-providers | Storage Providers Guide} for configuration details\n */\nexport class StorageManager {\n private providers: Map<string, StorageProvider> = new Map();\n private defaultProvider: string | null = null;\n\n /**\n * Registers a storage provider with the manager.\n *\n * @remarks\n * This method adds a new storage provider to the manager's registry and optionally\n * sets it as the default provider for subsequent operations. If no default provider\n * is currently set, the first registered provider automatically becomes the default.\n * @param name - Unique identifier for the provider\n * @param provider - The storage provider instance implementing the `StorageProvider` interface\n * @param isDefault - Whether this provider should be set as the default (defaults to `false`)\n * @example\n * ```typescript\n * const pinata = new PinataStorage({ jwt: 'your-jwt-token' });\n * storage.register('pinata', pinata, true); // Set as default\n *\n * const ipfs = new IPFSStorage({ apiEndpoint: 'https://...' });\n * storage.register('ipfs', ipfs); // Not default\n * ```\n */\n register(name: string, provider: StorageProvider, isDefault = false): void {\n this.providers.set(name, provider);\n\n if (isDefault || this.defaultProvider === null) {\n this.defaultProvider = name;\n }\n }\n\n /**\n * Retrieves a registered storage provider.\n *\n * @param name - Provider identifier.\n * If not specified, returns the default provider.\n * @returns The requested storage provider instance\n *\n * @throws {StorageError} With code 'NO_PROVIDER' if no provider available\n * @throws {StorageError} With code 'PROVIDER_NOT_FOUND' if named provider doesn't exist\n *\n * @example\n * ```typescript\n * const provider = storage.getProvider('pinata');\n * const config = provider.getConfig();\n * ```\n */\n getProvider(name?: string): StorageProvider {\n const providerName = name ?? this.defaultProvider;\n\n if (!providerName) {\n throw new StorageError(\n \"No storage provider specified and no default provider set\",\n \"NO_PROVIDER\",\n \"manager\",\n );\n }\n\n const provider = this.providers.get(providerName);\n if (!provider) {\n throw new StorageError(\n `Storage provider '${providerName}' not found`,\n \"PROVIDER_NOT_FOUND\",\n \"manager\",\n );\n }\n\n return provider;\n }\n\n /**\n * Lists all registered provider names.\n *\n * @returns Array of registered provider identifiers\n *\n * @example\n * ```typescript\n * const providers = storage.listProviders();\n * console.log('Available providers:', providers);\n * // Output: ['ipfs', 'pinata', 'google-drive']\n * ```\n */\n listProviders(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Gets the current default provider name.\n *\n * @returns Default provider identifier or null if none set\n *\n * @example\n * ```typescript\n * const defaultName = storage.getDefaultProvider();\n * if (defaultName) {\n * console.log(`Using ${defaultName} by default`);\n * }\n * ```\n */\n getDefaultProvider(): string | null {\n return this.defaultProvider;\n }\n\n /**\n * Sets the default storage provider.\n *\n * @param name - Provider identifier to set as default.\n * Must be a registered provider name.\n *\n * @throws {StorageError} With code 'PROVIDER_NOT_FOUND' if provider not registered\n *\n * @example\n * ```typescript\n * storage.setDefaultProvider('pinata');\n * // Now all operations without provider name will use Pinata\n * ```\n */\n setDefaultProvider(name: string): void {\n if (!this.providers.has(name)) {\n throw new StorageError(\n `Cannot set default provider '${name}': provider not registered`,\n \"PROVIDER_NOT_FOUND\",\n \"manager\",\n );\n }\n this.defaultProvider = name;\n }\n\n /**\n * Uploads a file using the specified or default storage provider.\n *\n * @remarks\n * This method uploads a file to the specified provider or falls back to the default\n * provider if none is specified. The upload result includes the storage URL, file size,\n * content type, and provider-specific metadata that can be used for subsequent operations.\n * @param file - The file blob to upload\n * @param filename - Optional custom filename (defaults to auto-generated name)\n * @param providerName - Optional provider identifier (uses default if not specified)\n * @returns A Promise that resolves to the storage upload result with URL and metadata\n * @throws {StorageError} When no provider is available or upload fails\n * @example\n * ```typescript\n * // Upload to default provider\n * const result = await storage.upload(fileBlob, 'data.json');\n * console.log(`Uploaded to: ${result.url}`);\n *\n * // Upload to specific provider\n * const result2 = await storage.upload(fileBlob, 'data.json', 'pinata');\n * ```\n */\n async upload(\n file: Blob,\n filename?: string,\n providerName?: string,\n ): Promise<StorageUploadResult> {\n const provider = this.getProvider(providerName);\n return provider.upload(file, filename);\n }\n\n /**\n * Downloads a file from storage.\n *\n * @param url - The storage URL to download from.\n * Format depends on the storage provider.\n * @param providerName - Optional provider identifier.\n * Uses default provider if not specified.\n * @returns The downloaded file as a Blob\n *\n * @throws {StorageError} If download fails or provider unavailable\n *\n * @example\n * ```typescript\n * const blob = await storage.download('ipfs://QmXxx...');\n * const text = await blob.text();\n * ```\n */\n async download(url: string, providerName?: string): Promise<Blob> {\n const provider = this.getProvider(providerName);\n return provider.download(url);\n }\n\n /**\n * Lists files in storage.\n *\n * @param options - Optional filtering and pagination.\n * @param options.namePattern - Pattern to filter files.\n * @param options.limit - Maximum files to return.\n * @param providerName - Optional provider identifier.\n * Uses default provider if not specified.\n * @returns Array of file metadata\n *\n * @throws {StorageError} If listing fails or not supported by provider\n *\n * @example\n * ```typescript\n * const files = await storage.list(\n * { namePattern: '*.json', limit: 10 },\n * 'google-drive'\n * );\n * ```\n */\n async list(\n options?: StorageListOptions,\n providerName?: string,\n ): Promise<StorageFile[]> {\n const provider = this.getProvider(providerName);\n return provider.list(options);\n }\n\n /**\n * Deletes a file from storage.\n *\n * @param url - The storage URL to delete.\n * Must be a valid URL for the provider.\n * @param providerName - Optional provider identifier.\n * Uses default provider if not specified.\n * @returns True if deletion succeeded, false otherwise\n *\n * @throws {StorageError} If deletion fails or not supported by provider\n *\n * @example\n * ```typescript\n * const success = await storage.delete('ipfs://QmXxx...');\n * if (success) {\n * console.log('File deleted successfully');\n * }\n * ```\n */\n async delete(url: string, providerName?: string): Promise<boolean> {\n const provider = this.getProvider(providerName);\n return provider.delete(url);\n }\n\n /**\n * Gets all registered storage provider names.\n *\n * @returns Array of provider identifiers\n *\n * @deprecated Use `listProviders()` instead\n *\n * @example\n * ```typescript\n * const providers = storage.getStorageProviders();\n * ```\n */\n getStorageProviders(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Gets the default storage provider name.\n *\n * @returns Default provider identifier or undefined if none set\n *\n * @deprecated Use `getDefaultProvider()` instead\n *\n * @example\n * ```typescript\n * const defaultProvider = storage.getDefaultStorageProvider();\n * ```\n */\n getDefaultStorageProvider(): string | undefined {\n return this.defaultProvider ?? undefined;\n }\n}\n"],"mappings":"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","names":[]}