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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +486 -0
  3. package/dist/browser.cjs +6912 -0
  4. package/dist/browser.cjs.map +1 -0
  5. package/dist/browser.d.cts +6 -0
  6. package/dist/browser.d.ts +6 -0
  7. package/dist/browser.js +131 -0
  8. package/dist/browser.js.map +1 -0
  9. package/dist/cdn/transaction-decoder.global.js +296 -0
  10. package/dist/cdn/transaction-decoder.global.js.map +1 -0
  11. package/dist/chunk-GGBHTWJL.js +437 -0
  12. package/dist/chunk-GGBHTWJL.js.map +1 -0
  13. package/dist/chunk-GXZOF3QY.js +839 -0
  14. package/dist/chunk-GXZOF3QY.js.map +1 -0
  15. package/dist/chunk-LJ6ES5XF.js +776 -0
  16. package/dist/chunk-LJ6ES5XF.js.map +1 -0
  17. package/dist/chunk-XVHJWV5U.js +4925 -0
  18. package/dist/chunk-XVHJWV5U.js.map +1 -0
  19. package/dist/data.cjs +5518 -0
  20. package/dist/data.cjs.map +1 -0
  21. package/dist/data.d.cts +43 -0
  22. package/dist/data.d.ts +43 -0
  23. package/dist/data.js +55 -0
  24. package/dist/data.js.map +1 -0
  25. package/dist/index-BzXh7poJ.d.cts +524 -0
  26. package/dist/index-BzXh7poJ.d.ts +524 -0
  27. package/dist/index.cjs +6912 -0
  28. package/dist/index.cjs.map +1 -0
  29. package/dist/index.d.cts +756 -0
  30. package/dist/index.d.ts +756 -0
  31. package/dist/index.js +131 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/server.cjs +5644 -0
  34. package/dist/server.cjs.map +1 -0
  35. package/dist/server.d.cts +217 -0
  36. package/dist/server.d.ts +217 -0
  37. package/dist/server.js +644 -0
  38. package/dist/server.js.map +1 -0
  39. package/dist/utils-CBAkjQh3.d.cts +108 -0
  40. package/dist/utils-xT9-km0r.d.ts +108 -0
  41. package/package.json +101 -0
  42. package/src/browser.ts +13 -0
  43. package/src/client/resolveAddresses.ts +157 -0
  44. package/src/core/addressCollector.ts +153 -0
  45. package/src/core/addressResolver.ts +135 -0
  46. package/src/core/dataModel.ts +888 -0
  47. package/src/core/instance.ts +33 -0
  48. package/src/core/integrateDecoder.ts +325 -0
  49. package/src/data.ts +70 -0
  50. package/src/decoder/GENERATOR_PROPOSAL.md +182 -0
  51. package/src/decoder/THREE_PHASE_EXAMPLE.md +108 -0
  52. package/src/decoder/aggregation.ts +218 -0
  53. package/src/decoder/browserCache.ts +237 -0
  54. package/src/decoder/cache/README.md +126 -0
  55. package/src/decoder/cache/index.ts +44 -0
  56. package/src/decoder/cache.ts +139 -0
  57. package/src/decoder/constants.ts +125 -0
  58. package/src/decoder/decodeTransaction.ts +292 -0
  59. package/src/decoder/errors.ts +95 -0
  60. package/src/decoder/events.ts +192 -0
  61. package/src/decoder/functionSignature.ts +344 -0
  62. package/src/decoder/getDataFromExternalSources.ts +248 -0
  63. package/src/decoder/graphqlWS.ts +22 -0
  64. package/src/decoder/interfaces.ts +185 -0
  65. package/src/decoder/keyValue.ts +5 -0
  66. package/src/decoder/kvCache.ts +241 -0
  67. package/src/decoder/lruCache.ts +184 -0
  68. package/src/decoder/lsp7Mint.test.ts +179 -0
  69. package/src/decoder/lsp7TransferBatch.test.ts +105 -0
  70. package/src/decoder/plugins/RegistryAbi.ts +562 -0
  71. package/src/decoder/plugins/enhanceBurntPix.ts +132 -0
  72. package/src/decoder/plugins/enhanceGraffiti.ts +70 -0
  73. package/src/decoder/plugins/enhanceLSP0ERC725Account.ts +179 -0
  74. package/src/decoder/plugins/enhanceLSP26FollowerSystem.ts +88 -0
  75. package/src/decoder/plugins/enhanceLSP6KeyManager.ts +231 -0
  76. package/src/decoder/plugins/enhanceLSP7DigitalAsset.ts +165 -0
  77. package/src/decoder/plugins/enhanceLSP8IdentifiableDigitalAsset.ts +170 -0
  78. package/src/decoder/plugins/enhanceLSP9Vault.ts +57 -0
  79. package/src/decoder/plugins/enhanceRetrieveAbi.ts +85 -0
  80. package/src/decoder/plugins/enhanceSetData.ts +135 -0
  81. package/src/decoder/plugins/index.ts +99 -0
  82. package/src/decoder/plugins/schemaDefault.ts +318 -0
  83. package/src/decoder/plugins/standardPlugin.ts +202 -0
  84. package/src/decoder/registry.ts +322 -0
  85. package/src/decoder/singleGQL.ts +293 -0
  86. package/src/decoder/transaction.ts +198 -0
  87. package/src/decoder/types.ts +465 -0
  88. package/src/decoder/utils.ts +212 -0
  89. package/src/example/usage.ts +172 -0
  90. package/src/index.ts +174 -0
  91. package/src/server/addressResolver.ts +68 -0
  92. package/src/server/caches.ts +209 -0
  93. package/src/server/decodeTransactionSync.ts +156 -0
  94. package/src/server/decodeTransactionsBatch.ts +207 -0
  95. package/src/server/finishDecoding.ts +116 -0
  96. package/src/server/index.ts +81 -0
  97. package/src/server/lsp23Resolver.test.ts +46 -0
  98. package/src/server/lsp23Resolver.ts +419 -0
  99. package/src/server/types.ts +168 -0
  100. package/src/server.ts +22 -0
  101. package/src/shared/addressResolver.ts +651 -0
  102. package/src/shared/cache.ts +144 -0
  103. package/src/shared/constants.ts +21 -0
  104. package/src/stubs/tty.ts +13 -0
  105. package/src/stubs/util.ts +42 -0
  106. package/src/types/index.ts +154 -0
  107. package/src/types/provider.ts +46 -0
  108. package/src/umd.ts +13 -0
  109. package/src/utils/debug.ts +49 -0
  110. package/src/utils/json-bigint.ts +47 -0
