@lukso/transaction-decoder 1.3.0-dev.c21633f → 1.3.0-dev.f500300

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/server.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  fetchMultipleAddresses
3
- } from "./chunk-FKBKAWB3.js";
3
+ } from "./chunk-EDDQHEAA.js";
4
4
  import {
5
5
  __name,
6
6
  collectDataKeys,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukso/transaction-decoder",
3
- "version": "1.3.0-dev.c21633f",
3
+ "version": "1.3.0-dev.f500300",
4
4
  "description": "Transaction decoder for LUKSO blockchain with reactive state management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -271,7 +271,7 @@ export async function fetchMultipleAddresses(
271
271
  const profiles: string[] = []
272
272
  const assets: string[] = []
273
273
  const tokens: string[] = []
274
- const tokenMapping = new Map<string, { address: Address; tokenId?: string }>()
274
+ const tokenMapping = new Map<string, { address: Address; tokenId: string }>()
275
275
 
276
276
  for (const key of uncachedAddresses) {
277
277
  const hasDash = key.includes('-')
@@ -1 +0,0 @@
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":[]}