@lukso/transaction-decoder 1.2.0-dev.e515cef → 1.3.0-dev.5916302

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 (71) hide show
  1. package/dist/browser.cjs +41 -73
  2. package/dist/browser.cjs.map +1 -1
  3. package/dist/browser.d.cts +1 -1
  4. package/dist/browser.d.ts +1 -1
  5. package/dist/browser.js +4 -4
  6. package/dist/cdn/transaction-decoder.global.js +13 -13
  7. package/dist/cdn/transaction-decoder.global.js.map +1 -1
  8. package/dist/{chunk-GGBHTWJL.js → chunk-EDDQHEAA.js} +5 -5
  9. package/dist/chunk-EDDQHEAA.js.map +1 -0
  10. package/dist/{chunk-GXZOF3QY.js → chunk-NDBDNXBI.js} +3 -27
  11. package/dist/chunk-NDBDNXBI.js.map +1 -0
  12. package/dist/{chunk-XVHJWV5U.js → chunk-T4H2HHIB.js} +25 -32
  13. package/dist/chunk-T4H2HHIB.js.map +1 -0
  14. package/dist/{chunk-G7JZHSYX.js → chunk-U7L4W2YL.js} +11 -12
  15. package/dist/chunk-U7L4W2YL.js.map +1 -0
  16. package/dist/data.cjs +31 -62
  17. package/dist/data.cjs.map +1 -1
  18. package/dist/data.d.cts +2 -2
  19. package/dist/data.d.ts +2 -2
  20. package/dist/data.js +2 -2
  21. package/dist/index.cjs +41 -73
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +4 -4
  26. package/dist/server.cjs +31 -43
  27. package/dist/server.cjs.map +1 -1
  28. package/dist/server.d.cts +1 -2
  29. package/dist/server.d.ts +1 -2
  30. package/dist/server.js +7 -12
  31. package/dist/server.js.map +1 -1
  32. package/dist/{utils-CBAkjQh3.d.cts → utils-BEpSreRR.d.cts} +1 -1
  33. package/dist/{utils-xT9-km0r.d.ts → utils-De_c6fUK.d.ts} +1 -1
  34. package/package.json +3 -3
  35. package/src/core/dataModel.ts +1 -31
  36. package/src/core/integrateDecoder.ts +1 -2
  37. package/src/decoder/browserCache.ts +1 -6
  38. package/src/decoder/errors.ts +2 -2
  39. package/src/decoder/events.ts +3 -3
  40. package/src/decoder/functionSignature.ts +9 -9
  41. package/src/decoder/getDataFromExternalSources.ts +2 -2
  42. package/src/decoder/interfaces.ts +1 -1
  43. package/src/decoder/kvCache.ts +1 -6
  44. package/src/decoder/lruCache.ts +1 -6
  45. package/src/decoder/lsp7TransferBatch.test.ts +0 -3
  46. package/src/decoder/plugins/enhanceBurntPix.ts +1 -2
  47. package/src/decoder/plugins/enhanceGraffiti.ts +3 -17
  48. package/src/decoder/plugins/enhanceLSP26FollowerSystem.ts +4 -8
  49. package/src/decoder/plugins/enhanceLSP6KeyManager.ts +0 -1
  50. package/src/decoder/plugins/enhanceLSP7DigitalAsset.ts +5 -7
  51. package/src/decoder/plugins/enhanceLSP9Vault.ts +7 -8
  52. package/src/decoder/plugins/enhanceRetrieveAbi.ts +5 -6
  53. package/src/decoder/plugins/index.ts +3 -1
  54. package/src/decoder/plugins/schemaDefault.ts +3 -4
  55. package/src/decoder/plugins/standardPlugin.ts +1 -1
  56. package/src/decoder/singleGQL.ts +2 -2
  57. package/src/decoder/transaction.ts +1 -2
  58. package/src/decoder/utils.ts +2 -2
  59. package/src/example/usage.ts +3 -4
  60. package/src/server/addressResolver.ts +1 -1
  61. package/src/server/decodeTransactionSync.ts +0 -1
  62. package/src/server/decodeTransactionsBatch.ts +1 -1
  63. package/src/server/finishDecoding.ts +4 -8
  64. package/src/server/lsp23Resolver.ts +2 -3
  65. package/src/server/types.ts +1 -1
  66. package/src/shared/addressResolver.ts +3 -3
  67. package/src/utils/json-bigint.ts +4 -4
  68. package/dist/chunk-G7JZHSYX.js.map +0 -1
  69. package/dist/chunk-GGBHTWJL.js.map +0 -1
  70. package/dist/chunk-GXZOF3QY.js.map +0 -1
  71. package/dist/chunk-XVHJWV5U.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  __name
3
- } from "./chunk-XVHJWV5U.js";
3
+ } from "./chunk-T4H2HHIB.js";
4
4
 
5
5
  // src/shared/addressResolver.ts
6
6
  import request, { gql } from "graphql-request";
@@ -202,7 +202,7 @@ async function fetchMultipleAddresses(addresses, graphqlEndpoint, cache) {
202
202
  }