@@ -0,0 +1,198 @@
1
+ import { type Hex, isAddress, isAddressEqual, slice, zeroAddress } from 'viem'
2
+ import {
3
+ type DecodeEventResult,
4
+ type DecoderOptions,
5
+ type DecoderResult,
6
+ ErrorType,
7
+ } from './types'
8
+ import { createNamedArgs } from './utils'
9
+
10
+ /**
11
+ * Decode transaction
12
+ * @param transaction Transaction to decode (should have data/input)
13
+ * @param options Decoder options
14
+ * @returns Promise<DecoderResult>
15
+ */
16
+ export async function decodeTransaction(
17
+ fullTransaction: DecoderResult,
18
+ options: DecoderOptions & {
19
+ preferError?: boolean
20
+ }
21
+ ): Promise<DecoderResult | undefined> {
22
+ const { preferError } = options
23
+ // Normalize input field - ensure we only have input, not data
24
+ const {
25
+ to,
26
+ from,
27
+ value,
28
+ input: rawInput,
29
+ data: rawData,
30
+ ...restTransaction
31
+ } = fullTransaction as DecoderResult & { data?: Hex }
32
+ const { logs, ...transaction } = {
33
+ ...restTransaction,
34
+ to,
35
+ from,
36
+ value,
37
+ input: rawInput || rawData,
38
+ }
39
+ const data = rawInput || rawData
40
+ if (!data || data === '0x') {
41
+ if (preferError) {
42
+ return {
43
+ ...transaction,
44
+ isDecoded: true,
45
+ functionName: undefined,
46
+ __decoder: undefined,
47
+ sig: slice(data || '0x', 0, 4),
48
+ resultType: 'error',
49
+ errorType: ErrorType.INVALID,
50
+ ...createNamedArgs([], []),
51
+ standard: undefined,
52
+ phase: 'enhanced',
53
+ } as DecoderResult
54
+ }
55
+ return {
56
+ ...transaction,
57
+ isDecoded: true,
58
+ functionName: undefined,
59
+ __decoder: undefined,
60
+ standard: undefined,
61
+ sig: slice(data || '0x', 0, 4),
62
+ ...createNamedArgs([], []),
63
+ resultType: 'execute',
64
+ phase: 'enhanced',
65
+ } as DecoderResult
66
+ }
67
+ let lastError: Error | undefined
68
+
69
+ // The caller is responsible for providing the appropriate plugin set
70
+ // For sync-only decoding, use pluginRegistry.getAll({ syncOnly: true })
71
+ // For full decoding, use pluginRegistry.getAll()
72
+ const activePlugins = options.plugins
73
+
74
+ for (const plugin of activePlugins) {
75
+ if (to && isAddress(to) && isAddressEqual(to, zeroAddress)) {
76
+ return {
77
+ ...transaction,
78
+ isDecoded: true,
79
+ ...createNamedArgs([], []),
80
+ resultType: 'create',
81
+ to,
82
+ from,
83
+ value,
84
+ logs,
85
+ phase: 'immediate',
86
+ } as DecoderResult
87
+ }
88
+
89
+ try {
90
+ const check = await plugin.enhance(transaction, options)
91
+ if (check) {
92
+ const output: DecodeEventResult[] = []
93
+ if (logs) {
94
+ for (const log of logs) {
95
+ const data = await plugin.decodeEvent(log, options)
96
+ if (data) {
97
+ output.push(data)
98
+ continue
99
+ }
100
+ let done = false
101
+ for (const eventPlugin of activePlugins) {
102
+ if (eventPlugin !== plugin) {
103
+ const data = await eventPlugin.decodeEvent(log, options)
104
+ if (data) {
105
+ output.push(data)
106
+ done = true
107
+ break
108
+ }
109
+ }
110
+ }
111
+ if (!done) {
112
+ output.push(log as DecodeEventResult)
113
+ }
114
+ }
115
+ check.logs = output
116
+ }
117
+ let phase: 'immediate' | 'enhanced' | 'complete' =
118
+ plugin.usesAsync ||
119
+ ('functionName' in check && check.functionName && check.standard) ||
120
+ check.input === '0x' ||
121
+ !check.input
122
+ ? 'enhanced'
123
+ : 'immediate'
124
+
125
+ // If result has children, check if ALL children are enhanced
126
+ // If any child is not enhanced, downgrade parent to 'immediate'
127
+ const resultWithChildren = check as { children?: DecoderResult[] }
128
+ if (
129
+ phase === 'enhanced' &&
130
+ resultWithChildren.children &&
131
+ Array.isArray(resultWithChildren.children) &&
132
+ resultWithChildren.children.length > 0
133
+ ) {
134
+ const allChildrenEnhanced = resultWithChildren.children.every(
135
+ (child: DecoderResult) => (child as any).phase === 'enhanced'
136
+ )
137
+ if (!allChildrenEnhanced) {
138
+ phase = 'immediate'
139
+ }
140
+ }
141
+
142
+ const result = {
143
+ ...transaction,
144
+ ...check,
145
+ phase,
146
+ } as DecoderResult
147
+ return result
148
+ }
149
+ } catch (e) {
150
+ console.error(e)
151
+ continue
152
+ }
153
+ }
154
+ let phase: 'immediate' | 'enhanced' | 'complete' =
155
+ ('functionName' in transaction &&
156
+ transaction.functionName &&
157
+ transaction.standard) ||
158
+ transaction.input === '0x' ||
159
+ !transaction.input
160
+ ? 'enhanced'
161
+ : 'immediate'
162
+
163
+ // If result has children, check if ALL children are enhanced
164
+ // If any child is not enhanced, downgrade parent to 'immediate'
165
+ const transactionWithChildren = transaction as { children?: DecoderResult[] }
166
+ if (
167
+ phase === 'enhanced' &&
168
+ transactionWithChildren.children &&
169
+ Array.isArray(transactionWithChildren.children) &&
170
+ transactionWithChildren.children.length > 0
171
+ ) {
172
+ const allChildrenEnhanced = transactionWithChildren.children.every(
173
+ (child: DecoderResult) => (child as any).phase === 'enhanced'
174
+ )
175
+ if (!allChildrenEnhanced) {
176
+ phase = 'immediate'
177
+ }
178
+ }
179
+
180
+ const result = {
181
+ ...transaction,
182
+ standard: undefined,
183
+ __decoder: undefined,
184
+ resultType: 'raw',
185
+ phase,
186
+ sig: slice(
187
+ fullTransaction.input ||
188
+ ('data' in fullTransaction && (fullTransaction.data as Hex)) ||
189
+ '0x',
190
+ 0,
191
+ 4
192
+ ),
193
+ ...createNamedArgs([], []),
194
+ ...(options.wrappers.length ? { wrappers: options.wrappers } : {}),
195
+ logs,
196
+ } as DecoderResult
197
+ return result
198
+ }
@@ -0,0 +1,465 @@
1
+ import type { ERC725JSONSchema } from '@erc725/erc725.js'
2
+ import type {
3
+ Abi,
4
+ AbiParameter,
5
+ Address,
6
+ Chain,
7
+ DecodeFunctionDataReturnType,
8
+ Hex,
9
+ Log,
10
+ Transaction,
11
+ } from 'viem'
12
+ import type { DataKey } from '../types'
13
+ import type { DecoderCache } from './cache'
14
+
15
+ /**
16
+ * Array length item: Represents the length of an ERC725 Array schema item.
17
+ */
18
+ export type ArrayLengthInfo = ERC725JSONSchema & {
19
+ type: 'ArrayLength'
20
+ value: number
21
+ pretty?: string
22
+ }
23
+
24
+ /**
25
+ * Array item: Represents the value of an ERC725 Array schema item.
26
+ */
27
+ export type ArrayItemInfo = ERC725JSONSchema & {
28
+ type: 'ArrayItem'
29
+ dynamic: number
30
+ value: unknown
31
+ pretty?: string
32
+ }
33
+
34
+ /**
35
+ * Value item: Represents the value of an ERC725 schema item.
36
+ */
37
+ export type ValueInfo = ERC725JSONSchema & {
38
+ type: 'Value'
39
+ dynamic?: string | string[]
40
+ value: unknown
41
+ data?: string
42
+ method?: string
43
+ url?: string
44
+ src?: string
45
+ pretty?: string
46
+ }
47
+
48
+ /**
49
+ * Undecoded item: Represents an undecoded ERC725 schema item (unknown, raw data).
50
+ */
51
+ export type UndecodedInfo = {
52
+ type: 'Undecoded'
53
+ key: string
54
+ name: undefined
55
+ value: string
56
+ }
57
+
58
+ /**
59
+ * Error item: Error happened during decoding or retrieval (404 or exception due to invalid data)
60
+ */
61
+ export type ErrorInfo = ERC725JSONSchema & {
62
+ type: 'Error'
63
+ key: string
64
+ value: string | Error
65
+ data?: string
66
+ method?: string
67
+ url?: string
68
+ src?: string
69
+ pretty?: string
70
+ }
71
+
72
+ /**
73
+ * Info item: Results of the decoded schema.
74
+ */
75
+ export type Info =
76
+ | ArrayLengthInfo
77
+ | ArrayItemInfo
78
+ | ValueInfo
79
+ | UndecodedInfo
80
+ | ErrorInfo
81
+
82
+ /**
83
+ * Add address as a property to the record so that obj.address instead of obj['address'] can be used
84
+ */
85
+ export type EnhancedInfo = {
86
+ address: `0x${string}`
87
+ standard?: string
88
+ tokenId?: `0x${string}`
89
+ name?: string
90
+ __gqltype?: 'Profile' | 'Asset' | 'Token'
91
+ [key: string]: unknown
92
+ }
93
+
94
+ export type NamedArgs = Record<
95
+ string | number,
96
+ AbiParameter & { value?: unknown }
97
+ >
98
+ export type ArrayArgs = Array<
99
+ AbiParameter & {
100
+ value?: unknown
101
+ }
102
+ >
103
+
104
+ export type ResultShared = {
105
+ resultType?: string
106
+ standard?: string
107
+ type?: string
108
+ sig?: `0x${string}` | null
109
+ graphqlData?: Record<Hex, EnhancedInfo>
110
+ /**
111
+ * Decoding phase - added by server-side decoder
112
+ */
113
+ phase?: 'immediate' | 'enhanced'
114
+ /**
115
+ * Whether this result was served from cache - added by server-side decoder
116
+ */
117
+ cached?: boolean
118
+ /**
119
+ * Time taken to decode (milliseconds)
120
+ */
121
+ timeTaken?: number
122
+
123
+ moduleHint?: string
124
+ logs?: DecodeEventResult[]
125
+ isDecoded?: boolean
126
+ error?: {
127
+ code: string
128
+ message: string
129
+ details: Error
130
+ }
131
+ processingError?: { message: string; code: unknown }
132
+ blockTimestamp?: number
133
+
134
+ /**
135
+ * List of addresses found in the transaction (to, from, args, namedArgs, wrappers)
136
+ */
137
+ addresses?: DataKey[]
138
+
139
+ transactionHash?: Hex
140
+
141
+ /**
142
+ * Custom data for view matching and extensibility.
143
+ * Populated by enhancers to provide additional context for view selection.
144
+ *
145
+ * Common use cases:
146
+ * - tokenType: 0 (token) | 1 (NFT) | 2 (collection)
147
+ * - isToken, isNFT, isCollection: boolean flags
148
+ * - operationType: 'mint' | 'burn' | 'transfer'
149
+ * - hasMetadata: boolean
150
+ * - customFlags: any enhancer-specific data
151
+ *
152
+ * This field is NOT typed to allow for plugin extensibility.
153
+ */
154
+ custom?: Record<string, unknown>
155
+ enhancementAttempted?: boolean
156
+ }
157
+
158
+ /*
159
+ * The following types are used to represent the different result types of a transaction.
160
+ * They are used in the decodeTransaction function to determine the type of transaction
161
+ * and the corresponding properties.
162
+ */
163
+ export type ResultError = {
164
+ resultType: 'error'
165
+ functionName?: string
166
+ errorType: ErrorType
167
+ sig: `0x${string}`
168
+ input?: `0x${string}` | null
169
+ args?: ArrayArgs
170
+ summary?: string
171
+ devdocs?: string
172
+ }
173
+
174
+ export type ResultAggregate = {
175
+ resultType: 'aggregate'
176
+ aggregate: {
177
+ count: number
178
+ blockRange: { from: number; to: number }
179
+ [key: string]: unknown
180
+ }
181
+ functionName?: string
182
+ args?: ArrayArgs
183
+ wrappers?: Array<ResultType>
184
+ devdocs?: string
185
+ }
186
+ export type ResultExecute = {
187
+ resultType: 'execute'
188
+ functionName?: string
189
+ args?: ArrayArgs
190
+ wrappers?: Array<ResultType>
191
+ devdocs?: string
192
+ }
193
+
194
+ export type ResultCreate = {
195
+ resultType: 'create'
196
+ wrappers?: Array<ResultType>
197
+ args?: ArrayArgs
198
+ }
199
+
200
+ export type ResultWrapper = {
201
+ resultType: 'wrapper'
202
+ functionName?: string
203
+ args?: ArrayArgs
204
+ devdocs?: string
205
+ }
206
+
207
+ export type ResultFollowProfile = {
208
+ resultType: 'followProfile'
209
+ functionName?: string
210
+ address: Address
211
+ }
212
+
213
+ export type ResultExecuteBatch = {
214
+ resultType: 'executeBatch'
215
+ functionName: string
216
+ args?: ArrayArgs
217
+ children: Array<ResultType & ResultShared>
218
+ wrappers?: Array<ResultType & ResultShared>
219
+ devdocs?: string
220
+ }
221
+
222
+ export type ResultSetDataBatch = {
223
+ resultType: 'setDataBatch'
224
+ functionName?: string
225
+ standard?: string
226
+ args?: ArrayArgs
227
+ children: Array<ResultSetData & ResultShared>
228
+ wrappers?: Array<ResultType & ResultShared>
229
+ devdocs?: string
230
+ }
231
+
232
+ export type ResultGrafitti = {
233
+ resultType: 'grafitti'
234
+ standard?: string
235
+ graffiti: string
236
+ devdocs?: string
237
+ functionName?: string
238
+ }
239
+
240
+ export type ResultSetData = {
241
+ resultType: 'setData'
242
+ functionName?: string
243
+ tokenId?: `0x${string}`
244
+ args?: ArrayArgs
245
+ wrappers?: Array<ResultType & ResultShared>
246
+ info?: Info
247
+ devdocs?: string
248
+ }
249
+
250
+ export type ResultRaw = {
251
+ resultType: 'raw'
252
+ standard?: string
253
+ input?: `0x${string}`
254
+ }
255
+
256
+ /**
257
+ * DecodeFunctionDataReturn: Represents the return type of a decodeTransaction function.
258
+ * There are extra properties added to the return type to make it more useful.
259
+ * Internally some of the properties are used to decode the data so in some places
260
+ * we use "any" to avoid type errors during the decoding process.
261
+ * The main offenders here are isDecoded: boolean and __decoder: string and so on.
262
+ * Rather than mixing those into the type, then it would make the types unnecessarily complex.
263
+ */
264
+ export type ResultComponent =
265
+ | ResultExecute
266
+ | ResultCreate
267
+ | ResultWrapper
268
+ | ResultSetDataBatch
269
+ | ResultExecuteBatch
270
+ | ResultSetData
271
+ | ResultGrafitti
272
+ | ResultRaw
273
+ | ResultError
274
+ | ResultAggregate
275
+ | ResultFollowProfile
276
+
277
+ /**
278
+ * The main result type returned by decodeTransaction.
279
+ */
280
+ export type ResultType = Partial<
281
+ Omit<Transaction, 'type' | 'logs' | 'blobVersionedHashes'>
282
+ > &
283
+ ResultShared &
284
+ ResultComponent & {
285
+ __decoder?: string
286
+ __decoderVerifiedContract?: boolean
287
+ type?: string
288
+ logs?: DecodeEventResult[]
289
+ blobVersionedHashes?: readonly Hex[]
290
+ }
291
+
292
+ /**
293
+ * CustomDecodeFunctionDataReturn: Represents the return type of a customDecodeFunctionData function.
294
+ * Basically the normal decodeFunctionData doesn't return the abi entry, so that
295
+ * we can't decode argument names and types.
296
+ */
297
+ export type CustomDecodeFunctionDataReturn<
298
+ abi extends Abi | readonly unknown[],
299
+ > = DecodeFunctionDataReturnType<abi> & {
300
+ args?: ArrayArgs
301
+ }
302
+
303
+ /**
304
+ * This is the modification record used to patch address values into any
305
+ * data structure. It will allow iterating through the data structure,
306
+ * collecting all things that look like addresses and pass isAddress.
307
+ * This will also include 0x00000000000ADDRESS.
308
+ */
309
+ export type AddressModifier = {
310
+ address: Address
311
+ path: Array<string | number>
312
+ tokenId?: `0x${string}`
313
+ root: Array<Record<string, unknown>> | Record<string, unknown> | unknown
314
+ }
315
+
316
+ export enum ErrorType {
317
+ EMPTY_REVERT = 'EMPTY_REVERT',
318
+ INVALID = 'INVALID',
319
+ PANIC = 'PANIC',
320
+ ERROR = 'ERROR',
321
+ CUSTOM_ERROR = 'CUSTOM_ERROR',
322
+ UNKNOWN = 'UNKNOWN',
323
+ }
324
+
325
+ /**
326
+ * The output of the enhancer
327
+ */
328
+ export type DecoderResult = ResultType &
329
+ ResultShared & {
330
+ /** Which aggregations apply (just keys, no plugin prefix) */
331
+ aggregationKeys?: string[]
332
+ }
333
+
334
+ /**
335
+ * Aggregation configuration for map/reduce operations
336
+ */
337
+ export interface Aggregation<T = any> {
338
+ /** Unique key for this aggregation within the plugin */
339
+ key: string
340
+ /** Extract/transform data from a single transaction */
341
+ map: (tx: DecoderResult) => T | undefined
342
+ /** Combine mapped data with existing state */
343
+ reduce: (state: T | undefined, mapped: T) => T
344
+ /** Transform state for final output */
345
+ finalize: (state: T) => Omit<ResultAggregate, 'resultType'>
346
+ }
347
+
348
+ /**
349
+ * Bitmap enum for controlling which async operations are enabled
350
+ */
351
+ export enum AsyncOperations {
352
+ /** No async operations (default) */
353
+ DISABLED = 0, // 0b000
354
+ /** Enable async plugins (ABI fetching, function signatures) */
355
+ ENABLE_PLUGINS = 1 << 0, // 0b001
356
+ /** Enable address resolution (profile/address metadata) */
357
+ ENABLE_ADDRESS_RESOLVE = 1 << 1, // 0b010
358
+ /** Enable external data fetching (IPFS, external JSON) */
359
+ ENABLE_EXTERNAL_DATA = 1 << 2, // 0b100
360
+ }
361
+
362
+ /**
363
+ * Options to modify operations which now also have to be sent down to the enhancer and plugin
364
+ */
365
+ export type DecoderOptions = {
366
+ plugins: ReadonlyArray<DecoderPlugin>
367
+ schemaPlugins: ReadonlyArray<SchemaPlugin>
368
+ preferError?: boolean
369
+ wrappers: Array<ResultType & ResultShared>
370
+ chain: Chain
371
+ /**
372
+ * Controls which async operations are enabled.
373
+ * Can be a boolean for backward compatibility (true = all async, false = none)
374
+ * or AsyncOperations enum for fine-grained control
375
+ */
376
+ async?: boolean | AsyncOperations
377
+ /** Cache implementation for async operations */
378
+ cache?: DecoderCache
379
+ /** Timeout for async operations in milliseconds */
380
+ timeout?: number
381
+ /** AbortSignal for cancelling async operations */
382
+ signal?: AbortSignal
383
+ }
384
+
385
+ /**
386
+ * Generic plugin into decoder (most of the time this will be wrapped with the standard plugin to provide
387
+ * additional or existing abis)
388
+ */
389
+ export type DecoderPlugin = {
390
+ enhance: (
391
+ transaction: DecoderResult,
392
+ options: DecoderOptions
393
+ ) => Promise<DecoderResult | undefined>
394
+ decodeEvent: (
395
+ log: DecodeEventResult,
396
+ options: DecoderOptions
397
+ ) => Promise<DecodeEventResult>
398
+ getAggregationKey?: EnhancerAggregationKeyCallback
399
+ summarize?: EnhancerSummarizeCallback
400
+ name?: string // Optional name for override detection
401
+ required?: boolean // Cannot be overridden, always runs first
402
+ priority?: number // Higher number = runs earlier (default: 0)
403
+ usesAsync?: boolean
404
+ /** Aggregations supported by this plugin */
405
+ aggregations?: Aggregation[]
406
+ }
407
+
408
+ export type PluginOptions = {
409
+ abiName: string
410
+ decoderName?: string
411
+ moduleHint?: string
412
+ name?: string // Plugin name for override detection
413
+ required?: boolean // Cannot be overridden, always runs first
414
+ priority?: number // Higher number = runs earlier (default: 0)
415
+ usesAsync?: boolean // Whether this plugin performs async operations
416
+ }
417
+ /**
418
+ * Type for the actual enhancement logic
419
+ */
420
+ export type EnhancerCallback = (
421
+ result: DecoderResult,
422
+ pluginOptions: PluginOptions,
423
+ options: DecoderOptions
424
+ ) => Promise<DecoderResult | undefined>
425
+
426
+ export type EnhancerAggregationKeyCallback = (
427
+ result: DecoderResult,
428
+ pluginOptions: PluginOptions,
429
+ options: DecoderOptions
430
+ ) => Promise<string | undefined>
431
+
432
+ export type EnhancerSummarizeCallback = (
433
+ aggregateKey: string,
434
+ result: DecoderResult[],
435
+ pluginOptions: PluginOptions,
436
+ options: DecoderOptions
437
+ ) => Promise<DecoderResult | undefined> // Most likely ResultAggregate
438
+
439
+ /**
440
+ * Plugins to execute decodeData with custom schema tables.
441
+ * The passed in data will contain the abi name, functionName and so on.
442
+ */
443
+ export type SchemaPlugin = ((
444
+ key: Hex,
445
+ value: Hex
446
+ ) => Promise<Info | undefined>) & {
447
+ name?: string // Optional name for override detection
448
+ required?: boolean // Cannot be overridden, always runs first
449
+ priority?: number // Higher number = runs earlier (default: 0)
450
+ }
451
+
452
+ /**
453
+ * Plugin callback function to decode events.
454
+ */
455
+ export type DecodeEventCallback = (
456
+ log: DecodeEventResult,
457
+ options: DecoderOptions
458
+ ) => Promise<DecodeEventResult>
459
+
460
+ export type DecodeEventResult =
461
+ | ({
462
+ eventName: string
463
+ args: ArrayArgs
464
+ } & Log)
465
+ | undefined