@opendatalabs/vana-sdk 0.1.0-alpha.a25bcc7 → 0.1.0-alpha.a6b60fc

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 +172 -140
  14. package/dist/controllers/data.cjs.map +1 -1
  15. package/dist/controllers/data.d.ts +213 -175
  16. package/dist/controllers/data.js +172 -140
  17. package/dist/controllers/data.js.map +1 -1
  18. package/dist/controllers/permissions.cjs +184 -190
  19. package/dist/controllers/permissions.cjs.map +1 -1
  20. package/dist/controllers/permissions.d.ts +29 -73
  21. package/dist/controllers/permissions.js +184 -190
  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 +19 -17
  27. package/dist/controllers/schemas.cjs.map +1 -1
  28. package/dist/controllers/schemas.d.ts +47 -40
  29. package/dist/controllers/schemas.js +19 -17
  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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/lazy-import.ts"],"sourcesContent":["/**\n * Utility for lazy-loading modules to avoid Turbopack TDZ issues\n *\n * WARNING: This is a workaround for Turbopack's strict module initialization.\n * Dependencies that access globals during init must be dynamically imported.\n */\n\n/**\n * Creates a lazy import function that caches the promise (not the module)\n * to avoid race conditions on concurrent first calls\n *\n * @param importFn - Function that returns a dynamic import promise\n * @returns Function that returns the cached import promise\n *\n * @example\n * const getOpenPGP = lazyImport(() => import('openpgp'));\n * const openpgp = await getOpenPGP();\n */\nexport function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T> {\n let cached: Promise<T> | null = null;\n\n return () => {\n cached ??= importFn().catch((err) => {\n // Clear cache on error so next attempt can retry\n cached = null;\n throw new Error(\"Failed to load module\", { cause: err });\n });\n return cached;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBO,SAAS,WAAc,UAA8C;AAC1E,MAAI,SAA4B;AAEhC,SAAO,MAAM;AACX,eAAW,SAAS,EAAE,MAAM,CAAC,QAAQ;AAEnC,eAAS;AACT,YAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,IACzD,CAAC;AACD,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/lazy-import.ts"],"sourcesContent":["/**\n * Provides lazy module loading to avoid Temporal Dead Zone issues.\n *\n * @remarks\n * This module implements a caching lazy import pattern to work around Turbopack's\n * strict module initialization. Dependencies that access globals during initialization\n * must be dynamically imported to prevent TDZ errors in Next.js environments.\n *\n * @see {@link https://github.com/vercel/next.js/issues/82632 | Turbopack TDZ Issue}\n *\n * @category Utilities\n * @module utils/lazy-import\n */\n\n/**\n * Creates a cached lazy import function for deferred module loading.\n *\n * @remarks\n * Caches the import promise (not the module) to prevent race conditions\n * during concurrent first calls. On import failure, clears the cache to\n * allow retry on next attempt.\n *\n * @typeParam T - The type of the module being imported\n *\n * @param importFn - Function that returns a dynamic import promise.\n * Should be a dynamic import expression like `() => import('module')`.\n * @returns A function that returns the cached import promise\n *\n * @example\n * ```typescript\n * // Create lazy loader for heavy crypto library\n * const getOpenPGP = lazyImport(() => import('openpgp'));\n *\n * // Use when needed (first call triggers import)\n * const openpgp = await getOpenPGP();\n * const encrypted = await openpgp.encrypt(data);\n *\n * // Subsequent calls return cached promise\n * const openpgp2 = await getOpenPGP(); // Same instance\n * ```\n *\n * @category Utilities\n */\nexport function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T> {\n let cached: Promise<T> | null = null;\n\n return () => {\n cached ??= importFn().catch((err) => {\n // Clear cache on error so next attempt can retry\n cached = null;\n throw new Error(\"Failed to load module\", { cause: err });\n });\n return cached;\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2CO,SAAS,WAAc,UAA8C;AAC1E,MAAI,SAA4B;AAEhC,SAAO,MAAM;AACX,eAAW,SAAS,EAAE,MAAM,CAAC,QAAQ;AAEnC,eAAS;AACT,YAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,IACzD,CAAC;AACD,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -1,18 +1,43 @@
1
1
  /**
2
- * Utility for lazy-loading modules to avoid Turbopack TDZ issues
2
+ * Provides lazy module loading to avoid Temporal Dead Zone issues.
3
3
  *
4
- * WARNING: This is a workaround for Turbopack's strict module initialization.
5
- * Dependencies that access globals during init must be dynamically imported.
4
+ * @remarks
5
+ * This module implements a caching lazy import pattern to work around Turbopack's
6
+ * strict module initialization. Dependencies that access globals during initialization
7
+ * must be dynamically imported to prevent TDZ errors in Next.js environments.
8
+ *
9
+ * @see {@link https://github.com/vercel/next.js/issues/82632 | Turbopack TDZ Issue}
10
+ *
11
+ * @category Utilities
12
+ * @module utils/lazy-import
6
13
  */
7
14
  /**
8
- * Creates a lazy import function that caches the promise (not the module)
9
- * to avoid race conditions on concurrent first calls
15
+ * Creates a cached lazy import function for deferred module loading.
16
+ *
17
+ * @remarks
18
+ * Caches the import promise (not the module) to prevent race conditions
19
+ * during concurrent first calls. On import failure, clears the cache to
20
+ * allow retry on next attempt.
21
+ *
22
+ * @typeParam T - The type of the module being imported
10
23
  *
11
- * @param importFn - Function that returns a dynamic import promise
12
- * @returns Function that returns the cached import promise
24
+ * @param importFn - Function that returns a dynamic import promise.
25
+ * Should be a dynamic import expression like `() => import('module')`.
26
+ * @returns A function that returns the cached import promise
13
27
  *
14
28
  * @example
29
+ * ```typescript
30
+ * // Create lazy loader for heavy crypto library
15
31
  * const getOpenPGP = lazyImport(() => import('openpgp'));
32
+ *
33
+ * // Use when needed (first call triggers import)
16
34
  * const openpgp = await getOpenPGP();
35
+ * const encrypted = await openpgp.encrypt(data);
36
+ *
37
+ * // Subsequent calls return cached promise
38
+ * const openpgp2 = await getOpenPGP(); // Same instance
39
+ * ```
40
+ *
41
+ * @category Utilities
17
42
  */
18
43
  export declare function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/lazy-import.ts"],"sourcesContent":["/**\n * Utility for lazy-loading modules to avoid Turbopack TDZ issues\n *\n * WARNING: This is a workaround for Turbopack's strict module initialization.\n * Dependencies that access globals during init must be dynamically imported.\n */\n\n/**\n * Creates a lazy import function that caches the promise (not the module)\n * to avoid race conditions on concurrent first calls\n *\n * @param importFn - Function that returns a dynamic import promise\n * @returns Function that returns the cached import promise\n *\n * @example\n * const getOpenPGP = lazyImport(() => import('openpgp'));\n * const openpgp = await getOpenPGP();\n */\nexport function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T> {\n let cached: Promise<T> | null = null;\n\n return () => {\n cached ??= importFn().catch((err) => {\n // Clear cache on error so next attempt can retry\n cached = null;\n throw new Error(\"Failed to load module\", { cause: err });\n });\n return cached;\n };\n}\n"],"mappings":"AAkBO,SAAS,WAAc,UAA8C;AAC1E,MAAI,SAA4B;AAEhC,SAAO,MAAM;AACX,eAAW,SAAS,EAAE,MAAM,CAAC,QAAQ;AAEnC,eAAS;AACT,YAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,IACzD,CAAC;AACD,WAAO;AAAA,EACT;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/lazy-import.ts"],"sourcesContent":["/**\n * Provides lazy module loading to avoid Temporal Dead Zone issues.\n *\n * @remarks\n * This module implements a caching lazy import pattern to work around Turbopack's\n * strict module initialization. Dependencies that access globals during initialization\n * must be dynamically imported to prevent TDZ errors in Next.js environments.\n *\n * @see {@link https://github.com/vercel/next.js/issues/82632 | Turbopack TDZ Issue}\n *\n * @category Utilities\n * @module utils/lazy-import\n */\n\n/**\n * Creates a cached lazy import function for deferred module loading.\n *\n * @remarks\n * Caches the import promise (not the module) to prevent race conditions\n * during concurrent first calls. On import failure, clears the cache to\n * allow retry on next attempt.\n *\n * @typeParam T - The type of the module being imported\n *\n * @param importFn - Function that returns a dynamic import promise.\n * Should be a dynamic import expression like `() => import('module')`.\n * @returns A function that returns the cached import promise\n *\n * @example\n * ```typescript\n * // Create lazy loader for heavy crypto library\n * const getOpenPGP = lazyImport(() => import('openpgp'));\n *\n * // Use when needed (first call triggers import)\n * const openpgp = await getOpenPGP();\n * const encrypted = await openpgp.encrypt(data);\n *\n * // Subsequent calls return cached promise\n * const openpgp2 = await getOpenPGP(); // Same instance\n * ```\n *\n * @category Utilities\n */\nexport function lazyImport<T>(importFn: () => Promise<T>): () => Promise<T> {\n let cached: Promise<T> | null = null;\n\n return () => {\n cached ??= importFn().catch((err) => {\n // Clear cache on error so next attempt can retry\n cached = null;\n throw new Error(\"Failed to load module\", { cause: err });\n });\n return cached;\n };\n}\n"],"mappings":"AA2CO,SAAS,WAAc,UAA8C;AAC1E,MAAI,SAA4B;AAEhC,SAAO,MAAM;AACX,eAAW,SAAS,EAAE,MAAM,CAAC,QAAQ;AAEnC,eAAS;AACT,YAAM,IAAI,MAAM,yBAAyB,EAAE,OAAO,IAAI,CAAC;AAAA,IACzD,CAAC;AACD,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -145,12 +145,18 @@ class SignatureCache {
145
145
  return (0, import_viem.toHex)(hashBytes);
146
146
  }
147
147
  /**
148
- * Deterministic JSON replacer that handles BigInt values and sorts object keys
149
- * This ensures consistent cache key generation for EIP-712 typed data
148
+ * Deterministic JSON replacer for consistent cache key generation.
149
+ *
150
+ * @remarks
151
+ * Handles BigInt serialization and sorts object keys to ensure
152
+ * identical objects always produce the same hash regardless of
153
+ * property order.
150
154
  *
151
155
  * @param _key - The object key being serialized (unused)
152
156
  * @param value - The value to serialize
153
157
  * @returns The serialized value with sorted keys for objects
158
+ *
159
+ * @internal
154
160
  */
155
161
  static deterministicReplacer(_key, value) {
156
162
  if (typeof value === "bigint") {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/signatureCache.ts"],"sourcesContent":["import type { Hash } from \"viem\";\nimport { getAddress, toHex } from \"viem\";\nimport type { VanaCacheAdapter } from \"../platform/interface\";\nimport { sha256 } from \"@noble/hashes/sha256\";\n\ninterface CachedSignature {\n signature: Hash;\n expires: number;\n}\n\n/**\n * Simple signature cache using platform cache adapter to avoid repeated signing of identical messages.\n *\n * @remarks\n * This cache significantly improves UX by avoiding repeated wallet signature prompts\n * for identical operations. It's particularly useful for operations that may be\n * retried or called multiple times with the same parameters.\n *\n * Features:\n * - Platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * - Configurable TTL (default 2 hours)\n * - Automatic cleanup of expired entries\n * - Cache keys based on wallet address + message hash\n *\n * @example\n * ```typescript\n * // Check cache before requesting signature\n * const cached = SignatureCache.get(cache, walletAddress, messageHash);\n * if (cached) {\n * return cached;\n * }\n *\n * // Request signature and cache it\n * const signature = await wallet.signTypedData(typedData);\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n * ```\n * @category Utilities\n */\nexport class SignatureCache {\n private static readonly PREFIX = \"vana_sig_\";\n private static readonly DEFAULT_TTL_HOURS = 2;\n\n /**\n * Get a cached signature if it exists and hasn't expired\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @returns The cached signature if valid, null if expired or not found\n * @example\n * ```typescript\n * const messageHash = SignatureCache.hashMessage(typedData);\n * const cached = SignatureCache.get(cache, '0x123...', messageHash);\n * if (cached) {\n * console.log('Using cached signature:', cached);\n * }\n * ```\n */\n static get(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n ): Hash | null {\n const key = this.getCacheKey(walletAddress, messageHash);\n\n try {\n const stored = cache.get(key);\n if (!stored) return null;\n\n const cached: CachedSignature = JSON.parse(stored);\n\n // Check if expired\n if (Date.now() > cached.expires) {\n cache.delete(key);\n return null;\n }\n\n return cached.signature;\n } catch {\n // Invalid JSON or storage error, clean up\n try {\n cache.delete(key);\n } catch {\n // Ignore cache cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Store a signature in the cache with configurable TTL\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to cache\n * @param ttlHours - Time to live in hours (default: 2)\n * @example\n * ```typescript\n * const signature = await wallet.signTypedData(typedData);\n * const messageHash = SignatureCache.hashMessage(typedData);\n *\n * // Cache for default 2 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n *\n * // Cache for 24 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);\n * ```\n */\n static set(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n signature: Hash,\n ttlHours: number = this.DEFAULT_TTL_HOURS,\n ): void {\n const key = this.getCacheKey(walletAddress, messageHash);\n const cached: CachedSignature = {\n signature,\n expires: Date.now() + ttlHours * 3600000, // Convert hours to milliseconds\n };\n\n try {\n cache.set(key, JSON.stringify(cached));\n } catch {\n // Storage quota exceeded or other error, ignore silently\n // Better to continue without caching than to fail\n }\n }\n\n /**\n * Clear all cached signatures (useful for testing or explicit cleanup)\n *\n * @param cache - Platform cache adapter instance\n * @example\n * ```typescript\n * // Clear all signatures when user logs out\n * SignatureCache.clear(cache);\n *\n * // Clear before running tests\n * beforeEach(() => {\n * SignatureCache.clear(cache);\n * });\n * ```\n */\n static clear(cache: VanaCacheAdapter): void {\n try {\n cache.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n private static getCacheKey(\n walletAddress: string,\n messageHash: string,\n ): string {\n return `${this.PREFIX}${getAddress(walletAddress)}:${messageHash}`;\n }\n\n /**\n * Generate a deterministic hash of a message object for cache key generation\n *\n * @remarks\n * Creates a cryptographically secure hash from complex objects including EIP-712 typed data.\n * Uses SHA-256 for collision resistance and deterministic key generation.\n * Handles BigInt serialization and sorts object keys for consistency.\n *\n * @param message - The message object to hash (typically EIP-712 typed data)\n * @returns A hex string hash (SHA-256) suitable for cache keys\n * @example\n * ```typescript\n * const typedData = {\n * domain: { name: 'Vana', version: '1' },\n * message: { nonce: 123n, grant: '...' }\n * };\n *\n * const hash = SignatureCache.hashMessage(typedData);\n * // Returns SHA-256 hash like: \"a1b2c3d4e5f6...\"\n * ```\n */\n static hashMessage(message: object): string {\n // Deterministically stringify the object with sorted keys\n const jsonString = JSON.stringify(message, this.deterministicReplacer);\n\n // Use SHA-256 for cryptographic hashing\n const hashBytes = sha256(new TextEncoder().encode(jsonString));\n return toHex(hashBytes);\n }\n\n /**\n * Deterministic JSON replacer that handles BigInt values and sorts object keys\n * This ensures consistent cache key generation for EIP-712 typed data\n *\n * @param _key - The object key being serialized (unused)\n * @param value - The value to serialize\n * @returns The serialized value with sorted keys for objects\n */\n private static deterministicReplacer(_key: string, value: unknown): unknown {\n if (typeof value === \"bigint\") {\n return `__BIGINT__${value.toString()}`;\n }\n // Sort object keys for deterministic serialization\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, key) => {\n sorted[key] = (value as Record<string, unknown>)[key];\n return sorted;\n },\n {} as Record<string, unknown>,\n );\n }\n return value;\n }\n}\n\n/**\n * Wrapper function to cache signature operations\n *\n * @param cache - The cache adapter to use for storage\n * @param walletAddress - The wallet address signing the message\n * @param typedData - The EIP-712 typed data being signed\n * @param signFn - Function that performs the actual signing\n * @param ttlHours - Cache TTL in hours (default 2)\n * @returns The signature (cached or newly generated)\n */\nexport async function withSignatureCache(\n cache: VanaCacheAdapter,\n walletAddress: string,\n typedData: Record<string, unknown>,\n signFn: () => Promise<Hash>,\n ttlHours?: number,\n): Promise<Hash> {\n // Create a hash of the typed data for the cache key\n const messageHash = SignatureCache.hashMessage(typedData);\n\n // Try to get from cache first\n const cached = SignatureCache.get(cache, walletAddress, messageHash);\n if (cached) {\n return cached;\n }\n\n // Not in cache, sign and store\n const signature = await signFn();\n SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);\n\n return signature;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/signatureCache.ts"],"sourcesContent":["/**\n * Provides signature caching to improve UX by avoiding repeated wallet prompts.\n *\n * @remarks\n * This module implements a secure signature cache that stores signed messages\n * temporarily to avoid repeatedly prompting users for the same signature.\n * It uses platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * and includes automatic expiration and cleanup.\n *\n * @category Utilities\n * @module utils/signatureCache\n */\n\nimport type { Hash } from \"viem\";\nimport { getAddress, toHex } from \"viem\";\nimport type { VanaCacheAdapter } from \"../platform/interface\";\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n/**\n * Represents a cached signature with expiration metadata.\n *\n * @internal\n */\ninterface CachedSignature {\n /** The cached signature hash */\n signature: Hash;\n /** Unix timestamp when this cache entry expires */\n expires: number;\n}\n\n/**\n * Simple signature cache using platform cache adapter to avoid repeated signing of identical messages.\n *\n * @remarks\n * This cache significantly improves UX by avoiding repeated wallet signature prompts\n * for identical operations. It's particularly useful for operations that may be\n * retried or called multiple times with the same parameters.\n *\n * Features:\n * - Platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * - Configurable TTL (default 2 hours)\n * - Automatic cleanup of expired entries\n * - Cache keys based on wallet address + message hash\n *\n * @example\n * ```typescript\n * // Check cache before requesting signature\n * const cached = SignatureCache.get(cache, walletAddress, messageHash);\n * if (cached) {\n * return cached;\n * }\n *\n * // Request signature and cache it\n * const signature = await wallet.signTypedData(typedData);\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n * ```\n * @category Utilities\n */\nexport class SignatureCache {\n private static readonly PREFIX = \"vana_sig_\";\n private static readonly DEFAULT_TTL_HOURS = 2;\n\n /**\n * Get a cached signature if it exists and hasn't expired\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @returns The cached signature if valid, null if expired or not found\n * @example\n * ```typescript\n * const messageHash = SignatureCache.hashMessage(typedData);\n * const cached = SignatureCache.get(cache, '0x123...', messageHash);\n * if (cached) {\n * console.log('Using cached signature:', cached);\n * }\n * ```\n */\n static get(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n ): Hash | null {\n const key = this.getCacheKey(walletAddress, messageHash);\n\n try {\n const stored = cache.get(key);\n if (!stored) return null;\n\n const cached: CachedSignature = JSON.parse(stored);\n\n // Check if expired\n if (Date.now() > cached.expires) {\n cache.delete(key);\n return null;\n }\n\n return cached.signature;\n } catch {\n // Invalid JSON or storage error, clean up\n try {\n cache.delete(key);\n } catch {\n // Ignore cache cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Store a signature in the cache with configurable TTL\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to cache\n * @param ttlHours - Time to live in hours (default: 2)\n * @example\n * ```typescript\n * const signature = await wallet.signTypedData(typedData);\n * const messageHash = SignatureCache.hashMessage(typedData);\n *\n * // Cache for default 2 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n *\n * // Cache for 24 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);\n * ```\n */\n static set(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n signature: Hash,\n ttlHours: number = this.DEFAULT_TTL_HOURS,\n ): void {\n const key = this.getCacheKey(walletAddress, messageHash);\n const cached: CachedSignature = {\n signature,\n expires: Date.now() + ttlHours * 3600000, // Convert hours to milliseconds\n };\n\n try {\n cache.set(key, JSON.stringify(cached));\n } catch {\n // Storage quota exceeded or other error, ignore silently\n // Better to continue without caching than to fail\n }\n }\n\n /**\n * Clear all cached signatures (useful for testing or explicit cleanup)\n *\n * @param cache - Platform cache adapter instance\n * @example\n * ```typescript\n * // Clear all signatures when user logs out\n * SignatureCache.clear(cache);\n *\n * // Clear before running tests\n * beforeEach(() => {\n * SignatureCache.clear(cache);\n * });\n * ```\n */\n static clear(cache: VanaCacheAdapter): void {\n try {\n cache.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n private static getCacheKey(\n walletAddress: string,\n messageHash: string,\n ): string {\n return `${this.PREFIX}${getAddress(walletAddress)}:${messageHash}`;\n }\n\n /**\n * Generate a deterministic hash of a message object for cache key generation\n *\n * @remarks\n * Creates a cryptographically secure hash from complex objects including EIP-712 typed data.\n * Uses SHA-256 for collision resistance and deterministic key generation.\n * Handles BigInt serialization and sorts object keys for consistency.\n *\n * @param message - The message object to hash (typically EIP-712 typed data)\n * @returns A hex string hash (SHA-256) suitable for cache keys\n * @example\n * ```typescript\n * const typedData = {\n * domain: { name: 'Vana', version: '1' },\n * message: { nonce: 123n, grant: '...' }\n * };\n *\n * const hash = SignatureCache.hashMessage(typedData);\n * // Returns SHA-256 hash like: \"a1b2c3d4e5f6...\"\n * ```\n */\n static hashMessage(message: object): string {\n // Deterministically stringify the object with sorted keys\n const jsonString = JSON.stringify(message, this.deterministicReplacer);\n\n // Use SHA-256 for cryptographic hashing\n const hashBytes = sha256(new TextEncoder().encode(jsonString));\n return toHex(hashBytes);\n }\n\n /**\n * Deterministic JSON replacer for consistent cache key generation.\n *\n * @remarks\n * Handles BigInt serialization and sorts object keys to ensure\n * identical objects always produce the same hash regardless of\n * property order.\n *\n * @param _key - The object key being serialized (unused)\n * @param value - The value to serialize\n * @returns The serialized value with sorted keys for objects\n *\n * @internal\n */\n private static deterministicReplacer(_key: string, value: unknown): unknown {\n if (typeof value === \"bigint\") {\n return `__BIGINT__${value.toString()}`;\n }\n // Sort object keys for deterministic serialization\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, key) => {\n sorted[key] = (value as Record<string, unknown>)[key];\n return sorted;\n },\n {} as Record<string, unknown>,\n );\n }\n return value;\n }\n}\n\n/**\n * Wraps signature operations with caching to avoid repeated prompts.\n *\n * @remarks\n * This helper function checks the cache before requesting a signature\n * and stores new signatures for future use. It significantly improves\n * UX for operations that may be retried or called multiple times.\n *\n * @param cache - The cache adapter to use for storage.\n * Obtain from platform adapter.\n * @param walletAddress - The wallet address signing the message.\n * Obtain from wallet connection.\n * @param typedData - The EIP-712 typed data being signed.\n * Typically permission or grant data.\n * @param signFn - Async function that performs the actual signing.\n * Usually calls wallet.signTypedData().\n * @param ttlHours - Cache TTL in hours.\n * Defaults to 2 hours.\n * @returns The signature (cached or newly generated)\n *\n * @example\n * ```typescript\n * const signature = await withSignatureCache(\n * platformAdapter.cache,\n * walletAddress,\n * typedData,\n * async () => wallet.signTypedData(typedData),\n * 24 // Cache for 24 hours\n * );\n * ```\n *\n * @category Utilities\n */\nexport async function withSignatureCache(\n cache: VanaCacheAdapter,\n walletAddress: string,\n typedData: Record<string, unknown>,\n signFn: () => Promise<Hash>,\n ttlHours?: number,\n): Promise<Hash> {\n // Create a hash of the typed data for the cache key\n const messageHash = SignatureCache.hashMessage(typedData);\n\n // Try to get from cache first\n const cached = SignatureCache.get(cache, walletAddress, messageHash);\n if (cached) {\n return cached;\n }\n\n // Not in cache, sign and store\n const signature = await signFn();\n SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);\n\n return signature;\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,15 @@
1
+ /**
2
+ * Provides signature caching to improve UX by avoiding repeated wallet prompts.
3
+ *
4
+ * @remarks
5
+ * This module implements a secure signature cache that stores signed messages
6
+ * temporarily to avoid repeatedly prompting users for the same signature.
7
+ * It uses platform-appropriate storage (sessionStorage in browser, memory in Node.js)
8
+ * and includes automatic expiration and cleanup.
9
+ *
10
+ * @category Utilities
11
+ * @module utils/signatureCache
12
+ */
1
13
  import type { Hash } from "viem";
2
14
  import type { VanaCacheAdapter } from "../platform/interface";
3
15
  /**
@@ -109,23 +121,52 @@ export declare class SignatureCache {
109
121
  */
110
122
  static hashMessage(message: object): string;
111
123
  /**
112
- * Deterministic JSON replacer that handles BigInt values and sorts object keys
113
- * This ensures consistent cache key generation for EIP-712 typed data
124
+ * Deterministic JSON replacer for consistent cache key generation.
125
+ *
126
+ * @remarks
127
+ * Handles BigInt serialization and sorts object keys to ensure
128
+ * identical objects always produce the same hash regardless of
129
+ * property order.
114
130
  *
115
131
  * @param _key - The object key being serialized (unused)
116
132
  * @param value - The value to serialize
117
133
  * @returns The serialized value with sorted keys for objects
134
+ *
135
+ * @internal
118
136
  */
119
137
  private static deterministicReplacer;
120
138
  }
121
139
  /**
122
- * Wrapper function to cache signature operations
140
+ * Wraps signature operations with caching to avoid repeated prompts.
123
141
  *
124
- * @param cache - The cache adapter to use for storage
125
- * @param walletAddress - The wallet address signing the message
126
- * @param typedData - The EIP-712 typed data being signed
127
- * @param signFn - Function that performs the actual signing
128
- * @param ttlHours - Cache TTL in hours (default 2)
142
+ * @remarks
143
+ * This helper function checks the cache before requesting a signature
144
+ * and stores new signatures for future use. It significantly improves
145
+ * UX for operations that may be retried or called multiple times.
146
+ *
147
+ * @param cache - The cache adapter to use for storage.
148
+ * Obtain from platform adapter.
149
+ * @param walletAddress - The wallet address signing the message.
150
+ * Obtain from wallet connection.
151
+ * @param typedData - The EIP-712 typed data being signed.
152
+ * Typically permission or grant data.
153
+ * @param signFn - Async function that performs the actual signing.
154
+ * Usually calls wallet.signTypedData().
155
+ * @param ttlHours - Cache TTL in hours.
156
+ * Defaults to 2 hours.
129
157
  * @returns The signature (cached or newly generated)
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const signature = await withSignatureCache(
162
+ * platformAdapter.cache,
163
+ * walletAddress,
164
+ * typedData,
165
+ * async () => wallet.signTypedData(typedData),
166
+ * 24 // Cache for 24 hours
167
+ * );
168
+ * ```
169
+ *
170
+ * @category Utilities
130
171
  */
131
172
  export declare function withSignatureCache(cache: VanaCacheAdapter, walletAddress: string, typedData: Record<string, unknown>, signFn: () => Promise<Hash>, ttlHours?: number): Promise<Hash>;
@@ -121,12 +121,18 @@ class SignatureCache {
121
121
  return toHex(hashBytes);
122
122
  }
123
123
  /**
124
- * Deterministic JSON replacer that handles BigInt values and sorts object keys
125
- * This ensures consistent cache key generation for EIP-712 typed data
124
+ * Deterministic JSON replacer for consistent cache key generation.
125
+ *
126
+ * @remarks
127
+ * Handles BigInt serialization and sorts object keys to ensure
128
+ * identical objects always produce the same hash regardless of
129
+ * property order.
126
130
  *
127
131
  * @param _key - The object key being serialized (unused)
128
132
  * @param value - The value to serialize
129
133
  * @returns The serialized value with sorted keys for objects
134
+ *
135
+ * @internal
130
136
  */
131
137
  static deterministicReplacer(_key, value) {
132
138
  if (typeof value === "bigint") {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/signatureCache.ts"],"sourcesContent":["import type { Hash } from \"viem\";\nimport { getAddress, toHex } from \"viem\";\nimport type { VanaCacheAdapter } from \"../platform/interface\";\nimport { sha256 } from \"@noble/hashes/sha256\";\n\ninterface CachedSignature {\n signature: Hash;\n expires: number;\n}\n\n/**\n * Simple signature cache using platform cache adapter to avoid repeated signing of identical messages.\n *\n * @remarks\n * This cache significantly improves UX by avoiding repeated wallet signature prompts\n * for identical operations. It's particularly useful for operations that may be\n * retried or called multiple times with the same parameters.\n *\n * Features:\n * - Platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * - Configurable TTL (default 2 hours)\n * - Automatic cleanup of expired entries\n * - Cache keys based on wallet address + message hash\n *\n * @example\n * ```typescript\n * // Check cache before requesting signature\n * const cached = SignatureCache.get(cache, walletAddress, messageHash);\n * if (cached) {\n * return cached;\n * }\n *\n * // Request signature and cache it\n * const signature = await wallet.signTypedData(typedData);\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n * ```\n * @category Utilities\n */\nexport class SignatureCache {\n private static readonly PREFIX = \"vana_sig_\";\n private static readonly DEFAULT_TTL_HOURS = 2;\n\n /**\n * Get a cached signature if it exists and hasn't expired\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @returns The cached signature if valid, null if expired or not found\n * @example\n * ```typescript\n * const messageHash = SignatureCache.hashMessage(typedData);\n * const cached = SignatureCache.get(cache, '0x123...', messageHash);\n * if (cached) {\n * console.log('Using cached signature:', cached);\n * }\n * ```\n */\n static get(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n ): Hash | null {\n const key = this.getCacheKey(walletAddress, messageHash);\n\n try {\n const stored = cache.get(key);\n if (!stored) return null;\n\n const cached: CachedSignature = JSON.parse(stored);\n\n // Check if expired\n if (Date.now() > cached.expires) {\n cache.delete(key);\n return null;\n }\n\n return cached.signature;\n } catch {\n // Invalid JSON or storage error, clean up\n try {\n cache.delete(key);\n } catch {\n // Ignore cache cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Store a signature in the cache with configurable TTL\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to cache\n * @param ttlHours - Time to live in hours (default: 2)\n * @example\n * ```typescript\n * const signature = await wallet.signTypedData(typedData);\n * const messageHash = SignatureCache.hashMessage(typedData);\n *\n * // Cache for default 2 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n *\n * // Cache for 24 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);\n * ```\n */\n static set(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n signature: Hash,\n ttlHours: number = this.DEFAULT_TTL_HOURS,\n ): void {\n const key = this.getCacheKey(walletAddress, messageHash);\n const cached: CachedSignature = {\n signature,\n expires: Date.now() + ttlHours * 3600000, // Convert hours to milliseconds\n };\n\n try {\n cache.set(key, JSON.stringify(cached));\n } catch {\n // Storage quota exceeded or other error, ignore silently\n // Better to continue without caching than to fail\n }\n }\n\n /**\n * Clear all cached signatures (useful for testing or explicit cleanup)\n *\n * @param cache - Platform cache adapter instance\n * @example\n * ```typescript\n * // Clear all signatures when user logs out\n * SignatureCache.clear(cache);\n *\n * // Clear before running tests\n * beforeEach(() => {\n * SignatureCache.clear(cache);\n * });\n * ```\n */\n static clear(cache: VanaCacheAdapter): void {\n try {\n cache.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n private static getCacheKey(\n walletAddress: string,\n messageHash: string,\n ): string {\n return `${this.PREFIX}${getAddress(walletAddress)}:${messageHash}`;\n }\n\n /**\n * Generate a deterministic hash of a message object for cache key generation\n *\n * @remarks\n * Creates a cryptographically secure hash from complex objects including EIP-712 typed data.\n * Uses SHA-256 for collision resistance and deterministic key generation.\n * Handles BigInt serialization and sorts object keys for consistency.\n *\n * @param message - The message object to hash (typically EIP-712 typed data)\n * @returns A hex string hash (SHA-256) suitable for cache keys\n * @example\n * ```typescript\n * const typedData = {\n * domain: { name: 'Vana', version: '1' },\n * message: { nonce: 123n, grant: '...' }\n * };\n *\n * const hash = SignatureCache.hashMessage(typedData);\n * // Returns SHA-256 hash like: \"a1b2c3d4e5f6...\"\n * ```\n */\n static hashMessage(message: object): string {\n // Deterministically stringify the object with sorted keys\n const jsonString = JSON.stringify(message, this.deterministicReplacer);\n\n // Use SHA-256 for cryptographic hashing\n const hashBytes = sha256(new TextEncoder().encode(jsonString));\n return toHex(hashBytes);\n }\n\n /**\n * Deterministic JSON replacer that handles BigInt values and sorts object keys\n * This ensures consistent cache key generation for EIP-712 typed data\n *\n * @param _key - The object key being serialized (unused)\n * @param value - The value to serialize\n * @returns The serialized value with sorted keys for objects\n */\n private static deterministicReplacer(_key: string, value: unknown): unknown {\n if (typeof value === \"bigint\") {\n return `__BIGINT__${value.toString()}`;\n }\n // Sort object keys for deterministic serialization\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, key) => {\n sorted[key] = (value as Record<string, unknown>)[key];\n return sorted;\n },\n {} as Record<string, unknown>,\n );\n }\n return value;\n }\n}\n\n/**\n * Wrapper function to cache signature operations\n *\n * @param cache - The cache adapter to use for storage\n * @param walletAddress - The wallet address signing the message\n * @param typedData - The EIP-712 typed data being signed\n * @param signFn - Function that performs the actual signing\n * @param ttlHours - Cache TTL in hours (default 2)\n * @returns The signature (cached or newly generated)\n */\nexport async function withSignatureCache(\n cache: VanaCacheAdapter,\n walletAddress: string,\n typedData: Record<string, unknown>,\n signFn: () => Promise<Hash>,\n ttlHours?: number,\n): Promise<Hash> {\n // Create a hash of the typed data for the cache key\n const messageHash = SignatureCache.hashMessage(typedData);\n\n // Try to get from cache first\n const cached = SignatureCache.get(cache, walletAddress, messageHash);\n if (cached) {\n return cached;\n }\n\n // Not in cache, sign and store\n const signature = await signFn();\n SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);\n\n return signature;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/signatureCache.ts"],"sourcesContent":["/**\n * Provides signature caching to improve UX by avoiding repeated wallet prompts.\n *\n * @remarks\n * This module implements a secure signature cache that stores signed messages\n * temporarily to avoid repeatedly prompting users for the same signature.\n * It uses platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * and includes automatic expiration and cleanup.\n *\n * @category Utilities\n * @module utils/signatureCache\n */\n\nimport type { Hash } from \"viem\";\nimport { getAddress, toHex } from \"viem\";\nimport type { VanaCacheAdapter } from \"../platform/interface\";\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n/**\n * Represents a cached signature with expiration metadata.\n *\n * @internal\n */\ninterface CachedSignature {\n /** The cached signature hash */\n signature: Hash;\n /** Unix timestamp when this cache entry expires */\n expires: number;\n}\n\n/**\n * Simple signature cache using platform cache adapter to avoid repeated signing of identical messages.\n *\n * @remarks\n * This cache significantly improves UX by avoiding repeated wallet signature prompts\n * for identical operations. It's particularly useful for operations that may be\n * retried or called multiple times with the same parameters.\n *\n * Features:\n * - Platform-appropriate storage (sessionStorage in browser, memory in Node.js)\n * - Configurable TTL (default 2 hours)\n * - Automatic cleanup of expired entries\n * - Cache keys based on wallet address + message hash\n *\n * @example\n * ```typescript\n * // Check cache before requesting signature\n * const cached = SignatureCache.get(cache, walletAddress, messageHash);\n * if (cached) {\n * return cached;\n * }\n *\n * // Request signature and cache it\n * const signature = await wallet.signTypedData(typedData);\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n * ```\n * @category Utilities\n */\nexport class SignatureCache {\n private static readonly PREFIX = \"vana_sig_\";\n private static readonly DEFAULT_TTL_HOURS = 2;\n\n /**\n * Get a cached signature if it exists and hasn't expired\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @returns The cached signature if valid, null if expired or not found\n * @example\n * ```typescript\n * const messageHash = SignatureCache.hashMessage(typedData);\n * const cached = SignatureCache.get(cache, '0x123...', messageHash);\n * if (cached) {\n * console.log('Using cached signature:', cached);\n * }\n * ```\n */\n static get(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n ): Hash | null {\n const key = this.getCacheKey(walletAddress, messageHash);\n\n try {\n const stored = cache.get(key);\n if (!stored) return null;\n\n const cached: CachedSignature = JSON.parse(stored);\n\n // Check if expired\n if (Date.now() > cached.expires) {\n cache.delete(key);\n return null;\n }\n\n return cached.signature;\n } catch {\n // Invalid JSON or storage error, clean up\n try {\n cache.delete(key);\n } catch {\n // Ignore cache cleanup errors\n }\n return null;\n }\n }\n\n /**\n * Store a signature in the cache with configurable TTL\n *\n * @param cache - Platform cache adapter instance\n * @param walletAddress - Wallet address that created the signature\n * @param messageHash - Hash of the message that was signed\n * @param signature - The signature to cache\n * @param ttlHours - Time to live in hours (default: 2)\n * @example\n * ```typescript\n * const signature = await wallet.signTypedData(typedData);\n * const messageHash = SignatureCache.hashMessage(typedData);\n *\n * // Cache for default 2 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature);\n *\n * // Cache for 24 hours\n * SignatureCache.set(cache, walletAddress, messageHash, signature, 24);\n * ```\n */\n static set(\n cache: VanaCacheAdapter,\n walletAddress: string,\n messageHash: string,\n signature: Hash,\n ttlHours: number = this.DEFAULT_TTL_HOURS,\n ): void {\n const key = this.getCacheKey(walletAddress, messageHash);\n const cached: CachedSignature = {\n signature,\n expires: Date.now() + ttlHours * 3600000, // Convert hours to milliseconds\n };\n\n try {\n cache.set(key, JSON.stringify(cached));\n } catch {\n // Storage quota exceeded or other error, ignore silently\n // Better to continue without caching than to fail\n }\n }\n\n /**\n * Clear all cached signatures (useful for testing or explicit cleanup)\n *\n * @param cache - Platform cache adapter instance\n * @example\n * ```typescript\n * // Clear all signatures when user logs out\n * SignatureCache.clear(cache);\n *\n * // Clear before running tests\n * beforeEach(() => {\n * SignatureCache.clear(cache);\n * });\n * ```\n */\n static clear(cache: VanaCacheAdapter): void {\n try {\n cache.clear();\n } catch {\n // Ignore storage errors\n }\n }\n\n private static getCacheKey(\n walletAddress: string,\n messageHash: string,\n ): string {\n return `${this.PREFIX}${getAddress(walletAddress)}:${messageHash}`;\n }\n\n /**\n * Generate a deterministic hash of a message object for cache key generation\n *\n * @remarks\n * Creates a cryptographically secure hash from complex objects including EIP-712 typed data.\n * Uses SHA-256 for collision resistance and deterministic key generation.\n * Handles BigInt serialization and sorts object keys for consistency.\n *\n * @param message - The message object to hash (typically EIP-712 typed data)\n * @returns A hex string hash (SHA-256) suitable for cache keys\n * @example\n * ```typescript\n * const typedData = {\n * domain: { name: 'Vana', version: '1' },\n * message: { nonce: 123n, grant: '...' }\n * };\n *\n * const hash = SignatureCache.hashMessage(typedData);\n * // Returns SHA-256 hash like: \"a1b2c3d4e5f6...\"\n * ```\n */\n static hashMessage(message: object): string {\n // Deterministically stringify the object with sorted keys\n const jsonString = JSON.stringify(message, this.deterministicReplacer);\n\n // Use SHA-256 for cryptographic hashing\n const hashBytes = sha256(new TextEncoder().encode(jsonString));\n return toHex(hashBytes);\n }\n\n /**\n * Deterministic JSON replacer for consistent cache key generation.\n *\n * @remarks\n * Handles BigInt serialization and sorts object keys to ensure\n * identical objects always produce the same hash regardless of\n * property order.\n *\n * @param _key - The object key being serialized (unused)\n * @param value - The value to serialize\n * @returns The serialized value with sorted keys for objects\n *\n * @internal\n */\n private static deterministicReplacer(_key: string, value: unknown): unknown {\n if (typeof value === \"bigint\") {\n return `__BIGINT__${value.toString()}`;\n }\n // Sort object keys for deterministic serialization\n if (value !== null && typeof value === \"object\" && !Array.isArray(value)) {\n return Object.keys(value as Record<string, unknown>)\n .sort()\n .reduce(\n (sorted, key) => {\n sorted[key] = (value as Record<string, unknown>)[key];\n return sorted;\n },\n {} as Record<string, unknown>,\n );\n }\n return value;\n }\n}\n\n/**\n * Wraps signature operations with caching to avoid repeated prompts.\n *\n * @remarks\n * This helper function checks the cache before requesting a signature\n * and stores new signatures for future use. It significantly improves\n * UX for operations that may be retried or called multiple times.\n *\n * @param cache - The cache adapter to use for storage.\n * Obtain from platform adapter.\n * @param walletAddress - The wallet address signing the message.\n * Obtain from wallet connection.\n * @param typedData - The EIP-712 typed data being signed.\n * Typically permission or grant data.\n * @param signFn - Async function that performs the actual signing.\n * Usually calls wallet.signTypedData().\n * @param ttlHours - Cache TTL in hours.\n * Defaults to 2 hours.\n * @returns The signature (cached or newly generated)\n *\n * @example\n * ```typescript\n * const signature = await withSignatureCache(\n * platformAdapter.cache,\n * walletAddress,\n * typedData,\n * async () => wallet.signTypedData(typedData),\n * 24 // Cache for 24 hours\n * );\n * ```\n *\n * @category Utilities\n */\nexport async function withSignatureCache(\n cache: VanaCacheAdapter,\n walletAddress: string,\n typedData: Record<string, unknown>,\n signFn: () => Promise<Hash>,\n ttlHours?: number,\n): Promise<Hash> {\n // Create a hash of the typed data for the cache key\n const messageHash = SignatureCache.hashMessage(typedData);\n\n // Try to get from cache first\n const cached = SignatureCache.get(cache, walletAddress, messageHash);\n if (cached) {\n return cached;\n }\n\n // Not in cache, sign and store\n const signature = await signFn();\n SignatureCache.set(cache, walletAddress, messageHash, signature, ttlHours);\n\n return signature;\n}\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/transactionHelpers.ts"],"sourcesContent":["/**\n * Helper functions for creating typed transaction POJOs\n */\n\nimport type { Hash, Address } from \"viem\";\nimport type { TransactionResult } from \"../types/operations\";\nimport type { Contract, Fn } from \"../generated/event-types\";\n\n/**\n * Creates a strongly-typed TransactionResult POJO.\n *\n * @remarks\n * This helper ensures all required fields are present and typed correctly,\n * reducing boilerplate and preventing mistakes.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name\n * @param input.fn - Function name\n * @param input.chainId - Optional chain ID\n * @param input.value - Optional transaction value\n * @param input.nonce - Optional nonce\n * @param input.to - Optional recipient address\n * @returns Typed TransactionResult\n *\n * @example\n * ```typescript\n * return tx({\n * hash,\n * from: account.address,\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\",\n * });\n * ```\n */\nexport function tx<C extends Contract, F extends Fn<C>>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n\n/**\n * Creates a transaction result with literal type inference.\n * Use this when you need TypeScript to preserve exact string literals.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name\n * @param input.fn - Function name\n * @param input.chainId - Optional chain ID\n * @param input.value - Optional transaction value\n * @param input.nonce - Optional nonce\n * @param input.to - Optional recipient address\n * @returns Typed TransactionResult\n *\n * @example\n * ```typescript\n * const transaction = txLiteral({\n * hash: '0x...',\n * from: '0x...',\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\",\n * });\n * // TypeScript knows exactly: DataPortabilityPermissions + revokePermission\n * ```\n */\nexport function txLiteral<\n const C extends Contract,\n const F extends Fn<C>,\n>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCO,SAAS,GAAwC,OAS5B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;AA4BO,SAAS,UAGd,OAS0B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/transactionHelpers.ts"],"sourcesContent":["/**\n * Helper functions for creating typed transaction POJOs\n */\n\nimport type { Hash, Address } from \"viem\";\nimport type { TransactionResult } from \"../types/operations\";\nimport type { Contract, Fn } from \"../generated/event-types\";\n\n/**\n * Creates typed TransactionResult with validation.\n *\n * @remarks\n * Ensures type safety for transaction results.\n * Reduces boilerplate in transaction handling.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash from the blockchain\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name being called\n * @param input.fn - Function name being executed\n * @param input.chainId - Optional chain ID for network identification\n * @param input.value - Optional transaction value in wei\n * @param input.nonce - Optional transaction nonce for ordering\n * @param input.to - Optional recipient address for the transaction\n * @returns Typed TransactionResult POJO\n *\n * @example\n * ```typescript\n * return tx({\n * hash,\n * from: account.address,\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\"\n * });\n * ```\n */\nexport function tx<C extends Contract, F extends Fn<C>>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n\n/**\n * Creates a transaction result with literal type inference.\n * Use this when you need TypeScript to preserve exact string literals.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name\n * @param input.fn - Function name\n * @param input.chainId - Optional chain ID\n * @param input.value - Optional transaction value\n * @param input.nonce - Optional nonce\n * @param input.to - Optional recipient address\n * @returns Typed TransactionResult\n *\n * @example\n * ```typescript\n * const transaction = txLiteral({\n * hash: '0x...',\n * from: '0x...',\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\",\n * });\n * // TypeScript knows exactly: DataPortabilityPermissions + revokePermission\n * ```\n */\nexport function txLiteral<\n const C extends Contract,\n const F extends Fn<C>,\n>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCO,SAAS,GAAwC,OAS5B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;AA4BO,SAAS,UAGd,OAS0B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;","names":[]}
@@ -5,22 +5,22 @@ import type { Hash, Address } from "viem";
5
5
  import type { TransactionResult } from "../types/operations";
6
6
  import type { Contract, Fn } from "../generated/event-types";
7
7
  /**
8
- * Creates a strongly-typed TransactionResult POJO.
8
+ * Creates typed TransactionResult with validation.
9
9
  *
10
10
  * @remarks
11
- * This helper ensures all required fields are present and typed correctly,
12
- * reducing boilerplate and preventing mistakes.
11
+ * Ensures type safety for transaction results.
12
+ * Reduces boilerplate in transaction handling.
13
13
  *
14
14
  * @param input - Transaction details
15
- * @param input.hash - Transaction hash
15
+ * @param input.hash - Transaction hash from the blockchain
16
16
  * @param input.from - Transaction sender address
17
- * @param input.contract - Contract name
18
- * @param input.fn - Function name
19
- * @param input.chainId - Optional chain ID
20
- * @param input.value - Optional transaction value
21
- * @param input.nonce - Optional nonce
22
- * @param input.to - Optional recipient address
23
- * @returns Typed TransactionResult
17
+ * @param input.contract - Contract name being called
18
+ * @param input.fn - Function name being executed
19
+ * @param input.chainId - Optional chain ID for network identification
20
+ * @param input.value - Optional transaction value in wei
21
+ * @param input.nonce - Optional transaction nonce for ordering
22
+ * @param input.to - Optional recipient address for the transaction
23
+ * @returns Typed TransactionResult POJO
24
24
  *
25
25
  * @example
26
26
  * ```typescript
@@ -28,7 +28,7 @@ import type { Contract, Fn } from "../generated/event-types";
28
28
  * hash,
29
29
  * from: account.address,
30
30
  * contract: "DataPortabilityPermissions",
31
- * fn: "revokePermission",
31
+ * fn: "revokePermission"
32
32
  * });
33
33
  * ```
34
34
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/transactionHelpers.ts"],"sourcesContent":["/**\n * Helper functions for creating typed transaction POJOs\n */\n\nimport type { Hash, Address } from \"viem\";\nimport type { TransactionResult } from \"../types/operations\";\nimport type { Contract, Fn } from \"../generated/event-types\";\n\n/**\n * Creates a strongly-typed TransactionResult POJO.\n *\n * @remarks\n * This helper ensures all required fields are present and typed correctly,\n * reducing boilerplate and preventing mistakes.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name\n * @param input.fn - Function name\n * @param input.chainId - Optional chain ID\n * @param input.value - Optional transaction value\n * @param input.nonce - Optional nonce\n * @param input.to - Optional recipient address\n * @returns Typed TransactionResult\n *\n * @example\n * ```typescript\n * return tx({\n * hash,\n * from: account.address,\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\",\n * });\n * ```\n */\nexport function tx<C extends Contract, F extends Fn<C>>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n\n/**\n * Creates a transaction result with literal type inference.\n * Use this when you need TypeScript to preserve exact string literals.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name\n * @param input.fn - Function name\n * @param input.chainId - Optional chain ID\n * @param input.value - Optional transaction value\n * @param input.nonce - Optional nonce\n * @param input.to - Optional recipient address\n * @returns Typed TransactionResult\n *\n * @example\n * ```typescript\n * const transaction = txLiteral({\n * hash: '0x...',\n * from: '0x...',\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\",\n * });\n * // TypeScript knows exactly: DataPortabilityPermissions + revokePermission\n * ```\n */\nexport function txLiteral<\n const C extends Contract,\n const F extends Fn<C>,\n>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n"],"mappings":"AAoCO,SAAS,GAAwC,OAS5B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;AA4BO,SAAS,UAGd,OAS0B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/transactionHelpers.ts"],"sourcesContent":["/**\n * Helper functions for creating typed transaction POJOs\n */\n\nimport type { Hash, Address } from \"viem\";\nimport type { TransactionResult } from \"../types/operations\";\nimport type { Contract, Fn } from \"../generated/event-types\";\n\n/**\n * Creates typed TransactionResult with validation.\n *\n * @remarks\n * Ensures type safety for transaction results.\n * Reduces boilerplate in transaction handling.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash from the blockchain\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name being called\n * @param input.fn - Function name being executed\n * @param input.chainId - Optional chain ID for network identification\n * @param input.value - Optional transaction value in wei\n * @param input.nonce - Optional transaction nonce for ordering\n * @param input.to - Optional recipient address for the transaction\n * @returns Typed TransactionResult POJO\n *\n * @example\n * ```typescript\n * return tx({\n * hash,\n * from: account.address,\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\"\n * });\n * ```\n */\nexport function tx<C extends Contract, F extends Fn<C>>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n\n/**\n * Creates a transaction result with literal type inference.\n * Use this when you need TypeScript to preserve exact string literals.\n *\n * @param input - Transaction details\n * @param input.hash - Transaction hash\n * @param input.from - Transaction sender address\n * @param input.contract - Contract name\n * @param input.fn - Function name\n * @param input.chainId - Optional chain ID\n * @param input.value - Optional transaction value\n * @param input.nonce - Optional nonce\n * @param input.to - Optional recipient address\n * @returns Typed TransactionResult\n *\n * @example\n * ```typescript\n * const transaction = txLiteral({\n * hash: '0x...',\n * from: '0x...',\n * contract: \"DataPortabilityPermissions\",\n * fn: \"revokePermission\",\n * });\n * // TypeScript knows exactly: DataPortabilityPermissions + revokePermission\n * ```\n */\nexport function txLiteral<\n const C extends Contract,\n const F extends Fn<C>,\n>(input: {\n hash: Hash;\n from: Address;\n contract: C;\n fn: F;\n chainId?: number;\n value?: bigint;\n nonce?: number;\n to?: Address;\n}): TransactionResult<C, F> {\n // Create a new plain object to ensure independence and true POJO behavior\n return {\n hash: input.hash,\n from: input.from,\n contract: input.contract,\n fn: input.fn,\n ...(input.chainId !== undefined && { chainId: input.chainId }),\n ...(input.value !== undefined && { value: input.value }),\n ...(input.nonce !== undefined && { nonce: input.nonce }),\n ...(input.to !== undefined && { to: input.to }),\n };\n}\n"],"mappings":"AAoCO,SAAS,GAAwC,OAS5B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;AA4BO,SAAS,UAGd,OAS0B;AAE1B,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,UAAU,MAAM;AAAA,IAChB,IAAI,MAAM;AAAA,IACV,GAAI,MAAM,YAAY,UAAa,EAAE,SAAS,MAAM,QAAQ;AAAA,IAC5D,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,UAAU,UAAa,EAAE,OAAO,MAAM,MAAM;AAAA,IACtD,GAAI,MAAM,OAAO,UAAa,EAAE,IAAI,MAAM,GAAG;AAAA,EAC/C;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/typedDataConverter.ts"],"sourcesContent":["import type { TypedDataDefinition } from \"viem\";\nimport type { GenericTypedData } from \"../types/permissions\";\n\n/**\n * Converts a GenericTypedData object to a Viem-compatible TypedDataDefinition.\n * This function ensures type safety when passing typed data to viem's signTypedData method.\n *\n * @param typedData - The typed data object to convert\n * @returns A properly typed TypedDataDefinition for use with viem\n */\nexport function toViemTypedDataDefinition(\n typedData: GenericTypedData,\n): TypedDataDefinition {\n // Transform the types to match viem's expected format with readonly arrays\n const viemTypes: Record<string, readonly { name: string; type: string }[]> =\n {};\n\n for (const [typeName, typeArray] of Object.entries(typedData.types)) {\n // Create a new readonly array for each type\n viemTypes[typeName] = typeArray.map((field) => ({\n name: field.name,\n type: field.type,\n })) as readonly { name: string; type: string }[];\n }\n\n return {\n domain: typedData.domain,\n types: viemTypes as TypedDataDefinition[\"types\"],\n primaryType: typedData.primaryType,\n message: typedData.message,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,SAAS,0BACd,WACqB;AAErB,QAAM,YACJ,CAAC;AAEH,aAAW,CAAC,UAAU,SAAS,KAAK,OAAO,QAAQ,UAAU,KAAK,GAAG;AAEnE,cAAU,QAAQ,IAAI,UAAU,IAAI,CAAC,WAAW;AAAA,MAC9C,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,IACd,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,QAAQ,UAAU;AAAA,IAClB,OAAO;AAAA,IACP,aAAa,UAAU;AAAA,IACvB,SAAS,UAAU;AAAA,EACrB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/typedDataConverter.ts"],"sourcesContent":["/**\n * Provides type-safe conversion between Vana and viem typed data formats.\n *\n * @remarks\n * This module bridges the gap between Vana's generic typed data structure\n * and viem's strict TypedDataDefinition format, ensuring compatibility\n * for EIP-712 signature operations.\n *\n * @category Utilities\n * @module typedDataConverter\n */\n\nimport type { TypedDataDefinition } from \"viem\";\nimport type { GenericTypedData } from \"../types/permissions\";\n\n/**\n * Converts a GenericTypedData object to a viem-compatible TypedDataDefinition.\n *\n * @remarks\n * Transforms Vana's flexible typed data format into viem's strict format\n * with readonly arrays. This ensures type safety when passing typed data\n * to viem's `signTypedData` method for EIP-712 signatures.\n *\n * @param typedData - The typed data object to convert.\n * Obtain from permission operations or server responses.\n * @returns A properly typed TypedDataDefinition for use with viem\n *\n * @example\n * ```typescript\n * const vanTypedData: GenericTypedData = {\n * domain: { name: 'Vana', version: '1', chainId: 14800 },\n * types: {\n * Permission: [\n * { name: 'grantee', type: 'address' },\n * { name: 'operation', type: 'string' }\n * ]\n * },\n * primaryType: 'Permission',\n * message: { grantee: '0x...', operation: 'read' }\n * };\n *\n * const viemTypedData = toViemTypedDataDefinition(vanaTypedData);\n * const signature = await walletClient.signTypedData(viemTypedData);\n * ```\n *\n * @category Utilities\n */\nexport function toViemTypedDataDefinition(\n typedData: GenericTypedData,\n): TypedDataDefinition {\n // Transform the types to match viem's expected format with readonly arrays\n const viemTypes: Record<string, readonly { name: string; type: string }[]> =\n {};\n\n for (const [typeName, typeArray] of Object.entries(typedData.types)) {\n // Create a new readonly array for each type\n viemTypes[typeName] = typeArray.map((field) => ({\n name: field.name,\n type: field.type,\n })) as readonly { name: string; type: string }[];\n }\n\n return {\n domain: typedData.domain,\n types: viemTypes as TypedDataDefinition[\"types\"],\n primaryType: typedData.primaryType,\n message: typedData.message,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA+CO,SAAS,0BACd,WACqB;AAErB,QAAM,YACJ,CAAC;AAEH,aAAW,CAAC,UAAU,SAAS,KAAK,OAAO,QAAQ,UAAU,KAAK,GAAG;AAEnE,cAAU,QAAQ,IAAI,UAAU,IAAI,CAAC,WAAW;AAAA,MAC9C,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,IACd,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,QAAQ,UAAU;AAAA,IAClB,OAAO;AAAA,IACP,aAAa,UAAU;AAAA,IACvB,SAAS,UAAU;AAAA,EACrB;AACF;","names":[]}
@@ -1,10 +1,46 @@
1
+ /**
2
+ * Provides type-safe conversion between Vana and viem typed data formats.
3
+ *
4
+ * @remarks
5
+ * This module bridges the gap between Vana's generic typed data structure
6
+ * and viem's strict TypedDataDefinition format, ensuring compatibility
7
+ * for EIP-712 signature operations.
8
+ *
9
+ * @category Utilities
10
+ * @module typedDataConverter
11
+ */
1
12
  import type { TypedDataDefinition } from "viem";
2
13
  import type { GenericTypedData } from "../types/permissions";
3
14
  /**
4
- * Converts a GenericTypedData object to a Viem-compatible TypedDataDefinition.
5
- * This function ensures type safety when passing typed data to viem's signTypedData method.
15
+ * Converts a GenericTypedData object to a viem-compatible TypedDataDefinition.
6
16
  *
7
- * @param typedData - The typed data object to convert
17
+ * @remarks
18
+ * Transforms Vana's flexible typed data format into viem's strict format
19
+ * with readonly arrays. This ensures type safety when passing typed data
20
+ * to viem's `signTypedData` method for EIP-712 signatures.
21
+ *
22
+ * @param typedData - The typed data object to convert.
23
+ * Obtain from permission operations or server responses.
8
24
  * @returns A properly typed TypedDataDefinition for use with viem
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const vanTypedData: GenericTypedData = {
29
+ * domain: { name: 'Vana', version: '1', chainId: 14800 },
30
+ * types: {
31
+ * Permission: [
32
+ * { name: 'grantee', type: 'address' },
33
+ * { name: 'operation', type: 'string' }
34
+ * ]
35
+ * },
36
+ * primaryType: 'Permission',
37
+ * message: { grantee: '0x...', operation: 'read' }
38
+ * };
39
+ *
40
+ * const viemTypedData = toViemTypedDataDefinition(vanaTypedData);
41
+ * const signature = await walletClient.signTypedData(viemTypedData);
42
+ * ```
43
+ *
44
+ * @category Utilities
9
45
  */
10
46
  export declare function toViemTypedDataDefinition(typedData: GenericTypedData): TypedDataDefinition;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/typedDataConverter.ts"],"sourcesContent":["import type { TypedDataDefinition } from \"viem\";\nimport type { GenericTypedData } from \"../types/permissions\";\n\n/**\n * Converts a GenericTypedData object to a Viem-compatible TypedDataDefinition.\n * This function ensures type safety when passing typed data to viem's signTypedData method.\n *\n * @param typedData - The typed data object to convert\n * @returns A properly typed TypedDataDefinition for use with viem\n */\nexport function toViemTypedDataDefinition(\n typedData: GenericTypedData,\n): TypedDataDefinition {\n // Transform the types to match viem's expected format with readonly arrays\n const viemTypes: Record<string, readonly { name: string; type: string }[]> =\n {};\n\n for (const [typeName, typeArray] of Object.entries(typedData.types)) {\n // Create a new readonly array for each type\n viemTypes[typeName] = typeArray.map((field) => ({\n name: field.name,\n type: field.type,\n })) as readonly { name: string; type: string }[];\n }\n\n return {\n domain: typedData.domain,\n types: viemTypes as TypedDataDefinition[\"types\"],\n primaryType: typedData.primaryType,\n message: typedData.message,\n };\n}\n"],"mappings":"AAUO,SAAS,0BACd,WACqB;AAErB,QAAM,YACJ,CAAC;AAEH,aAAW,CAAC,UAAU,SAAS,KAAK,OAAO,QAAQ,UAAU,KAAK,GAAG;AAEnE,cAAU,QAAQ,IAAI,UAAU,IAAI,CAAC,WAAW;AAAA,MAC9C,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,IACd,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,QAAQ,UAAU;AAAA,IAClB,OAAO;AAAA,IACP,aAAa,UAAU;AAAA,IACvB,SAAS,UAAU;AAAA,EACrB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/typedDataConverter.ts"],"sourcesContent":["/**\n * Provides type-safe conversion between Vana and viem typed data formats.\n *\n * @remarks\n * This module bridges the gap between Vana's generic typed data structure\n * and viem's strict TypedDataDefinition format, ensuring compatibility\n * for EIP-712 signature operations.\n *\n * @category Utilities\n * @module typedDataConverter\n */\n\nimport type { TypedDataDefinition } from \"viem\";\nimport type { GenericTypedData } from \"../types/permissions\";\n\n/**\n * Converts a GenericTypedData object to a viem-compatible TypedDataDefinition.\n *\n * @remarks\n * Transforms Vana's flexible typed data format into viem's strict format\n * with readonly arrays. This ensures type safety when passing typed data\n * to viem's `signTypedData` method for EIP-712 signatures.\n *\n * @param typedData - The typed data object to convert.\n * Obtain from permission operations or server responses.\n * @returns A properly typed TypedDataDefinition for use with viem\n *\n * @example\n * ```typescript\n * const vanTypedData: GenericTypedData = {\n * domain: { name: 'Vana', version: '1', chainId: 14800 },\n * types: {\n * Permission: [\n * { name: 'grantee', type: 'address' },\n * { name: 'operation', type: 'string' }\n * ]\n * },\n * primaryType: 'Permission',\n * message: { grantee: '0x...', operation: 'read' }\n * };\n *\n * const viemTypedData = toViemTypedDataDefinition(vanaTypedData);\n * const signature = await walletClient.signTypedData(viemTypedData);\n * ```\n *\n * @category Utilities\n */\nexport function toViemTypedDataDefinition(\n typedData: GenericTypedData,\n): TypedDataDefinition {\n // Transform the types to match viem's expected format with readonly arrays\n const viemTypes: Record<string, readonly { name: string; type: string }[]> =\n {};\n\n for (const [typeName, typeArray] of Object.entries(typedData.types)) {\n // Create a new readonly array for each type\n viemTypes[typeName] = typeArray.map((field) => ({\n name: field.name,\n type: field.type,\n })) as readonly { name: string; type: string }[];\n }\n\n return {\n domain: typedData.domain,\n types: viemTypes as TypedDataDefinition[\"types\"],\n primaryType: typedData.primaryType,\n message: typedData.message,\n };\n}\n"],"mappings":"AA+CO,SAAS,0BACd,WACqB;AAErB,QAAM,YACJ,CAAC;AAEH,aAAW,CAAC,UAAU,SAAS,KAAK,OAAO,QAAQ,UAAU,KAAK,GAAG;AAEnE,cAAU,QAAQ,IAAI,UAAU,IAAI,CAAC,WAAW;AAAA,MAC9C,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,IACd,EAAE;AAAA,EACJ;AAEA,SAAO;AAAA,IACL,QAAQ,UAAU;AAAA,IAClB,OAAO;AAAA,IACP,aAAa,UAAU;AAAA,IACvB,SAAS,UAAU;AAAA,EACrB;AACF;","names":[]}
@@ -24,6 +24,13 @@ __export(urlResolver_exports, {
24
24
  module.exports = __toCommonJS(urlResolver_exports);
25
25
  var import_download = require("./download");
26
26
  class UrlResolutionError extends Error {
27
+ /**
28
+ * Creates a new URL resolution error.
29
+ *
30
+ * @param message - Description of what went wrong
31
+ * @param url - The URL that failed to resolve
32
+ * @param cause - The underlying error that caused the failure
33
+ */
27
34
  constructor(message, url, cause) {
28
35
  super(message);
29
36
  this.url = url;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/urlResolver.ts"],"sourcesContent":["/**\n * Universal URL resolver for the Vana SDK\n *\n * Handles fetching data from various protocols (IPFS, HTTP, Arweave, etc.)\n * in a consistent, reliable way.\n */\n\nimport { universalFetch } from \"./download\";\n\n/**\n * Error thrown when URL resolution fails\n */\nexport class UrlResolutionError extends Error {\n constructor(\n message: string,\n public readonly url: string,\n public override readonly cause?: Error,\n ) {\n super(message);\n this.name = \"UrlResolutionError\";\n }\n}\n\n/**\n * Fetches and parses JSON data from any supported URL protocol\n *\n * @param url - The URL to fetch from (supports ipfs://, https://, http://, ar://)\n * @param downloadRelayer - Optional download relayer for CORS bypass\n * @param downloadRelayer.proxyDownload - Function to proxy downloads through application server\n * @returns Promise resolving to the parsed JSON data\n * @throws {UrlResolutionError} When the URL cannot be resolved or parsed\n *\n * @example\n * ```typescript\n * // Fetch from IPFS\n * const data = await fetchFromUrl(\"ipfs://QmXxx...\");\n *\n * // Fetch from HTTPS\n * const data = await fetchFromUrl(\"https://example.com/data.json\");\n *\n * // Handles protocol conversion internally\n * const schema = await fetchFromUrl(schemaDefinitionUrl);\n * ```\n */\nexport async function fetchFromUrl(\n url: string,\n downloadRelayer?: { proxyDownload: (url: string) => Promise<Blob> },\n): Promise<unknown> {\n try {\n // Use unified download utility with automatic fallbacks\n const response = await universalFetch(url, downloadRelayer);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Parse JSON response\n const data = await response.json();\n return data;\n } catch (error) {\n throw new UrlResolutionError(\n `Failed to fetch from ${url}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n url,\n error instanceof Error ? error : undefined,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,sBAA+B;AAKxB,MAAM,2BAA2B,MAAM;AAAA,EAC5C,YACE,SACgB,KACS,OACzB;AACA,UAAM,OAAO;AAHG;AACS;AAGzB,SAAK,OAAO;AAAA,EACd;AACF;AAuBA,eAAsB,aACpB,KACA,iBACkB;AAClB,MAAI;AAEF,UAAM,WAAW,UAAM,gCAAe,KAAK,eAAe;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IACnE;AAGA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,wBAAwB,GAAG,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACxF;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/urlResolver.ts"],"sourcesContent":["/**\n * Provides universal URL resolution across multiple protocols.\n *\n * @remarks\n * This module enables fetching data from various protocols including IPFS,\n * HTTP/HTTPS, and Arweave through a unified interface. It handles protocol\n * conversion, gateway selection, and fallback strategies automatically.\n *\n * @category Utilities\n * @module utils/urlResolver\n */\n\nimport { universalFetch } from \"./download\";\n\n/**\n * Indicates that URL resolution or data fetching failed.\n *\n * @remarks\n * This error provides context about which URL failed and why,\n * making it easier to debug issues with external resources.\n *\n * @category Errors\n */\nexport class UrlResolutionError extends Error {\n /**\n * Creates a new URL resolution error.\n *\n * @param message - Description of what went wrong\n * @param url - The URL that failed to resolve\n * @param cause - The underlying error that caused the failure\n */\n constructor(\n message: string,\n public readonly url: string,\n public override readonly cause?: Error,\n ) {\n super(message);\n this.name = \"UrlResolutionError\";\n }\n}\n\n/**\n * Fetches and parses JSON data from any supported URL protocol\n *\n * @param url - The URL to fetch from (supports ipfs://, https://, http://, ar://)\n * @param downloadRelayer - Optional download relayer for CORS bypass\n * @param downloadRelayer.proxyDownload - Function to proxy downloads through application server\n * @returns Promise resolving to the parsed JSON data\n * @throws {UrlResolutionError} When the URL cannot be resolved or parsed\n *\n * @example\n * ```typescript\n * // Fetch from IPFS\n * const data = await fetchFromUrl(\"ipfs://QmXxx...\");\n *\n * // Fetch from HTTPS\n * const data = await fetchFromUrl(\"https://example.com/data.json\");\n *\n * // Handles protocol conversion internally\n * const schema = await fetchFromUrl(schemaDefinitionUrl);\n * ```\n */\nexport async function fetchFromUrl(\n url: string,\n downloadRelayer?: { proxyDownload: (url: string) => Promise<Blob> },\n): Promise<unknown> {\n try {\n // Use unified download utility with automatic fallbacks\n const response = await universalFetch(url, downloadRelayer);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Parse JSON response\n const data = await response.json();\n return data;\n } catch (error) {\n throw new UrlResolutionError(\n `Failed to fetch from ${url}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n url,\n error instanceof Error ? error : undefined,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,sBAA+B;AAWxB,MAAM,2BAA2B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5C,YACE,SACgB,KACS,OACzB;AACA,UAAM,OAAO;AAHG;AACS;AAGzB,SAAK,OAAO;AAAA,EACd;AACF;AAuBA,eAAsB,aACpB,KACA,iBACkB;AAClB,MAAI;AAEF,UAAM,WAAW,UAAM,gCAAe,KAAK,eAAe;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IACnE;AAGA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,wBAAwB,GAAG,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACxF;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
@@ -1,15 +1,33 @@
1
1
  /**
2
- * Universal URL resolver for the Vana SDK
2
+ * Provides universal URL resolution across multiple protocols.
3
3
  *
4
- * Handles fetching data from various protocols (IPFS, HTTP, Arweave, etc.)
5
- * in a consistent, reliable way.
4
+ * @remarks
5
+ * This module enables fetching data from various protocols including IPFS,
6
+ * HTTP/HTTPS, and Arweave through a unified interface. It handles protocol
7
+ * conversion, gateway selection, and fallback strategies automatically.
8
+ *
9
+ * @category Utilities
10
+ * @module utils/urlResolver
6
11
  */
7
12
  /**
8
- * Error thrown when URL resolution fails
13
+ * Indicates that URL resolution or data fetching failed.
14
+ *
15
+ * @remarks
16
+ * This error provides context about which URL failed and why,
17
+ * making it easier to debug issues with external resources.
18
+ *
19
+ * @category Errors
9
20
  */
10
21
  export declare class UrlResolutionError extends Error {
11
22
  readonly url: string;
12
23
  readonly cause?: Error | undefined;
24
+ /**
25
+ * Creates a new URL resolution error.
26
+ *
27
+ * @param message - Description of what went wrong
28
+ * @param url - The URL that failed to resolve
29
+ * @param cause - The underlying error that caused the failure
30
+ */
13
31
  constructor(message: string, url: string, cause?: Error | undefined);
14
32
  }
15
33
  /**
@@ -1,5 +1,12 @@
1
1
  import { universalFetch } from "./download";
2
2
  class UrlResolutionError extends Error {
3
+ /**
4
+ * Creates a new URL resolution error.
5
+ *
6
+ * @param message - Description of what went wrong
7
+ * @param url - The URL that failed to resolve
8
+ * @param cause - The underlying error that caused the failure
9
+ */
3
10
  constructor(message, url, cause) {
4
11
  super(message);
5
12
  this.url = url;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/urlResolver.ts"],"sourcesContent":["/**\n * Universal URL resolver for the Vana SDK\n *\n * Handles fetching data from various protocols (IPFS, HTTP, Arweave, etc.)\n * in a consistent, reliable way.\n */\n\nimport { universalFetch } from \"./download\";\n\n/**\n * Error thrown when URL resolution fails\n */\nexport class UrlResolutionError extends Error {\n constructor(\n message: string,\n public readonly url: string,\n public override readonly cause?: Error,\n ) {\n super(message);\n this.name = \"UrlResolutionError\";\n }\n}\n\n/**\n * Fetches and parses JSON data from any supported URL protocol\n *\n * @param url - The URL to fetch from (supports ipfs://, https://, http://, ar://)\n * @param downloadRelayer - Optional download relayer for CORS bypass\n * @param downloadRelayer.proxyDownload - Function to proxy downloads through application server\n * @returns Promise resolving to the parsed JSON data\n * @throws {UrlResolutionError} When the URL cannot be resolved or parsed\n *\n * @example\n * ```typescript\n * // Fetch from IPFS\n * const data = await fetchFromUrl(\"ipfs://QmXxx...\");\n *\n * // Fetch from HTTPS\n * const data = await fetchFromUrl(\"https://example.com/data.json\");\n *\n * // Handles protocol conversion internally\n * const schema = await fetchFromUrl(schemaDefinitionUrl);\n * ```\n */\nexport async function fetchFromUrl(\n url: string,\n downloadRelayer?: { proxyDownload: (url: string) => Promise<Blob> },\n): Promise<unknown> {\n try {\n // Use unified download utility with automatic fallbacks\n const response = await universalFetch(url, downloadRelayer);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Parse JSON response\n const data = await response.json();\n return data;\n } catch (error) {\n throw new UrlResolutionError(\n `Failed to fetch from ${url}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n url,\n error instanceof Error ? error : undefined,\n );\n }\n}\n"],"mappings":"AAOA,SAAS,sBAAsB;AAKxB,MAAM,2BAA2B,MAAM;AAAA,EAC5C,YACE,SACgB,KACS,OACzB;AACA,UAAM,OAAO;AAHG;AACS;AAGzB,SAAK,OAAO;AAAA,EACd;AACF;AAuBA,eAAsB,aACpB,KACA,iBACkB;AAClB,MAAI;AAEF,UAAM,WAAW,MAAM,eAAe,KAAK,eAAe;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IACnE;AAGA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,wBAAwB,GAAG,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACxF;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/urlResolver.ts"],"sourcesContent":["/**\n * Provides universal URL resolution across multiple protocols.\n *\n * @remarks\n * This module enables fetching data from various protocols including IPFS,\n * HTTP/HTTPS, and Arweave through a unified interface. It handles protocol\n * conversion, gateway selection, and fallback strategies automatically.\n *\n * @category Utilities\n * @module utils/urlResolver\n */\n\nimport { universalFetch } from \"./download\";\n\n/**\n * Indicates that URL resolution or data fetching failed.\n *\n * @remarks\n * This error provides context about which URL failed and why,\n * making it easier to debug issues with external resources.\n *\n * @category Errors\n */\nexport class UrlResolutionError extends Error {\n /**\n * Creates a new URL resolution error.\n *\n * @param message - Description of what went wrong\n * @param url - The URL that failed to resolve\n * @param cause - The underlying error that caused the failure\n */\n constructor(\n message: string,\n public readonly url: string,\n public override readonly cause?: Error,\n ) {\n super(message);\n this.name = \"UrlResolutionError\";\n }\n}\n\n/**\n * Fetches and parses JSON data from any supported URL protocol\n *\n * @param url - The URL to fetch from (supports ipfs://, https://, http://, ar://)\n * @param downloadRelayer - Optional download relayer for CORS bypass\n * @param downloadRelayer.proxyDownload - Function to proxy downloads through application server\n * @returns Promise resolving to the parsed JSON data\n * @throws {UrlResolutionError} When the URL cannot be resolved or parsed\n *\n * @example\n * ```typescript\n * // Fetch from IPFS\n * const data = await fetchFromUrl(\"ipfs://QmXxx...\");\n *\n * // Fetch from HTTPS\n * const data = await fetchFromUrl(\"https://example.com/data.json\");\n *\n * // Handles protocol conversion internally\n * const schema = await fetchFromUrl(schemaDefinitionUrl);\n * ```\n */\nexport async function fetchFromUrl(\n url: string,\n downloadRelayer?: { proxyDownload: (url: string) => Promise<Blob> },\n): Promise<unknown> {\n try {\n // Use unified download utility with automatic fallbacks\n const response = await universalFetch(url, downloadRelayer);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Parse JSON response\n const data = await response.json();\n return data;\n } catch (error) {\n throw new UrlResolutionError(\n `Failed to fetch from ${url}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n url,\n error instanceof Error ? error : undefined,\n );\n }\n}\n"],"mappings":"AAYA,SAAS,sBAAsB;AAWxB,MAAM,2BAA2B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ5C,YACE,SACgB,KACS,OACzB;AACA,UAAM,OAAO;AAHG;AACS;AAGzB,SAAK,OAAO;AAAA,EACd;AACF;AAuBA,eAAsB,aACpB,KACA,iBACkB;AAClB,MAAI;AAEF,UAAM,WAAW,MAAM,eAAe,KAAK,eAAe;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,IACnE;AAGA,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,wBAAwB,GAAG,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACxF;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;","names":[]}
@@ -48,7 +48,8 @@ function hasAddress(account) {
48
48
  return /^0x[a-fA-F0-9]{40}$/.test(account);
49
49
  }
50
50
  if (typeof account === "object" && "address" in account) {
51
- const addr = account.address;
51
+ const accountWithAddress = account;
52
+ const addr = accountWithAddress.address;
52
53
  return typeof addr === "string" && /^0x[a-fA-F0-9]{40}$/.test(addr);
53
54
  }
54
55
  return false;