203
203
  if (data.Token) {
204
204
  for (const token of data.Token) {
205
- const { id, baseAsset, tokenId, ...rest } = token;
205
+ const { id: _id, baseAsset, tokenId, ...rest } = token;
206
206
  if (baseAsset?.id && tokenId) {
207
207
  const enhancedInfo = {
208
208
  address: baseAsset.id,
@@ -366,7 +366,7 @@ async function getImage(images, options) {
366
366
  return options.fallback ? { src: options.fallback, width: 128, height: 128 } : void 0;
367
367
  }
368
368
  try {
369
- let isImage = void 0;
369
+ let isImage;
370
370
  if (typeof caches !== "undefined" && !ignoreHead) {
371
371
  const cache = await caches.open("image-types");
372
372
  const cached = await cache.match(url);
@@ -378,7 +378,7 @@ async function getImage(images, options) {
378
378
  }
379
379
  }
380
380
  if (!isImage && !ignoreHead) {
381
- const now = Date.now();
381
+ const _now = Date.now();
382
382
  isImage = await fetch(url, { method: "HEAD" }).then((response) => {
383
383
  if (response.ok) {
384
384
  const mime = response.headers.get("content-type") || "";
@@ -434,4 +434,4 @@ export {
434
434
  fetchProfilesByControllers,
435
435
  getImage
436
436
  };
437
- //# sourceMappingURL=chunk-GGBHTWJL.js.map
437
+ //# sourceMappingURL=chunk-EDDQHEAA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/addressResolver.ts"],"sourcesContent":["import request, { gql } from 'graphql-request'\nimport type { Address, Chain, Hex } from 'viem'\nimport { lukso } from 'viem/chains'\nimport type { DataKey, EnhancedInfo } from '../types'\nimport type { AddressIdentityCache } from './cache'\n\n/**\n * GraphQL queries for address resolution\n * Using the exact schema from addressGQL.ts\n */\nconst addressesGql = gql`\nquery AddressQuery($profiles: [String!], $assets: [String!], $tokens: [String!]) {\n Profile(\n where: {id: {_in: $profiles}}\n ) {\n fullName\n id\n name\n tags\n description\n standard\n controllers {\n address\n tags\n permissions\n }\n owner {\n id\n }\n profileImages(where: {error: {_is_null: true}}, order_by: {width: asc}) {\n width\n height\n src\n verified\n }\n backgroundImages(where: {error: {_is_null: true}}, order_by: {width: asc}) {\n width\n height\n src\n verified\n }\n avatars(where: {error: {_is_null: true}}, order_by: {width: asc}) {\n width\n height\n src\n verified\n }\n }\n Token(where: {id: {_in: $tokens}}) {\n id\n baseAsset {\n id\n description\n icons {\n src\n verified\n width\n height\n }\n isCollection\n isLSP7\n isUnknown\n name\n standard\n interfaces\n decimals\n owner_id\n lsp4Creators {\n profile_id\n }\n }\n formattedTokenId\n icons {\n src\n verified\n width\n height\n }\n images(where: {index: {_eq: 0}}) {\n src\n verified\n width\n height\n }\n lsp4TokenName\n lsp4TokenSymbol\n lsp4TokenType\n lsp8TokenIdFormat\n tokenId\n name\n description\n lsp4Creators {\n profile_id\n }\n }\n Asset(where: {id: {_in: $assets}}) {\n id\n images(where: {index: {_eq: 0}}) {\n src\n width\n verified\n height\n }\n interfaces\n isCollection\n isLSP7\n isUnknown\n lsp4TokenName\n lsp4TokenSymbol\n lsp4TokenType\n method\n name\n icons {\n src\n width\n height\n }\n description\n decimals\n standard\n owner_id\n lsp4Creators {\n profile_id\n }\n }\n}\n`\n\n// Image data structure from GraphQL\nexport interface ImageData {\n width?: number\n height?: number\n url?: string // Raw URL (may be ipfs://)\n src?: string // Resolved HTTPS URL (fallback to url if not present)\n verified?: boolean\n}\n\n// Link data structure from GraphQL\nexport interface LinkData {\n url: string\n title?: string\n}\n\n// Profile data from GraphQL\nexport interface ProfileData {\n id: Hex\n name?: string\n fullName?: string\n tags?: string[]\n description?: string\n links?: LinkData[]\n standard?: string\n controllers?: Array<{\n address: string\n tags?: string[]\n permissions?: Hex\n }>\n owner?: { id: string }\n profileImages?: ImageData[]\n backgroundImages?: ImageData[]\n avatars?: ImageData[]\n}\n\n// Asset data from GraphQL\nexport interface AssetData {\n id: Hex\n name?: string\n standard?: string\n lsp4TokenName?: string\n lsp4TokenSymbol?: string\n lsp4TokenType?: string\n method?: string\n description?: string\n links?: LinkData[]\n decimals?: number\n interfaces?: string[]\n isCollection?: boolean\n isLSP7?: boolean\n isUnknown?: boolean\n icons?: ImageData[]\n images?: ImageData[]\n}\n\n// Token data from GraphQL\nexport interface TokenData {\n id: Hex\n tokenId?: Hex\n name?: string\n description?: string\n links?: LinkData[]\n lsp4TokenName?: string\n lsp4TokenSymbol?: string\n lsp4TokenType?: string\n lsp8TokenIdFormat?: string\n formattedTokenId?: string\n baseAsset?: {\n id: Hex\n description?: string\n icons?: ImageData[]\n isCollection?: boolean\n isLSP7?: boolean\n isUnknown?: boolean\n name?: string\n standard?: string\n interfaces?: string[]\n decimals?: number\n }\n icons?: ImageData[]\n images?: ImageData[]\n}\n\nexport type TFetchAddressData = {\n Profile?: ProfileData[]\n Asset?: AssetData[]\n Token?: TokenData[]\n}\n\n/**\n * Fetch multiple addresses from GraphQL and return them as a Map\n * This is the shared implementation that both server and core can use\n */\nexport async function fetchMultipleAddresses(\n addresses: readonly DataKey[],\n graphqlEndpoint: string,\n cache?: AddressIdentityCache\n): Promise<Map<DataKey, EnhancedInfo>> {\n const results = new Map<DataKey, EnhancedInfo>()\n\n if (addresses.length === 0) {\n return results\n }\n\n // Check cache first if provided\n const uncachedAddresses: DataKey[] = []\n\n if (cache) {\n // Try to get many at once if supported\n if (cache.getMany) {\n const cachedResults = await cache.getMany(addresses)\n for (const [key, value] of cachedResults) {\n results.set(key, value)\n }\n // Find which ones we still need to fetch\n for (const addr of addresses) {\n if (!results.has(addr)) {\n uncachedAddresses.push(addr)\n }\n }\n } else {\n // Fall back to individual lookups\n for (const addr of addresses) {\n const cached = await cache.get(addr)\n if (cached) {\n results.set(addr, cached)\n } else {\n uncachedAddresses.push(addr)\n }\n }\n }\n\n // If all were cached, return early\n if (uncachedAddresses.length === 0) {\n return results\n }\n } else {\n // No cache, fetch all\n uncachedAddresses.push(...addresses)\n }\n\n // Parse addresses and tokens\n const profiles: string[] = []\n const assets: string[] = []\n const tokens: string[] = []\n const tokenMapping = new Map<string, { address: Address; tokenId: string }>()\n\n for (const key of uncachedAddresses) {\n const hasDash = key.includes('-')\n const hasColon = key.includes(':')\n\n if (hasColon || hasDash) {\n const normalizedKey = key.replace(/[-:]/, '-')\n tokens.push(normalizedKey)\n const [address, tokenId] = key.split(/[-:]/)\n tokenMapping.set(key, { address: address as Address, tokenId })\n } else {\n // Regular addresses - could be profiles or assets\n profiles.push(key)\n assets.push(key)\n }\n }\n\n try {\n // Fetch data from GraphQL\n const data = (await request(graphqlEndpoint, addressesGql, {\n profiles,\n assets,\n tokens,\n })) as TFetchAddressData\n\n // Process profiles\n if (data.Profile) {\n for (const profile of data.Profile) {\n if (profile.standard !== 'LSP0ERC725Account') {\n continue\n }\n const enhancedInfo: EnhancedInfo = {\n address: profile.id as Address,\n __gqltype: 'Profile',\n name: profile.name || profile.fullName,\n fullName: profile.fullName,\n standard: profile.standard,\n tags: profile.tags,\n description: profile.description,\n owner: profile.owner,\n controllers: profile.controllers,\n profileImages: profile.profileImages,\n backgroundImages: profile.backgroundImages,\n avatars: profile.avatars,\n }\n results.set(profile.id as Address, enhancedInfo)\n }\n }\n\n // Process tokens (must be before assets per addressGQL.ts logic)\n if (data.Token) {\n for (const token of data.Token) {\n const { id: _id, baseAsset, tokenId, ...rest } = token\n\n // Tokens have a composite ID format and baseAsset reference\n if (baseAsset?.id && tokenId) {\n const enhancedInfo: EnhancedInfo = {\n address: baseAsset.id as Address,\n tokenId: tokenId as Address,\n __gqltype: 'Token',\n ...rest,\n baseAsset,\n }\n // Store with both dash and colon separators to handle both formats\n const keyWithColon = `${baseAsset.id}:${tokenId}` as DataKey\n const keyWithDash = `${baseAsset.id}-${tokenId}` as DataKey\n results.set(keyWithColon, enhancedInfo)\n results.set(keyWithDash, enhancedInfo)\n }\n }\n }\n\n // Process assets\n if (data.Asset) {\n for (const asset of data.Asset) {\n if (asset.standard === 'LSP0ERC725Account') {\n // Skip profiles - already processed\n continue\n }\n const enhancedInfo: EnhancedInfo = {\n address: asset.id as Address,\n __gqltype: 'Asset',\n ...asset,\n }\n if (!results.has(asset.id as Address)) {\n results.set(asset.id as Address, enhancedInfo)\n }\n }\n }\n\n // Cache the newly fetched results\n if (cache) {\n const newEntries: Array<[DataKey, EnhancedInfo]> = []\n\n // Collect all new entries\n for (const [key, value] of results) {\n // Only cache entries that were fetched (not from cache)\n const isCached = addresses.some(\n (addr) => addr.toLowerCase() === key.toLowerCase()\n )\n\n if (\n isCached &&\n uncachedAddresses.some(\n (addr) => addr.toLowerCase() === key.toLowerCase()\n )\n ) {\n newEntries.push([key, value])\n }\n }\n\n // Use batch update if available\n if (cache.setMany && newEntries.length > 0) {\n await cache.setMany(newEntries)\n } else {\n // Fall back to individual updates\n for (const [key, value] of newEntries) {\n await cache.set(key, value)\n }\n }\n }\n\n return results\n } catch (error) {\n console.error('Failed to fetch addresses:', error)\n return results\n }\n}\n\n/**\n * Get GraphQL endpoint for a given chain\n */\nexport function getGraphQLEndpoint(chain: Chain): string {\n return chain.id === lukso.id\n ? 'https://envio.lukso-mainnet.universal.tech/v1/graphql'\n : 'https://envio.lukso-testnet.universal.tech/v1/graphql'\n}\n\n/**\n * GraphQL query to find profiles controlled by specific addresses\n */\nconst profilesByControllerGql = gql`\nquery ProfilesByController($controllerAddresses: [String!]) {\n Profile(\n where: {\n controllers: {\n address: { _in: $controllerAddresses }\n tags: {\n _contains: [\n \"ADDCONTROLLER\"\n \"EDITPERMISSIONS\"\n \"SUPER_TRANSFERVALUE\"\n \"TRANSFERVALUE\"\n \"SUPER_CALL\"\n \"CALL\"\n \"SUPER_STATICCALL\"\n \"STATICCALL\"\n \"DEPLOY\"\n \"SUPER_SETDATA\"\n \"SETDATA\"\n \"ENCRYPT\"\n \"DECRYPT\"\n \"SIGN\"\n \"EXECUTE_RELAY_CALL\"\n ]\n }\n }\n }\n order_by: { blockNumber: asc }\n ) {\n fullName\n id\n name\n tags\n description\n standard\n controllers {\n address\n tags\n permissions\n }\n owner {\n id\n }\n profileImages(where: {error: {_is_null: true}}, order_by: {width: asc}) {\n width\n height\n src\n verified\n }\n backgroundImages(where: {error: {_is_null: true}}, order_by: {width: asc}) {\n width\n height\n src\n verified\n }\n avatars(where: {error: {_is_null: true}}, order_by: {width: asc}) {\n width\n height\n src\n verified\n }\n }\n}\n`\n\n/**\n * Find profiles controlled by specific controller addresses\n * @param controllerAddresses - Array of controller addresses to search for\n * @param chain - Which chain to query\n * @returns Array of profile data\n */\nexport async function fetchProfilesByControllers(\n controllerAddresses: readonly Address[],\n chain: Chain\n): Promise<ProfileData[]> {\n const graphqlEndpoint = getGraphQLEndpoint(chain)\n\n try {\n const data = (await request(graphqlEndpoint, profilesByControllerGql, {\n controllerAddresses: controllerAddresses.map((addr) =>\n addr.toLowerCase()\n ),\n })) as { Profile?: ProfileData[] }\n\n return data.Profile || []\n } catch (error) {\n console.error(\n `Failed to fetch profiles by controllers on ${chain.name}:`,\n error\n )\n return []\n }\n}\n\nexport type ImageURL = {\n url?: string\n data?: string\n src?: string\n width: number\n height: number\n index?: number\n verified?: string\n}\n\n/**\n * Assuming the images are sorted ascending by width and/or height pick the first\n * image that's larger than the requested size * dpr and process that one.\n * By default this will assume the data came from the indexer and therefore\n * we do not need to verify the existence of all the images (i.e. HEAD requests for\n * each image) Setting ignoreHead to false is important during RPC mode so that\n * we can skip images that are not really available.\n *\n * @param images - array of images\n * @param options - specify arguments for search/processing\n * @returns { width, height, src } - the image that fits the criteria\n */\nexport async function getImage(\n images: ImageURL[],\n options: {\n width: number\n height?: number\n index?: number\n ignoreVerification?: boolean\n forcePng?: boolean\n ignoreHead?: boolean\n fallback?: string\n dpr?: number\n }\n): Promise<{ width: number; height: number; src?: string } | undefined> {\n const {\n width,\n height: _height,\n index,\n ignoreVerification,\n ignoreHead = true, // By default we don't want to do HEAD requests for all images.\n dpr = 1,\n } = options\n const boost = dpr === 1 ? 1.5 : 1\n const height = _height || width\n const { src: _src, verified } =\n (images || []).find(\n (i) =>\n i.width >= width * boost * dpr &&\n i.height &&\n i.height >= height * boost * dpr &&\n (index ? i.index === index : i.index === undefined)\n ) ||\n images?.at(-1) ||\n {}\n // We're talking about images here, so we should be using /image/ instead of /ipfs/\n const url = _src?.startsWith('https://api.universalprofile.cloud/ipfs/')\n ? _src?.replace(/\\/ipfs\\//, '/image/')\n : _src\n if (!url) {\n return options.fallback\n ? { src: options.fallback, width: 128, height: 128 }\n : undefined\n }\n try {\n let isImage: string | undefined\n if (typeof caches !== 'undefined' && !ignoreHead) {\n const cache = await caches.open('image-types')\n const cached = await cache.match(url)\n if (cached) {\n const response = await cached.json()\n if (response) {\n isImage = response\n }\n }\n }\n if (!isImage && !ignoreHead) {\n // HEAD will return 200, 404 and so including the 'content-type'\n // We use this to determine what type of images we have.\n // If the images came from the indexer then this test\n // has already been done on the indexer and we can skip it here.\n const _now = Date.now()\n isImage = await fetch(url, { method: 'HEAD' })\n .then((response) => {\n if (response.ok) {\n const mime = response.headers.get('content-type') || ''\n response.body?.cancel()\n return /^image\\//.test(mime) ? mime : undefined\n }\n response.body?.cancel()\n return undefined\n })\n .catch((error) => {\n console.error((error as Error).stack)\n return undefined\n })\n if (isImage != null && typeof caches !== 'undefined') {\n const cache = await caches.open('image-types')\n await cache\n .put(url, new Response(JSON.stringify(isImage)))\n .catch((error) => {\n console.error((error as Error).stack, url)\n })\n }\n }\n if (isImage || ignoreHead) {\n const finalUrl = new URL(url)\n const { searchParams } = finalUrl\n const qs = new URLSearchParams(searchParams)\n if (width) {\n qs.set('width', `${width * boost}`)\n }\n if (width || height) {\n qs.set('height', `${(height || width) * boost}`)\n }\n qs.set('fit', 'cover')\n qs.set('dpr', dpr.toString())\n if (\n !options.ignoreHead &&\n !/\\/svg/.test(isImage || '') &&\n options.forcePng\n ) {\n qs.set('format', 'png')\n }\n finalUrl.search = qs.toString()\n const image = finalUrl.toString()\n return {\n width,\n height: height || width,\n src:\n verified === 'INVALID' && !ignoreVerification\n ? `${image}&blur=30`\n : image,\n }\n }\n } catch (error) {\n console.error((error as Error).stack)\n }\n return options.fallback\n ? { src: options.fallback, width: 128, height: 128 }\n : undefined\n}\n"],"mappings":"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","names":[]}
@@ -4,11 +4,11 @@ import {
4
4
  decodeTransaction,
5
5
  isAsyncOperationEnabled,
6
6
  pluginRegistry
7
- } from "./chunk-XVHJWV5U.js";
7
+ } from "./chunk-T4H2HHIB.js";
8
8
 
9
9
  // src/core/dataModel.ts
10
10
  import { batch, effect, signal } from "@preact/signals-core";
11
- import { hexToBigInt, isHex, size, slice } from "viem";
11
+ import { isHex, size } from "viem";
12
12
  function deepFreeze(obj) {
13
13
  if (obj === null || typeof obj !== "object" || Object.isFrozen(obj)) {
14
14
  return obj;
@@ -39,30 +39,6 @@ var DataModel = class {
39
39
  constructor(options = {}) {
40
40
  this.options = options;
41
41
  }
42
- /**
43
- * Extract a 20-byte address from a potentially 32-byte hex value
44
- * If the input is 32 bytes, validates it's zero-padded and takes the rightmost 20 bytes
45
- * If the input is 20 bytes, returns it as-is
46
- */
47
- extractAddress(hex) {
48
- if (!isHex(hex)) {
49
- throw new Error(`Invalid hex value: ${hex}`);
50
- }
51
- const bytes = size(hex);
52
- if (bytes === 32) {
53
- const first12Bytes = slice(hex, 0, 12);
54
- if (hexToBigInt(first12Bytes) !== 0n) {
55
- throw new Error(
56
- `Invalid 32-byte address: first 12 bytes must be zero for a padded address, got ${first12Bytes}`
57
- );
58
- }
59
- return slice(hex, 12, 32);
60
- }
61
- if (bytes === 20) {
62
- return hex;
63
- }
64
- throw new Error(`Invalid address length: ${bytes} bytes`);
65
- }
66
42
  /**
67
43
  * Get or create a signal for a specific key
68
44
  */
@@ -836,4 +812,4 @@ export {
836
812
  decodeTransaction2 as decodeTransaction,
837
813
  decodeTransactionAsync
838
814
  };
839
- //# sourceMappingURL=chunk-GXZOF3QY.js.map
815
+ //# sourceMappingURL=chunk-NDBDNXBI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/dataModel.ts","../src/core/instance.ts","../src/decoder/decodeTransaction.ts","../src/shared/constants.ts"],"sourcesContent":["// Core data model implementation\nimport { batch, effect, type Signal, signal } from '@preact/signals-core'\nimport type { Address, Hex } from 'viem'\nimport { isHex, size } from 'viem'\nimport type {\n AddressState,\n DataKey,\n DataModelOptions,\n DecoderResult,\n EnhancedInfo,\n IDataModel,\n IDataModelConsumer,\n TransactionState,\n} from '../types'\nimport { collectDataKeys } from './addressCollector'\n\n// Helper type for deep freezing - kept internal to this module\ntype DeepReadonly<T> = T extends (infer R)[]\n ? DeepReadonlyArray<R>\n : T extends (...args: unknown[]) => unknown\n ? T\n : T extends object\n ? DeepReadonlyObject<T>\n : T\n\ninterface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}\n\ntype DeepReadonlyObject<T> = {\n readonly [P in keyof T]: DeepReadonly<T[P]>\n}\n\n/**\n * Deep freeze an object to prevent any modifications\n * Returns the same object if it's already frozen\n */\nexport function deepFreeze<T>(obj: T): T {\n // Primitives and already frozen objects don't need processing\n if (obj === null || typeof obj !== 'object' || Object.isFrozen(obj)) {\n return obj\n }\n\n // Freeze the object itself\n Object.freeze(obj)\n\n // Recursively freeze all properties\n for (const prop of Object.getOwnPropertyNames(obj)) {\n const value = (obj as Record<string, unknown>)[prop]\n if (value !== null && typeof value === 'object') {\n deepFreeze(value)\n }\n }\n\n return obj\n}\n\nexport interface TransactionKey {\n hash: Hex\n decoderIndex?: number // For batch transactions\n}\n\nexport class DataModel implements IDataModel {\n // Nested map structure: Address -> (TokenId | null) -> Signal\n private dataSignals = new Map<Address, Signal<AddressState>>()\n\n // Transaction signals: Hash -> (DecoderIndex | null) -> Signal\n private transactionSignals = new Map<\n Hex,\n Map<number | null, Signal<TransactionState>>\n >()\n\n // Keep track of unique transaction hashes in order\n private transactionOrder: Array<Hex> = []\n\n private options: DataModelOptions\n\n // Track pending resolved data updates\n private pendingResolvedUpdate = false\n\n constructor(options: DataModelOptions = {}) {\n this.options = options\n }\n\n /**\n * Get or create a signal for a specific key\n */\n private getOrCreateSignal(key: DataKey): Signal<AddressState> {\n let sig = this.dataSignals.get(key)\n if (!sig) {\n sig = signal<AddressState>({\n loading: false,\n data: undefined,\n error: undefined,\n lastUpdated: undefined,\n })\n\n this.dataSignals.set(key, sig)\n\n // Notify about missing keys (for external fetching)\n if (this.options.onMissingKeys) {\n // Debounce notifications\n setTimeout(() => {\n const missing = this.getMissingKeys()\n if (missing.length > 0) {\n this.options.onMissingKeys?.(missing)\n }\n }, 0)\n }\n }\n\n return sig\n }\n\n /**\n * Extract transaction key from transaction JSON\n */\n private getTransactionKey(transaction: unknown): TransactionKey {\n if (!transaction || typeof transaction !== 'object') {\n throw new Error('Transaction must be an object')\n }\n\n const tx = transaction as Record<string, unknown>\n if (!tx.hash && !tx.transactionHash) {\n throw new Error('Transaction must have hash or transactionHash')\n }\n\n return {\n hash: (tx.hash || tx.transactionHash) as Hex,\n decoderIndex: tx.decoderIndex ? (tx.decoderIndex as number) : undefined,\n }\n }\n\n /**\n * Get or create the inner map for a transaction hash\n */\n private getOrCreateTransactionMap(\n hash: Hex\n ): Map<number | null, Signal<TransactionState>> {\n const normalizedHash = hash.toLowerCase() as Hex\n let map = this.transactionSignals.get(normalizedHash)\n if (!map) {\n map = new Map()\n this.transactionSignals.set(normalizedHash, map)\n }\n return map\n }\n\n /**\n * Add one or more transactions to the model\n * Collects all addresses from all transactions and marks them as loading\n */\n addTransactions<T extends unknown | unknown[]>(\n jsonTransactions: T\n ): T extends unknown[]\n ? Array<Signal<TransactionState>>\n : Signal<TransactionState> {\n // Normalize input to array\n const transactions = Array.isArray(jsonTransactions)\n ? jsonTransactions\n : [jsonTransactions]\n const isSingle = !Array.isArray(jsonTransactions)\n // First, collect all addresses from all transactions\n const allAddresses = new Set<string>()\n const transactionAddresses: DataKey[][] = []\n\n for (const tx of transactions) {\n const addresses = collectDataKeys(tx)\n transactionAddresses.push(addresses)\n\n // Add to set for deduplication\n for (const addr of addresses) {\n allAddresses.add(addr)\n }\n }\n\n // Convert back to DataKey array\n const uniqueAddresses = Array.from(allAddresses) as DataKey[]\n\n // Mark all addresses as loading at once\n if (uniqueAddresses.length > 0) {\n this.setLoading(uniqueAddresses)\n }\n\n // Now add each transaction\n const results = transactions.map((tx, index) => {\n const key = this.getTransactionKey(tx)\n const normalizedHash = key.hash.toLowerCase() as Hex\n const decoderIndex = key.decoderIndex || null\n\n const isNewHash = !this.transactionSignals.has(normalizedHash)\n const txMap = this.getOrCreateTransactionMap(normalizedHash)\n\n if (txMap.has(decoderIndex)) {\n throw new Error(\n `Transaction already exists: ${normalizedHash}:${decoderIndex || 0}`\n )\n }\n\n // Create frozen data once\n const frozenData = deepFreeze(\n structuredClone(tx)\n ) as unknown as DeepReadonly<DecoderResult>\n\n // Create reactive transaction with frozen data\n const sig = signal<TransactionState>({\n data: frozenData,\n loading: false,\n addresses: Object.freeze([...transactionAddresses[index]]) as DataKey[],\n error: undefined,\n lastUpdated: Date.now(),\n resolvedData: frozenData, // Start with the same frozen data\n addressesResolved: false,\n })\n\n txMap.set(decoderIndex, sig)\n\n // Track transaction order (only for new hashes)\n if (isNewHash) {\n this.transactionOrder.push(normalizedHash)\n }\n\n // Notify about new transaction\n if (this.options.onNewTransaction) {\n this.options.onNewTransaction(tx)\n }\n\n return sig\n })\n\n // Return single signal if input was single, otherwise return array\n return (isSingle ? results[0] : results) as T extends unknown[]\n ? Array<Signal<TransactionState>>\n : Signal<TransactionState>\n }\n\n /**\n * Get an existing transaction signal (returns undefined if not found)\n */\n getTransaction(\n jsonTransaction: unknown\n ): Signal<TransactionState> | undefined {\n const key = this.getTransactionKey(jsonTransaction)\n const normalizedHash = key.hash.toLowerCase() as Hex\n const decoderIndex = key.decoderIndex || null\n\n const txMap = this.transactionSignals.get(normalizedHash)\n if (!txMap) {\n return undefined\n }\n\n return txMap.get(decoderIndex)\n }\n\n /**\n * Get transaction by hash and decoder index\n */\n getTransactionByKey(\n hash: Hex,\n decoderIndex?: number\n ): Signal<TransactionState> | undefined {\n const normalizedHash = hash.toLowerCase() as Hex\n const txMap = this.transactionSignals.get(normalizedHash)\n if (!txMap) {\n return undefined\n }\n\n return txMap.get(decoderIndex || null)\n }\n\n /**\n * Update a transaction's data and re-collect addresses\n * Useful after async decoding completes\n */\n updateTransactionData(\n hash: Hex,\n newData: DecoderResult,\n decoderIndex?: number\n ): void {\n const normalizedHash = hash.toLowerCase() as Hex\n const txMap = this.transactionSignals.get(normalizedHash)\n if (!txMap) return\n\n const sig = txMap.get(decoderIndex ?? null)\n if (!sig) return\n\n // Re-collect addresses with the new decoded data\n const newAddresses = collectDataKeys(newData, true, [\n ...sig.value.addresses,\n ])\n\n // Create frozen data once\n const frozenData = deepFreeze(structuredClone(newData))\n\n // Update the signal with frozen data\n sig.value = {\n ...sig.value,\n data: frozenData,\n addresses: Object.freeze([...newAddresses]) as DataKey[],\n lastUpdated: Date.now(),\n // Start with the current data, will be enhanced when addresses load\n resolvedData: frozenData,\n addressesResolved: false,\n }\n\n // Mark any new addresses as loading\n this.setLoading(newAddresses)\n\n // Check if we can create resolved data immediately\n queueMicrotask(() => {\n this.updateResolvedTransactionData()\n })\n }\n\n /**\n * Get all decoded transactions for a hash by index (insertion order)\n */\n getTransactionsByIndex(\n index: number\n ): Map<number | null, Signal<TransactionState>> | undefined {\n if (index < 0 || index >= this.transactionOrder.length) {\n return undefined\n }\n\n const hash = this.transactionOrder[index]\n return this.transactionSignals.get(hash)\n }\n\n /**\n * Get transaction hash by index\n */\n getTransactionHashByIndex(index: number): Hex | undefined {\n return this.transactionOrder[index]\n }\n\n /**\n * Get number of unique transaction hashes\n */\n getTransactionCount(): number {\n return this.transactionOrder.length\n }\n\n /**\n * Get number of decoded transactions for a specific hash\n */\n getDecodedCount(hash: Hex): number {\n const normalizedHash = hash.toLowerCase() as Hex\n const txMap = this.transactionSignals.get(normalizedHash)\n return txMap ? txMap.size : 0\n }\n\n /**\n * Get all decoded transactions for a specific hash\n */\n getDecodedTransactions(hash: Hex): Array<Signal<TransactionState>> {\n const normalizedHash = hash.toLowerCase() as Hex\n const txMap = this.transactionSignals.get(normalizedHash)\n return txMap ? Array.from(txMap.values()) : []\n }\n\n /**\n * Get address signal (alias for getSignal for clearer API)\n */\n getAddress(address: DataKey): Signal<AddressState> {\n return this.getSignal(address)\n }\n\n /**\n * Inject data into the model\n * Can be called multiple times to progressively add/update data\n */\n injectData(dataList: EnhancedInfo[]): void {\n batch(() => {\n for (const data of dataList) {\n const key: DataKey = data.tokenId\n ? `${data.address as Hex}:${data.tokenId}`\n : (data.address as Hex)\n\n const sig = this.getOrCreateSignal(key)\n\n // Update the signal with frozen data\n sig.value = {\n loading: false,\n data: deepFreeze(structuredClone(data)),\n error: undefined,\n lastUpdated: Date.now(),\n }\n }\n })\n\n // After the batch, check if any transactions need their resolved data updated\n this.updateResolvedTransactionData()\n }\n\n /**\n * Update a single item\n */\n updateData(data: EnhancedInfo): void {\n const key: DataKey = data.tokenId\n ? `${data.address as Hex}:${data.tokenId}`\n : (data.address as Hex)\n\n const sig = this.getOrCreateSignal(key)\n\n sig.value = {\n loading: false,\n data: deepFreeze(structuredClone(data)),\n error: undefined,\n lastUpdated: Date.now(),\n }\n\n // Debounce the resolved data update using a microtask\n if (!this.pendingResolvedUpdate) {\n this.pendingResolvedUpdate = true\n queueMicrotask(() => {\n this.pendingResolvedUpdate = false\n this.updateResolvedTransactionData()\n })\n }\n }\n\n /**\n * Mark keys as loading\n */\n setLoading(keys: DataKey[]): void {\n batch(() => {\n for (const key of keys) {\n const sig = this.getOrCreateSignal(key)\n sig.value = { ...sig.value, loading: true }\n }\n })\n }\n\n /**\n * Mark a key as errored\n */\n setError(key: DataKey, error: string): void {\n const sig = this.getOrCreateSignal(key)\n sig.value = {\n loading: false,\n data: undefined,\n error,\n lastUpdated: Date.now(),\n }\n }\n\n /**\n * Get signal for a key (creates one if doesn't exist)\n */\n getSignal(key: DataKey): Signal<AddressState> {\n return this.getOrCreateSignal(key)\n }\n\n /**\n * Subscribe to key updates\n */\n subscribe(key: DataKey, callback: (state: AddressState) => void): () => void {\n const sig = this.getSignal(key)\n return effect(() => callback(sig.value))\n }\n\n /**\n * Get current state of a key\n */\n getState(key: DataKey): AddressState {\n return this.getSignal(key).value\n }\n\n /**\n * Get all keys that have no data\n */\n getMissingKeys(): DataKey[] {\n const missingKeys: DataKey[] = []\n\n for (const [key] of this.dataSignals) {\n missingKeys.push(key as Hex)\n }\n\n return missingKeys\n }\n\n /**\n * Get all keys currently loading\n */\n getLoadingKeys(): DataKey[] {\n const loadingKeys: DataKey[] = []\n\n for (const [key, sig] of this.dataSignals) {\n if (sig.value.loading) {\n loadingKeys.push(key as Hex)\n }\n }\n\n return loadingKeys\n }\n\n /**\n * Check if we have data for a key\n */\n hasData(key: DataKey): boolean {\n const sig = this.dataSignals.get(key)\n return sig ? sig.value.data !== undefined : false\n }\n\n /**\n * Clear all data\n */\n clear(): void {\n batch(() => {\n // Clear address data\n for (const sig of this.dataSignals.values()) {\n sig.value = {\n loading: false,\n data: undefined,\n error: undefined,\n lastUpdated: undefined,\n }\n }\n\n // Clear transaction data\n for (const txMap of this.transactionSignals.values()) {\n for (const sig of txMap.values()) {\n sig.value = {\n ...sig.value,\n loading: false,\n error: undefined,\n }\n }\n }\n })\n }\n\n /**\n * Remove specific keys from cache\n */\n remove(keys: DataKey[]): void {\n for (const key of keys) {\n this.dataSignals.delete(key)\n }\n }\n\n /**\n * Get all cached keys\n */\n getAllKeys(): ReadonlyArray<DataKey> {\n const keys: DataKey[] = []\n\n for (const [key] of this.dataSignals) {\n keys.push(key as Hex)\n }\n\n return Object.freeze(keys)\n }\n\n /**\n * Get all data as a plain object (for debugging/serialization)\n */\n getAllData(): Readonly<Record<string, AddressState>> {\n const result: Record<string, AddressState> = {}\n\n for (const [key, sig] of this.dataSignals) {\n result[key] = sig.value\n }\n\n return Object.freeze(result)\n }\n\n /**\n * Get all transaction data (for debugging)\n */\n getAllTransactions(): Readonly<Record<string, TransactionState>> {\n const result: Record<string, TransactionState> = {}\n\n for (const [hash, txMap] of this.transactionSignals) {\n for (const [decoderIndex, sig] of txMap) {\n const key = decoderIndex === null ? hash : `${hash}:${decoderIndex}`\n result[key] = sig.value\n }\n }\n\n return Object.freeze(result)\n }\n\n /**\n * Get all transactions in order (returns all decoded transactions grouped by hash)\n */\n getTransactionsInOrder(): Array<{\n hash: Hex\n transactions: Array<Signal<TransactionState>>\n }> {\n const result: Array<{\n hash: Hex\n transactions: Array<Signal<TransactionState>>\n }> = []\n\n for (const hash of this.transactionOrder) {\n const txMap = this.transactionSignals.get(hash)\n if (txMap) {\n result.push({\n hash,\n transactions: Array.from(txMap.values()),\n })\n }\n }\n\n return result\n }\n\n /**\n * Create a resolved version of transaction data with all addresses populated\n */\n createResolvedTransactionData(\n transactionData: DecoderResult,\n addresses: ReadonlyArray<DataKey>\n ): DecoderResult {\n // Clone the transaction data to avoid modifying the original\n const resolved = structuredClone(transactionData)\n\n // Create a map of address data for quick lookup\n const addressMap = new Map<string, EnhancedInfo>()\n\n for (const key of addresses) {\n const addressData = this.getData(key)\n if (addressData) {\n addressMap.set(key.toLowerCase(), addressData)\n }\n }\n\n // Use the path-based approach to replace addresses\n this.replaceAddressesWithPaths(resolved, addressMap)\n\n // Deep freeze the result\n return deepFreeze(resolved)\n }\n\n /**\n * Replace addresses using path information (similar to collectAddressesWithPaths)\n */\n private replaceAddressesWithPaths(\n data: unknown,\n addressMap: Map<string, EnhancedInfo>\n ): void {\n function traverse(\n obj: unknown,\n path: Array<string | number> = [],\n parent?: Record<string, unknown> | unknown[]\n ): void {\n // Handle string case first\n if (typeof obj === 'string' && obj.startsWith('0x')) {\n // Use regex to detect zero-padded addresses\n const isPaddedAddress = /^0x0*([a-fA-F0-9]{40})$/.test(obj)\n\n if (isPaddedAddress || (isHex(obj) && size(obj as Hex) === 20)) {\n // Extract the actual address (remove padding if needed)\n const address = isPaddedAddress\n ? (obj.replace(/^0x0*([a-fA-F0-9]{40})$/, '0x$1') as Address)\n : obj\n\n // Skip if too many zeros (likely not an address)\n if (\n address\n .slice(2)\n .split('')\n .filter((c: string) => c === '0').length > 10\n ) {\n return\n }\n\n // Check for tokenId in parent\n const currentKey = path[path.length - 1]\n const tokenId =\n parent &&\n !Array.isArray(parent) &&\n 'tokenId' in parent &&\n parent.tokenId\n ? (parent.tokenId as Hex)\n : undefined\n\n // Look up the address data\n let addressData: EnhancedInfo | undefined\n if (tokenId) {\n const compositeKey = `${address.toLowerCase()}_${tokenId.toLowerCase()}`\n addressData = addressMap.get(compositeKey)\n } else {\n addressData = addressMap.get(address.toLowerCase())\n }\n\n // Replace the address with the data if found\n if (addressData && parent) {\n if (Array.isArray(parent) && typeof currentKey === 'number') {\n parent[currentKey] = addressData\n } else if (\n !Array.isArray(parent) &&\n typeof currentKey === 'string'\n ) {\n parent[currentKey] = addressData\n }\n }\n }\n return\n }\n\n if (!obj || typeof obj !== 'object') return\n\n if (Array.isArray(obj)) {\n for (let index = 0; index < obj.length; index++) {\n traverse(obj[index], path.concat([index]), obj)\n }\n } else {\n const record = obj as Record<string, unknown>\n for (const [key, value] of Object.entries(record)) {\n traverse(value, path.concat([key]), record)\n }\n }\n }\n\n traverse(data)\n }\n\n /**\n * Update resolved transaction data for all transactions where addresses are loaded\n */\n private updateResolvedTransactionData(): void {\n // Go through all transactions\n for (const [_hash, txMap] of this.transactionSignals) {\n for (const [_decoderIndex, signal] of txMap) {\n const currentState = signal.value\n\n // Skip if already resolved or if no addresses\n if (\n currentState.addressesResolved ||\n currentState.addresses.length === 0\n ) {\n continue\n }\n\n // Check if all addresses are loaded\n let allAddressesLoaded = true\n for (const addressKey of currentState.addresses) {\n const addressState = this.getState(addressKey)\n if (addressState.loading || !addressState.data) {\n allAddressesLoaded = false\n break\n }\n }\n\n // If all addresses are loaded, create resolved data\n if (allAddressesLoaded) {\n const resolvedData = this.createResolvedTransactionData(\n currentState.data as DecoderResult,\n currentState.addresses\n )\n\n // Update the transaction state\n signal.value = {\n ...currentState,\n resolvedData: resolvedData as DeepReadonly<DecoderResult>,\n addressesResolved: true,\n lastUpdated: Date.now(),\n }\n }\n }\n }\n }\n\n /**\n * Get data by key - convenience method that handles both 20 and 32 byte addresses\n */\n getData(key: DataKey): DeepReadonly<EnhancedInfo> | undefined {\n return this.getState(key).data\n }\n\n /**\n * Check if a key is loading\n */\n isLoading(key: DataKey): boolean {\n return this.getState(key).loading\n }\n\n /**\n * Get error for a key\n */\n getError(key: DataKey): string | undefined {\n return this.getState(key).error\n }\n}\n\n/**\n * Create a read-only consumer proxy that only exposes safe read methods\n */\nexport function createConsumerProxy(model: DataModel): IDataModelConsumer {\n const consumerMethods = [\n // Transaction read methods\n 'getTransaction',\n 'getTransactionByKey',\n 'getTransactionsByIndex',\n 'getTransactionHashByIndex',\n 'getTransactionCount',\n 'getDecodedCount',\n 'getDecodedTransactions',\n 'getTransactionsInOrder',\n // Address read methods\n 'getAddress',\n 'getSignal',\n 'subscribe',\n 'getState',\n 'hasData',\n 'getData',\n 'isLoading',\n 'getError',\n // Collection read methods\n 'getAllKeys',\n 'getAllData',\n 'getAllTransactions',\n ]\n\n const proxy = new Proxy(model, {\n get(target, prop, receiver) {\n if (typeof prop === 'string' && consumerMethods.includes(prop)) {\n const value = Reflect.get(target, prop, receiver)\n if (typeof value === 'function') {\n return value.bind(target)\n }\n return value\n }\n // Block access to all other properties and methods\n return undefined\n },\n set() {\n return false // Prevent modifications\n },\n deleteProperty() {\n return false\n },\n defineProperty() {\n return false\n },\n setPrototypeOf() {\n return false\n },\n }) as IDataModelConsumer\n\n return proxy\n}\n\n/**\n * Create a secure DataModel instance\n * Freezes the prototype to prevent prototype pollution attacks\n */\nexport function createDataModel(options?: DataModelOptions): IDataModel {\n const model = new DataModel(options)\n\n // Freeze the prototype to prevent modification\n Object.freeze(DataModel.prototype)\n\n // Freeze the constructor\n Object.freeze(DataModel)\n\n return model\n}\n","import type { IDataModel, IDataModelConsumer } from '../types'\nimport { createConsumerProxy, DataModel } from './dataModel'\n\n// Create the singleton instance\nconst dataModelInstance = new DataModel()\n\n// Freeze the prototype and constructor to prevent prototype pollution\nObject.freeze(DataModel.prototype)\nObject.freeze(DataModel)\n\n// Export the full model for data providers to import\n// Note: We don't freeze dataModel as data providers need to modify it\nexport const dataModel: IDataModel = dataModelInstance\n\n// Create consumer-only proxy for public API (frozen)\nexport const consumerModel: IDataModelConsumer =\n createConsumerProxy(dataModelInstance)\n\n// Export a function to optionally create global instance\n// This allows consumers to control when/if the global is created\nexport function createGlobalInstance(): void {\n if (typeof window !== 'undefined') {\n // Create consumer-only proxy for window\n const consumerProxy = createConsumerProxy(dataModelInstance)\n\n Object.defineProperty(window, 'TransactionDecoder', {\n value: consumerProxy,\n writable: false,\n configurable: false,\n enumerable: true,\n })\n }\n}\n","import { type Signal, signal } from '@preact/signals-core'\nimport type { Hex, Transaction } from 'viem'\nimport { collectDataKeys } from '../core/addressCollector'\nimport { deepFreeze } from '../core/dataModel'\nimport { pluginRegistry } from '../decoder/registry'\nimport { decodeTransaction as decodeTransactionCore } from '../decoder/transaction'\nimport {\n AsyncOperations,\n type DecoderOptions,\n type DecoderResult,\n ErrorType,\n} from '../decoder/types'\nimport { isAsyncOperationEnabled } from '../decoder/utils'\nimport { ERROR_CODES } from '../shared/constants'\nimport type { DataKey, TransactionState } from '../types'\n\n/**\n * Address resolver interface for batch resolution\n */\nexport interface AddressResolver {\n resolveAddresses(addresses: DataKey[]): Promise<void>\n}\n\n/**\n * Result from decoding a transaction\n */\nexport interface TransactionDecoderResult {\n // Immediate sync result\n immediate: DecoderResult\n\n // Signal that updates as async decoding progresses\n signal: Signal<TransactionState>\n}\n\n/**\n * Decode a transaction with progressive enhancement\n * @param transaction - Raw transaction data or array of transactions\n * @param options - Decoder options\n * @returns Immediate result and reactive signal (or array of them)\n */\nexport async function decodeTransaction<\n T extends DecoderResult | DecoderResult[],\n>(\n transaction: T,\n options: DecoderOptions & { addressResolver?: AddressResolver }\n): Promise<\n T extends Transaction[]\n ? TransactionDecoderResult[]\n : TransactionDecoderResult\n> {\n const isBatch = Array.isArray(transaction)\n const transactions: DecoderResult[] = isBatch\n ? (transaction as unknown as DecoderResult[])\n : [transaction as DecoderResult]\n\n const results = await decodeTransactionBatch(transactions, options)\n\n // Return single result if single input\n if (isBatch) {\n return results as T extends Transaction[]\n ? TransactionDecoderResult[]\n : TransactionDecoderResult\n }\n return results[0] as T extends Transaction[]\n ? TransactionDecoderResult[]\n : TransactionDecoderResult\n}\n\n/**\n * Internal batch decoder with three-phase approach\n */\nasync function decodeTransactionBatch(\n transactions: DecoderResult[],\n options: DecoderOptions & { addressResolver?: AddressResolver }\n): Promise<TransactionDecoderResult[]> {\n // Extract names of plugins provided in options (these will override registered ones)\n const overridePluginNames =\n options.plugins\n ?.map((p) => p.name)\n .filter((name): name is string => typeof name === 'string') || []\n\n const overrideSchemaNames =\n options.schemaPlugins\n ?.map((p) => p.name)\n .filter((name): name is string => typeof name === 'string') || []\n\n // Get registered plugins, excluding those being overridden\n const registeredPlugins = await pluginRegistry.getAll({\n excludeNames: overridePluginNames,\n })\n const registeredSchemaPlugins =\n pluginRegistry.getAllSchema(overrideSchemaNames)\n\n // Merge: provided plugins override registered ones\n const allPlugins = [...registeredPlugins, ...(options.plugins || [])]\n const allSchemaPlugins = [\n ...registeredSchemaPlugins,\n ...(options.schemaPlugins || []),\n ]\n\n // Phase 1: Sync decode\n const syncOptions: DecoderOptions = {\n ...options,\n plugins: allPlugins.filter(({ usesAsync }) => !usesAsync),\n schemaPlugins: allSchemaPlugins,\n async: false,\n }\n\n const results = await Promise.all(\n transactions.map(async (tx) => {\n const initialResult = await decodeTransactionCore(tx, syncOptions)\n const initialData = deepFreeze(initialResult || createErrorResult(tx))\n\n // Create signal with frozen data\n const txSignal = signal<TransactionState>({\n loading: false,\n data: initialData as DecoderResult,\n decodingStatus: initialResult ? 'decoded' : 'failed',\n addresses: collectDataKeys(tx),\n addressesResolved: false,\n lastUpdated: Date.now(),\n })\n\n return {\n transaction: tx,\n immediate: initialData,\n signal: txSignal,\n }\n })\n )\n\n // Check if we have any async plugins for phase 2\n // For now, assume we have async plugins if async operations are enabled\n // since plugins themselves no longer have the async property\n const hasAsyncPlugins = true\n const pluginsEnabled = isAsyncOperationEnabled(\n options.async,\n AsyncOperations.ENABLE_PLUGINS\n )\n\n if (hasAsyncPlugins && pluginsEnabled) {\n // Phase 2: ABI retrieval (async plugins)\n const asyncOptions: DecoderOptions = {\n ...options,\n plugins: allPlugins,\n schemaPlugins: allSchemaPlugins,\n async: true,\n }\n\n // Run async decoding for all transactions\n for (const { transaction, signal: txSignal } of results) {\n decodeTransactionCore(transaction, asyncOptions)\n .then((enhanced) => {\n if (enhanced) {\n txSignal.value = {\n ...txSignal.value,\n data: deepFreeze(enhanced) as DecoderResult,\n decodingStatus: 'enhanced',\n addresses: collectDataKeys(enhanced),\n lastUpdated: Date.now(),\n }\n }\n })\n .catch((error) => {\n console.error('Async decode error:', error)\n txSignal.value = {\n ...txSignal.value,\n decodingStatus: 'failed',\n error: error instanceof Error ? error.message : 'Unknown error',\n loading: false,\n }\n })\n }\n }\n\n // Phase 3: Address resolution (if resolver provided and enabled)\n const addressResolveEnabled = isAsyncOperationEnabled(\n options.async,\n AsyncOperations.ENABLE_ADDRESS_RESOLVE\n )\n\n if (options.addressResolver && addressResolveEnabled) {\n // Collect all unique addresses from all transactions\n const allAddresses = new Set<DataKey>()\n for (const { signal: txSignal } of results) {\n for (const addr of txSignal.value.addresses) {\n allAddresses.add(addr)\n }\n }\n\n // Batch resolve addresses\n if (allAddresses.size > 0) {\n options.addressResolver\n .resolveAddresses(Array.from(allAddresses))\n .then(() => {\n // Update all signals to indicate addresses are resolved\n for (const { signal: txSignal } of results) {\n if (txSignal.value.decodingStatus !== 'failed') {\n txSignal.value = {\n ...txSignal.value,\n addressesResolved: true,\n decodingStatus: 'complete',\n lastUpdated: Date.now(),\n }\n }\n }\n })\n .catch((error) => {\n console.error('Address resolution error:', error)\n // Don't fail the transaction, just log the error\n })\n }\n } else if (!hasAsyncPlugins || (!pluginsEnabled && !addressResolveEnabled)) {\n // No async operations enabled, mark as complete\n for (const { signal: txSignal } of results) {\n if (txSignal.value.decodingStatus !== 'failed') {\n txSignal.value = {\n ...txSignal.value,\n decodingStatus: 'complete',\n }\n }\n }\n }\n\n return results.map((r) => ({\n immediate: r.immediate,\n signal: r.signal,\n }))\n}\n\nfunction createErrorResult(transaction: DecoderResult): DecoderResult {\n return {\n ...transaction,\n resultType: 'error' as const,\n isDecoded: false,\n errorType: ErrorType.ERROR,\n sig: transaction.input?.slice(0, 10) as Hex,\n error: {\n code: ERROR_CODES.DECODING_FAILED,\n message: 'Failed to decode transaction',\n details: new Error('Decoder returned undefined'),\n },\n }\n}\n\n/**\n * Decode a transaction and wait for complete result\n * Convenience wrapper for when you need a promise\n */\nexport async function decodeTransactionAsync<\n T extends DecoderResult | DecoderResult[],\n>(\n transaction: T,\n options: DecoderOptions & { addressResolver?: AddressResolver }\n): Promise<T extends Transaction[] ? DecoderResult[] : DecoderResult> {\n const isBatch = Array.isArray(transaction)\n const result = await decodeTransaction(transaction, options)\n const results = isBatch\n ? (result as TransactionDecoderResult[])\n : [result as TransactionDecoderResult]\n\n // Wait for all decodings to complete\n const finalResults = await Promise.all(\n results.map(\n ({ signal }) =>\n new Promise<DecoderResult>((resolve) => {\n const checkComplete = () => {\n const state = signal.value\n if (\n state.decodingStatus === 'complete' ||\n state.decodingStatus === 'failed'\n ) {\n resolve(state.data as DecoderResult)\n } else {\n // Check again on next tick\n setTimeout(checkComplete, 10)\n }\n }\n checkComplete()\n })\n )\n )\n\n if (isBatch) {\n return finalResults as T extends Transaction[]\n ? DecoderResult[]\n : DecoderResult\n }\n return finalResults[0] as T extends Transaction[]\n ? DecoderResult[]\n : DecoderResult\n}\n","/**\n * Shared constants\n */\n\nexport const DECODER_VERSION = '0.1.0'\n\nexport const DEFAULT_CONFIG = {\n endpoint: 'https://api.lukso.network/decoder',\n batchSize: 100,\n retryAttempts: 3,\n timeout: 30000,\n} as const\n\nexport const ERROR_CODES = {\n INVALID_TRANSACTION: 'INVALID_TRANSACTION',\n DECODING_FAILED: 'DECODING_FAILED',\n NETWORK_ERROR: 'NETWORK_ERROR',\n RATE_LIMIT: 'RATE_LIMIT',\n UNAUTHORIZED: 'UNAUTHORIZED',\n NOT_FOUND: 'NOT_FOUND',\n} as const\n"],"mappings":"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","names":["signal","signal","decodeTransaction","signal"]}
@@ -804,7 +804,7 @@ var getDataFromExternalSources = /* @__PURE__ */ __name((schemas, dataFromChain,
804
804
  urlDataWithHash,
805
805
  ipfsGateway
806
806
  ));
807
- let length = "unknown";
807
+ let _length = "unknown";
808
808
  if (!url.startsWith("data:") && /[=?/]$/.test(url)) {
809
809
  return dataEntry;
810
810
  }
@@ -816,7 +816,7 @@ var getDataFromExternalSources = /* @__PURE__ */ __name((schemas, dataFromChain,
816
816
  }
817
817
  return response.arrayBuffer().then((buffer) => new Uint8Array(buffer));
818
818
  });
819
- length = receivedData.length.toString();
819
+ _length = receivedData.length.toString();
820
820
  const captureHashes = {};
821
821
  const captureErrors = [];
822
822
  if (receivedData.length >= 2) {
@@ -936,7 +936,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
936
936
  });
937
937
  if (schema) {
938
938
  try {
939
- const name = schema.name.replace(/[:\[\]]|<.*?>/g, "");
939
+ const name = schema.name.replace(/[:[\]]|<.*?>/g, "");
940
940
  if (schema.keyType === "Array") {
941
941
  if (schema.key === key) {
942
942
  const hexString = value.slice(2);
@@ -944,7 +944,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
944
944
  for (let i = 0; i < hexString.length; i += 2) {
945
945
  all[i / 2] = Number.parseInt(hexString.substring(i, i + 2), 16);
946
946
  }
947
- const [{ start, end } = { start: 0, end: 0 }] = all.reduce(
947
+ const [{ start: _start, end } = { start: 0, end: 0 }] = all.reduce(
948
948
  (acc, byte, index_) => {
949
949
  let isZero = byte === 0 || index_ === 0;
950
950
  const last = acc.at(-1);
@@ -1010,7 +1010,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
1010
1010
  value: data2
1011
1011
  };
1012
1012
  }
1013
- let dynamicKeyParts = void 0;
1013
+ let dynamicKeyParts;
1014
1014
  if (isDynamicKeyName(schema.name)) {
1015
1015
  dynamicKeyParts = decodeMappingKey(key, schema).map(
1016
1016
  ({ value: value2 }) => isHex2(value2) ? value2.toLowerCase() : `${value2}`
@@ -1574,9 +1574,9 @@ function customDecodeEventLog(parameters) {
1574
1574
  };
1575
1575
  }
1576
1576
  __name(customDecodeEventLog, "customDecodeEventLog");
1577
- function decodeEvent(chain, abi3, log) {
1578
- const { data: _data, address, ...rest } = log;
1579
- let lastError;
1577
+ function decodeEvent(_chain, abi3, log) {
1578
+ const { data: _data } = log;
1579
+ let _lastError;
1580
1580
  try {
1581
1581
  const result = customDecodeEventLog({
1582
1582
  abi: abi3,
@@ -2228,7 +2228,7 @@ var enhanceBurntPixPlugin = standardPlugin(
2228
2228
  aggregations: [refineAggregation]
2229
2229
  }
2230
2230
  );
2231
- async function enhanceBurntPix(result, pluginOptions, options) {
2231
+ async function enhanceBurntPix(result, pluginOptions, _options) {
2232
2232
  if ("functionName" in result && result.functionName === "refine") {
2233
2233
  return {
2234
2234
  ...result,
@@ -2243,25 +2243,20 @@ __name(enhanceBurntPix, "enhanceBurntPix");
2243
2243
  var enhanceBurntPix_default = enhanceBurntPixPlugin;
2244
2244
 
2245
2245
  // src/decoder/plugins/enhanceGraffiti.ts
2246
- import {
2247
- bytesToString,
2248
- hexToBytes,
2249
- size as size3,
2250
- slice as slice2
2251
- } from "viem";
2246
+ import { bytesToString, hexToBytes, size as size3, slice as slice2 } from "viem";
2252
2247
  var enhanceGraffitiPlugin = Object.freeze({
2253
2248
  enhance: /* @__PURE__ */ __name(async (result, options) => enhanceGraffiti(
2254
2249
  result,
2255
2250
  { abiName: "graffiti", decoderName: "graffiti" },
2256
2251
  options
2257
2252
  ), "enhance"),
2258
- decodeEvent: /* @__PURE__ */ __name(async (log, options) => void 0, "decodeEvent"),
2253
+ decodeEvent: /* @__PURE__ */ __name(async (_log, _options) => void 0, "decodeEvent"),
2259
2254
  required: true,
2260
2255
  priority: 1e3,
2261
2256
  name: "graffiti"
2262
2257
  });
2263
2258
  async function enhanceGraffiti(result, _pluginOptions, _options) {
2264
- const { functionName, sig, args, input } = result;
2259
+ const { input } = result;
2265
2260
  if (input && size3(input || "0x") >= 4 && slice2(input || "0x", 0, 4) === "0x00000000") {
2266
2261
  let graffiti = slice2(input, 4);
2267
2262
  try {
@@ -2333,7 +2328,7 @@ async function decodeTransaction(fullTransaction, options) {
2333
2328
  phase: "enhanced"
2334
2329
  };
2335
2330
  }
2336
- let lastError;
2331
+ let _lastError;
2337
2332
  const activePlugins = options.plugins;
2338
2333
  for (const plugin of activePlugins) {
2339
2334
  if (to && isAddress(to) && isAddressEqual(to, zeroAddress)) {
@@ -2396,7 +2391,6 @@ async function decodeTransaction(fullTransaction, options) {
2396
2391
  }
2397
2392
  } catch (e) {
2398
2393
  console.error(e);
2399
- continue;
2400
2394
  }
2401
2395
  }
2402
2396
  let phase = "functionName" in transaction && transaction.functionName && transaction.standard || transaction.input === "0x" || !transaction.input ? "enhanced" : "immediate";
@@ -3322,7 +3316,6 @@ async function enhanceKeyManager(result, pluginOptions, options) {
3322
3316
  sig,
3323
3317
  args,
3324
3318
  input,
3325
- blockNumber,
3326
3319
  to: _to,
3327
3320
  from: _from,
3328
3321
  value
@@ -3592,7 +3585,7 @@ async function enhanceLSP7Metadata(result, options) {
3592
3585
  }
3593
3586
  __name(enhanceLSP7Metadata, "enhanceLSP7Metadata");
3594
3587
  async function enhanceLSP26FollowerSystem(result, _pluginOptions, _options) {
3595
- const { functionName, sig, args, input, blockNumber, to, from, value } = result;
3588
+ const { functionName } = result;
3596
3589
  switch (functionName) {
3597
3590
  }
3598
3591
  return void 0;
@@ -3752,8 +3745,8 @@ var enhanceLSP9VaultPlugin = standardPlugin(
3752
3745
  }, "decodeEvent")
3753
3746
  }
3754
3747
  );
3755
- async function enhanceLSP9Vault(result, pluginOptions, options) {
3756
- const { functionName, sig, args, input, blockNumber, to, from, value } = result;
3748
+ async function enhanceLSP9Vault(result, _pluginOptions, _options) {
3749
+ const { functionName } = result;
3757
3750
  switch (functionName) {
3758
3751
  }
3759
3752
  return void 0;
@@ -3784,7 +3777,7 @@ var enhanceLSP26FollowerSystemPlugin = standardPlugin(
3784
3777
  }
3785
3778
  );
3786
3779
  async function enhanceLSP26FollowerSystem2(result, _pluginOptions, _options) {
3787
- const { functionName, sig, args, input, blockNumber, to, from, value } = result;
3780
+ const { functionName, args } = result;
3788
3781
  const { args: _args, ...partialResult } = result;
3789
3782
  switch (functionName) {
3790
3783
  case "follow":
@@ -3800,7 +3793,6 @@ async function enhanceLSP26FollowerSystem2(result, _pluginOptions, _options) {
3800
3793
  }
3801
3794
  ]
3802
3795
  };
3803
- break;
3804
3796
  case "followBatch":
3805
3797
  case "unfollowBatch":
3806
3798
  return {
@@ -3812,7 +3804,6 @@ async function enhanceLSP26FollowerSystem2(result, _pluginOptions, _options) {
3812
3804
  address
3813
3805
  }))
3814
3806
  };
3815
- break;
3816
3807
  }
3817
3808
  return void 0;
3818
3809
  }
@@ -4528,7 +4519,7 @@ var LRUDecoderCache = class {
4528
4519
  if (cached && (!cached.expires || now < cached.expires)) {
4529
4520
  return cached.value;
4530
4521
  }
4531
- if (cached && cached.stale && now < cached.stale && !this.promises.has(key)) {
4522
+ if (cached?.stale && now < cached.stale && !this.promises.has(key)) {
4532
4523
  const backgroundPromise = factory(options?.signal).then(async (fresh) => {
4533
4524
  await this.set(key, fresh, options);
4534
4525
  return fresh;
@@ -4610,7 +4601,7 @@ async function fetchAbi(chain, address, options) {
4610
4601
  let isProxy = false;
4611
4602
  let decoderVerifiedContract = false;
4612
4603
  let factoryName;
4613
- const originalKey = key;
4604
+ const _originalKey = key;
4614
4605
  const addressUrl = new URL(`/api/v2/addresses/${key}`, explorer);
4615
4606
  const addressRes = await fetch(addressUrl, { signal });
4616
4607
  if (addressRes.ok) {
@@ -4778,7 +4769,7 @@ var getFunctionSignature = /* @__PURE__ */ __name(async (chain, input, to, prefe
4778
4769
  __decoder: methods.__decoder || FUNCTION_DICTIONARY_URL
4779
4770
  };
4780
4771
  }
4781
- } catch (error) {
4772
+ } catch (_error) {
4782
4773
  }
4783
4774
  }
4784
4775
  }
@@ -4817,7 +4808,7 @@ var enhanceRetrieveAbiPlugin = standardPlugin(
4817
4808
  }
4818
4809
  );
4819
4810
  async function enhanceRetrieveAbi(result, _pluginOptions, options) {
4820
- const { functionName, sig, args, input, blockNumber, to, from, value } = result;
4811
+ const { input, to, from, value } = result;
4821
4812
  try {
4822
4813
  const decoded = await getFunctionSignature(
4823
4814
  options.chain,
@@ -4844,7 +4835,9 @@ __name(enhanceRetrieveAbi, "enhanceRetrieveAbi");
4844
4835
  var enhanceRetrieveAbi_default = enhanceRetrieveAbiPlugin;
4845
4836
 
4846
4837
  // src/decoder/plugins/index.ts
4847
- [enhanceLSP0ERC725Account_default, enhanceLSP6KeyManager_default, enhanceLSP7DigitalAsset_default, enhanceLSP8IdentifiableDigitalAsset_default, enhanceLSP9Vault_default, enhanceLSP26FollowerSystem_default, enhanceBurntPix_default].forEach((p) => p);
4838
+ [enhanceLSP0ERC725Account_default, enhanceLSP6KeyManager_default, enhanceLSP7DigitalAsset_default, enhanceLSP8IdentifiableDigitalAsset_default, enhanceLSP9Vault_default, enhanceLSP26FollowerSystem_default, enhanceBurntPix_default].forEach((p) => {
4839
+ p;
4840
+ });
4848
4841
  var defaultPlugins = Object.freeze([
4849
4842
  enhanceGraffiti_default,
4850
4843
  enhanceLSP6KeyManager_default,
@@ -4922,4 +4915,4 @@ export {
4922
4915
  decodeKeyValue,
4923
4916
  decodeKeyValueRaw
4924
4917
  };
4925
- //# sourceMappingURL=chunk-XVHJWV5U.js.map
4918
+ //# sourceMappingURL=chunk-T4H2HHIB.js.map