@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,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
consumerModel,
|
|
3
3
|
decodeTransaction
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NDBDNXBI.js";
|
|
5
5
|
import {
|
|
6
6
|
fetchMultipleAddresses
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-EDDQHEAA.js";
|
|
8
8
|
import {
|
|
9
9
|
__name,
|
|
10
10
|
collectDataKeys,
|
|
11
11
|
defaultPlugins,
|
|
12
12
|
defaultSchemaPlugins
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-T4H2HHIB.js";
|
|
14
14
|
|
|
15
15
|
// src/shared/cache.ts
|
|
16
16
|
function isPromise(value) {
|
|
@@ -328,7 +328,7 @@ var DecoderIntegration = class {
|
|
|
328
328
|
*/
|
|
329
329
|
async addAndDecodeTransactions(transactions) {
|
|
330
330
|
const signals = this.dataModel.addTransactions(transactions);
|
|
331
|
-
const decodingPromises = transactions.map(async (tx,
|
|
331
|
+
const decodingPromises = transactions.map(async (tx, _index) => {
|
|
332
332
|
const transactionOptions = {
|
|
333
333
|
...this.decoderOptions,
|
|
334
334
|
wrappers: []
|
|
@@ -567,8 +567,7 @@ function buildLSP23DeploymentQuery(config) {
|
|
|
567
567
|
controllerAddresses,
|
|
568
568
|
profileAddresses,
|
|
569
569
|
fromBlock = 0,
|
|
570
|
-
toBlock
|
|
571
|
-
chainId
|
|
570
|
+
toBlock
|
|
572
571
|
} = config;
|
|
573
572
|
if (profileAddresses && profileAddresses.length > 0) {
|
|
574
573
|
return {
|
|
@@ -651,7 +650,7 @@ function parseLSP23DeploymentsFromHypersync(response, chainId, controllerAddress
|
|
|
651
650
|
}
|
|
652
651
|
}
|
|
653
652
|
const controllerSet = controllerAddresses ? new Set(controllerAddresses.map((addr) => addr.toLowerCase())) : null;
|
|
654
|
-
for (const [txHash,
|
|
653
|
+
for (const [txHash, _profileAddress] of create2Traces) {
|
|
655
654
|
const tx = txMap.get(txHash);
|
|
656
655
|
if (!tx) continue;
|
|
657
656
|
if (controllerSet && !controllerSet.has(tx.from.toLowerCase())) {
|
|
@@ -689,12 +688,12 @@ var JSONbigString = {
|
|
|
689
688
|
/**
|
|
690
689
|
* Stringify an object, converting BigInt values to strings with 'n' suffix
|
|
691
690
|
*/
|
|
692
|
-
stringify: /* @__PURE__ */ __name((obj,
|
|
691
|
+
stringify: /* @__PURE__ */ __name((obj, _replacer, space) => {
|
|
693
692
|
return JSON.stringify(
|
|
694
693
|
obj,
|
|
695
|
-
(
|
|
694
|
+
(_key, value) => {
|
|
696
695
|
if (typeof value === "bigint") {
|
|
697
|
-
return value.toString()
|
|
696
|
+
return `${value.toString()}n`;
|
|
698
697
|
}
|
|
699
698
|
return value;
|
|
700
699
|
},
|
|
@@ -705,7 +704,7 @@ var JSONbigString = {
|
|
|
705
704
|
* Parse a JSON string, converting strings ending with 'n' back to BigInt
|
|
706
705
|
*/
|
|
707
706
|
parse: /* @__PURE__ */ __name((text) => {
|
|
708
|
-
return JSON.parse(text, (
|
|
707
|
+
return JSON.parse(text, (_key, value) => {
|
|
709
708
|
if (typeof value === "string" && /^\d+n$/.test(value)) {
|
|
710
709
|
return BigInt(value.slice(0, -1));
|
|
711
710
|
}
|
|
@@ -773,4 +772,4 @@ export {
|
|
|
773
772
|
getAllData,
|
|
774
773
|
getAllTransactions
|
|
775
774
|
};
|
|
776
|
-
//# sourceMappingURL=chunk-
|
|
775
|
+
//# sourceMappingURL=chunk-U7L4W2YL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/cache.ts","../src/client/resolveAddresses.ts","../src/core/addressResolver.ts","../src/core/integrateDecoder.ts","../src/server/lsp23Resolver.ts","../src/utils/json-bigint.ts","../src/index.ts"],"sourcesContent":["import type { DataKey, EnhancedInfo } from '../types'\n\n/**\n * Address identity cache interface\n * Can be implemented with different backends (LRU, Redis, etc.)\n */\nexport interface AddressIdentityCache {\n /**\n * Get cached address data\n */\n get(\n key: DataKey\n ): EnhancedInfo | undefined | Promise<EnhancedInfo | undefined>\n\n /**\n * Set address data in cache\n */\n set(key: DataKey, value: EnhancedInfo): void | Promise<void>\n\n /**\n * Check if address is in cache\n */\n has(key: DataKey): boolean | Promise<boolean>\n\n /**\n * Get multiple addresses at once\n */\n getMany?(\n keys: readonly DataKey[]\n ): Map<DataKey, EnhancedInfo> | Promise<Map<DataKey, EnhancedInfo>>\n\n /**\n * Set multiple addresses at once\n */\n setMany?(entries: Array<[DataKey, EnhancedInfo]>): void | Promise<void>\n\n /**\n * Clear all cached data\n */\n clear?(): void | Promise<void>\n}\n\n/**\n * Type guard to check if value is a promise\n */\nfunction isPromise<T>(value: T | Promise<T>): value is Promise<T> {\n return value instanceof Promise\n}\n\n/**\n * Helper to convert DataKey to cache key string\n */\nexport function getDataKeyCacheKey(key: DataKey): string {\n return key.toLowerCase()\n}\n\n/**\n * Convert a DataKey to the standardized string format\n * @param dataKey - A hex string (address or address:tokenId)\n * @returns The same string\n */\nexport function dataKeyToString(dataKey: DataKey): string {\n return dataKey\n}\n\n/**\n * Parse a string to a DataKey\n * @param str - String in format \"address\" or \"address:tokenId\"\n * @returns DataKey as a hex string\n */\nexport function parseDataKey(str: string): DataKey {\n // Just return the string as-is since DataKey is now always a string\n return str as DataKey\n}\n\n/**\n * Create a simple in-memory address cache\n */\nexport function createMemoryAddressIdentityCache(\n ttlMs: number = 1000 * 60 * 5 // 5 minutes default\n): AddressIdentityCache {\n const cache = new Map<string, { data: EnhancedInfo; expires: number }>()\n\n return {\n get(key: DataKey): EnhancedInfo | undefined {\n const cacheKey = getDataKeyCacheKey(key)\n const entry = cache.get(cacheKey)\n\n if (!entry) return undefined\n\n if (Date.now() > entry.expires) {\n cache.delete(cacheKey)\n return undefined\n }\n\n return entry.data\n },\n\n set(key: DataKey, value: EnhancedInfo): void {\n const cacheKey = getDataKeyCacheKey(key)\n cache.set(cacheKey, {\n data: value,\n expires: Date.now() + ttlMs,\n })\n },\n\n has(key: DataKey): boolean {\n const cacheKey = getDataKeyCacheKey(key)\n const entry = cache.get(cacheKey)\n\n if (!entry) return false\n\n if (Date.now() > entry.expires) {\n cache.delete(cacheKey)\n return false\n }\n\n return true\n },\n\n getMany(keys: DataKey[]): Map<DataKey, EnhancedInfo> {\n const results = new Map<DataKey, EnhancedInfo>()\n\n for (const key of keys) {\n const data = this.get(key)\n if (data && !isPromise(data)) {\n results.set(key, data)\n }\n }\n\n return results\n },\n\n setMany(entries: Array<[DataKey, EnhancedInfo]>): void {\n for (const [key, value] of entries) {\n this.set(key, value)\n }\n },\n\n clear(): void {\n cache.clear()\n },\n }\n}\n","import type { Chain } from 'viem'\nimport type { AddressIdentityCache } from '../shared/cache'\nimport { getDataKeyCacheKey } from '../shared/cache'\nimport type { DataKey, EnhancedInfo } from '../types'\n\nexport interface ResolveAddressesOptions {\n /**\n * API endpoint URL (defaults to '/api/resolveAddresses')\n */\n endpoint?: string\n\n /**\n * Optional cache to check before making API call\n */\n cache?: AddressIdentityCache\n\n /**\n * Maximum number of addresses per batch (defaults to 100)\n */\n batchSize?: number\n\n /**\n * Request timeout in milliseconds (defaults to 10000)\n */\n timeout?: number\n}\n\nexport interface ResolveAddressesResponse {\n success: boolean\n addresses?: Record<string, EnhancedInfo>\n cached?: number\n fetched?: number\n total?: number\n error?: string\n}\n\n/**\n * Resolve addresses using the API endpoint\n * This allows clients to populate the server cache and get resolved addresses\n */\nexport async function resolveAddresses(\n addresses: DataKey[],\n chain: Chain,\n options: ResolveAddressesOptions = {}\n): Promise<Map<DataKey, EnhancedInfo>> {\n const {\n endpoint = '/api/resolveAddresses',\n cache,\n batchSize = 100,\n timeout = 10000,\n } = options\n\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 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 if (uncachedAddresses.length === 0) {\n return results\n }\n } else {\n uncachedAddresses.push(...addresses)\n }\n\n // Process in batches\n const batches: DataKey[][] = []\n for (let i = 0; i < uncachedAddresses.length; i += batchSize) {\n batches.push(uncachedAddresses.slice(i, i + batchSize))\n }\n\n // Fetch all batches in parallel\n const batchPromises = batches.map(async (batch) => {\n try {\n // DataKey is now just Hex string, use batch directly\n const apiAddresses = batch\n\n // Make API request with timeout\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n chainId: chain.id,\n addresses: apiAddresses,\n }),\n signal: controller.signal,\n })\n\n clearTimeout(timeoutId)\n\n if (!response.ok) {\n console.error(\n `Address resolution failed: ${response.status} ${response.statusText}`\n )\n return\n }\n\n const data: ResolveAddressesResponse = await response.json()\n\n if (data.success && data.addresses) {\n // Convert response back to DataKey -> EnhancedInfo map\n for (const [cacheKey, enhancedInfo] of Object.entries(data.addresses)) {\n // Find the original DataKey that matches this cache key\n const matchingKey = batch.find(\n (key) => getDataKeyCacheKey(key) === cacheKey\n )\n\n if (matchingKey) {\n results.set(matchingKey, enhancedInfo)\n\n // Update cache if provided\n if (cache) {\n await cache.set(matchingKey, enhancedInfo)\n }\n }\n }\n }\n } catch (error) {\n console.error('Failed to resolve addresses batch:', error)\n }\n })\n\n await Promise.all(batchPromises)\n\n return results\n}\n\n/**\n * Create a cache-through address resolver that uses the API\n * This can be used as a drop-in replacement for fetchMultipleAddresses\n */\nexport function createApiAddressResolver(\n chain: Chain,\n options: ResolveAddressesOptions = {}\n) {\n return async (addresses: DataKey[]): Promise<Map<DataKey, EnhancedInfo>> => {\n return resolveAddresses(addresses, chain, options)\n }\n}\n","import type { Chain } from 'viem'\nimport { fetchMultipleAddresses } from '../shared/addressResolver'\nimport type { AddressIdentityCache } from '../shared/cache'\nimport type { DataKey, EnhancedInfo, IDataModel } from '../types'\n\n/**\n * Configuration for address resolver\n */\nexport interface AddressResolverConfig {\n dataModel: IDataModel\n graphqlEndpoint: string\n chain: Chain\n batchSize?: number\n batchDelay?: number\n cache?: AddressIdentityCache\n}\n\n/**\n * Resolve addresses using GraphQL\n * Replaces the old patchValue mechanism\n */\nexport class AddressResolver {\n private dataModel: IDataModel\n private graphqlEndpoint: string\n private batchSize: number\n private batchDelay: number\n private pendingAddresses = new Set<string>()\n private batchTimer?: NodeJS.Timeout\n private cache?: AddressIdentityCache\n\n constructor(config: AddressResolverConfig) {\n this.dataModel = config.dataModel\n this.graphqlEndpoint = config.graphqlEndpoint\n this.batchSize = config.batchSize || 50\n this.batchDelay = config.batchDelay || 100\n this.cache = config.cache\n }\n\n /**\n * Start watching for missing addresses\n */\n startWatching() {\n // Check for missing addresses periodically\n setInterval(() => {\n const missing = this.dataModel.getMissingKeys()\n if (missing.length > 0) {\n this.queueAddresses(missing)\n }\n }, 1000)\n }\n\n /**\n * Queue addresses for batch resolution\n */\n queueAddresses(addresses: DataKey[]) {\n // Add to pending set\n for (const addr of addresses) {\n this.pendingAddresses.add(addr)\n }\n\n // Clear existing timer\n if (this.batchTimer) {\n clearTimeout(this.batchTimer)\n }\n\n // Set new timer\n this.batchTimer = setTimeout(() => {\n this.processBatch()\n }, this.batchDelay)\n\n // Process immediately if batch is full\n if (this.pendingAddresses.size >= this.batchSize) {\n clearTimeout(this.batchTimer)\n this.processBatch()\n }\n }\n\n /**\n * Process a batch of addresses\n */\n private async processBatch() {\n const batch = Array.from(this.pendingAddresses).slice(0, this.batchSize)\n if (batch.length === 0) return\n\n // Remove from pending\n for (const key of batch) {\n this.pendingAddresses.delete(key)\n }\n\n // Convert batch keys back to DataKey format\n const dataKeys: DataKey[] = batch.map((key) => {\n return key as DataKey\n })\n\n try {\n // Fetch data using shared implementation with cache\n const results = await fetchMultipleAddresses(\n dataKeys,\n this.graphqlEndpoint,\n this.cache\n )\n\n // Convert to array for injection\n const enhancedData: EnhancedInfo[] = Array.from(results.values())\n\n // Inject data into model\n if (enhancedData.length > 0) {\n this.dataModel.injectData(enhancedData)\n }\n } catch (error) {\n console.error('Failed to resolve addresses:', error)\n\n // Mark addresses as having errors\n for (const key of dataKeys) {\n this.dataModel.setError(key, 'Failed to fetch address data')\n }\n }\n\n // Continue processing if more pending\n if (this.pendingAddresses.size > 0) {\n this.batchTimer = setTimeout(() => {\n this.processBatch()\n }, this.batchDelay)\n }\n }\n\n /**\n * Stop watching for addresses\n */\n stopWatching() {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer)\n }\n }\n}\n","import { effect } from '@preact/signals-core'\nimport { lukso } from 'viem/chains'\nimport { decodeTransaction } from '../decoder/decodeTransaction'\nimport { defaultPlugins, defaultSchemaPlugins } from '../decoder/plugins'\nimport type { DecoderOptions, DecoderResult } from '../decoder/types'\nimport type { DataKey, EnhancedInfo, IDataModel } from '../types'\nimport { collectDataKeys } from './addressCollector'\n\n/**\n * Configuration for decoder integration\n */\nexport interface DecoderIntegrationConfig {\n dataModel: IDataModel\n decoderOptions?: Partial<DecoderOptions>\n addressCache?: AddressCache\n}\n\n/**\n * External cache interface for address data\n */\nexport interface AddressCache {\n get(key: DataKey): Promise<EnhancedInfo | undefined>\n set(key: DataKey, value: EnhancedInfo): Promise<void>\n has(key: DataKey): Promise<boolean>\n delete(key: DataKey): Promise<void>\n clear(): Promise<void>\n}\n\n/**\n * Integrate the decoder with the data model\n * Handles progressive transaction enhancement and address population\n */\nexport class DecoderIntegration {\n private dataModel: IDataModel\n private decoderOptions: DecoderOptions\n private addressCache?: AddressCache\n\n constructor(config: DecoderIntegrationConfig) {\n this.dataModel = config.dataModel\n this.addressCache = config.addressCache\n\n // Set up default decoder options\n this.decoderOptions = {\n plugins: defaultPlugins,\n schemaPlugins: defaultSchemaPlugins,\n wrappers: [],\n chain: config.decoderOptions?.chain || lukso,\n ...config.decoderOptions,\n }\n }\n\n /**\n * Add and decode a transaction\n * @param transaction - Raw transaction data\n * @returns Transaction signal that updates as decoding progresses\n */\n async addAndDecodeTransaction(transaction: DecoderResult) {\n // Add transaction to data model\n const signal = this.dataModel.addTransactions(transaction)\n\n // Create fresh wrappers array for this transaction\n const transactionOptions: DecoderOptions = {\n ...this.decoderOptions,\n wrappers: [], // Fresh array for collecting wrappers in this decode hierarchy\n }\n\n // Start decoding process\n const { signal: decodingSignal } = await decodeTransaction(\n transaction,\n transactionOptions\n )\n\n // Update transaction data as decoding progresses\n effect(() => {\n const state = decodingSignal.value\n if (state.data) {\n const decodedResult = state.data as DecoderResult\n\n // Process any collected wrappers\n if (transactionOptions.wrappers.length > 0) {\n // Only certain result types support wrappers\n if (\n 'wrappers' in decodedResult &&\n typeof decodedResult === 'object'\n ) {\n ;(decodedResult as Record<string, unknown>).wrappers =\n transactionOptions.wrappers\n }\n\n // Extract addresses from wrappers\n for (const wrapper of transactionOptions.wrappers) {\n this.updateAddressesFromDecoded(wrapper as DecoderResult)\n }\n }\n\n // Flatten nested batch transactions if configured\n const processedResult = this.flattenBatchTransactions(decodedResult)\n\n if (transaction.hash) {\n this.dataModel.updateTransactionData(\n transaction.hash,\n processedResult,\n 0 // decoder index\n )\n }\n\n // Extract and update addresses from decoded data\n this.updateAddressesFromDecoded(processedResult)\n }\n })\n\n return signal\n }\n\n /**\n * Add and decode multiple transactions\n * @param transactions - Array of raw transactions\n * @returns Array of transaction signals\n */\n async addAndDecodeTransactions(transactions: DecoderResult[]) {\n // Add all transactions to data model\n const signals = this.dataModel.addTransactions(transactions)\n\n // Start decoding for each transaction\n const decodingPromises = transactions.map(async (tx, _index) => {\n // Create fresh wrappers array for each transaction\n const transactionOptions: DecoderOptions = {\n ...this.decoderOptions,\n wrappers: [], // Fresh array for collecting wrappers in this decode hierarchy\n }\n\n const { signal: decodingSignal } = await decodeTransaction(\n tx,\n transactionOptions\n )\n\n // Update transaction data as decoding progresses\n effect(() => {\n const state = decodingSignal.value\n if (state.data) {\n const decodedResult = state.data as DecoderResult\n\n // Process any collected wrappers\n if (transactionOptions.wrappers.length > 0) {\n // Only certain result types support wrappers\n if (\n 'wrappers' in decodedResult &&\n typeof decodedResult === 'object'\n ) {\n ;(decodedResult as Record<string, unknown>).wrappers =\n transactionOptions.wrappers\n }\n\n // Extract addresses from wrappers\n for (const wrapper of transactionOptions.wrappers) {\n this.updateAddressesFromDecoded(wrapper as DecoderResult)\n }\n }\n\n // Flatten nested batch transactions if configured\n const processedResult = this.flattenBatchTransactions(decodedResult)\n\n if (tx.hash) {\n this.dataModel.updateTransactionData(\n tx.hash,\n processedResult,\n 0 // decoder index\n )\n }\n\n // Extract and update addresses from decoded data\n this.updateAddressesFromDecoded(processedResult)\n }\n })\n\n return decodingSignal\n })\n\n await Promise.all(decodingPromises)\n return signals\n }\n\n /**\n * Extract and register addresses from decoded transaction data\n */\n private async updateAddressesFromDecoded(decodedData: DecoderResult) {\n const addresses = collectDataKeys(decodedData)\n\n // Check cache and inject into data model\n for (const address of addresses) {\n // Check cache first\n if (this.addressCache) {\n const cached = await this.addressCache.get(address)\n if (cached) {\n // Inject into data model\n this.dataModel.updateData(cached)\n }\n }\n\n // Ensure the address signal exists (creates empty signal if not)\n // This allows views to getAddress() without errors\n this.dataModel.getAddress(address)\n }\n }\n\n /**\n * Flatten nested batch transactions\n * If a batch contains another batch as a child, flatten all sub-transactions into the parent's children\n *\n * Structure:\n * - Wrappers: The \"invisible\" execute functions (execute, executeRelayCall, etc.) that wrap the actual transaction\n * - Children: The actual transactions being executed\n *\n * Result:\n * - Single transaction: { resultType: 'execute', wrappers: [...] }\n * - Batch transaction: { resultType: 'executeBatch', children: [flat list], wrappers: [...] }\n *\n * This ensures only ONE level of batch with all transactions flattened\n */\n private flattenBatchTransactions(result: DecoderResult): DecoderResult {\n // Only process batch result types\n if (\n result.resultType !== 'executeBatch' &&\n result.resultType !== 'setDataBatch'\n ) {\n return result\n }\n\n // Type guard to ensure we have children property\n if (!('children' in result) || !Array.isArray(result.children)) {\n return result\n }\n\n // Flatten children - if any child is also a batch, merge its children up\n const flattenedChildren: unknown[] = []\n\n for (const child of result.children) {\n if (typeof child === 'object' && child && 'resultType' in child) {\n const childResult = child as Record<string, unknown>\n if (\n childResult.resultType === 'executeBatch' ||\n childResult.resultType === 'setDataBatch'\n ) {\n // This child is also a batch - flatten its children into our array\n if (\n 'children' in childResult &&\n Array.isArray(childResult.children)\n ) {\n flattenedChildren.push(...childResult.children)\n }\n } else {\n // Regular child - keep as is\n flattenedChildren.push(child)\n }\n }\n }\n\n // Return updated result with flattened children\n return {\n ...result,\n children: flattenedChildren,\n } as DecoderResult\n }\n\n /**\n * Load missing address data\n * This would be called by an external service that fetches address data\n */\n async loadAddressData(addressData: EnhancedInfo[]) {\n // Update data model\n this.dataModel.injectData(addressData)\n\n // Update cache if available\n if (this.addressCache) {\n await Promise.all(\n addressData.map((data) => {\n const key: DataKey = data.tokenId\n ? (`${data.address}:${data.tokenId}` as DataKey)\n : (data.address as DataKey)\n return this.addressCache?.set(key, data) ?? Promise.resolve()\n })\n )\n }\n }\n\n /**\n * Get addresses that need to be fetched\n */\n getMissingAddresses(): DataKey[] {\n return this.dataModel.getMissingKeys()\n }\n\n /**\n * Get addresses currently being loaded\n */\n getLoadingAddresses(): DataKey[] {\n return this.dataModel.getLoadingKeys()\n }\n}\n\n/**\n * Create a simple in-memory address cache\n */\nexport function createMemoryAddressCache(): AddressCache {\n const cache = new Map<string, EnhancedInfo>()\n\n return {\n async get(key: DataKey) {\n return cache.get(key)\n },\n async set(key: DataKey, value: EnhancedInfo) {\n cache.set(key, value)\n },\n async has(key: DataKey) {\n return cache.has(key)\n },\n async delete(key: DataKey) {\n cache.delete(key)\n },\n async clear() {\n cache.clear()\n },\n }\n}\n","import type { Address } from 'viem'\nimport {\n bytesToHex,\n decodeAbiParameters,\n isHex,\n parseAbiParameters,\n} from 'viem'\n\n/**\n * LSP23 Factory address (same on all networks)\n */\nexport const LSP23_FACTORY_ADDRESS =\n '0x2300000a84d25df63081feaa37ba6b62c4c89a30' as const\n\n/**\n * deployERC1167Proxies function selector\n */\nexport const DEPLOY_ERC1167_PROXIES_SELECTOR = '0x6a66a753' as const\n\n/**\n * LSP23 deployment data structure\n */\nexport interface LSP23DeploymentData {\n profileAddress: Address\n urdAddress: Address\n deployerAddress: Address // The controller that deployed this profile\n salt: string\n primaryImplementation: Address\n secondaryImplementation: Address\n postDeploymentModule: Address\n initializationCalldata: string\n deploymentCalldata: string // Full calldata to deployERC1167Proxies\n transactionHash: string\n blockNumber: bigint\n blockTimestamp: number // Unix timestamp of the block\n chainId: number\n}\n\n/**\n * Contract deployment tuple structures\n * Primary: (bytes32 salt, uint256 fundingAmount, address implementationContract, bytes initializeCalldata)\n * Secondary: (uint256 fundingAmount, address implementationContract, bytes addInitializeCalldata, bool addConstructor, bytes constructorParams)\n */\n\n/**\n * Decode deployERC1167Proxies calldata\n *\n * Function signature:\n * deployERC1167Proxies(\n * (bytes32 salt, uint256 fundingAmount, address implementationContract, bytes initializeCalldata) primaryContractDeployment,\n * (uint256 fundingAmount, address implementationContract, bytes addInitializeCalldata, bool addConstructor, bytes constructorParams) secondaryContractDeployment,\n * address postDeploymentModule,\n * bytes postDeploymentModuleCalldata\n * )\n */\nexport function decodeDeploymentCalldata(input: string): {\n salt: string\n primaryImplementation: Address\n secondaryImplementation: Address\n postDeploymentModule: Address\n initializationCalldata: string\n} | null {\n try {\n // Remove function selector (first 4 bytes / 8 hex chars + 0x)\n const params = `0x${input.slice(10)}` as `0x${string}`\n\n // Decode the parameters\n const decoded = decodeAbiParameters(\n parseAbiParameters(\n '(bytes32,uint256,address,bytes), (uint256,address,bytes,bool,bytes), address, bytes'\n ),\n params\n )\n\n const [\n primaryDeployment,\n secondaryDeployment,\n postDeploymentModule,\n postDeploymentModuleCalldata,\n ] = decoded\n\n // Primary deployment tuple: (bytes32 salt, uint256 fundingAmount, address implementationContract, bytes initializeCalldata)\n const [salt, , primaryImplementation] = primaryDeployment as [\n string,\n bigint,\n Address,\n string,\n ]\n\n // Secondary deployment tuple: (uint256 fundingAmount, address implementationContract, bytes addInitializeCalldata, bool addConstructor, bytes constructorParams)\n const [, secondaryImplementation] = secondaryDeployment as [\n bigint,\n Address,\n string,\n boolean,\n string,\n ]\n\n if (!primaryImplementation || !secondaryImplementation) {\n return null\n }\n\n return {\n salt,\n primaryImplementation,\n secondaryImplementation,\n postDeploymentModule: postDeploymentModule as Address,\n initializationCalldata: postDeploymentModuleCalldata as string,\n }\n } catch (error) {\n console.error('Failed to decode LSP23 deployment calldata:', error)\n return null\n }\n}\n\n/**\n * Decode deployERC1167Proxies output to get deployed addresses\n *\n * Returns: (address primaryContractAddress, address secondaryContractAddress)\n */\nexport function decodeDeploymentOutput(output: string): {\n profileAddress: Address\n urdAddress: Address\n} | null {\n try {\n const decoded = decodeAbiParameters(\n parseAbiParameters('address, address'),\n output as `0x${string}`\n )\n\n return {\n profileAddress: decoded[0],\n urdAddress: decoded[1],\n }\n } catch (error) {\n console.error('Failed to decode LSP23 deployment output:', error)\n return null\n }\n}\n\n/**\n * Extract controller addresses from initialization calldata\n *\n * The initializationCalldata contains a setDataBatch call that sets up controller permissions.\n * Function: setDataBatch(bytes32[] dataKeys, bytes[] dataValues)\n *\n * The dataKeys contain entries like:\n * - AddressPermissions:Permissions:<controller-address>\n *\n * We extract controller addresses from these keys.\n */\nexport function extractControllersFromInitCalldata(\n initializationCalldata: string\n): Address[] {\n try {\n if (!initializationCalldata || initializationCalldata === '0x') {\n return []\n }\n\n // The postDeploymentModuleCalldata is raw ABI-encoded (bytes32[], bytes[])\n // No function selector - decode directly\n const decoded = decodeAbiParameters(\n parseAbiParameters('bytes32[], bytes[]'),\n initializationCalldata as `0x${string}`\n )\n\n const [dataKeys, dataValues] = decoded\n const controllers: Address[] = []\n\n // Look for AddressPermissions[] keys\n // The key is 0xdf30dba06db6a30e65354d9a64c60986 followed by zeros\n // The controller address is in the corresponding value at the same index (encoded as bytes)\n const ADDRESS_PERMISSIONS_ARRAY_PREFIX =\n '0xdf30dba06db6a30e65354d9a64c60986'\n\n for (let i = 0; i < dataKeys.length; i++) {\n const keyStr = dataKeys[i].toLowerCase()\n if (keyStr.startsWith(ADDRESS_PERMISSIONS_ARRAY_PREFIX)) {\n // The value contains the controller address\n const value = dataValues[i]\n\n // Convert to hex if it's not already\n const valueHex = isHex(value) ? value : bytesToHex(value as Uint8Array)\n\n // The value should be a 20-byte address (40 hex chars + 0x = 42 total)\n // or possibly 32 bytes with padding\n if (valueHex.length === 42) {\n // Exactly 20 bytes - this is the address\n const addr = valueHex as Address\n if (\n addr !== '0x0000000000000000000000000000000000000000' &&\n !controllers.some((c) => c.toLowerCase() === addr.toLowerCase())\n ) {\n controllers.push(addr)\n }\n }\n }\n }\n\n return controllers\n } catch (error) {\n console.error('Failed to extract controllers from init calldata:', error)\n return []\n }\n}\n\n/**\n * Hypersync query configuration for LSP23 deployments\n */\nexport interface HypersyncQueryConfig {\n /**\n * Controller addresses (derived keys) that deployed profiles\n * We only want LSP23 data for profiles WE created, not imported\n */\n controllerAddresses?: Address[]\n\n /**\n * Profile addresses to query deployment data for\n * More efficient than querying by controllers when we already know the profiles\n */\n profileAddresses?: Address[]\n\n /**\n * Starting block (0 for genesis)\n */\n fromBlock?: number\n\n /**\n * Ending block (undefined for latest)\n */\n toBlock?: number\n\n /**\n * Chain ID to query\n */\n chainId: number\n}\n\n/**\n * Build Hypersync query to find LSP23 deployments\n *\n * Strategy 1 (by profileAddresses - RECOMMENDED):\n * Query CREATE2 traces where the created address matches our profile addresses.\n * Then filter transactions to LSP23 factory and verify deployer is one of our controllers.\n * This is more efficient when we already know the profile addresses from GraphQL.\n *\n * Strategy 2 (by controllerAddresses - LEGACY):\n * Query transactions TO the LSP23 factory FROM our controller addresses.\n * This scans the entire chain history for all deployments by our controllers.\n */\nexport function buildLSP23DeploymentQuery(config: HypersyncQueryConfig) {\n const {\n controllerAddresses,\n profileAddresses,\n fromBlock = 0,\n toBlock,\n } = config\n\n // Prefer querying by profile addresses (more efficient)\n if (profileAddresses && profileAddresses.length > 0) {\n return {\n from_block: fromBlock,\n to_block: toBlock,\n // Query CREATE2 traces where the created address is one of our profiles\n traces: [\n {\n type: ['create2'],\n to: profileAddresses.map((addr) => addr.toLowerCase()),\n },\n ],\n // Also get the transactions to verify they're to the LSP23 factory\n transactions: [\n {\n to: [LSP23_FACTORY_ADDRESS.toLowerCase()],\n },\n ],\n field_selection: {\n transaction: ['hash', 'from', 'to', 'input', 'output', 'block_number'],\n trace: ['transaction_hash', 'type', 'from', 'to'],\n block: ['number', 'timestamp'],\n },\n include_all_blocks: false,\n }\n }\n\n // Fall back to querying by controller addresses (less efficient)\n if (controllerAddresses && controllerAddresses.length > 0) {\n return {\n from_block: fromBlock,\n to_block: toBlock,\n // Query transactions to the LSP23 factory from our controllers\n transactions: [\n {\n from: controllerAddresses.map((addr) => addr.toLowerCase()),\n to: [LSP23_FACTORY_ADDRESS.toLowerCase()],\n },\n ],\n // Also get traces to see the CREATE2 operations\n traces: [\n {\n type: ['create2'],\n // No filter on 'to' - we'll match by transaction hash\n },\n ],\n field_selection: {\n transaction: ['hash', 'from', 'to', 'input', 'output', 'block_number'],\n trace: ['transaction_hash', 'type', 'from', 'to'],\n block: ['number', 'timestamp'],\n },\n include_all_blocks: false,\n }\n }\n\n throw new Error(\n 'Either profileAddresses or controllerAddresses must be provided'\n )\n}\n\n/**\n * Parse Hypersync response to extract LSP23 deployment data\n * @param response - Hypersync API response\n * @param chainId - Chain ID\n * @param controllerAddresses - Optional list of controller addresses to filter by (only return deployments from these deployers)\n */\nexport function parseLSP23DeploymentsFromHypersync(\n response: any,\n chainId: number,\n controllerAddresses?: Address[]\n): LSP23DeploymentData[] {\n const deployments: LSP23DeploymentData[] = []\n\n if (!response?.data) {\n return deployments\n }\n\n // Build a map of block number -> timestamp\n const blockTimestamps = new Map<number, number>()\n for (const block of response.data.blocks || []) {\n blockTimestamps.set(block.number, block.timestamp)\n }\n\n // Build a map of transaction hash -> transaction data\n const txMap = new Map<string, any>()\n for (const tx of response.data.transactions || []) {\n if (\n tx.to?.toLowerCase() === LSP23_FACTORY_ADDRESS.toLowerCase() &&\n tx.input?.startsWith(DEPLOY_ERC1167_PROXIES_SELECTOR)\n ) {\n txMap.set(tx.hash.toLowerCase(), tx)\n }\n }\n\n // Process traces to find CREATE2 operations\n const create2Traces = new Map<string, Address>() // txHash -> created profile address\n\n for (const trace of response.data.traces || []) {\n if (trace.type === 'create2' && trace.to) {\n create2Traces.set(\n trace.transaction_hash.toLowerCase(),\n trace.to as Address\n )\n }\n }\n\n // Create a Set of lowercase controller addresses for efficient filtering\n const controllerSet = controllerAddresses\n ? new Set(controllerAddresses.map((addr) => addr.toLowerCase()))\n : null\n\n // Match transactions with traces\n for (const [txHash, _profileAddress] of create2Traces) {\n const tx = txMap.get(txHash)\n if (!tx) continue\n\n // If controller filtering is enabled, verify the deployer is one of our controllers\n if (controllerSet && !controllerSet.has(tx.from.toLowerCase())) {\n continue\n }\n\n // Decode the transaction\n const decodedInput = decodeDeploymentCalldata(tx.input)\n const decodedOutput = tx.output ? decodeDeploymentOutput(tx.output) : null\n\n if (!decodedInput || !decodedOutput) continue\n\n // Get block timestamp for this transaction\n const blockTimestamp = blockTimestamps.get(tx.block_number) || 0\n\n deployments.push({\n profileAddress: decodedOutput.profileAddress,\n urdAddress: decodedOutput.urdAddress,\n deployerAddress: tx.from as Address, // The controller that deployed this profile\n salt: decodedInput.salt,\n primaryImplementation: decodedInput.primaryImplementation,\n secondaryImplementation: decodedInput.secondaryImplementation,\n postDeploymentModule: decodedInput.postDeploymentModule,\n initializationCalldata: decodedInput.initializationCalldata,\n deploymentCalldata: tx.input, // Full calldata to deployERC1167Proxies\n transactionHash: tx.hash,\n blockNumber: BigInt(tx.block_number),\n blockTimestamp, // Unix timestamp of the block\n chainId,\n })\n }\n\n return deployments\n}\n\n/**\n * Note: Hypersync querying should be done server-side to protect HYPERSYNC_TOKEN.\n * Use the wallet-app API endpoint /api/lsp23Deployments instead of calling Hypersync directly.\n *\n * This module exports:\n * - buildLSP23DeploymentQuery() - Build the Hypersync query structure\n * - parseLSP23DeploymentsFromHypersync() - Parse Hypersync response\n * - decodeDeploymentCalldata() - Decode LSP23 transaction input\n * - decodeDeploymentOutput() - Decode LSP23 transaction output\n */\n","/**\n * JSON serializer/deserializer that preserves BigInt types\n *\n * This implementation uses an 'n' suffix to indicate BigInt values,\n * ensuring that values that were originally BigInt remain BigInt,\n * and values that were originally numbers remain numbers.\n *\n * Example:\n * - BigInt(123) serializes to \"123n\"\n * - Number(123) serializes to 123\n *\n * This is important for blockchain data where some values must be BigInt\n * (e.g., gas, value, nonce) while others should remain as numbers\n * (e.g., array indices, status codes).\n */\n\nexport const JSONbigString = {\n /**\n * Stringify an object, converting BigInt values to strings with 'n' suffix\n */\n stringify: (obj: any, _replacer?: any, space?: string | number): string => {\n return JSON.stringify(\n obj,\n (_key, value) => {\n if (typeof value === 'bigint') {\n return `${value.toString()}n`\n }\n return value\n },\n space\n )\n },\n\n /**\n * Parse a JSON string, converting strings ending with 'n' back to BigInt\n */\n parse: (text: string): any => {\n return JSON.parse(text, (_key, value) => {\n if (typeof value === 'string' && /^\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1))\n }\n return value\n })\n },\n}\n\nexport default JSONbigString\n","/**\n * @lukso/decoder - Consumer API\n *\n * This is the main entry point for consumers of the decoder.\n * Import data provider functions from '@lukso/transaction-decoder/data' instead.\n */\n\nimport { consumerModel, createGlobalInstance } from './core/instance'\n\n// Export all types that consumers need\nexport type {\n AddressState,\n DataKey,\n EnhancedInfo,\n IDataModelConsumer,\n TransactionState,\n} from './types'\n// DecoderResult is exported from decoder/types via the decoder imports below\n\n// Export all consumer methods directly\nexport const getTransaction = consumerModel.getTransaction.bind(consumerModel)\nexport const getTransactionByKey =\n consumerModel.getTransactionByKey.bind(consumerModel)\nexport const getTransactionsByIndex =\n consumerModel.getTransactionsByIndex.bind(consumerModel)\nexport const getTransactionHashByIndex =\n consumerModel.getTransactionHashByIndex.bind(consumerModel)\nexport const getTransactionCount =\n consumerModel.getTransactionCount.bind(consumerModel)\nexport const getDecodedCount = consumerModel.getDecodedCount.bind(consumerModel)\nexport const getDecodedTransactions =\n consumerModel.getDecodedTransactions.bind(consumerModel)\nexport const getTransactionsInOrder =\n consumerModel.getTransactionsInOrder.bind(consumerModel)\n\n// Address methods\nexport const getAddress = consumerModel.getAddress.bind(consumerModel)\nexport const getSignal = consumerModel.getSignal.bind(consumerModel)\nexport const subscribe = consumerModel.subscribe.bind(consumerModel)\nexport const getState = consumerModel.getState.bind(consumerModel)\nexport const hasData = consumerModel.hasData.bind(consumerModel)\nexport const getData = consumerModel.getData.bind(consumerModel)\nexport const isLoading = consumerModel.isLoading.bind(consumerModel)\nexport const getError = consumerModel.getError.bind(consumerModel)\n\n// Collection methods\nexport const getAllKeys = consumerModel.getAllKeys.bind(consumerModel)\nexport const getAllData = consumerModel.getAllData.bind(consumerModel)\nexport const getAllTransactions =\n consumerModel.getAllTransactions.bind(consumerModel)\n\n// Also export the consumer model instance for advanced usage\nexport { consumerModel }\n\n// Export the function to create global instance (for manual setup)\nexport { createGlobalInstance }\n\n// Export client utilities\nexport {\n createApiAddressResolver,\n type ResolveAddressesOptions,\n type ResolveAddressesResponse,\n resolveAddresses,\n} from './client/resolveAddresses'\n// Export address collection utilities from core\nexport { collectDataKeys } from './core/addressCollector'\nexport {\n AddressResolver,\n type AddressResolverConfig,\n} from './core/addressResolver'\n// Export integration classes\nexport {\n type AddressCache,\n createMemoryAddressCache,\n DecoderIntegration,\n type DecoderIntegrationConfig,\n} from './core/integrateDecoder'\n// Export aggregation utilities\nexport {\n type AggregationState,\n PluginAggregationEngine,\n standardAggregation,\n} from './decoder/aggregation'\nexport type {\n AddressResolver as TransactionAddressResolver,\n TransactionDecoderResult,\n} from './decoder/decodeTransaction'\n// Export decoder integration utilities\nexport {\n decodeTransaction,\n decodeTransactionAsync,\n} from './decoder/decodeTransaction'\n// Export plugin development utilities\n// Export default plugins to ensure they're imported and register themselves\nexport {\n createAggregationKey,\n defaultPlugins,\n defaultSchemaPlugins,\n standardPlugin,\n standardSchemaPlugin,\n} from './decoder/plugins'\nexport type {\n PluginMetadata,\n SchemaPluginMetadata,\n} from './decoder/registry'\nexport {\n createNamedPlugin,\n createNamedSchemaPlugin,\n pluginRegistry,\n registerPlugin,\n registerSchemaPlugin,\n} from './decoder/registry'\nexport type {\n Aggregation,\n DecodeEventCallback,\n DecodeEventResult,\n DecoderPlugin,\n DecoderResult,\n EnhancerCallback,\n PluginOptions,\n ResultAggregate,\n ResultCreate,\n ResultError,\n ResultExecute,\n ResultExecuteBatch,\n ResultFollowProfile,\n ResultGrafitti,\n ResultRaw,\n ResultSetData,\n ResultSetDataBatch,\n ResultWrapper,\n SchemaPlugin,\n} from './decoder/types'\n// Export utility functions\nexport { getArgByName, needsEnhancement } from './decoder/utils'\n// Export LSP23 deployment resolver utilities\n// Note: Actual Hypersync querying should be done via wallet-app API to protect HYPERSYNC_TOKEN\nexport {\n buildLSP23DeploymentQuery,\n DEPLOY_ERC1167_PROXIES_SELECTOR,\n decodeDeploymentCalldata,\n decodeDeploymentOutput,\n extractControllersFromInitCalldata,\n type HypersyncQueryConfig,\n LSP23_FACTORY_ADDRESS,\n type LSP23DeploymentData,\n parseLSP23DeploymentsFromHypersync,\n} from './server/lsp23Resolver'\n// Export shared address resolver utilities\nexport {\n type AssetData,\n fetchMultipleAddresses,\n fetchProfilesByControllers,\n getGraphQLEndpoint,\n getImage,\n type ImageData,\n type ImageURL,\n type LinkData,\n type ProfileData,\n type TFetchAddressData,\n type TokenData,\n} from './shared/addressResolver'\n// Export cache utilities\nexport {\n type AddressIdentityCache,\n createMemoryAddressIdentityCache,\n dataKeyToString,\n getDataKeyCacheKey,\n parseDataKey,\n} from './shared/cache'\n// Export debug utility for edge/worker environments\nexport { createDebug } from './utils/debug'\n// Export JSON BigInt serializer/deserializer\nexport { JSONbigString } from './utils/json-bigint'\n// Release update\n// build 1\n"],"mappings":"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","names":[]}
|
package/dist/data.cjs
CHANGED
|
@@ -3,7 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
3
3
|
|
|
4
4
|
// src/core/dataModel.ts
|
|
5
5
|
import { batch, effect, signal } from "@preact/signals-core";
|
|
6
|
-
import {
|
|
6
|
+
import { isHex as isHex2, size as size2 } from "viem";
|
|
7
7
|
|
|
8
8
|
// src/core/addressCollector.ts
|
|
9
9
|
import { isHex, size } from "viem";
|
|
@@ -215,30 +215,6 @@ var DataModel = class {
|
|
|
215
215
|
constructor(options = {}) {
|
|
216
216
|
this.options = options;
|
|
217
217
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Extract a 20-byte address from a potentially 32-byte hex value
|
|
220
|
-
* If the input is 32 bytes, validates it's zero-padded and takes the rightmost 20 bytes
|
|
221
|
-
* If the input is 20 bytes, returns it as-is
|
|
222
|
-
*/
|
|
223
|
-
extractAddress(hex) {
|
|
224
|
-
if (!isHex2(hex)) {
|
|
225
|
-
throw new Error(`Invalid hex value: ${hex}`);
|
|
226
|
-
}
|
|
227
|
-
const bytes = size2(hex);
|
|
228
|
-
if (bytes === 32) {
|
|
229
|
-
const first12Bytes = slice2(hex, 0, 12);
|
|
230
|
-
if (hexToBigInt(first12Bytes) !== 0n) {
|
|
231
|
-
throw new Error(
|
|
232
|
-
`Invalid 32-byte address: first 12 bytes must be zero for a padded address, got ${first12Bytes}`
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
return slice2(hex, 12, 32);
|
|
236
|
-
}
|
|
237
|
-
if (bytes === 20) {
|
|
238
|
-
return hex;
|
|
239
|
-
}
|
|
240
|
-
throw new Error(`Invalid address length: ${bytes} bytes`);
|
|
241
|
-
}
|
|
242
218
|
/**
|
|
243
219
|
* Get or create a signal for a specific key
|
|
244
220
|
*/
|
|
@@ -1329,7 +1305,7 @@ Object.freeze(PluginRegistry);
|
|
|
1329
1305
|
var pluginRegistry = new PluginRegistry();
|
|
1330
1306
|
|
|
1331
1307
|
// src/decoder/transaction.ts
|
|
1332
|
-
import { isAddress, isAddressEqual, slice as
|
|
1308
|
+
import { isAddress, isAddressEqual, slice as slice2, zeroAddress } from "viem";
|
|
1333
1309
|
async function decodeTransaction(fullTransaction, options) {
|
|
1334
1310
|
const { preferError } = options;
|
|
1335
1311
|
const {
|
|
@@ -1355,7 +1331,7 @@ async function decodeTransaction(fullTransaction, options) {
|
|
|
1355
1331
|
isDecoded: true,
|
|
1356
1332
|
functionName: void 0,
|
|
1357
1333
|
__decoder: void 0,
|
|
1358
|
-
sig:
|
|
1334
|
+
sig: slice2(data || "0x", 0, 4),
|
|
1359
1335
|
resultType: "error",
|
|
1360
1336
|
errorType: "INVALID" /* INVALID */,
|
|
1361
1337
|
...createNamedArgs([], []),
|
|
@@ -1369,13 +1345,13 @@ async function decodeTransaction(fullTransaction, options) {
|
|
|
1369
1345
|
functionName: void 0,
|
|
1370
1346
|
__decoder: void 0,
|
|
1371
1347
|
standard: void 0,
|
|
1372
|
-
sig:
|
|
1348
|
+
sig: slice2(data || "0x", 0, 4),
|
|
1373
1349
|
...createNamedArgs([], []),
|
|
1374
1350
|
resultType: "execute",
|
|
1375
1351
|
phase: "enhanced"
|
|
1376
1352
|
};
|
|
1377
1353
|
}
|
|
1378
|
-
let
|
|
1354
|
+
let _lastError;
|
|
1379
1355
|
const activePlugins = options.plugins;
|
|
1380
1356
|
for (const plugin of activePlugins) {
|
|
1381
1357
|
if (to && isAddress(to) && isAddressEqual(to, zeroAddress)) {
|
|
@@ -1438,7 +1414,6 @@ async function decodeTransaction(fullTransaction, options) {
|
|
|
1438
1414
|
}
|
|
1439
1415
|
} catch (e) {
|
|
1440
1416
|
console.error(e);
|
|
1441
|
-
continue;
|
|
1442
1417
|
}
|
|
1443
1418
|
}
|
|
1444
1419
|
let phase = "functionName" in transaction && transaction.functionName && transaction.standard || transaction.input === "0x" || !transaction.input ? "enhanced" : "immediate";
|
|
@@ -1457,7 +1432,7 @@ async function decodeTransaction(fullTransaction, options) {
|
|
|
1457
1432
|
__decoder: void 0,
|
|
1458
1433
|
resultType: "raw",
|
|
1459
1434
|
phase,
|
|
1460
|
-
sig:
|
|
1435
|
+
sig: slice2(
|
|
1461
1436
|
fullTransaction.input || "data" in fullTransaction && fullTransaction.data || "0x",
|
|
1462
1437
|
0,
|
|
1463
1438
|
4
|
|
@@ -1726,9 +1701,9 @@ function customDecodeEventLog(parameters) {
|
|
|
1726
1701
|
};
|
|
1727
1702
|
}
|
|
1728
1703
|
__name(customDecodeEventLog, "customDecodeEventLog");
|
|
1729
|
-
function decodeEvent(
|
|
1730
|
-
const { data: _data
|
|
1731
|
-
let
|
|
1704
|
+
function decodeEvent(_chain, abi3, log) {
|
|
1705
|
+
const { data: _data } = log;
|
|
1706
|
+
let _lastError;
|
|
1732
1707
|
try {
|
|
1733
1708
|
const result = customDecodeEventLog({
|
|
1734
1709
|
abi: abi3,
|
|
@@ -1810,7 +1785,7 @@ var getDataFromExternalSources = /* @__PURE__ */ __name((schemas, dataFromChain,
|
|
|
1810
1785
|
urlDataWithHash,
|
|
1811
1786
|
ipfsGateway
|
|
1812
1787
|
));
|
|
1813
|
-
let
|
|
1788
|
+
let _length = "unknown";
|
|
1814
1789
|
if (!url.startsWith("data:") && /[=?/]$/.test(url)) {
|
|
1815
1790
|
return dataEntry;
|
|
1816
1791
|
}
|
|
@@ -1822,7 +1797,7 @@ var getDataFromExternalSources = /* @__PURE__ */ __name((schemas, dataFromChain,
|
|
|
1822
1797
|
}
|
|
1823
1798
|
return response.arrayBuffer().then((buffer) => new Uint8Array(buffer));
|
|
1824
1799
|
});
|
|
1825
|
-
|
|
1800
|
+
_length = receivedData.length.toString();
|
|
1826
1801
|
const captureHashes = {};
|
|
1827
1802
|
const captureErrors = [];
|
|
1828
1803
|
if (receivedData.length >= 2) {
|
|
@@ -1942,7 +1917,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
|
|
|
1942
1917
|
});
|
|
1943
1918
|
if (schema) {
|
|
1944
1919
|
try {
|
|
1945
|
-
const name = schema.name.replace(/[
|
|
1920
|
+
const name = schema.name.replace(/[:[\]]|<.*?>/g, "");
|
|
1946
1921
|
if (schema.keyType === "Array") {
|
|
1947
1922
|
if (schema.key === key) {
|
|
1948
1923
|
const hexString = value.slice(2);
|
|
@@ -1950,7 +1925,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
|
|
|
1950
1925
|
for (let i = 0; i < hexString.length; i += 2) {
|
|
1951
1926
|
all[i / 2] = Number.parseInt(hexString.substring(i, i + 2), 16);
|
|
1952
1927
|
}
|
|
1953
|
-
const [{ start, end } = { start: 0, end: 0 }] = all.reduce(
|
|
1928
|
+
const [{ start: _start, end } = { start: 0, end: 0 }] = all.reduce(
|
|
1954
1929
|
(acc, byte, index_) => {
|
|
1955
1930
|
let isZero = byte === 0 || index_ === 0;
|
|
1956
1931
|
const last = acc.at(-1);
|
|
@@ -2016,7 +1991,7 @@ function decodeKeyValuePlugin(defaultSchema2, process2) {
|
|
|
2016
1991
|
value: data2
|
|
2017
1992
|
};
|
|
2018
1993
|
}
|
|
2019
|
-
let dynamicKeyParts
|
|
1994
|
+
let dynamicKeyParts;
|
|
2020
1995
|
if (isDynamicKeyName(schema.name)) {
|
|
2021
1996
|
dynamicKeyParts = decodeMappingKey(key, schema).map(
|
|
2022
1997
|
({ value: value2 }) => isHex3(value2) ? value2.toLowerCase() : `${value2}`
|
|
@@ -2957,7 +2932,7 @@ var enhanceBurntPixPlugin = standardPlugin(
|
|
|
2957
2932
|
aggregations: [refineAggregation]
|
|
2958
2933
|
}
|
|
2959
2934
|
);
|
|
2960
|
-
async function enhanceBurntPix(result, pluginOptions,
|
|
2935
|
+
async function enhanceBurntPix(result, pluginOptions, _options) {
|
|
2961
2936
|
if ("functionName" in result && result.functionName === "refine") {
|
|
2962
2937
|
return {
|
|
2963
2938
|
...result,
|
|
@@ -2972,27 +2947,22 @@ __name(enhanceBurntPix, "enhanceBurntPix");
|
|
|
2972
2947
|
var enhanceBurntPix_default = enhanceBurntPixPlugin;
|
|
2973
2948
|
|
|
2974
2949
|
// src/decoder/plugins/enhanceGraffiti.ts
|
|
2975
|
-
import {
|
|
2976
|
-
bytesToString,
|
|
2977
|
-
hexToBytes,
|
|
2978
|
-
size as size4,
|
|
2979
|
-
slice as slice4
|
|
2980
|
-
} from "viem";
|
|
2950
|
+
import { bytesToString, hexToBytes, size as size4, slice as slice3 } from "viem";
|
|
2981
2951
|
var enhanceGraffitiPlugin = Object.freeze({
|
|
2982
2952
|
enhance: /* @__PURE__ */ __name(async (result, options) => enhanceGraffiti(
|
|
2983
2953
|
result,
|
|
2984
2954
|
{ abiName: "graffiti", decoderName: "graffiti" },
|
|
2985
2955
|
options
|
|
2986
2956
|
), "enhance"),
|
|
2987
|
-
decodeEvent: /* @__PURE__ */ __name(async (
|
|
2957
|
+
decodeEvent: /* @__PURE__ */ __name(async (_log, _options) => void 0, "decodeEvent"),
|
|
2988
2958
|
required: true,
|
|
2989
2959
|
priority: 1e3,
|
|
2990
2960
|
name: "graffiti"
|
|
2991
2961
|
});
|
|
2992
2962
|
async function enhanceGraffiti(result, _pluginOptions, _options) {
|
|
2993
|
-
const {
|
|
2994
|
-
if (input && size4(input || "0x") >= 4 &&
|
|
2995
|
-
let graffiti =
|
|
2963
|
+
const { input } = result;
|
|
2964
|
+
if (input && size4(input || "0x") >= 4 && slice3(input || "0x", 0, 4) === "0x00000000") {
|
|
2965
|
+
let graffiti = slice3(input, 4);
|
|
2996
2966
|
try {
|
|
2997
2967
|
graffiti = bytesToString(hexToBytes(graffiti));
|
|
2998
2968
|
} catch {
|
|
@@ -3909,7 +3879,6 @@ async function enhanceKeyManager(result, pluginOptions, options) {
|
|
|
3909
3879
|
sig,
|
|
3910
3880
|
args,
|
|
3911
3881
|
input,
|
|
3912
|
-
blockNumber,
|
|
3913
3882
|
to: _to,
|
|
3914
3883
|
from: _from,
|
|
3915
3884
|
value
|
|
@@ -4179,7 +4148,7 @@ async function enhanceLSP7Metadata(result, options) {
|
|
|
4179
4148
|
}
|
|
4180
4149
|
__name(enhanceLSP7Metadata, "enhanceLSP7Metadata");
|
|
4181
4150
|
async function enhanceLSP26FollowerSystem(result, _pluginOptions, _options) {
|
|
4182
|
-
const { functionName
|
|
4151
|
+
const { functionName } = result;
|
|
4183
4152
|
switch (functionName) {
|
|
4184
4153
|
}
|
|
4185
4154
|
return void 0;
|
|
@@ -4339,8 +4308,8 @@ var enhanceLSP9VaultPlugin = standardPlugin(
|
|
|
4339
4308
|
}, "decodeEvent")
|
|
4340
4309
|
}
|
|
4341
4310
|
);
|
|
4342
|
-
async function enhanceLSP9Vault(result,
|
|
4343
|
-
const { functionName
|
|
4311
|
+
async function enhanceLSP9Vault(result, _pluginOptions, _options) {
|
|
4312
|
+
const { functionName } = result;
|
|
4344
4313
|
switch (functionName) {
|
|
4345
4314
|
}
|
|
4346
4315
|
return void 0;
|
|
@@ -4371,7 +4340,7 @@ var enhanceLSP26FollowerSystemPlugin = standardPlugin(
|
|
|
4371
4340
|
}
|
|
4372
4341
|
);
|
|
4373
4342
|
async function enhanceLSP26FollowerSystem2(result, _pluginOptions, _options) {
|
|
4374
|
-
const { functionName,
|
|
4343
|
+
const { functionName, args } = result;
|
|
4375
4344
|
const { args: _args, ...partialResult } = result;
|
|
4376
4345
|
switch (functionName) {
|
|
4377
4346
|
case "follow":
|
|
@@ -4387,7 +4356,6 @@ async function enhanceLSP26FollowerSystem2(result, _pluginOptions, _options) {
|
|
|
4387
4356
|
}
|
|
4388
4357
|
]
|
|
4389
4358
|
};
|
|
4390
|
-
break;
|
|
4391
4359
|
case "followBatch":
|
|
4392
4360
|
case "unfollowBatch":
|
|
4393
4361
|
return {
|
|
@@ -4399,7 +4367,6 @@ async function enhanceLSP26FollowerSystem2(result, _pluginOptions, _options) {
|
|
|
4399
4367
|
address
|
|
4400
4368
|
}))
|
|
4401
4369
|
};
|
|
4402
|
-
break;
|
|
4403
4370
|
}
|
|
4404
4371
|
return void 0;
|
|
4405
4372
|
}
|
|
@@ -5115,7 +5082,7 @@ var LRUDecoderCache = class {
|
|
|
5115
5082
|
if (cached && (!cached.expires || now < cached.expires)) {
|
|
5116
5083
|
return cached.value;
|
|
5117
5084
|
}
|
|
5118
|
-
if (cached
|
|
5085
|
+
if (cached?.stale && now < cached.stale && !this.promises.has(key)) {
|
|
5119
5086
|
const backgroundPromise = factory(options?.signal).then(async (fresh) => {
|
|
5120
5087
|
await this.set(key, fresh, options);
|
|
5121
5088
|
return fresh;
|
|
@@ -5197,7 +5164,7 @@ async function fetchAbi(chain, address, options) {
|
|
|
5197
5164
|
let isProxy = false;
|
|
5198
5165
|
let decoderVerifiedContract = false;
|
|
5199
5166
|
let factoryName;
|
|
5200
|
-
const
|
|
5167
|
+
const _originalKey = key;
|
|
5201
5168
|
const addressUrl = new URL(`/api/v2/addresses/${key}`, explorer);
|
|
5202
5169
|
const addressRes = await fetch(addressUrl, { signal: signal3 });
|
|
5203
5170
|
if (addressRes.ok) {
|
|
@@ -5365,7 +5332,7 @@ var getFunctionSignature = /* @__PURE__ */ __name(async (chain, input, to, prefe
|
|
|
5365
5332
|
__decoder: methods.__decoder || FUNCTION_DICTIONARY_URL
|
|
5366
5333
|
};
|
|
5367
5334
|
}
|
|
5368
|
-
} catch (
|
|
5335
|
+
} catch (_error) {
|
|
5369
5336
|
}
|
|
5370
5337
|
}
|
|
5371
5338
|
}
|
|
@@ -5404,7 +5371,7 @@ var enhanceRetrieveAbiPlugin = standardPlugin(
|
|
|
5404
5371
|
}
|
|
5405
5372
|
);
|
|
5406
5373
|
async function enhanceRetrieveAbi(result, _pluginOptions, options) {
|
|
5407
|
-
const {
|
|
5374
|
+
const { input, to, from, value } = result;
|
|
5408
5375
|
try {
|
|
5409
5376
|
const decoded = await getFunctionSignature(
|
|
5410
5377
|
options.chain,
|
|
@@ -5431,7 +5398,9 @@ __name(enhanceRetrieveAbi, "enhanceRetrieveAbi");
|
|
|
5431
5398
|
var enhanceRetrieveAbi_default = enhanceRetrieveAbiPlugin;
|
|
5432
5399
|
|
|
5433
5400
|
// src/decoder/plugins/index.ts
|
|
5434
|
-
[enhanceLSP0ERC725Account_default, enhanceLSP6KeyManager_default, enhanceLSP7DigitalAsset_default, enhanceLSP8IdentifiableDigitalAsset_default, enhanceLSP9Vault_default, enhanceLSP26FollowerSystem_default, enhanceBurntPix_default].forEach((p) =>
|
|
5401
|
+
[enhanceLSP0ERC725Account_default, enhanceLSP6KeyManager_default, enhanceLSP7DigitalAsset_default, enhanceLSP8IdentifiableDigitalAsset_default, enhanceLSP9Vault_default, enhanceLSP26FollowerSystem_default, enhanceBurntPix_default].forEach((p) => {
|
|
5402
|
+
p;
|
|
5403
|
+
});
|
|
5435
5404
|
var defaultPlugins = Object.freeze([
|
|
5436
5405
|
enhanceGraffiti_default,
|
|
5437
5406
|
enhanceLSP6KeyManager_default,
|