@lukso/transaction-decoder 1.0.1-dev.0f1bea5

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 (110) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +486 -0
  3. package/dist/browser.cjs +6912 -0
  4. package/dist/browser.cjs.map +1 -0
  5. package/dist/browser.d.cts +6 -0
  6. package/dist/browser.d.ts +6 -0
  7. package/dist/browser.js +131 -0
  8. package/dist/browser.js.map +1 -0
  9. package/dist/cdn/transaction-decoder.global.js +296 -0
  10. package/dist/cdn/transaction-decoder.global.js.map +1 -0
  11. package/dist/chunk-GGBHTWJL.js +437 -0
  12. package/dist/chunk-GGBHTWJL.js.map +1 -0
  13. package/dist/chunk-GXZOF3QY.js +839 -0
  14. package/dist/chunk-GXZOF3QY.js.map +1 -0
  15. package/dist/chunk-LJ6ES5XF.js +776 -0
  16. package/dist/chunk-LJ6ES5XF.js.map +1 -0
  17. package/dist/chunk-XVHJWV5U.js +4925 -0
  18. package/dist/chunk-XVHJWV5U.js.map +1 -0
  19. package/dist/data.cjs +5518 -0
  20. package/dist/data.cjs.map +1 -0
  21. package/dist/data.d.cts +43 -0
  22. package/dist/data.d.ts +43 -0
  23. package/dist/data.js +55 -0
  24. package/dist/data.js.map +1 -0
  25. package/dist/index-BzXh7poJ.d.cts +524 -0
  26. package/dist/index-BzXh7poJ.d.ts +524 -0
  27. package/dist/index.cjs +6912 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +756 -0
  30. package/dist/index.d.ts +756 -0
  31. package/dist/index.js +131 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/server.cjs +5644 -0
  34. package/dist/server.cjs.map +1 -0
  35. package/dist/server.d.cts +217 -0
  36. package/dist/server.d.ts +217 -0
  37. package/dist/server.js +644 -0
  38. package/dist/server.js.map +1 -0
  39. package/dist/utils-CBAkjQh3.d.cts +108 -0
  40. package/dist/utils-xT9-km0r.d.ts +108 -0
  41. package/package.json +101 -0
  42. package/src/browser.ts +13 -0
  43. package/src/client/resolveAddresses.ts +157 -0
  44. package/src/core/addressCollector.ts +153 -0
  45. package/src/core/addressResolver.ts +135 -0
  46. package/src/core/dataModel.ts +888 -0
  47. package/src/core/instance.ts +33 -0
  48. package/src/core/integrateDecoder.ts +325 -0
  49. package/src/data.ts +70 -0
  50. package/src/decoder/GENERATOR_PROPOSAL.md +182 -0
  51. package/src/decoder/THREE_PHASE_EXAMPLE.md +108 -0
  52. package/src/decoder/aggregation.ts +218 -0
  53. package/src/decoder/browserCache.ts +237 -0
  54. package/src/decoder/cache/README.md +126 -0
  55. package/src/decoder/cache/index.ts +44 -0
  56. package/src/decoder/cache.ts +139 -0
  57. package/src/decoder/constants.ts +125 -0
  58. package/src/decoder/decodeTransaction.ts +292 -0
  59. package/src/decoder/errors.ts +95 -0
  60. package/src/decoder/events.ts +192 -0
  61. package/src/decoder/functionSignature.ts +344 -0
  62. package/src/decoder/getDataFromExternalSources.ts +248 -0
  63. package/src/decoder/graphqlWS.ts +22 -0
  64. package/src/decoder/interfaces.ts +185 -0
  65. package/src/decoder/keyValue.ts +5 -0
  66. package/src/decoder/kvCache.ts +241 -0
  67. package/src/decoder/lruCache.ts +184 -0
  68. package/src/decoder/lsp7Mint.test.ts +179 -0
  69. package/src/decoder/lsp7TransferBatch.test.ts +105 -0
  70. package/src/decoder/plugins/RegistryAbi.ts +562 -0
  71. package/src/decoder/plugins/enhanceBurntPix.ts +132 -0
  72. package/src/decoder/plugins/enhanceGraffiti.ts +70 -0
  73. package/src/decoder/plugins/enhanceLSP0ERC725Account.ts +179 -0
  74. package/src/decoder/plugins/enhanceLSP26FollowerSystem.ts +88 -0
  75. package/src/decoder/plugins/enhanceLSP6KeyManager.ts +231 -0
  76. package/src/decoder/plugins/enhanceLSP7DigitalAsset.ts +165 -0
  77. package/src/decoder/plugins/enhanceLSP8IdentifiableDigitalAsset.ts +170 -0
  78. package/src/decoder/plugins/enhanceLSP9Vault.ts +57 -0
  79. package/src/decoder/plugins/enhanceRetrieveAbi.ts +85 -0
  80. package/src/decoder/plugins/enhanceSetData.ts +135 -0
  81. package/src/decoder/plugins/index.ts +99 -0
  82. package/src/decoder/plugins/schemaDefault.ts +318 -0
  83. package/src/decoder/plugins/standardPlugin.ts +202 -0
  84. package/src/decoder/registry.ts +322 -0
  85. package/src/decoder/singleGQL.ts +293 -0
  86. package/src/decoder/transaction.ts +198 -0
  87. package/src/decoder/types.ts +465 -0
  88. package/src/decoder/utils.ts +212 -0
  89. package/src/example/usage.ts +172 -0
  90. package/src/index.ts +174 -0
  91. package/src/server/addressResolver.ts +68 -0
  92. package/src/server/caches.ts +209 -0
  93. package/src/server/decodeTransactionSync.ts +156 -0
  94. package/src/server/decodeTransactionsBatch.ts +207 -0
  95. package/src/server/finishDecoding.ts +116 -0
  96. package/src/server/index.ts +81 -0
  97. package/src/server/lsp23Resolver.test.ts +46 -0
  98. package/src/server/lsp23Resolver.ts +419 -0
  99. package/src/server/types.ts +168 -0
  100. package/src/server.ts +22 -0
  101. package/src/shared/addressResolver.ts +651 -0
  102. package/src/shared/cache.ts +144 -0
  103. package/src/shared/constants.ts +21 -0
  104. package/src/stubs/tty.ts +13 -0
  105. package/src/stubs/util.ts +42 -0
  106. package/src/types/index.ts +154 -0
  107. package/src/types/provider.ts +46 -0
  108. package/src/umd.ts +13 -0
  109. package/src/utils/debug.ts +49 -0
  110. package/src/utils/json-bigint.ts +47 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/addressResolver.ts","../src/server/caches.ts","../src/server/decodeTransactionSync.ts","../src/server/decodeTransactionsBatch.ts","../src/server/finishDecoding.ts","../src/server/index.ts"],"sourcesContent":["import type { Chain } from 'viem'\nimport { fetchMultipleAddresses } from '../shared/addressResolver'\nimport type { AddressIdentityCache } from '../shared/cache'\nimport type { DataKey, EnhancedInfo } from '../types'\nimport type { ServerDecoderCaches } from './caches'\n\n/**\n * Server-side address resolver with caching\n */\nexport class ServerAddressResolver {\n private cacheAdapter: AddressIdentityCache\n\n constructor(\n private graphqlEndpoint: string,\n private chain: Chain,\n private caches: ServerDecoderCaches\n ) {\n // Create adapter to use ServerDecoderCaches as AddressIdentityCache\n this.cacheAdapter = {\n get: (key: DataKey) => this.caches.getAddress(key),\n set: (key: DataKey, value: EnhancedInfo) =>\n this.caches.setAddress(key, value),\n has: (key: DataKey) => this.caches.hasAddress(key),\n getMany: (keys: DataKey[]) => this.caches.getAddresses(keys),\n }\n }\n\n /**\n * Resolve addresses, using cache when possible\n */\n async resolveAddresses(\n addresses: readonly DataKey[]\n ): Promise<Map<DataKey, EnhancedInfo>> {\n // Use the shared implementation with cache adapter\n return fetchMultipleAddresses(\n addresses,\n this.graphqlEndpoint,\n this.cacheAdapter\n )\n }\n\n /**\n * Resolve addresses with timeout\n */\n async resolveAddressesWithTimeout(\n addresses: DataKey[],\n timeoutMs: number\n ): Promise<Map<DataKey, EnhancedInfo>> {\n return Promise.race([\n this.resolveAddresses(addresses),\n new Promise<Map<DataKey, EnhancedInfo>>((resolve) => {\n setTimeout(() => {\n // On timeout, return whatever we have cached\n const results = this.caches.getAddresses(addresses)\n resolve(results)\n }, timeoutMs)\n }),\n ])\n }\n\n /**\n * Warm the cache with specific addresses\n */\n async warmCache(addresses: DataKey[]): Promise<void> {\n // Simply call resolveAddresses which will cache any uncached addresses\n await this.resolveAddresses(addresses)\n }\n}\n","import { LRUCache } from 'lru-cache'\nimport type { Abi } from 'viem'\nimport type { DecoderResult, Info } from '../decoder/types'\nimport type { DataKey, EnhancedInfo } from '../types'\nimport type { CacheStats } from './types'\n\n/**\n * Multi-level caching system for server-side decoder\n */\nexport class ServerDecoderCaches {\n // Level 1: Decoded transaction cache (keyed by transaction hash)\n private transactionCache: LRUCache<string, DecoderResult>\n private transactionStats = { hits: 0, misses: 0 }\n\n // Level 2: Address metadata cache (keyed by address or address:tokenId)\n private addressCache: LRUCache<string, EnhancedInfo>\n private addressStats = { hits: 0, misses: 0 }\n\n // Level 3: Contract ABI cache (keyed by address)\n private abiCache: LRUCache<string, Abi>\n private abiStats = { hits: 0, misses: 0 }\n\n // Level 4: Schema decode cache (keyed by key:value)\n private schemaCache: LRUCache<string, Info>\n private schemaStats = { hits: 0, misses: 0 }\n\n constructor(\n options: {\n transactionCacheSize?: number\n addressCacheSize?: number\n abiCacheSize?: number\n schemaCacheSize?: number\n } = {}\n ) {\n // Transaction cache - store complete decoded results\n this.transactionCache = new LRUCache<string, DecoderResult>({\n max: options.transactionCacheSize || 10000,\n ttl: 1000 * 60 * 60, // 1 hour TTL\n updateAgeOnGet: true,\n updateAgeOnHas: true,\n })\n\n // Address cache - store profile/asset metadata\n this.addressCache = new LRUCache<string, EnhancedInfo>({\n max: options.addressCacheSize || 50000,\n ttl: 1000 * 60 * 60 * 24, // 24 hour TTL\n updateAgeOnGet: true,\n updateAgeOnHas: true,\n })\n\n // ABI cache - store contract ABIs\n this.abiCache = new LRUCache<string, Abi>({\n max: options.abiCacheSize || 5000,\n ttl: 1000 * 60 * 60 * 24 * 7, // 7 day TTL (ABIs rarely change)\n updateAgeOnGet: true,\n updateAgeOnHas: true,\n })\n\n // Schema cache - store decoded schema values\n this.schemaCache = new LRUCache<string, Info>({\n max: options.schemaCacheSize || 10000,\n ttl: 1000 * 60 * 60, // 1 hour TTL\n updateAgeOnGet: true,\n updateAgeOnHas: true,\n })\n }\n\n /**\n * Get cache key for a data key (address or address:tokenId)\n */\n private getDataKeyCacheKey(key: DataKey): string {\n return key.toLowerCase()\n }\n\n // Transaction cache methods\n getTransaction(hash: string): DecoderResult | undefined {\n const result = this.transactionCache.get(hash.toLowerCase())\n if (result) {\n this.transactionStats.hits++\n return { ...result, cached: true }\n }\n this.transactionStats.misses++\n return undefined\n }\n\n setTransaction(hash: string, result: DecoderResult): void {\n this.transactionCache.set(hash.toLowerCase(), result)\n }\n\n // Address cache methods\n getAddress(key: DataKey): EnhancedInfo | undefined {\n const cacheKey = this.getDataKeyCacheKey(key)\n const result = this.addressCache.get(cacheKey)\n if (result) {\n this.addressStats.hits++\n return result\n }\n this.addressStats.misses++\n return undefined\n }\n\n setAddress(key: DataKey, data: EnhancedInfo): void {\n const cacheKey = this.getDataKeyCacheKey(key)\n this.addressCache.set(cacheKey, data)\n }\n\n hasAddress(key: DataKey): boolean {\n return this.addressCache.has(this.getDataKeyCacheKey(key))\n }\n\n getAddresses(keys: DataKey[]): Map<DataKey, EnhancedInfo> {\n const results = new Map<DataKey, EnhancedInfo>()\n for (const key of keys) {\n const data = this.getAddress(key)\n if (data) {\n results.set(key, data)\n }\n }\n return results\n }\n\n // ABI cache methods\n getAbi(address: string): Abi | undefined {\n const result = this.abiCache.get(address.toLowerCase())\n if (result) {\n this.abiStats.hits++\n return result\n }\n this.abiStats.misses++\n return undefined\n }\n\n setAbi(address: string, abi: Abi): void {\n this.abiCache.set(address.toLowerCase(), abi)\n }\n\n hasAbi(address: string): boolean {\n return this.abiCache.has(address.toLowerCase())\n }\n\n // Schema cache methods\n getSchema(key: string, value: string): Info | undefined {\n const cacheKey = `${key}:${value}`\n const result = this.schemaCache.get(cacheKey)\n if (result) {\n this.schemaStats.hits++\n return result\n }\n this.schemaStats.misses++\n return undefined\n }\n\n setSchema(key: string, value: string, info: Info): void {\n const cacheKey = `${key}:${value}`\n this.schemaCache.set(cacheKey, info)\n }\n\n // Cache management\n clear(): void {\n this.transactionCache.clear()\n this.addressCache.clear()\n this.abiCache.clear()\n this.schemaCache.clear()\n\n // Reset stats\n this.transactionStats = { hits: 0, misses: 0 }\n this.addressStats = { hits: 0, misses: 0 }\n this.abiStats = { hits: 0, misses: 0 }\n this.schemaStats = { hits: 0, misses: 0 }\n }\n\n getStats(): CacheStats {\n const calculateHitRate = (stats: { hits: number; misses: number }) => {\n const total = stats.hits + stats.misses\n return total > 0 ? stats.hits / total : 0\n }\n\n return {\n transactions: {\n size: this.transactionCache.size,\n maxSize: this.transactionCache.max,\n hits: this.transactionStats.hits,\n misses: this.transactionStats.misses,\n hitRate: calculateHitRate(this.transactionStats),\n },\n addresses: {\n size: this.addressCache.size,\n maxSize: this.addressCache.max,\n hits: this.addressStats.hits,\n misses: this.addressStats.misses,\n hitRate: calculateHitRate(this.addressStats),\n },\n abis: {\n size: this.abiCache.size,\n maxSize: this.abiCache.max,\n hits: this.abiStats.hits,\n misses: this.abiStats.misses,\n hitRate: calculateHitRate(this.abiStats),\n },\n schemas: {\n size: this.schemaCache.size,\n maxSize: this.schemaCache.max,\n hits: this.schemaStats.hits,\n misses: this.schemaStats.misses,\n hitRate: calculateHitRate(this.schemaStats),\n },\n }\n }\n}\n","import type { Transaction } from 'viem'\nimport { collectDataKeys } from '../core/addressCollector'\nimport { pluginRegistry } from '../decoder/registry'\nimport { decodeTransaction as decodeTransactionCore } from '../decoder/transaction'\nimport type { DecoderResult } from '../decoder/types'\nimport { needsEnhancement } from '../decoder/utils'\nimport type { ServerDecoderCaches } from './caches'\nimport type { ServerDecoderOptions } from './types'\n\n/**\n * Decode a single transaction with time-bounded enhancement\n */\nexport async function decodeTransactionSync(\n transaction: DecoderResult,\n options: ServerDecoderOptions,\n caches: ServerDecoderCaches\n): Promise<DecoderResult> {\n const startTime = Date.now()\n const { timeoutMs = 800, enableEnhancement = true, chain } = options\n\n // Check transaction cache first\n if (transaction.hash) {\n const cached = caches.getTransaction(transaction.hash)\n if (cached) {\n return cached\n }\n }\n\n try {\n // Phase 1: Immediate decode (sync plugins only)\n const phase1Start = Date.now()\n const plugins = await pluginRegistry.getAll({ syncOnly: true })\n const schemaPlugins = pluginRegistry.getAllSchema()\n\n const immediateOptions = {\n chain,\n plugins,\n schemaPlugins,\n wrappers: [],\n async: false,\n }\n const immediateResult = await decodeTransactionCore(\n transaction,\n immediateOptions\n )\n\n if (!immediateResult) {\n return {\n ...createErrorResult(transaction),\n phase: 'immediate',\n cached: false,\n timeTaken: Date.now() - startTime,\n }\n }\n\n let currentResult: DecoderResult = immediateResult\n let phase: 'immediate' | 'enhanced' | 'complete' = 'immediate'\n\n // Transfer collected wrappers if any\n if (immediateOptions.wrappers.length > 0) {\n ;(currentResult as any).wrappers = immediateOptions.wrappers\n }\n\n // Collect addresses from the decoded result\n const addresses = collectDataKeys(currentResult)\n currentResult.addresses = addresses\n\n // Check if we have time for enhancement\n const phase1Time = Date.now() - phase1Start\n if (enableEnhancement && phase1Time < timeoutMs * 0.6) {\n // Check if enhancement is actually needed\n if (!needsEnhancement(currentResult)) {\n // Already fully decoded during immediate phase\n phase = 'enhanced'\n } else {\n // Phase 2: Enhancement with async plugins\n try {\n const allPlugins = await pluginRegistry.getAll()\n const enhancedOptions = {\n chain,\n plugins: allPlugins,\n schemaPlugins,\n wrappers: [],\n async: true,\n }\n const enhancedResult = await Promise.race([\n decodeTransactionCore(transaction, enhancedOptions),\n // Timeout for phase 2\n new Promise<null>((resolve) =>\n setTimeout(() => resolve(null), timeoutMs * 0.6 - phase1Time)\n ),\n ])\n\n if (enhancedResult) {\n currentResult = enhancedResult\n phase = 'enhanced'\n\n // Merge wrappers from both phases (immediate + enhanced)\n const allWrappers = [\n ...((immediateOptions.wrappers || []) as any[]),\n ...(enhancedOptions.wrappers || []),\n ].filter(\n (w, i, arr) =>\n // Deduplicate by checking if this is the first occurrence\n arr.findIndex(\n (x) => JSON.stringify(x) === JSON.stringify(w)\n ) === i\n )\n\n if (allWrappers.length > 0) {\n ;(currentResult as any).wrappers = allWrappers\n }\n\n // Re-collect addresses from enhanced result\n currentResult.addresses = collectDataKeys(currentResult)\n }\n } catch (error) {\n console.error('Enhancement failed:', error)\n }\n }\n }\n\n const result: DecoderResult = {\n ...currentResult,\n phase,\n cached: false,\n timeTaken: Date.now() - startTime,\n }\n\n // Cache the result if we have a hash\n if (transaction.hash) {\n caches.setTransaction(transaction.hash, result)\n }\n\n return result\n } catch (error) {\n console.error('Failed to decode transaction:', error)\n return {\n ...createErrorResult(transaction),\n phase: 'immediate',\n cached: false,\n timeTaken: Date.now() - startTime,\n }\n }\n}\n\nfunction createErrorResult(transaction: DecoderResult): DecoderResult {\n return {\n ...transaction,\n isDecoded: false,\n resultType: 'error',\n errorType: 'UNKNOWN',\n sig: '0x' as `0x${string}`,\n addresses: [],\n } as DecoderResult\n}\n","import { collectDataKeys } from '../core/addressCollector'\nimport { pluginRegistry } from '../decoder/registry'\nimport { decodeTransaction as decodeTransactionCore } from '../decoder/transaction'\nimport type { DecoderResult, ResultShared } from '../decoder/types'\nimport { needsEnhancement } from '../decoder/utils'\nimport type { ServerDecoderCaches } from './caches'\nimport type { BatchDecodeResult, ServerDecoderOptions } from './types'\n\n/**\n * Decode multiple transactions with batching and time budget\n */\nexport async function decodeTransactionsBatch(\n transactions: DecoderResult[],\n options: ServerDecoderOptions,\n caches: ServerDecoderCaches\n): Promise<BatchDecodeResult> {\n const startTime = Date.now()\n const { timeoutMs = 800, enableEnhancement = true, chain } = options\n\n // Step 1: Check cache for all transactions\n const results: (DecoderResult | null)[] = transactions.map((tx) => {\n if (tx.transactionHash) {\n const cached = caches.getTransaction(tx.transactionHash)\n if (cached) return cached\n }\n return null\n })\n\n // Find uncached transactions\n const uncachedIndexes: number[] = []\n const uncachedTransactions: DecoderResult[] = []\n results.forEach((result, index) => {\n if (!result) {\n uncachedIndexes.push(index)\n uncachedTransactions.push(transactions[index])\n }\n })\n\n // If all are cached, return early\n if (uncachedTransactions.length === 0) {\n return {\n results: results as DecoderResult[],\n }\n }\n\n try {\n // Get plugins once for all transactions\n const syncPlugins = await pluginRegistry.getAll({ syncOnly: true })\n const allPlugins = await pluginRegistry.getAll()\n const schemaPlugins = pluginRegistry.getAllSchema()\n\n // Phase 1: Immediate decode for all uncached transactions\n const phase1Start = Date.now()\n const immediateOptionsArray = uncachedTransactions.map(() => ({\n chain,\n plugins: syncPlugins,\n schemaPlugins,\n wrappers: [],\n async: false,\n }))\n\n const immediateResults: DecoderResult[] = (\n await Promise.all(\n uncachedTransactions.map(async (tx, i) => {\n return await decodeTransactionCore(tx, immediateOptionsArray[i])\n })\n )\n ).filter(Boolean) as DecoderResult[]\n\n // Create result objects and collect addresses\n const newResults: DecoderResult[] = immediateResults\n .map((result, i) => {\n const data = result || createErrorResult(uncachedTransactions[i])\n\n // Transfer wrappers from immediate phase options\n if (immediateOptionsArray[i].wrappers.length > 0) {\n ;(data as any).wrappers = immediateOptionsArray[i].wrappers\n }\n\n // Collect addresses from the decoded result\n data.addresses = collectDataKeys(data)\n ;(data as ResultShared).timeTaken = Date.now() - startTime\n return data\n })\n .filter(Boolean) as DecoderResult[]\n\n // Check if we have time for enhancement\n const phase1Time = Date.now() - phase1Start\n if (enableEnhancement && phase1Time < timeoutMs * 0.6) {\n // Phase 2: Enhancement with async plugins (batch all transactions)\n try {\n const enhancedOptionsArray = uncachedTransactions.map(() => ({\n chain,\n plugins: allPlugins,\n schemaPlugins,\n wrappers: [],\n async: true,\n }))\n\n const enhancePromises = uncachedTransactions.map((tx, i) => {\n // Only enhance if immediate decode succeeded\n if (!immediateResults[i]) return null\n\n // Check if enhancement is actually needed\n if (!needsEnhancement(immediateResults[i])) {\n // Already fully decoded during immediate phase\n return null\n }\n\n return decodeTransactionCore(tx, enhancedOptionsArray[i])\n })\n\n // Wait for all enhancements with remaining time budget\n const remainingTime = timeoutMs * 0.6 - phase1Time\n const enhancedResults = await Promise.all(enhancePromises)\n\n // Update results with enhanced data\n enhancedResults.forEach((enhanced, i) => {\n if (enhanced) {\n // Merge wrappers from both phases (immediate + enhanced)\n const immediateWrappers = immediateOptionsArray[i].wrappers || []\n const enhancedWrappers = enhancedOptionsArray[i].wrappers || []\n const allWrappers = [\n ...immediateWrappers,\n ...enhancedWrappers,\n ].filter(\n (w, idx, arr) =>\n // Deduplicate by checking if this is the first occurrence\n arr.findIndex(\n (x) => JSON.stringify(x) === JSON.stringify(w)\n ) === idx\n )\n\n // Enhancement returned a new result\n newResults[i] = enhanced\n\n // Add merged wrappers if any\n if (allWrappers.length > 0) {\n ;(newResults[i] as any).wrappers = allWrappers\n }\n\n // Re-collect addresses from enhanced result\n newResults[i].addresses = collectDataKeys(enhanced)\n newResults[i].phase = 'enhanced'\n } else if (\n immediateResults[i] &&\n !needsEnhancement(immediateResults[i])\n ) {\n // Enhancement was skipped because already fully decoded\n newResults[i].phase = 'enhanced'\n }\n })\n } catch (error) {\n console.error('Batch enhancement failed:', error)\n }\n }\n\n // Update timings\n const totalTime = Date.now() - startTime\n newResults.forEach((result) => {\n result.timeTaken = totalTime\n })\n\n // Cache all new results\n newResults.forEach((result, i) => {\n const tx = uncachedTransactions[i]\n if (tx.hash) {\n caches.setTransaction(tx.hash, result)\n }\n })\n\n // Merge cached and new results\n uncachedIndexes.forEach((originalIndex, i) => {\n results[originalIndex] = newResults[i]\n })\n\n return {\n results: results as DecoderResult[],\n }\n } catch (error) {\n console.error('Batch decode failed:', error)\n // Return error results for uncached transactions\n uncachedIndexes.forEach((originalIndex) => {\n results[originalIndex] = {\n ...createErrorResult(transactions[originalIndex]),\n phase: 'immediate',\n cached: false,\n timeTaken: Date.now() - startTime,\n }\n })\n\n return {\n results: results as DecoderResult[],\n }\n }\n}\n\nfunction createErrorResult(transaction: DecoderResult): DecoderResult {\n return {\n ...transaction,\n isDecoded: false,\n resultType: 'error',\n errorType: 'UNKNOWN',\n sig: '0x' as `0x${string}`,\n addresses: [],\n } as DecoderResult\n}\n","import { collectDataKeys } from '../core/addressCollector'\nimport { pluginRegistry } from '../decoder/registry'\nimport { decodeTransaction as decodeTransactionCore } from '../decoder/transaction'\nimport type { DecoderResult, ResultShared } from '../decoder/types'\nimport { createDebug } from '../utils/debug'\nimport type { ServerDecoderCaches } from './caches'\nimport type { ServerDecoderOptions } from './types'\n\nconst debug = createDebug('decoder:finishDecoding')\n\n/**\n * Finish decoding a transaction by running enhancement phase\n * This only does phase 2 (async plugins) - address resolution should be done separately\n */\nexport async function finishDecoding(\n transaction: DecoderResult,\n options: ServerDecoderOptions,\n caches: ServerDecoderCaches\n): Promise<DecoderResult> {\n const startTime = Date.now()\n const {\n timeoutMs = 5000, // Give more time for finishing\n chain,\n } = options\n\n try {\n // Check cache first\n const txHash = transaction.hash || transaction.transactionHash\n if (txHash) {\n const cached = caches.getTransaction(txHash)\n if (cached && cached.enhancementAttempted) {\n return {\n ...cached,\n cached: true,\n timeTaken: 0,\n } as DecoderResult\n }\n }\n\n // Get all plugins\n const allPlugins = await pluginRegistry.getAll()\n const schemaPlugins = pluginRegistry.getAllSchema()\n\n const enhancedOptions = {\n chain,\n plugins: allPlugins,\n schemaPlugins,\n wrappers: [],\n async: true,\n }\n\n // Wrappers and children must be removed when finishing decoding, because otherwise\n // the decoder will build hierarchical structures which are infinite.\n const {\n wrappers,\n children: _children,\n addresses: _addresses,\n ...transactionWithoutWrappers\n } = transaction as DecoderResult & {\n children?: unknown[]\n wrappers?: unknown[]\n addresses?: unknown[]\n }\n\n // Simply pass the entire transaction hierarchy to decodeTransactionCore\n // It will handle children properly and return a fully enhanced copy\n const enhancedResult = await decodeTransactionCore(\n transactionWithoutWrappers as DecoderResult,\n enhancedOptions\n )\n\n if (!enhancedResult) {\n if (txHash) {\n caches.setTransaction(txHash, {\n ...transaction,\n enhancementAttempted: true,\n })\n }\n return transaction\n }\n\n const result = {\n ...enhancedResult,\n // Only add wrappers if there are any\n ...((wrappers?.length || 0) > 0 ? { wrappers } : {}),\n cached: false,\n timeTaken: Date.now() - startTime,\n enhancementAttempted: true,\n } as DecoderResult\n\n // Always update cache with the enhanced result\n if (txHash) {\n caches.setTransaction(txHash, result)\n }\n\n return result\n } catch (error) {\n console.error('Failed to finish decoding transaction:', error)\n return {\n ...createErrorResult(transaction),\n phase: 'immediate',\n cached: false,\n timeTaken: Date.now() - startTime,\n }\n }\n}\n\nfunction createErrorResult(transaction: DecoderResult): DecoderResult {\n return {\n ...transaction,\n resultType: 'error',\n errorType: 'UNKNOWN',\n sig: '0x' as `0x${string}`,\n addresses: [],\n } as DecoderResult\n}\n","import { ServerAddressResolver } from './addressResolver'\nimport { ServerDecoderCaches } from './caches'\nimport { decodeTransactionSync } from './decodeTransactionSync'\nimport { decodeTransactionsBatch } from './decodeTransactionsBatch'\nimport { finishDecoding } from './finishDecoding'\nimport type {\n ServerDecoder,\n ServerDecoderConfig,\n ServerDecoderOptions,\n} from './types'\n\n// Import plugins to ensure they are registered\nimport '../decoder/plugins'\n\n/**\n * Create a server-optimized decoder instance\n */\nexport function createServerDecoder(\n config: ServerDecoderConfig\n): ServerDecoder {\n // Create caches\n const caches = new ServerDecoderCaches({\n transactionCacheSize: config.transactionCacheSize,\n addressCacheSize: config.addressCacheSize,\n abiCacheSize: config.abiCacheSize,\n schemaCacheSize: config.schemaCacheSize,\n })\n\n // Create address resolver\n const addressResolver = new ServerAddressResolver(\n config.graphqlEndpoint,\n config.defaultChain,\n caches\n )\n\n // Return server decoder interface\n return {\n async decodeTransaction(transaction, options) {\n const opts: ServerDecoderOptions = {\n chain: config.defaultChain,\n timeoutMs: config.defaultTimeout,\n ...options,\n }\n return decodeTransactionSync(transaction, opts, caches)\n },\n\n async decodeTransactionsBatch(transactions, options) {\n const opts: ServerDecoderOptions = {\n chain: config.defaultChain,\n timeoutMs: config.defaultTimeout,\n ...options,\n }\n return decodeTransactionsBatch(transactions, opts, caches)\n },\n\n async finishDecoding(transaction, options) {\n const opts: ServerDecoderOptions = {\n chain: config.defaultChain,\n timeoutMs: config.defaultTimeout,\n ...options,\n }\n return finishDecoding(transaction, opts, caches)\n },\n\n clearCaches() {\n caches.clear()\n },\n\n getCacheStats() {\n return caches.getStats()\n },\n\n async warmAddressCache(addresses) {\n await addressResolver.warmCache(addresses)\n },\n\n async resolveAddresses(addresses, timeoutMs = 3000) {\n return addressResolver.resolveAddressesWithTimeout(addresses, timeoutMs)\n },\n }\n}\n"],"mappings":"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","names":["createErrorResult","createErrorResult"]}
@@ -0,0 +1,108 @@
1
+ import { g as IDataModelConsumer, I as IDataModel, c as DataKey, b as DecoderResult, T as TransactionState, h as DecoderOptions, P as PluginOptions, i as EnhancerCallback, j as DecodeEventCallback, k as EnhancerAggregationKeyCallback, l as EnhancerSummarizeCallback, m as Aggregation, n as DecoderPlugin, e as Info, S as SchemaPlugin, o as ResultSetData, A as ArrayArgs, C as CustomDecodeFunctionDataReturn, E as EnhancedInfo } from './index-BzXh7poJ.cjs';
2
+ import { Signal } from '@preact/signals-core';
3
+ import { Transaction, Abi, Hex, AbiParameter, DecodeFunctionDataParameters, Address, Chain, PublicClient } from 'viem';
4
+ import { ERC725JSONSchema } from '@erc725/erc725.js';
5
+
6
+ declare const dataModel: IDataModel;
7
+ declare const consumerModel: IDataModelConsumer;
8
+ declare function createGlobalInstance(): void;
9
+
10
+ /**
11
+ * Address resolver interface for batch resolution
12
+ */
13
+ interface AddressResolver {
14
+ resolveAddresses(addresses: DataKey[]): Promise<void>;
15
+ }
16
+ /**
17
+ * Result from decoding a transaction
18
+ */
19
+ interface TransactionDecoderResult {
20
+ immediate: DecoderResult;
21
+ signal: Signal<TransactionState>;
22
+ }
23
+ /**
24
+ * Decode a transaction with progressive enhancement
25
+ * @param transaction - Raw transaction data or array of transactions
26
+ * @param options - Decoder options
27
+ * @returns Immediate result and reactive signal (or array of them)
28
+ */
29
+ declare function decodeTransaction<T extends DecoderResult | DecoderResult[]>(transaction: T, options: DecoderOptions & {
30
+ addressResolver?: AddressResolver;
31
+ }): Promise<T extends Transaction[] ? TransactionDecoderResult[] : TransactionDecoderResult>;
32
+ /**
33
+ * Decode a transaction and wait for complete result
34
+ * Convenience wrapper for when you need a promise
35
+ */
36
+ declare function decodeTransactionAsync<T extends DecoderResult | DecoderResult[]>(transaction: T, options: DecoderOptions & {
37
+ addressResolver?: AddressResolver;
38
+ }): Promise<T extends Transaction[] ? DecoderResult[] : DecoderResult>;
39
+
40
+ /**
41
+ * Helper to create aggregation keys with plugin prefix
42
+ */
43
+ declare function createAggregationKey(pluginOptions: PluginOptions, key: string): string;
44
+ /**
45
+ *
46
+ * @param abi abi to use for decoding
47
+ * @param pluginOptions options to name abi, decoder or module (optional since the enhancer can provide some or all)
48
+ * @param enhance callback to do the actual enhancement once the abi function was decoded.
49
+ * @returns enhanced transaction
50
+ */
51
+ declare function standardPlugin<T extends Abi | readonly unknown[]>(abi: T, pluginOptions: PluginOptions, callbacks: {
52
+ enhance: EnhancerCallback;
53
+ decodeEvent: DecodeEventCallback;
54
+ overrideEnhance?: EnhancerCallback;
55
+ getAggregationKey?: EnhancerAggregationKeyCallback;
56
+ summarize?: EnhancerSummarizeCallback;
57
+ aggregations?: Aggregation[];
58
+ }): DecoderPlugin;
59
+ /**
60
+ * Creates a standard schema plugin from ERC725 schemas
61
+ * @param schemas Array of ERC725JSONSchema objects
62
+ * @param pluginOptions Options including name, required, priority
63
+ * @param process Optional post-processing function
64
+ * @returns SchemaPlugin
65
+ */
66
+ declare function standardSchemaPlugin(schemas: ERC725JSONSchema[], pluginOptions?: {
67
+ name?: string;
68
+ required?: boolean;
69
+ priority?: number;
70
+ }, process?: (output: Info) => Promise<Info>): SchemaPlugin;
71
+
72
+ declare const defaultPlugins: ReadonlyArray<DecoderPlugin>;
73
+ declare const defaultSchemaPlugins: ReadonlyArray<SchemaPlugin>;
74
+
75
+ declare function decodeKeyValue(result: ResultSetData, options: DecoderOptions): Promise<Info | undefined>;
76
+ declare function decodeKeyValueRaw(key: Hex, value: Hex, options: DecoderOptions): Promise<Info | undefined>;
77
+
78
+ /**
79
+ * Custom decoder for function data with additional named args support
80
+ * It's essentially the same code as decodeFunctionData, but also
81
+ * returning a namedArgs where we zip together the args and the inputs.
82
+ */
83
+ declare function customDecodeFunctionData<const abi extends Abi | readonly unknown[], preferError = false>(parameters: Partial<DecodeFunctionDataParameters<abi> & {
84
+ namedArgs?: Record<number, AbiParameter & {
85
+ value?: unknown;
86
+ }> | Record<string, unknown>;
87
+ }>, preferError?: boolean): CustomDecodeFunctionDataReturn<abi> | undefined;
88
+ declare function createNamedArgs(args: unknown[] | readonly unknown[], inputs?: AbiParameter[] | readonly AbiParameter[]): {
89
+ args: ArrayArgs;
90
+ };
91
+ /**
92
+ * Get an argument value by its name from the args array.
93
+ * This utility function allows accessing arguments by name without needing namedArgs.
94
+ *
95
+ * @param args - The array of arguments with their metadata
96
+ * @param name - The name of the argument to find
97
+ * @returns The value of the argument if found, undefined otherwise
98
+ */
99
+ declare function getArgByName(args: ArrayArgs | undefined, name: string): unknown;
100
+ declare function extractAddress(address?: Address | EnhancedInfo): `0x${string}` | undefined;
101
+ declare function getPublicClient(chain: Chain): PublicClient;
102
+ /**
103
+ * Check if a decoded result needs enhancement
104
+ * Returns true if the result OR any of its children need enhancement
105
+ */
106
+ declare function needsEnhancement(result: DecoderResult): boolean;
107
+
108
+ export { type AddressResolver as A, type TransactionDecoderResult as T, decodeTransaction as a, decodeKeyValue as b, decodeKeyValueRaw as c, dataModel as d, createNamedArgs as e, customDecodeFunctionData as f, extractAddress as g, getPublicClient as h, consumerModel as i, createGlobalInstance as j, decodeTransactionAsync as k, createAggregationKey as l, defaultPlugins as m, defaultSchemaPlugins as n, standardPlugin as o, getArgByName as p, needsEnhancement as q, standardSchemaPlugin as s };
@@ -0,0 +1,108 @@
1
+ import { g as IDataModelConsumer, I as IDataModel, c as DataKey, b as DecoderResult, T as TransactionState, h as DecoderOptions, P as PluginOptions, i as EnhancerCallback, j as DecodeEventCallback, k as EnhancerAggregationKeyCallback, l as EnhancerSummarizeCallback, m as Aggregation, n as DecoderPlugin, e as Info, S as SchemaPlugin, o as ResultSetData, A as ArrayArgs, C as CustomDecodeFunctionDataReturn, E as EnhancedInfo } from './index-BzXh7poJ.js';
2
+ import { Signal } from '@preact/signals-core';
3
+ import { Transaction, Abi, Hex, AbiParameter, DecodeFunctionDataParameters, Address, Chain, PublicClient } from 'viem';
4
+ import { ERC725JSONSchema } from '@erc725/erc725.js';
5
+
6
+ declare const dataModel: IDataModel;
7
+ declare const consumerModel: IDataModelConsumer;
8
+ declare function createGlobalInstance(): void;
9
+
10
+ /**
11
+ * Address resolver interface for batch resolution
12
+ */
13
+ interface AddressResolver {
14
+ resolveAddresses(addresses: DataKey[]): Promise<void>;
15
+ }
16
+ /**
17
+ * Result from decoding a transaction
18
+ */
19
+ interface TransactionDecoderResult {
20
+ immediate: DecoderResult;
21
+ signal: Signal<TransactionState>;
22
+ }
23
+ /**
24
+ * Decode a transaction with progressive enhancement
25
+ * @param transaction - Raw transaction data or array of transactions
26
+ * @param options - Decoder options
27
+ * @returns Immediate result and reactive signal (or array of them)
28
+ */
29
+ declare function decodeTransaction<T extends DecoderResult | DecoderResult[]>(transaction: T, options: DecoderOptions & {
30
+ addressResolver?: AddressResolver;
31
+ }): Promise<T extends Transaction[] ? TransactionDecoderResult[] : TransactionDecoderResult>;
32
+ /**
33
+ * Decode a transaction and wait for complete result
34
+ * Convenience wrapper for when you need a promise
35
+ */
36
+ declare function decodeTransactionAsync<T extends DecoderResult | DecoderResult[]>(transaction: T, options: DecoderOptions & {
37
+ addressResolver?: AddressResolver;
38
+ }): Promise<T extends Transaction[] ? DecoderResult[] : DecoderResult>;
39
+
40
+ /**
41
+ * Helper to create aggregation keys with plugin prefix
42
+ */
43
+ declare function createAggregationKey(pluginOptions: PluginOptions, key: string): string;
44
+ /**
45
+ *
46
+ * @param abi abi to use for decoding
47
+ * @param pluginOptions options to name abi, decoder or module (optional since the enhancer can provide some or all)
48
+ * @param enhance callback to do the actual enhancement once the abi function was decoded.
49
+ * @returns enhanced transaction
50
+ */
51
+ declare function standardPlugin<T extends Abi | readonly unknown[]>(abi: T, pluginOptions: PluginOptions, callbacks: {
52
+ enhance: EnhancerCallback;
53
+ decodeEvent: DecodeEventCallback;
54
+ overrideEnhance?: EnhancerCallback;
55
+ getAggregationKey?: EnhancerAggregationKeyCallback;
56
+ summarize?: EnhancerSummarizeCallback;
57
+ aggregations?: Aggregation[];
58
+ }): DecoderPlugin;
59
+ /**
60
+ * Creates a standard schema plugin from ERC725 schemas
61
+ * @param schemas Array of ERC725JSONSchema objects
62
+ * @param pluginOptions Options including name, required, priority
63
+ * @param process Optional post-processing function
64
+ * @returns SchemaPlugin
65
+ */
66
+ declare function standardSchemaPlugin(schemas: ERC725JSONSchema[], pluginOptions?: {
67
+ name?: string;
68
+ required?: boolean;
69
+ priority?: number;
70
+ }, process?: (output: Info) => Promise<Info>): SchemaPlugin;
71
+
72
+ declare const defaultPlugins: ReadonlyArray<DecoderPlugin>;
73
+ declare const defaultSchemaPlugins: ReadonlyArray<SchemaPlugin>;
74
+
75
+ declare function decodeKeyValue(result: ResultSetData, options: DecoderOptions): Promise<Info | undefined>;
76
+ declare function decodeKeyValueRaw(key: Hex, value: Hex, options: DecoderOptions): Promise<Info | undefined>;
77
+
78
+ /**
79
+ * Custom decoder for function data with additional named args support
80
+ * It's essentially the same code as decodeFunctionData, but also
81
+ * returning a namedArgs where we zip together the args and the inputs.
82
+ */
83
+ declare function customDecodeFunctionData<const abi extends Abi | readonly unknown[], preferError = false>(parameters: Partial<DecodeFunctionDataParameters<abi> & {
84
+ namedArgs?: Record<number, AbiParameter & {
85
+ value?: unknown;
86
+ }> | Record<string, unknown>;
87
+ }>, preferError?: boolean): CustomDecodeFunctionDataReturn<abi> | undefined;
88
+ declare function createNamedArgs(args: unknown[] | readonly unknown[], inputs?: AbiParameter[] | readonly AbiParameter[]): {
89
+ args: ArrayArgs;
90
+ };
91
+ /**
92
+ * Get an argument value by its name from the args array.
93
+ * This utility function allows accessing arguments by name without needing namedArgs.
94
+ *
95
+ * @param args - The array of arguments with their metadata
96
+ * @param name - The name of the argument to find
97
+ * @returns The value of the argument if found, undefined otherwise
98
+ */
99
+ declare function getArgByName(args: ArrayArgs | undefined, name: string): unknown;
100
+ declare function extractAddress(address?: Address | EnhancedInfo): `0x${string}` | undefined;
101
+ declare function getPublicClient(chain: Chain): PublicClient;
102
+ /**
103
+ * Check if a decoded result needs enhancement
104
+ * Returns true if the result OR any of its children need enhancement
105
+ */
106
+ declare function needsEnhancement(result: DecoderResult): boolean;
107
+
108
+ export { type AddressResolver as A, type TransactionDecoderResult as T, decodeTransaction as a, decodeKeyValue as b, decodeKeyValueRaw as c, dataModel as d, createNamedArgs as e, customDecodeFunctionData as f, extractAddress as g, getPublicClient as h, consumerModel as i, createGlobalInstance as j, decodeTransactionAsync as k, createAggregationKey as l, defaultPlugins as m, defaultSchemaPlugins as n, standardPlugin as o, getArgByName as p, needsEnhancement as q, standardSchemaPlugin as s };
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "@lukso/transaction-decoder",
3
+ "version": "1.0.1-dev.0f1bea5",
4
+ "description": "Transaction decoder for LUKSO blockchain with reactive state management",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./data": {
16
+ "types": "./dist/data.d.ts",
17
+ "import": "./dist/data.js",
18
+ "require": "./dist/data.cjs"
19
+ },
20
+ "./browser": {
21
+ "types": "./dist/browser.d.ts",
22
+ "import": "./dist/browser.js",
23
+ "require": "./dist/browser.cjs"
24
+ },
25
+ "./server": {
26
+ "types": "./dist/server.d.ts",
27
+ "import": "./dist/server.js",
28
+ "require": "./dist/server.cjs"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "src",
34
+ "README.md"
35
+ ],
36
+ "unpkg": "dist/cdn/transaction-decoder.global.js",
37
+ "jsdelivr": "dist/cdn/transaction-decoder.global.js",
38
+ "dependencies": {
39
+ "@erc725/erc725.js": "^0.28.2",
40
+ "@lukso/lsp-smart-contracts": "0.16.7",
41
+ "@lukso/lsp23-contracts": "0.15.5",
42
+ "@lukso/lsp26-contracts": "^0.1.7",
43
+ "@lukso/lsp3-contracts": "0.16.6",
44
+ "@lukso/lsp4-contracts": "0.16.7",
45
+ "@lukso/lsp6-contracts": "0.15.5",
46
+ "@lukso/lsp7-contracts": "0.16.8",
47
+ "@lukso/lsp8-contracts": "0.16.7",
48
+ "@lukso/lsp9-contracts": "0.15.5",
49
+ "@lukso/universalprofile-contracts": "0.15.5",
50
+ "@preact/signals-core": "^1.12.1",
51
+ "graphql-request": "^7.3.5",
52
+ "graphql-ws": "^6.0.6",
53
+ "lru-cache": "^11.2.4",
54
+ "viem": "^2.41.2"
55
+ },
56
+ "devDependencies": {
57
+ "@biomejs/biome": "^2.3.8",
58
+ "@types/debug": "^4.1.12",
59
+ "@types/node": "^24.10.1",
60
+ "tsup": "^8.5.1",
61
+ "typescript": "^5.9.3",
62
+ "vitest": "^4.0.15"
63
+ },
64
+ "peerDependencies": {
65
+ "viem": "^2.0.0"
66
+ },
67
+ "keywords": [
68
+ "lukso",
69
+ "blockchain",
70
+ "decoder",
71
+ "transaction",
72
+ "reactive",
73
+ "signals"
74
+ ],
75
+ "author": "LUKSO",
76
+ "license": "MIT",
77
+ "repository": {
78
+ "type": "git",
79
+ "url": "https://github.com/lukso-network/decoder.git"
80
+ },
81
+ "bugs": {
82
+ "url": "https://github.com/lukso-network/decoder/issues"
83
+ },
84
+ "homepage": "https://github.com/lukso-network/decoder#readme",
85
+ "onlyBuiltDependencies": [
86
+ "@biomejs/biome",
87
+ "esbuild"
88
+ ],
89
+ "scripts": {
90
+ "build": "tsup",
91
+ "build:watch": "tsup --watch --dts",
92
+ "build:lib": "tsup",
93
+ "dev": "tsup --watch --dts",
94
+ "type-check": "tsc --noEmit",
95
+ "lint": "biome lint",
96
+ "lint:fix": "biome lint --fix",
97
+ "test": "vitest run",
98
+ "test:watch": "vitest",
99
+ "clean": "rm -rf dist"
100
+ }
101
+ }
package/src/browser.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Browser entry point for @lukso/transaction-decoder
3
+ * This file exports the library for browser environments without setting globals
4
+ */
5
+
6
+ // Import the instance and global creation function
7
+ import { createGlobalInstance } from './core/instance'
8
+
9
+ // Re-export everything from the main entry for bundlers
10
+ export * from './index'
11
+
12
+ // Also export the function to create global instance if needed
13
+ export { createGlobalInstance }
@@ -0,0 +1,157 @@
1
+ import type { Chain } from 'viem'
2
+ import type { AddressIdentityCache } from '../shared/cache'
3
+ import { getDataKeyCacheKey } from '../shared/cache'
4
+ import type { DataKey, EnhancedInfo } from '../types'
5
+
6
+ export interface ResolveAddressesOptions {
7
+ /**
8
+ * API endpoint URL (defaults to '/api/resolveAddresses')
9
+ */
10
+ endpoint?: string
11
+
12
+ /**
13
+ * Optional cache to check before making API call
14
+ */
15
+ cache?: AddressIdentityCache
16
+
17
+ /**
18
+ * Maximum number of addresses per batch (defaults to 100)
19
+ */
20
+ batchSize?: number
21
+
22
+ /**
23
+ * Request timeout in milliseconds (defaults to 10000)
24
+ */
25
+ timeout?: number
26
+ }
27
+
28
+ export interface ResolveAddressesResponse {
29
+ success: boolean
30
+ addresses?: Record<string, EnhancedInfo>
31
+ cached?: number
32
+ fetched?: number
33
+ total?: number
34
+ error?: string
35
+ }
36
+
37
+ /**
38
+ * Resolve addresses using the API endpoint
39
+ * This allows clients to populate the server cache and get resolved addresses
40
+ */
41
+ export async function resolveAddresses(
42
+ addresses: DataKey[],
43
+ chain: Chain,
44
+ options: ResolveAddressesOptions = {}
45
+ ): Promise<Map<DataKey, EnhancedInfo>> {
46
+ const {
47
+ endpoint = '/api/resolveAddresses',
48
+ cache,
49
+ batchSize = 100,
50
+ timeout = 10000,
51
+ } = options
52
+
53
+ const results = new Map<DataKey, EnhancedInfo>()
54
+
55
+ if (addresses.length === 0) {
56
+ return results
57
+ }
58
+
59
+ // Check cache first if provided
60
+ const uncachedAddresses: DataKey[] = []
61
+
62
+ if (cache) {
63
+ for (const addr of addresses) {
64
+ const cached = await cache.get(addr)
65
+ if (cached) {
66
+ results.set(addr, cached)
67
+ } else {
68
+ uncachedAddresses.push(addr)
69
+ }
70
+ }
71
+
72
+ if (uncachedAddresses.length === 0) {
73
+ return results
74
+ }
75
+ } else {
76
+ uncachedAddresses.push(...addresses)
77
+ }
78
+
79
+ // Process in batches
80
+ const batches: DataKey[][] = []
81
+ for (let i = 0; i < uncachedAddresses.length; i += batchSize) {
82
+ batches.push(uncachedAddresses.slice(i, i + batchSize))
83
+ }
84
+
85
+ // Fetch all batches in parallel
86
+ const batchPromises = batches.map(async (batch) => {
87
+ try {
88
+ // DataKey is now just Hex string, use batch directly
89
+ const apiAddresses = batch
90
+
91
+ // Make API request with timeout
92
+ const controller = new AbortController()
93
+ const timeoutId = setTimeout(() => controller.abort(), timeout)
94
+
95
+ const response = await fetch(endpoint, {
96
+ method: 'POST',
97
+ headers: {
98
+ 'Content-Type': 'application/json',
99
+ },
100
+ body: JSON.stringify({
101
+ chainId: chain.id,
102
+ addresses: apiAddresses,
103
+ }),
104
+ signal: controller.signal,
105
+ })
106
+
107
+ clearTimeout(timeoutId)
108
+
109
+ if (!response.ok) {
110
+ console.error(
111
+ `Address resolution failed: ${response.status} ${response.statusText}`
112
+ )
113
+ return
114
+ }
115
+
116
+ const data: ResolveAddressesResponse = await response.json()
117
+
118
+ if (data.success && data.addresses) {
119
+ // Convert response back to DataKey -> EnhancedInfo map
120
+ for (const [cacheKey, enhancedInfo] of Object.entries(data.addresses)) {
121
+ // Find the original DataKey that matches this cache key
122
+ const matchingKey = batch.find(
123
+ (key) => getDataKeyCacheKey(key) === cacheKey
124
+ )
125
+
126
+ if (matchingKey) {
127
+ results.set(matchingKey, enhancedInfo)
128
+
129
+ // Update cache if provided
130
+ if (cache) {
131
+ await cache.set(matchingKey, enhancedInfo)
132
+ }
133
+ }
134
+ }
135
+ }
136
+ } catch (error) {
137
+ console.error('Failed to resolve addresses batch:', error)
138
+ }
139
+ })
140
+
141
+ await Promise.all(batchPromises)
142
+
143
+ return results
144
+ }
145
+
146
+ /**
147
+ * Create a cache-through address resolver that uses the API
148
+ * This can be used as a drop-in replacement for fetchMultipleAddresses
149
+ */
150
+ export function createApiAddressResolver(
151
+ chain: Chain,
152
+ options: ResolveAddressesOptions = {}
153
+ ) {
154
+ return async (addresses: DataKey[]): Promise<Map<DataKey, EnhancedInfo>> => {
155
+ return resolveAddresses(addresses, chain, options)
156
+ }
157
+ }