@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.
- package/LICENSE +201 -0
- package/README.md +486 -0
- package/dist/browser.cjs +6912 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +6 -0
- package/dist/browser.d.ts +6 -0
- package/dist/browser.js +131 -0
- package/dist/browser.js.map +1 -0
- package/dist/cdn/transaction-decoder.global.js +296 -0
- package/dist/cdn/transaction-decoder.global.js.map +1 -0
- package/dist/chunk-GGBHTWJL.js +437 -0
- package/dist/chunk-GGBHTWJL.js.map +1 -0
- package/dist/chunk-GXZOF3QY.js +839 -0
- package/dist/chunk-GXZOF3QY.js.map +1 -0
- package/dist/chunk-LJ6ES5XF.js +776 -0
- package/dist/chunk-LJ6ES5XF.js.map +1 -0
- package/dist/chunk-XVHJWV5U.js +4925 -0
- package/dist/chunk-XVHJWV5U.js.map +1 -0
- package/dist/data.cjs +5518 -0
- package/dist/data.cjs.map +1 -0
- package/dist/data.d.cts +43 -0
- package/dist/data.d.ts +43 -0
- package/dist/data.js +55 -0
- package/dist/data.js.map +1 -0
- package/dist/index-BzXh7poJ.d.cts +524 -0
- package/dist/index-BzXh7poJ.d.ts +524 -0
- package/dist/index.cjs +6912 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +756 -0
- package/dist/index.d.ts +756 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/server.cjs +5644 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +217 -0
- package/dist/server.d.ts +217 -0
- package/dist/server.js +644 -0
- package/dist/server.js.map +1 -0
- package/dist/utils-CBAkjQh3.d.cts +108 -0
- package/dist/utils-xT9-km0r.d.ts +108 -0
- package/package.json +101 -0
- package/src/browser.ts +13 -0
- package/src/client/resolveAddresses.ts +157 -0
- package/src/core/addressCollector.ts +153 -0
- package/src/core/addressResolver.ts +135 -0
- package/src/core/dataModel.ts +888 -0
- package/src/core/instance.ts +33 -0
- package/src/core/integrateDecoder.ts +325 -0
- package/src/data.ts +70 -0
- package/src/decoder/GENERATOR_PROPOSAL.md +182 -0
- package/src/decoder/THREE_PHASE_EXAMPLE.md +108 -0
- package/src/decoder/aggregation.ts +218 -0
- package/src/decoder/browserCache.ts +237 -0
- package/src/decoder/cache/README.md +126 -0
- package/src/decoder/cache/index.ts +44 -0
- package/src/decoder/cache.ts +139 -0
- package/src/decoder/constants.ts +125 -0
- package/src/decoder/decodeTransaction.ts +292 -0
- package/src/decoder/errors.ts +95 -0
- package/src/decoder/events.ts +192 -0
- package/src/decoder/functionSignature.ts +344 -0
- package/src/decoder/getDataFromExternalSources.ts +248 -0
- package/src/decoder/graphqlWS.ts +22 -0
- package/src/decoder/interfaces.ts +185 -0
- package/src/decoder/keyValue.ts +5 -0
- package/src/decoder/kvCache.ts +241 -0
- package/src/decoder/lruCache.ts +184 -0
- package/src/decoder/lsp7Mint.test.ts +179 -0
- package/src/decoder/lsp7TransferBatch.test.ts +105 -0
- package/src/decoder/plugins/RegistryAbi.ts +562 -0
- package/src/decoder/plugins/enhanceBurntPix.ts +132 -0
- package/src/decoder/plugins/enhanceGraffiti.ts +70 -0
- package/src/decoder/plugins/enhanceLSP0ERC725Account.ts +179 -0
- package/src/decoder/plugins/enhanceLSP26FollowerSystem.ts +88 -0
- package/src/decoder/plugins/enhanceLSP6KeyManager.ts +231 -0
- package/src/decoder/plugins/enhanceLSP7DigitalAsset.ts +165 -0
- package/src/decoder/plugins/enhanceLSP8IdentifiableDigitalAsset.ts +170 -0
- package/src/decoder/plugins/enhanceLSP9Vault.ts +57 -0
- package/src/decoder/plugins/enhanceRetrieveAbi.ts +85 -0
- package/src/decoder/plugins/enhanceSetData.ts +135 -0
- package/src/decoder/plugins/index.ts +99 -0
- package/src/decoder/plugins/schemaDefault.ts +318 -0
- package/src/decoder/plugins/standardPlugin.ts +202 -0
- package/src/decoder/registry.ts +322 -0
- package/src/decoder/singleGQL.ts +293 -0
- package/src/decoder/transaction.ts +198 -0
- package/src/decoder/types.ts +465 -0
- package/src/decoder/utils.ts +212 -0
- package/src/example/usage.ts +172 -0
- package/src/index.ts +174 -0
- package/src/server/addressResolver.ts +68 -0
- package/src/server/caches.ts +209 -0
- package/src/server/decodeTransactionSync.ts +156 -0
- package/src/server/decodeTransactionsBatch.ts +207 -0
- package/src/server/finishDecoding.ts +116 -0
- package/src/server/index.ts +81 -0
- package/src/server/lsp23Resolver.test.ts +46 -0
- package/src/server/lsp23Resolver.ts +419 -0
- package/src/server/types.ts +168 -0
- package/src/server.ts +22 -0
- package/src/shared/addressResolver.ts +651 -0
- package/src/shared/cache.ts +144 -0
- package/src/shared/constants.ts +21 -0
- package/src/stubs/tty.ts +13 -0
- package/src/stubs/util.ts +42 -0
- package/src/types/index.ts +154 -0
- package/src/types/provider.ts +46 -0
- package/src/umd.ts +13 -0
- package/src/utils/debug.ts +49 -0
- package/src/utils/json-bigint.ts +47 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { DataKey, EnhancedInfo } from '../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Address identity cache interface
|
|
5
|
+
* Can be implemented with different backends (LRU, Redis, etc.)
|
|
6
|
+
*/
|
|
7
|
+
export interface AddressIdentityCache {
|
|
8
|
+
/**
|
|
9
|
+
* Get cached address data
|
|
10
|
+
*/
|
|
11
|
+
get(
|
|
12
|
+
key: DataKey
|
|
13
|
+
): EnhancedInfo | undefined | Promise<EnhancedInfo | undefined>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Set address data in cache
|
|
17
|
+
*/
|
|
18
|
+
set(key: DataKey, value: EnhancedInfo): void | Promise<void>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Check if address is in cache
|
|
22
|
+
*/
|
|
23
|
+
has(key: DataKey): boolean | Promise<boolean>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get multiple addresses at once
|
|
27
|
+
*/
|
|
28
|
+
getMany?(
|
|
29
|
+
keys: readonly DataKey[]
|
|
30
|
+
): Map<DataKey, EnhancedInfo> | Promise<Map<DataKey, EnhancedInfo>>
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Set multiple addresses at once
|
|
34
|
+
*/
|
|
35
|
+
setMany?(entries: Array<[DataKey, EnhancedInfo]>): void | Promise<void>
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Clear all cached data
|
|
39
|
+
*/
|
|
40
|
+
clear?(): void | Promise<void>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Type guard to check if value is a promise
|
|
45
|
+
*/
|
|
46
|
+
function isPromise<T>(value: T | Promise<T>): value is Promise<T> {
|
|
47
|
+
return value instanceof Promise
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Helper to convert DataKey to cache key string
|
|
52
|
+
*/
|
|
53
|
+
export function getDataKeyCacheKey(key: DataKey): string {
|
|
54
|
+
return key.toLowerCase()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Convert a DataKey to the standardized string format
|
|
59
|
+
* @param dataKey - A hex string (address or address:tokenId)
|
|
60
|
+
* @returns The same string
|
|
61
|
+
*/
|
|
62
|
+
export function dataKeyToString(dataKey: DataKey): string {
|
|
63
|
+
return dataKey
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Parse a string to a DataKey
|
|
68
|
+
* @param str - String in format "address" or "address:tokenId"
|
|
69
|
+
* @returns DataKey as a hex string
|
|
70
|
+
*/
|
|
71
|
+
export function parseDataKey(str: string): DataKey {
|
|
72
|
+
// Just return the string as-is since DataKey is now always a string
|
|
73
|
+
return str as DataKey
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Create a simple in-memory address cache
|
|
78
|
+
*/
|
|
79
|
+
export function createMemoryAddressIdentityCache(
|
|
80
|
+
ttlMs: number = 1000 * 60 * 5 // 5 minutes default
|
|
81
|
+
): AddressIdentityCache {
|
|
82
|
+
const cache = new Map<string, { data: EnhancedInfo; expires: number }>()
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
get(key: DataKey): EnhancedInfo | undefined {
|
|
86
|
+
const cacheKey = getDataKeyCacheKey(key)
|
|
87
|
+
const entry = cache.get(cacheKey)
|
|
88
|
+
|
|
89
|
+
if (!entry) return undefined
|
|
90
|
+
|
|
91
|
+
if (Date.now() > entry.expires) {
|
|
92
|
+
cache.delete(cacheKey)
|
|
93
|
+
return undefined
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return entry.data
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
set(key: DataKey, value: EnhancedInfo): void {
|
|
100
|
+
const cacheKey = getDataKeyCacheKey(key)
|
|
101
|
+
cache.set(cacheKey, {
|
|
102
|
+
data: value,
|
|
103
|
+
expires: Date.now() + ttlMs,
|
|
104
|
+
})
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
has(key: DataKey): boolean {
|
|
108
|
+
const cacheKey = getDataKeyCacheKey(key)
|
|
109
|
+
const entry = cache.get(cacheKey)
|
|
110
|
+
|
|
111
|
+
if (!entry) return false
|
|
112
|
+
|
|
113
|
+
if (Date.now() > entry.expires) {
|
|
114
|
+
cache.delete(cacheKey)
|
|
115
|
+
return false
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return true
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
getMany(keys: DataKey[]): Map<DataKey, EnhancedInfo> {
|
|
122
|
+
const results = new Map<DataKey, EnhancedInfo>()
|
|
123
|
+
|
|
124
|
+
for (const key of keys) {
|
|
125
|
+
const data = this.get(key)
|
|
126
|
+
if (data && !isPromise(data)) {
|
|
127
|
+
results.set(key, data)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return results
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
setMany(entries: Array<[DataKey, EnhancedInfo]>): void {
|
|
135
|
+
for (const [key, value] of entries) {
|
|
136
|
+
this.set(key, value)
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
clear(): void {
|
|
141
|
+
cache.clear()
|
|
142
|
+
},
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const DECODER_VERSION = '0.1.0'
|
|
6
|
+
|
|
7
|
+
export const DEFAULT_CONFIG = {
|
|
8
|
+
endpoint: 'https://api.lukso.network/decoder',
|
|
9
|
+
batchSize: 100,
|
|
10
|
+
retryAttempts: 3,
|
|
11
|
+
timeout: 30000,
|
|
12
|
+
} as const
|
|
13
|
+
|
|
14
|
+
export const ERROR_CODES = {
|
|
15
|
+
INVALID_TRANSACTION: 'INVALID_TRANSACTION',
|
|
16
|
+
DECODING_FAILED: 'DECODING_FAILED',
|
|
17
|
+
NETWORK_ERROR: 'NETWORK_ERROR',
|
|
18
|
+
RATE_LIMIT: 'RATE_LIMIT',
|
|
19
|
+
UNAUTHORIZED: 'UNAUTHORIZED',
|
|
20
|
+
NOT_FOUND: 'NOT_FOUND',
|
|
21
|
+
} as const
|
package/src/stubs/tty.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub for Node.js tty module in edge/worker environments
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const isatty = () => false
|
|
6
|
+
export const ReadStream = class ReadStream {}
|
|
7
|
+
export const WriteStream = class WriteStream {}
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
isatty,
|
|
11
|
+
ReadStream,
|
|
12
|
+
WriteStream,
|
|
13
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub for Node.js util module in edge/worker environments
|
|
3
|
+
* Only includes what debug module might use
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const inspect = (obj: any) => {
|
|
7
|
+
try {
|
|
8
|
+
return JSON.stringify(obj, null, 2)
|
|
9
|
+
} catch {
|
|
10
|
+
return String(obj)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const format = (f: string, ...args: any[]) => {
|
|
15
|
+
let i = 0
|
|
16
|
+
return f.replace(/%[sdj%]/g, (x) => {
|
|
17
|
+
if (x === '%%') return '%'
|
|
18
|
+
if (i >= args.length) return x
|
|
19
|
+
switch (x) {
|
|
20
|
+
case '%s':
|
|
21
|
+
return String(args[i++])
|
|
22
|
+
case '%d':
|
|
23
|
+
return Number(args[i++]).toString()
|
|
24
|
+
case '%j':
|
|
25
|
+
try {
|
|
26
|
+
return JSON.stringify(args[i++])
|
|
27
|
+
} catch {
|
|
28
|
+
return '[Circular]'
|
|
29
|
+
}
|
|
30
|
+
default:
|
|
31
|
+
return x
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const debuglog = () => () => {}
|
|
37
|
+
|
|
38
|
+
export default {
|
|
39
|
+
inspect,
|
|
40
|
+
format,
|
|
41
|
+
debuglog,
|
|
42
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types for @lukso/decoder
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Signal } from '@preact/signals-core'
|
|
6
|
+
import type { Hex } from 'viem'
|
|
7
|
+
import type { DecoderResult, EnhancedInfo } from '../decoder/types'
|
|
8
|
+
|
|
9
|
+
// Re-export decoder types
|
|
10
|
+
export type { DecoderResult, EnhancedInfo } from '../decoder/types'
|
|
11
|
+
export { AsyncOperations } from '../decoder/types'
|
|
12
|
+
|
|
13
|
+
// Key is always a hex string - for tokens it's in the format "address:tokenId"
|
|
14
|
+
export type DataKey = Hex
|
|
15
|
+
|
|
16
|
+
// Helper type to make all properties deeply readonly
|
|
17
|
+
type DeepReadonly<T> = T extends (infer R)[]
|
|
18
|
+
? DeepReadonlyArray<R>
|
|
19
|
+
: T extends (...args: unknown[]) => unknown
|
|
20
|
+
? T
|
|
21
|
+
: T extends object
|
|
22
|
+
? DeepReadonlyObject<T>
|
|
23
|
+
: T
|
|
24
|
+
|
|
25
|
+
interface DeepReadonlyArray<T> extends ReadonlyArray<DeepReadonly<T>> {}
|
|
26
|
+
|
|
27
|
+
type DeepReadonlyObject<T> = {
|
|
28
|
+
readonly [P in keyof T]: DeepReadonly<T[P]>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* State wrapper for address/asset information
|
|
33
|
+
*/
|
|
34
|
+
export interface AddressState {
|
|
35
|
+
loading: boolean
|
|
36
|
+
data?: DeepReadonly<EnhancedInfo>
|
|
37
|
+
error?: string
|
|
38
|
+
lastUpdated?: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Transaction decoding status
|
|
43
|
+
* - raw: No decoding attempted yet
|
|
44
|
+
* - decoded: Sync decoding complete (phase 1)
|
|
45
|
+
* - enhanced: ABI retrieval complete (phase 2)
|
|
46
|
+
* - complete: Address resolution complete (phase 3)
|
|
47
|
+
* - failed: Decoding failed
|
|
48
|
+
*/
|
|
49
|
+
export type DecodingStatus =
|
|
50
|
+
| 'raw'
|
|
51
|
+
| 'decoded'
|
|
52
|
+
| 'enhanced'
|
|
53
|
+
| 'complete'
|
|
54
|
+
| 'failed'
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* State wrapper for decoded transactions
|
|
58
|
+
*/
|
|
59
|
+
export interface TransactionState {
|
|
60
|
+
loading: boolean
|
|
61
|
+
data: DeepReadonly<DecoderResult>
|
|
62
|
+
addresses: ReadonlyArray<DataKey>
|
|
63
|
+
error?: string
|
|
64
|
+
lastUpdated?: number
|
|
65
|
+
decodingStatus?: DecodingStatus
|
|
66
|
+
addressesResolved?: boolean
|
|
67
|
+
resolvedData?: DeepReadonly<DecoderResult> // Transaction with all addresses populated
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Options for creating a data model instance
|
|
72
|
+
*/
|
|
73
|
+
export interface DataModelOptions {
|
|
74
|
+
onMissingKeys?: (keys: DataKey[]) => void
|
|
75
|
+
onNewTransaction?: (transaction: unknown) => void
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Read-only interface for consumers (views, components)
|
|
80
|
+
* This is the interface available on window.transactionDecoder
|
|
81
|
+
*/
|
|
82
|
+
export interface IDataModelConsumer {
|
|
83
|
+
// Transaction read methods
|
|
84
|
+
getTransaction(jsonTransaction: unknown): Signal<TransactionState> | undefined
|
|
85
|
+
getTransactionByKey(
|
|
86
|
+
hash: Hex,
|
|
87
|
+
decoderIndex?: number
|
|
88
|
+
): Signal<TransactionState> | undefined
|
|
89
|
+
getTransactionsByIndex(
|
|
90
|
+
index: number
|
|
91
|
+
): Map<number | null, Signal<TransactionState>> | undefined
|
|
92
|
+
getTransactionHashByIndex(index: number): Hex | undefined
|
|
93
|
+
getTransactionCount(): number
|
|
94
|
+
getDecodedCount(hash: Hex): number
|
|
95
|
+
getDecodedTransactions(hash: Hex): Array<Signal<TransactionState>>
|
|
96
|
+
getTransactionsInOrder(): Array<{
|
|
97
|
+
hash: Hex
|
|
98
|
+
transactions: Array<Signal<TransactionState>>
|
|
99
|
+
}>
|
|
100
|
+
|
|
101
|
+
// Address read methods
|
|
102
|
+
getAddress(address: DataKey): Signal<AddressState>
|
|
103
|
+
getSignal(key: DataKey): Signal<AddressState>
|
|
104
|
+
subscribe(key: DataKey, callback: (state: AddressState) => void): () => void
|
|
105
|
+
getState(key: DataKey): AddressState
|
|
106
|
+
hasData(key: DataKey): boolean
|
|
107
|
+
getData(key: DataKey): DeepReadonly<EnhancedInfo> | undefined
|
|
108
|
+
isLoading(key: DataKey): boolean
|
|
109
|
+
getError(key: DataKey): string | undefined
|
|
110
|
+
|
|
111
|
+
// Collection read methods
|
|
112
|
+
getAllKeys(): ReadonlyArray<DataKey>
|
|
113
|
+
getAllData(): Readonly<Record<string, AddressState>>
|
|
114
|
+
getAllTransactions(): Readonly<Record<string, TransactionState>>
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Full interface for data management (used by data providers)
|
|
119
|
+
* Includes all consumer methods plus data modification methods
|
|
120
|
+
*/
|
|
121
|
+
export interface IDataModel extends IDataModelConsumer {
|
|
122
|
+
// Transaction management methods
|
|
123
|
+
addTransactions<T extends unknown | unknown[]>(
|
|
124
|
+
jsonTransactions: T
|
|
125
|
+
): T extends unknown[]
|
|
126
|
+
? Array<Signal<TransactionState>>
|
|
127
|
+
: Signal<TransactionState>
|
|
128
|
+
updateTransactionData(
|
|
129
|
+
hash: Hex,
|
|
130
|
+
newData: DecoderResult,
|
|
131
|
+
decoderIndex?: number
|
|
132
|
+
): void
|
|
133
|
+
|
|
134
|
+
// Address management methods
|
|
135
|
+
injectData(dataList: EnhancedInfo[]): void
|
|
136
|
+
updateData(data: EnhancedInfo): void
|
|
137
|
+
setLoading(keys: DataKey[]): void
|
|
138
|
+
setError(key: DataKey, error: string): void
|
|
139
|
+
|
|
140
|
+
// Collection management methods
|
|
141
|
+
getMissingKeys(): DataKey[]
|
|
142
|
+
getLoadingKeys(): DataKey[]
|
|
143
|
+
|
|
144
|
+
// Management methods
|
|
145
|
+
clear(): void
|
|
146
|
+
remove(keys: DataKey[]): void
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Global window augmentation (only set by UMD builds or manual createGlobalInstance() call)
|
|
150
|
+
declare global {
|
|
151
|
+
interface Window {
|
|
152
|
+
TransactionDecoder?: IDataModelConsumer
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for data providers
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Address, Hex } from 'viem'
|
|
6
|
+
import type { TransactionState } from '.'
|
|
7
|
+
|
|
8
|
+
export interface TransactionInput {
|
|
9
|
+
hash: Hex
|
|
10
|
+
chainId: number
|
|
11
|
+
from: Address
|
|
12
|
+
to?: Address
|
|
13
|
+
value: string | bigint
|
|
14
|
+
data: Hex
|
|
15
|
+
blockNumber?: string | bigint
|
|
16
|
+
timestamp?: number
|
|
17
|
+
status?: 'pending' | 'success' | 'failed'
|
|
18
|
+
metadata?: TransactionState
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface TransactionUpdate {
|
|
22
|
+
hash: Hex
|
|
23
|
+
chainId: number
|
|
24
|
+
status?: 'pending' | 'success' | 'failed'
|
|
25
|
+
blockNumber?: string | bigint
|
|
26
|
+
timestamp?: number
|
|
27
|
+
metadata?: Partial<TransactionState>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ProviderConfig {
|
|
31
|
+
apiKey?: string
|
|
32
|
+
endpoint?: string
|
|
33
|
+
batchSize?: number
|
|
34
|
+
retryAttempts?: number
|
|
35
|
+
timeout?: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface SubmissionResult {
|
|
39
|
+
success: boolean
|
|
40
|
+
transactionHash: Hex
|
|
41
|
+
message?: string
|
|
42
|
+
error?: {
|
|
43
|
+
code: string
|
|
44
|
+
message: string
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/umd.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UMD entry point for @lukso/transaction-decoder
|
|
3
|
+
* This file automatically sets up window.TransactionDecoder for CDN usage
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Import the instance setup function
|
|
7
|
+
import { createGlobalInstance } from './core/instance'
|
|
8
|
+
|
|
9
|
+
// Re-export everything from the main entry
|
|
10
|
+
export * from './index'
|
|
11
|
+
|
|
12
|
+
// Automatically create the global instance for UMD builds
|
|
13
|
+
createGlobalInstance()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug wrapper for edge/worker environments
|
|
3
|
+
* This avoids the tty dependency in the debug module
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const debugInstances = new Map<string, boolean>()
|
|
7
|
+
|
|
8
|
+
// Simple debug implementation that doesn't rely on Node.js modules
|
|
9
|
+
export function createDebug(namespace: string) {
|
|
10
|
+
// Check if this namespace is enabled
|
|
11
|
+
const DEBUG = (typeof process !== 'undefined' && process.env?.DEBUG) || ''
|
|
12
|
+
|
|
13
|
+
// Simple pattern matching
|
|
14
|
+
const isEnabled = () => {
|
|
15
|
+
if (!DEBUG) return false
|
|
16
|
+
if (DEBUG === '*') return true
|
|
17
|
+
|
|
18
|
+
const patterns = DEBUG.split(',').map((p) => p.trim())
|
|
19
|
+
for (const pattern of patterns) {
|
|
20
|
+
if (pattern === namespace) return true
|
|
21
|
+
if (pattern.endsWith('*') && namespace.startsWith(pattern.slice(0, -1)))
|
|
22
|
+
return true
|
|
23
|
+
if (pattern.startsWith('-')) {
|
|
24
|
+
const negPattern = pattern.slice(1)
|
|
25
|
+
if (negPattern === namespace) return false
|
|
26
|
+
if (
|
|
27
|
+
negPattern.endsWith('*') &&
|
|
28
|
+
namespace.startsWith(negPattern.slice(0, -1))
|
|
29
|
+
)
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
debugInstances.set(namespace, isEnabled())
|
|
37
|
+
|
|
38
|
+
return (...args: any[]) => {
|
|
39
|
+
if (!debugInstances.get(namespace)) return
|
|
40
|
+
|
|
41
|
+
const timestamp = new Date().toISOString()
|
|
42
|
+
const prefix = `[${timestamp}] ${namespace}`
|
|
43
|
+
|
|
44
|
+
// In Cloudflare Workers, console.log is the only option
|
|
45
|
+
console.log(prefix, ...args)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default createDebug
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON serializer/deserializer that preserves BigInt types
|
|
3
|
+
*
|
|
4
|
+
* This implementation uses an 'n' suffix to indicate BigInt values,
|
|
5
|
+
* ensuring that values that were originally BigInt remain BigInt,
|
|
6
|
+
* and values that were originally numbers remain numbers.
|
|
7
|
+
*
|
|
8
|
+
* Example:
|
|
9
|
+
* - BigInt(123) serializes to "123n"
|
|
10
|
+
* - Number(123) serializes to 123
|
|
11
|
+
*
|
|
12
|
+
* This is important for blockchain data where some values must be BigInt
|
|
13
|
+
* (e.g., gas, value, nonce) while others should remain as numbers
|
|
14
|
+
* (e.g., array indices, status codes).
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export const JSONbigString = {
|
|
18
|
+
/**
|
|
19
|
+
* Stringify an object, converting BigInt values to strings with 'n' suffix
|
|
20
|
+
*/
|
|
21
|
+
stringify: (obj: any, replacer?: any, space?: string | number): string => {
|
|
22
|
+
return JSON.stringify(
|
|
23
|
+
obj,
|
|
24
|
+
(key, value) => {
|
|
25
|
+
if (typeof value === 'bigint') {
|
|
26
|
+
return value.toString() + 'n'
|
|
27
|
+
}
|
|
28
|
+
return value
|
|
29
|
+
},
|
|
30
|
+
space
|
|
31
|
+
)
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parse a JSON string, converting strings ending with 'n' back to BigInt
|
|
36
|
+
*/
|
|
37
|
+
parse: (text: string): any => {
|
|
38
|
+
return JSON.parse(text, (key, value) => {
|
|
39
|
+
if (typeof value === 'string' && /^\d+n$/.test(value)) {
|
|
40
|
+
return BigInt(value.slice(0, -1))
|
|
41
|
+
}
|
|
42
|
+
return value
|
|
43
|
+
})
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default JSONbigString
|