@lukso/transaction-decoder 1.2.0 → 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.
- package/dist/browser.cjs +41 -73
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +4 -4
- package/dist/cdn/transaction-decoder.global.js +68 -67
- package/dist/cdn/transaction-decoder.global.js.map +1 -1
- package/dist/{chunk-GGBHTWJL.js → chunk-EDDQHEAA.js} +5 -5
- package/dist/chunk-EDDQHEAA.js.map +1 -0
- package/dist/{chunk-GXZOF3QY.js → chunk-NDBDNXBI.js} +3 -27
- package/dist/chunk-NDBDNXBI.js.map +1 -0
- package/dist/{chunk-XVHJWV5U.js → chunk-T4H2HHIB.js} +25 -32
- package/dist/chunk-T4H2HHIB.js.map +1 -0
- package/dist/{chunk-R6H2MOR5.js → chunk-U7L4W2YL.js} +11 -12
- package/dist/chunk-U7L4W2YL.js.map +1 -0
- package/dist/data.cjs +31 -62
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.cts +2 -2
- package/dist/data.d.ts +2 -2
- package/dist/data.js +2 -2
- package/dist/index.cjs +41 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/server.cjs +31 -43
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -2
- package/dist/server.d.ts +1 -2
- package/dist/server.js +7 -12
- package/dist/server.js.map +1 -1
- package/dist/{utils-CBAkjQh3.d.cts → utils-BEpSreRR.d.cts} +1 -1
- package/dist/{utils-xT9-km0r.d.ts → utils-De_c6fUK.d.ts} +1 -1
- package/package.json +3 -3
- package/src/core/dataModel.ts +1 -31
- package/src/core/integrateDecoder.ts +1 -2
- package/src/decoder/browserCache.ts +1 -6
- package/src/decoder/errors.ts +2 -2
- package/src/decoder/events.ts +3 -3
- package/src/decoder/functionSignature.ts +9 -9
- package/src/decoder/getDataFromExternalSources.ts +2 -2
- package/src/decoder/interfaces.ts +1 -1
- package/src/decoder/kvCache.ts +1 -6
- package/src/decoder/lruCache.ts +1 -6
- package/src/decoder/lsp7TransferBatch.test.ts +0 -3
- package/src/decoder/plugins/enhanceBurntPix.ts +1 -2
- package/src/decoder/plugins/enhanceGraffiti.ts +3 -17
- package/src/decoder/plugins/enhanceLSP26FollowerSystem.ts +4 -8
- package/src/decoder/plugins/enhanceLSP6KeyManager.ts +0 -1
- package/src/decoder/plugins/enhanceLSP7DigitalAsset.ts +5 -7
- package/src/decoder/plugins/enhanceLSP9Vault.ts +7 -8
- package/src/decoder/plugins/enhanceRetrieveAbi.ts +5 -6
- package/src/decoder/plugins/index.ts +3 -1
- package/src/decoder/plugins/schemaDefault.ts +3 -4
- package/src/decoder/plugins/standardPlugin.ts +1 -1
- package/src/decoder/singleGQL.ts +2 -2
- package/src/decoder/transaction.ts +1 -2
- package/src/decoder/utils.ts +2 -2
- package/src/example/usage.ts +3 -4
- package/src/index.ts +1 -1
- package/src/server/addressResolver.ts +1 -1
- package/src/server/decodeTransactionSync.ts +0 -1
- package/src/server/decodeTransactionsBatch.ts +1 -1
- package/src/server/finishDecoding.ts +4 -8
- package/src/server/lsp23Resolver.ts +2 -3
- package/src/server/types.ts +1 -1
- package/src/shared/addressResolver.ts +3 -3
- package/src/utils/json-bigint.ts +4 -4
- package/dist/chunk-GGBHTWJL.js.map +0 -1
- package/dist/chunk-GXZOF3QY.js.map +0 -1
- package/dist/chunk-R6H2MOR5.js.map +0 -1
- package/dist/chunk-XVHJWV5U.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__name
|
|
3
|
-
} from "./chunk-
|
|
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
|
|
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
|
|
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-
|
|
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":";;;;;AAAA,OAAO,WAAW,WAAW;AAE7B,SAAS,aAAa;AAQtB,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmNrB,eAAsB,uBACpB,WACA,iBACA,OACqC;AACrC,QAAM,UAAU,oBAAI,IAA2B;AAE/C,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,EACT;AAGA,QAAM,oBAA+B,CAAC;AAEtC,MAAI,OAAO;AAET,QAAI,MAAM,SAAS;AACjB,YAAM,gBAAgB,MAAM,MAAM,QAAQ,SAAS;AACnD,iBAAW,CAAC,KAAK,KAAK,KAAK,eAAe;AACxC,gBAAQ,IAAI,KAAK,KAAK;AAAA,MACxB;AAEA,iBAAW,QAAQ,WAAW;AAC5B,YAAI,CAAC,QAAQ,IAAI,IAAI,GAAG;AACtB,4BAAkB,KAAK,IAAI;AAAA,QAC7B;AAAA,MACF;AAAA,IACF,OAAO;AAEL,iBAAW,QAAQ,WAAW;AAC5B,cAAM,SAAS,MAAM,MAAM,IAAI,IAAI;AACnC,YAAI,QAAQ;AACV,kBAAQ,IAAI,MAAM,MAAM;AAAA,QAC1B,OAAO;AACL,4BAAkB,KAAK,IAAI;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAGA,QAAI,kBAAkB,WAAW,GAAG;AAClC,aAAO;AAAA,IACT;AAAA,EACF,OAAO;AAEL,sBAAkB,KAAK,GAAG,SAAS;AAAA,EACrC;AAGA,QAAM,WAAqB,CAAC;AAC5B,QAAM,SAAmB,CAAC;AAC1B,QAAM,SAAmB,CAAC;AAC1B,QAAM,eAAe,oBAAI,IAAmD;AAE5E,aAAW,OAAO,mBAAmB;AACnC,UAAM,UAAU,IAAI,SAAS,GAAG;AAChC,UAAM,WAAW,IAAI,SAAS,GAAG;AAEjC,QAAI,YAAY,SAAS;AACvB,YAAM,gBAAgB,IAAI,QAAQ,QAAQ,GAAG;AAC7C,aAAO,KAAK,aAAa;AACzB,YAAM,CAAC,SAAS,OAAO,IAAI,IAAI,MAAM,MAAM;AAC3C,mBAAa,IAAI,KAAK,EAAE,SAA6B,QAAQ,CAAC;AAAA,IAChE,OAAO;AAEL,eAAS,KAAK,GAAG;AACjB,aAAO,KAAK,GAAG;AAAA,IACjB;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,OAAQ,MAAM,QAAQ,iBAAiB,cAAc;AAAA,MACzD;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAGD,QAAI,KAAK,SAAS;AAChB,iBAAW,WAAW,KAAK,SAAS;AAClC,YAAI,QAAQ,aAAa,qBAAqB;AAC5C;AAAA,QACF;AACA,cAAM,eAA6B;AAAA,UACjC,SAAS,QAAQ;AAAA,UACjB,WAAW;AAAA,UACX,MAAM,QAAQ,QAAQ,QAAQ;AAAA,UAC9B,UAAU,QAAQ;AAAA,UAClB,UAAU,QAAQ;AAAA,UAClB,MAAM,QAAQ;AAAA,UACd,aAAa,QAAQ;AAAA,UACrB,OAAO,QAAQ;AAAA,UACf,aAAa,QAAQ;AAAA,UACrB,eAAe,QAAQ;AAAA,UACvB,kBAAkB,QAAQ;AAAA,UAC1B,SAAS,QAAQ;AAAA,QACnB;AACA,gBAAQ,IAAI,QAAQ,IAAe,YAAY;AAAA,MACjD;AAAA,IACF;AAGA,QAAI,KAAK,OAAO;AACd,iBAAW,SAAS,KAAK,OAAO;AAC9B,cAAM,EAAE,IAAI,KAAK,WAAW,SAAS,GAAG,KAAK,IAAI;AAGjD,YAAI,WAAW,MAAM,SAAS;AAC5B,gBAAM,eAA6B;AAAA,YACjC,SAAS,UAAU;AAAA,YACnB;AAAA,YACA,WAAW;AAAA,YACX,GAAG;AAAA,YACH;AAAA,UACF;AAEA,gBAAM,eAAe,GAAG,UAAU,EAAE,IAAI,OAAO;AAC/C,gBAAM,cAAc,GAAG,UAAU,EAAE,IAAI,OAAO;AAC9C,kBAAQ,IAAI,cAAc,YAAY;AACtC,kBAAQ,IAAI,aAAa,YAAY;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,OAAO;AACd,iBAAW,SAAS,KAAK,OAAO;AAC9B,YAAI,MAAM,aAAa,qBAAqB;AAE1C;AAAA,QACF;AACA,cAAM,eAA6B;AAAA,UACjC,SAAS,MAAM;AAAA,UACf,WAAW;AAAA,UACX,GAAG;AAAA,QACL;AACA,YAAI,CAAC,QAAQ,IAAI,MAAM,EAAa,GAAG;AACrC,kBAAQ,IAAI,MAAM,IAAe,YAAY;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO;AACT,YAAM,aAA6C,CAAC;AAGpD,iBAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAElC,cAAM,WAAW,UAAU;AAAA,UACzB,CAAC,SAAS,KAAK,YAAY,MAAM,IAAI,YAAY;AAAA,QACnD;AAEA,YACE,YACA,kBAAkB;AAAA,UAChB,CAAC,SAAS,KAAK,YAAY,MAAM,IAAI,YAAY;AAAA,QACnD,GACA;AACA,qBAAW,KAAK,CAAC,KAAK,KAAK,CAAC;AAAA,QAC9B;AAAA,MACF;AAGA,UAAI,MAAM,WAAW,WAAW,SAAS,GAAG;AAC1C,cAAM,MAAM,QAAQ,UAAU;AAAA,MAChC,OAAO;AAEL,mBAAW,CAAC,KAAK,KAAK,KAAK,YAAY;AACrC,gBAAM,MAAM,IAAI,KAAK,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,8BAA8B,KAAK;AACjD,WAAO;AAAA,EACT;AACF;AApLsB;AAyLf,SAAS,mBAAmB,OAAsB;AACvD,SAAO,MAAM,OAAO,MAAM,KACtB,0DACA;AACN;AAJgB;AAShB,IAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuEhC,eAAsB,2BACpB,qBACA,OACwB;AACxB,QAAM,kBAAkB,mBAAmB,KAAK;AAEhD,MAAI;AACF,UAAM,OAAQ,MAAM,QAAQ,iBAAiB,yBAAyB;AAAA,MACpE,qBAAqB,oBAAoB;AAAA,QAAI,CAAC,SAC5C,KAAK,YAAY;AAAA,MACnB;AAAA,IACF,CAAC;AAED,WAAO,KAAK,WAAW,CAAC;AAAA,EAC1B,SAAS,OAAO;AACd,YAAQ;AAAA,MACN,8CAA8C,MAAM,IAAI;AAAA,MACxD;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AACF;AArBsB;AA6CtB,eAAsB,SACpB,QACA,SAUsE;AACtE,QAAM;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,aAAa;AAAA;AAAA,IACb,MAAM;AAAA,EACR,IAAI;AACJ,QAAM,QAAQ,QAAQ,IAAI,MAAM;AAChC,QAAM,SAAS,WAAW;AAC1B,QAAM,EAAE,KAAK,MAAM,SAAS,KACzB,UAAU,CAAC,GAAG;AAAA,IACb,CAAC,MACC,EAAE,SAAS,QAAQ,QAAQ,OAC3B,EAAE,UACF,EAAE,UAAU,SAAS,QAAQ,QAC5B,QAAQ,EAAE,UAAU,QAAQ,EAAE,UAAU;AAAA,EAC7C,KACA,QAAQ,GAAG,EAAE,KACb,CAAC;AAEH,QAAM,MAAM,MAAM,WAAW,0CAA0C,IACnE,MAAM,QAAQ,YAAY,SAAS,IACnC;AACJ,MAAI,CAAC,KAAK;AACR,WAAO,QAAQ,WACX,EAAE,KAAK,QAAQ,UAAU,OAAO,KAAK,QAAQ,IAAI,IACjD;AAAA,EACN;AACA,MAAI;AACF,QAAI;AACJ,QAAI,OAAO,WAAW,eAAe,CAAC,YAAY;AAChD,YAAM,QAAQ,MAAM,OAAO,KAAK,aAAa;AAC7C,YAAM,SAAS,MAAM,MAAM,MAAM,GAAG;AACpC,UAAI,QAAQ;AACV,cAAM,WAAW,MAAM,OAAO,KAAK;AACnC,YAAI,UAAU;AACZ,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,WAAW,CAAC,YAAY;AAK3B,YAAM,OAAO,KAAK,IAAI;AACtB,gBAAU,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,CAAC,EAC1C,KAAK,CAAC,aAAa;AAClB,YAAI,SAAS,IAAI;AACf,gBAAM,OAAO,SAAS,QAAQ,IAAI,cAAc,KAAK;AACrD,mBAAS,MAAM,OAAO;AACtB,iBAAO,WAAW,KAAK,IAAI,IAAI,OAAO;AAAA,QACxC;AACA,iBAAS,MAAM,OAAO;AACtB,eAAO;AAAA,MACT,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,gBAAQ,MAAO,MAAgB,KAAK;AACpC,eAAO;AAAA,MACT,CAAC;AACH,UAAI,WAAW,QAAQ,OAAO,WAAW,aAAa;AACpD,cAAM,QAAQ,MAAM,OAAO,KAAK,aAAa;AAC7C,cAAM,MACH,IAAI,KAAK,IAAI,SAAS,KAAK,UAAU,OAAO,CAAC,CAAC,EAC9C,MAAM,CAAC,UAAU;AAChB,kBAAQ,MAAO,MAAgB,OAAO,GAAG;AAAA,QAC3C,CAAC;AAAA,MACL;AAAA,IACF;AACA,QAAI,WAAW,YAAY;AACzB,YAAM,WAAW,IAAI,IAAI,GAAG;AAC5B,YAAM,EAAE,aAAa,IAAI;AACzB,YAAM,KAAK,IAAI,gBAAgB,YAAY;AAC3C,UAAI,OAAO;AACT,WAAG,IAAI,SAAS,GAAG,QAAQ,KAAK,EAAE;AAAA,MACpC;AACA,UAAI,SAAS,QAAQ;AACnB,WAAG,IAAI,UAAU,IAAI,UAAU,SAAS,KAAK,EAAE;AAAA,MACjD;AACA,SAAG,IAAI,OAAO,OAAO;AACrB,SAAG,IAAI,OAAO,IAAI,SAAS,CAAC;AAC5B,UACE,CAAC,QAAQ,cACT,CAAC,QAAQ,KAAK,WAAW,EAAE,KAC3B,QAAQ,UACR;AACA,WAAG,IAAI,UAAU,KAAK;AAAA,MACxB;AACA,eAAS,SAAS,GAAG,SAAS;AAC9B,YAAM,QAAQ,SAAS,SAAS;AAChC,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,UAAU;AAAA,QAClB,KACE,aAAa,aAAa,CAAC,qBACvB,GAAG,KAAK,aACR;AAAA,MACR;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAO,MAAgB,KAAK;AAAA,EACtC;AACA,SAAO,QAAQ,WACX,EAAE,KAAK,QAAQ,UAAU,OAAO,KAAK,QAAQ,IAAI,IACjD;AACN;AAvHsB;","names":[]}
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
decodeTransaction,
|
|
5
5
|
isAsyncOperationEnabled,
|
|
6
6
|
pluginRegistry
|
|
7
|
-
} from "./chunk-
|
|
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 {
|
|
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-
|
|
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
|
|
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
|
-
|
|
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(/[
|
|
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
|
|
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(
|
|
1578
|
-
const { data: _data
|
|
1579
|
-
let
|
|
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,
|
|
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 (
|
|
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 {
|
|
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
|
|
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
|
|
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,
|
|
3756
|
-
const { functionName
|
|
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,
|
|
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
|
|
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
|
|
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 (
|
|
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 {
|
|
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) =>
|
|
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-
|
|
4918
|
+
//# sourceMappingURL=chunk-T4H2HHIB.js.map
|