@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,165 @@
|
|
|
1
|
+
import {
|
|
2
|
+
lsp7BurnableAbi,
|
|
3
|
+
lsp7CappedSupplyAbi,
|
|
4
|
+
lsp7DigitalAssetAbi,
|
|
5
|
+
lsp7MintableAbi,
|
|
6
|
+
lsp7VotesAbi,
|
|
7
|
+
} from '@lukso/lsp7-contracts/abi'
|
|
8
|
+
import type { AbiParameter } from 'viem'
|
|
9
|
+
import { CacheKeyPrefix, makeCacheKey } from '../cache'
|
|
10
|
+
import { decodeEvent } from '../events'
|
|
11
|
+
import { pluginRegistry } from '../registry'
|
|
12
|
+
import type {
|
|
13
|
+
DecodeEventResult,
|
|
14
|
+
DecoderOptions,
|
|
15
|
+
DecoderResult,
|
|
16
|
+
PluginOptions,
|
|
17
|
+
ResultType,
|
|
18
|
+
} from '../types'
|
|
19
|
+
import { getPublicClient } from '../utils'
|
|
20
|
+
import { standardPlugin } from '.'
|
|
21
|
+
import { enhanceSetData } from './enhanceSetData'
|
|
22
|
+
|
|
23
|
+
const LSP7 = [
|
|
24
|
+
...lsp7DigitalAssetAbi,
|
|
25
|
+
...lsp7MintableAbi,
|
|
26
|
+
...lsp7BurnableAbi,
|
|
27
|
+
...lsp7CappedSupplyAbi,
|
|
28
|
+
...lsp7VotesAbi,
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
export const enhanceLSP7DigitalAssetPlugin = standardPlugin(
|
|
32
|
+
LSP7,
|
|
33
|
+
{
|
|
34
|
+
name: 'lsp7',
|
|
35
|
+
abiName: 'LSP7DigitalAsset',
|
|
36
|
+
decoderName: '@lukso/lsp-smart-contracts',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
enhance: async (result, pluginOptions, options) => {
|
|
40
|
+
const setData = await enhanceSetData(
|
|
41
|
+
result,
|
|
42
|
+
{ ...pluginOptions, abiName: '', decoderName: '' },
|
|
43
|
+
options
|
|
44
|
+
)
|
|
45
|
+
if (setData) {
|
|
46
|
+
return setData
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Add token metadata for LSP7 contracts for view matching
|
|
50
|
+
if (options.async) {
|
|
51
|
+
await enhanceLSP7Metadata(result, options)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const follow = await enhanceLSP26FollowerSystem(
|
|
55
|
+
result,
|
|
56
|
+
pluginOptions,
|
|
57
|
+
options
|
|
58
|
+
)
|
|
59
|
+
if (follow) {
|
|
60
|
+
return follow
|
|
61
|
+
}
|
|
62
|
+
return result
|
|
63
|
+
},
|
|
64
|
+
decodeEvent: async (log: DecodeEventResult, options: DecoderOptions) => {
|
|
65
|
+
return decodeEvent(options.chain, LSP7, log)
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Fetch and cache LSP7 contract metadata for view matching.
|
|
72
|
+
* This function reads LSP4TokenType from the contract to determine if it's a token, NFT, or collection.
|
|
73
|
+
* Results are cached per contract address to avoid redundant RPC calls for batch operations.
|
|
74
|
+
*
|
|
75
|
+
* @param result - The decoder result to enhance with metadata
|
|
76
|
+
* @param options - Decoder options containing cache and chain client
|
|
77
|
+
*/
|
|
78
|
+
async function enhanceLSP7Metadata(
|
|
79
|
+
result: DecoderResult,
|
|
80
|
+
options: DecoderOptions
|
|
81
|
+
): Promise<void> {
|
|
82
|
+
if (!options.cache || !result.to) return
|
|
83
|
+
|
|
84
|
+
const contractAddress = result.to
|
|
85
|
+
const cacheKey = makeCacheKey(
|
|
86
|
+
CacheKeyPrefix.CONTRACT_METADATA,
|
|
87
|
+
contractAddress,
|
|
88
|
+
'lsp4-token-type'
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
// Use cache.getOrSet for automatic deduplication
|
|
93
|
+
// If 5 transactions hit the same contract, only 1 RPC call is made
|
|
94
|
+
const metadata = await options.cache.getOrSet(
|
|
95
|
+
cacheKey,
|
|
96
|
+
async () => {
|
|
97
|
+
const client = getPublicClient(options.chain)
|
|
98
|
+
|
|
99
|
+
// Read LSP4TokenType from contract
|
|
100
|
+
// Key: keccak256('LSP4TokenType') = 0xe0261fa95db2eb3b5439bd033cda66d56b96f92f243a8228fd87550ed7bdfdb3
|
|
101
|
+
const tokenTypeData = await client.readContract({
|
|
102
|
+
address: contractAddress,
|
|
103
|
+
abi: LSP7,
|
|
104
|
+
functionName: 'getData',
|
|
105
|
+
args: [
|
|
106
|
+
'0xe0261fa95db2eb3b5439bd033cda66d56b96f92f243a8228fd87550ed7bdfdb3',
|
|
107
|
+
],
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Parse token type (0 = Token, 1 = NFT, 2 = Collection)
|
|
111
|
+
const typeValue = tokenTypeData
|
|
112
|
+
? Number.parseInt(tokenTypeData as string, 16)
|
|
113
|
+
: 0
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
tokenType: typeValue,
|
|
117
|
+
isToken: typeValue === 0,
|
|
118
|
+
isNFT: typeValue === 1,
|
|
119
|
+
isCollection: typeValue === 2,
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
ttl: 1000 * 60 * 60 * 24, // Cache for 24 hours (metadata rarely changes)
|
|
124
|
+
signal: options.signal,
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
// Add to result.custom for view matching
|
|
129
|
+
result.custom = result.custom || {}
|
|
130
|
+
Object.assign(result.custom, metadata)
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.warn('Failed to fetch LSP7 metadata:', error)
|
|
133
|
+
// Set defaults on error (assume token)
|
|
134
|
+
result.custom = result.custom || {}
|
|
135
|
+
result.custom.tokenType = 0
|
|
136
|
+
result.custom.isToken = true
|
|
137
|
+
result.custom.isNFT = false
|
|
138
|
+
result.custom.isCollection = false
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
*
|
|
144
|
+
* @param result enhanced if it's LSP7DigitalAsset
|
|
145
|
+
* @param pluginOptions
|
|
146
|
+
* @param options
|
|
147
|
+
* @returns
|
|
148
|
+
*/
|
|
149
|
+
export async function enhanceLSP26FollowerSystem(
|
|
150
|
+
result: DecoderResult,
|
|
151
|
+
_pluginOptions: PluginOptions,
|
|
152
|
+
_options: DecoderOptions
|
|
153
|
+
) {
|
|
154
|
+
const { functionName, sig, args, input, blockNumber, to, from, value } =
|
|
155
|
+
result as ResultType & {
|
|
156
|
+
sig?: `0x${string}`
|
|
157
|
+
functionName?: string
|
|
158
|
+
args: Array<AbiParameter & { value?: unknown }>
|
|
159
|
+
}
|
|
160
|
+
switch (functionName) {
|
|
161
|
+
}
|
|
162
|
+
return undefined
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export default enhanceLSP7DigitalAssetPlugin
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import {
|
|
2
|
+
lsp8BurnableAbi,
|
|
3
|
+
lsp8CappedSupplyAbi,
|
|
4
|
+
lsp8EnumerableAbi,
|
|
5
|
+
lsp8IdentifiableDigitalAssetAbi,
|
|
6
|
+
lsp8MintableAbi,
|
|
7
|
+
lsp8VotesAbi,
|
|
8
|
+
} from '@lukso/lsp8-contracts/abi'
|
|
9
|
+
import type { AbiParameter } from 'viem'
|
|
10
|
+
import { decodeEvent } from '../events'
|
|
11
|
+
import type {
|
|
12
|
+
DecodeEventResult,
|
|
13
|
+
DecoderOptions,
|
|
14
|
+
DecoderResult,
|
|
15
|
+
PluginOptions,
|
|
16
|
+
ResultShared,
|
|
17
|
+
ResultType,
|
|
18
|
+
} from '../types'
|
|
19
|
+
import { createNamedArgs } from '../utils'
|
|
20
|
+
import { decodeKeyValueRaw, standardPlugin } from '.'
|
|
21
|
+
import { enhanceSetData } from './enhanceSetData'
|
|
22
|
+
|
|
23
|
+
const LSP8 = [
|
|
24
|
+
...lsp8IdentifiableDigitalAssetAbi,
|
|
25
|
+
...lsp8MintableAbi,
|
|
26
|
+
...lsp8BurnableAbi,
|
|
27
|
+
...lsp8CappedSupplyAbi,
|
|
28
|
+
...lsp8EnumerableAbi,
|
|
29
|
+
...lsp8VotesAbi,
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
export const enhanceLSP8IdentifiableDigitalAssetPlugin = standardPlugin(
|
|
33
|
+
LSP8,
|
|
34
|
+
{
|
|
35
|
+
name: 'lsp8',
|
|
36
|
+
abiName: 'LSP8IdentifiableDigitalAsset',
|
|
37
|
+
decoderName: '@lukso/lsp-smart-contracts',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
enhance: async (result, pluginOptions, options) => {
|
|
41
|
+
const setData = await enhanceSetData(result, pluginOptions, options)
|
|
42
|
+
if (setData) {
|
|
43
|
+
return setData
|
|
44
|
+
}
|
|
45
|
+
return await enhanceLSP8IdentifiableDigitalAsset(
|
|
46
|
+
result,
|
|
47
|
+
pluginOptions,
|
|
48
|
+
options
|
|
49
|
+
)
|
|
50
|
+
},
|
|
51
|
+
decodeEvent: async (log: DecodeEventResult, options: DecoderOptions) => {
|
|
52
|
+
const event = decodeEvent(options.chain, LSP8, log)
|
|
53
|
+
if (event) {
|
|
54
|
+
const tokenId = event.args.find(({ name }) => name === 'tokenId')?.value
|
|
55
|
+
if (tokenId) {
|
|
56
|
+
event.address = `${event.address}:${tokenId}`
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return event
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param result enhanced if it's LSP8
|
|
67
|
+
* @param pluginOptions
|
|
68
|
+
* @param options
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
71
|
+
export async function enhanceLSP8IdentifiableDigitalAsset(
|
|
72
|
+
result: ResultType & ResultShared & { moduleHint?: string },
|
|
73
|
+
pluginOptions: PluginOptions,
|
|
74
|
+
options: DecoderOptions
|
|
75
|
+
) {
|
|
76
|
+
const setData = await enhanceSetData(
|
|
77
|
+
result,
|
|
78
|
+
{ ...pluginOptions, abiName: '', decoderName: '' },
|
|
79
|
+
options
|
|
80
|
+
)
|
|
81
|
+
if (setData) {
|
|
82
|
+
return setData
|
|
83
|
+
}
|
|
84
|
+
const { functionName, sig, args, input, blockNumber, to, from, value } =
|
|
85
|
+
result as ResultType & {
|
|
86
|
+
sig?: `0x${string}`
|
|
87
|
+
functionName?: string
|
|
88
|
+
args: Array<AbiParameter & { value?: unknown }>
|
|
89
|
+
}
|
|
90
|
+
switch (functionName) {
|
|
91
|
+
case 'setDataForTokenId': {
|
|
92
|
+
// Single setDataForTokenId
|
|
93
|
+
const [tokenId, _key, _value] = args.map(({ value }) => value) as [
|
|
94
|
+
`0x${string}`,
|
|
95
|
+
`0x${string}`,
|
|
96
|
+
`0x${string}`,
|
|
97
|
+
]
|
|
98
|
+
return {
|
|
99
|
+
blockNumber,
|
|
100
|
+
...result,
|
|
101
|
+
__decoder: pluginOptions.decoderName,
|
|
102
|
+
resultType: 'setDataBatch',
|
|
103
|
+
standard: pluginOptions.abiName,
|
|
104
|
+
input,
|
|
105
|
+
children: [
|
|
106
|
+
{
|
|
107
|
+
...result,
|
|
108
|
+
standard: pluginOptions.abiName,
|
|
109
|
+
tokenId,
|
|
110
|
+
to: `${to}:${tokenId}`,
|
|
111
|
+
from,
|
|
112
|
+
value,
|
|
113
|
+
info: await decodeKeyValueRaw(_key, _value, options),
|
|
114
|
+
},
|
|
115
|
+
] as Array<DecoderResult>,
|
|
116
|
+
} as DecoderResult
|
|
117
|
+
}
|
|
118
|
+
case 'setDataBatchForTokenIds': {
|
|
119
|
+
// Multiple setDataBatchForTokenIds
|
|
120
|
+
const children: Array<ResultType> = []
|
|
121
|
+
const [tokenIds, keys, values] = args.map(({ value }) => value) as [
|
|
122
|
+
`0x${string}`[],
|
|
123
|
+
`0x${string}`[],
|
|
124
|
+
`0x${string}`[],
|
|
125
|
+
]
|
|
126
|
+
for (let i = 0; i < tokenIds.length; i++) {
|
|
127
|
+
const tokenId = tokenIds[i] as `0x${string}`
|
|
128
|
+
const key = keys[i] as `0x${string}`
|
|
129
|
+
const _value = values[i] as `0x${string}`
|
|
130
|
+
children.push({
|
|
131
|
+
...result,
|
|
132
|
+
resultType: 'setData',
|
|
133
|
+
__decoder: '@lukso/lsp-smart-contracts',
|
|
134
|
+
standard: key,
|
|
135
|
+
...createNamedArgs(
|
|
136
|
+
[tokenId, key, _value],
|
|
137
|
+
[
|
|
138
|
+
{ name: 'tokenId', type: 'bytes32' },
|
|
139
|
+
{ name: 'key', type: 'bytes32' },
|
|
140
|
+
{ name: 'value', type: 'bytes' },
|
|
141
|
+
]
|
|
142
|
+
),
|
|
143
|
+
tokenId,
|
|
144
|
+
phase: 'enhanced',
|
|
145
|
+
to: `${to}:${tokenId}`,
|
|
146
|
+
from,
|
|
147
|
+
value,
|
|
148
|
+
info: await decodeKeyValueRaw(key, _value, options),
|
|
149
|
+
} as DecoderResult)
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
...result,
|
|
153
|
+
__decoder: pluginOptions.decoderName,
|
|
154
|
+
functionName,
|
|
155
|
+
sig,
|
|
156
|
+
input,
|
|
157
|
+
standard: pluginOptions.abiName,
|
|
158
|
+
resultType: 'setDataBatch',
|
|
159
|
+
...(args ? { args } : {}),
|
|
160
|
+
to,
|
|
161
|
+
from,
|
|
162
|
+
value,
|
|
163
|
+
children,
|
|
164
|
+
} as DecoderResult
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return result
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export default enhanceLSP8IdentifiableDigitalAssetPlugin
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { lsp9VaultAbi as LSP9 } from '@lukso/lsp9-contracts/abi'
|
|
2
|
+
import type { AbiParameter } from 'viem'
|
|
3
|
+
import { decodeEvent } from '../events'
|
|
4
|
+
import type {
|
|
5
|
+
DecodeEventResult,
|
|
6
|
+
DecoderOptions,
|
|
7
|
+
PluginOptions,
|
|
8
|
+
ResultShared,
|
|
9
|
+
ResultType,
|
|
10
|
+
} from '../types'
|
|
11
|
+
import { standardPlugin } from '.'
|
|
12
|
+
import { enhanceSetData } from './enhanceSetData'
|
|
13
|
+
|
|
14
|
+
export const enhanceLSP9VaultPlugin = standardPlugin(
|
|
15
|
+
LSP9,
|
|
16
|
+
{
|
|
17
|
+
name: 'lsp9',
|
|
18
|
+
abiName: 'LSP9Vault',
|
|
19
|
+
decoderName: '@lukso/lsp-smart-contracts',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
enhance: async (result, pluginOptions, options) => {
|
|
23
|
+
const setData = await enhanceSetData(result, pluginOptions, options)
|
|
24
|
+
if (setData) {
|
|
25
|
+
return setData
|
|
26
|
+
}
|
|
27
|
+
return await enhanceLSP9Vault(result, pluginOptions, options)
|
|
28
|
+
},
|
|
29
|
+
decodeEvent: async (log: DecodeEventResult, options: DecoderOptions) => {
|
|
30
|
+
return decodeEvent(options.chain, LSP9, log)
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param result enhanced if it's LSP8
|
|
37
|
+
* @param pluginOptions
|
|
38
|
+
* @param options
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
41
|
+
export async function enhanceLSP9Vault(
|
|
42
|
+
result: ResultType & ResultShared & { moduleHint?: string },
|
|
43
|
+
pluginOptions: PluginOptions,
|
|
44
|
+
options: DecoderOptions
|
|
45
|
+
) {
|
|
46
|
+
const { functionName, sig, args, input, blockNumber, to, from, value } =
|
|
47
|
+
result as ResultType & {
|
|
48
|
+
sig?: `0x${string}`
|
|
49
|
+
functionName?: string
|
|
50
|
+
args: Array<AbiParameter & { value?: unknown }>
|
|
51
|
+
}
|
|
52
|
+
switch (functionName) {
|
|
53
|
+
}
|
|
54
|
+
return undefined
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default enhanceLSP9VaultPlugin
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { abi as LSP9 } from '@lukso/lsp-smart-contracts/artifacts/LSP9Vault.json'
|
|
2
|
+
import type { AbiParameter } from 'viem'
|
|
3
|
+
import { decodeEvent } from '../events'
|
|
4
|
+
import { fetchAbi, getFunctionSignature } from '../functionSignature'
|
|
5
|
+
import type {
|
|
6
|
+
DecodeEventResult,
|
|
7
|
+
DecoderOptions,
|
|
8
|
+
DecoderResult,
|
|
9
|
+
PluginOptions,
|
|
10
|
+
ResultShared,
|
|
11
|
+
ResultType,
|
|
12
|
+
} from '../types'
|
|
13
|
+
import { standardPlugin } from '.'
|
|
14
|
+
|
|
15
|
+
export const enhanceRetrieveAbiPlugin = standardPlugin(
|
|
16
|
+
LSP9,
|
|
17
|
+
{
|
|
18
|
+
abiName: 'Internal',
|
|
19
|
+
decoderName: 'explorer',
|
|
20
|
+
name: 'abiRetrieve',
|
|
21
|
+
usesAsync: true,
|
|
22
|
+
priority: 0,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
enhance: async () => {
|
|
26
|
+
return undefined
|
|
27
|
+
},
|
|
28
|
+
overrideEnhance: enhanceRetrieveAbi,
|
|
29
|
+
decodeEvent: async (log: DecodeEventResult, options: DecoderOptions) => {
|
|
30
|
+
if (!log) {
|
|
31
|
+
return undefined
|
|
32
|
+
}
|
|
33
|
+
const info = await fetchAbi(options.chain, log.address)
|
|
34
|
+
// TBD. This will only work with explorer download of abi
|
|
35
|
+
if (info) {
|
|
36
|
+
const result = decodeEvent(options.chain, info.abi, log)
|
|
37
|
+
if (result) {
|
|
38
|
+
return { ...result, __decoder: info.explorer }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return undefined
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @param result enhanced if it's LSP8
|
|
48
|
+
* @param pluginOptions
|
|
49
|
+
* @param options
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
export async function enhanceRetrieveAbi(
|
|
53
|
+
result: ResultType & ResultShared & { moduleHint?: string },
|
|
54
|
+
_pluginOptions: PluginOptions,
|
|
55
|
+
options: DecoderOptions
|
|
56
|
+
) {
|
|
57
|
+
const { functionName, sig, args, input, blockNumber, to, from, value } =
|
|
58
|
+
result as ResultType & {
|
|
59
|
+
sig?: `0x${string}`
|
|
60
|
+
functionName?: string
|
|
61
|
+
args: Array<AbiParameter & { value?: unknown }>
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const decoded = await getFunctionSignature(
|
|
65
|
+
options.chain,
|
|
66
|
+
input,
|
|
67
|
+
(to || undefined) as `0x${string}` | undefined,
|
|
68
|
+
options.preferError
|
|
69
|
+
)
|
|
70
|
+
if (decoded) {
|
|
71
|
+
return {
|
|
72
|
+
...result,
|
|
73
|
+
...decoded,
|
|
74
|
+
resultType: 'execute',
|
|
75
|
+
to,
|
|
76
|
+
from,
|
|
77
|
+
value,
|
|
78
|
+
input,
|
|
79
|
+
} as DecoderResult
|
|
80
|
+
}
|
|
81
|
+
} catch {}
|
|
82
|
+
return undefined
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export default enhanceRetrieveAbiPlugin
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { AbiParameter } from 'viem'
|
|
2
|
+
import type {
|
|
3
|
+
DecoderOptions,
|
|
4
|
+
DecoderResult,
|
|
5
|
+
PluginOptions,
|
|
6
|
+
ResultSetData,
|
|
7
|
+
ResultShared,
|
|
8
|
+
ResultType,
|
|
9
|
+
} from '../types'
|
|
10
|
+
import { createNamedArgs } from '../utils'
|
|
11
|
+
import { decodeKeyValueRaw } from '.'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param result decode setData and setDataBatch as either a single or many setData items.
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
export async function enhanceSetData(
|
|
19
|
+
result: ResultType & ResultShared & { moduleHint?: string },
|
|
20
|
+
pluginOptions: PluginOptions,
|
|
21
|
+
options: DecoderOptions
|
|
22
|
+
): Promise<DecoderResult | undefined> {
|
|
23
|
+
const { functionName, sig, args, input, blockNumber, to, from, value } =
|
|
24
|
+
result as ResultType & {
|
|
25
|
+
sig?: `0x${string}`
|
|
26
|
+
functionName?: string
|
|
27
|
+
args: Array<AbiParameter & { value?: unknown }>
|
|
28
|
+
namedArgs?:
|
|
29
|
+
| Record<number, AbiParameter & { value?: unknown }>
|
|
30
|
+
| Record<string, unknown>
|
|
31
|
+
}
|
|
32
|
+
switch (functionName) {
|
|
33
|
+
case 'setData': {
|
|
34
|
+
const [_key, _value] = args.map(({ value }) => value) as `0x${string}`[]
|
|
35
|
+
// Single setData
|
|
36
|
+
return {
|
|
37
|
+
...result,
|
|
38
|
+
resultType: 'setDataBatch',
|
|
39
|
+
functionName,
|
|
40
|
+
standard: result.standard || pluginOptions.abiName || 'LSPContract',
|
|
41
|
+
__decoder:
|
|
42
|
+
result.__decoder ||
|
|
43
|
+
pluginOptions.decoderName ||
|
|
44
|
+
'@lukso/lsp-smart-contracts',
|
|
45
|
+
input,
|
|
46
|
+
blockNumber,
|
|
47
|
+
sig,
|
|
48
|
+
args,
|
|
49
|
+
children: [
|
|
50
|
+
{
|
|
51
|
+
...result,
|
|
52
|
+
info: await decodeKeyValueRaw(_key, _value, options),
|
|
53
|
+
standard: result.standard || pluginOptions.abiName || 'LSPContract',
|
|
54
|
+
__decoder:
|
|
55
|
+
result.__decoder ||
|
|
56
|
+
pluginOptions.decoderName ||
|
|
57
|
+
'@lukso/lsp-smart-contracts',
|
|
58
|
+
phase: 'enhanced',
|
|
59
|
+
to,
|
|
60
|
+
from,
|
|
61
|
+
value,
|
|
62
|
+
...(args
|
|
63
|
+
? {
|
|
64
|
+
...createNamedArgs(
|
|
65
|
+
[_key, _value],
|
|
66
|
+
[
|
|
67
|
+
{ name: 'key', type: 'bytes32' },
|
|
68
|
+
{ name: 'value', type: 'bytes' },
|
|
69
|
+
]
|
|
70
|
+
),
|
|
71
|
+
}
|
|
72
|
+
: {}),
|
|
73
|
+
},
|
|
74
|
+
] as unknown as Array<ResultSetData>,
|
|
75
|
+
to,
|
|
76
|
+
from,
|
|
77
|
+
value,
|
|
78
|
+
} as DecoderResult
|
|
79
|
+
}
|
|
80
|
+
case 'setDataBatch': {
|
|
81
|
+
// Multiple setDataBatch
|
|
82
|
+
const children: Array<ResultType> = []
|
|
83
|
+
const [keys, values] = args.map(({ value }) => value) as [
|
|
84
|
+
`0x${string}`[],
|
|
85
|
+
`0x${string}`[],
|
|
86
|
+
]
|
|
87
|
+
for (let i = 0; i < keys.length; i++) {
|
|
88
|
+
const key = keys[i] as `0x${string}`
|
|
89
|
+
const _value = values[i] as `0x${string}`
|
|
90
|
+
children.push({
|
|
91
|
+
...result,
|
|
92
|
+
resultType: 'setData',
|
|
93
|
+
standard: result.standard || pluginOptions.abiName || 'LSPContract',
|
|
94
|
+
__decoder:
|
|
95
|
+
result.__decoder ||
|
|
96
|
+
pluginOptions.decoderName ||
|
|
97
|
+
'@lukso/lsp-smart-contracts',
|
|
98
|
+
phase: 'enhanced',
|
|
99
|
+
to,
|
|
100
|
+
from,
|
|
101
|
+
value,
|
|
102
|
+
...createNamedArgs(
|
|
103
|
+
[key, _value],
|
|
104
|
+
[
|
|
105
|
+
{ name: 'key', type: 'bytes32' },
|
|
106
|
+
{ name: 'value', type: 'bytes' },
|
|
107
|
+
]
|
|
108
|
+
),
|
|
109
|
+
info: await decodeKeyValueRaw(key, _value, options),
|
|
110
|
+
} as DecoderResult)
|
|
111
|
+
}
|
|
112
|
+
const setDataBatchResult = {
|
|
113
|
+
...result,
|
|
114
|
+
resultType: 'setDataBatch',
|
|
115
|
+
functionName,
|
|
116
|
+
sig,
|
|
117
|
+
input,
|
|
118
|
+
...(args ? { args } : {}),
|
|
119
|
+
standard: result.standard || pluginOptions.abiName || 'LSPContract',
|
|
120
|
+
__decoder:
|
|
121
|
+
result.__decoder ||
|
|
122
|
+
pluginOptions.decoderName ||
|
|
123
|
+
'@lukso/lsp-smart-contracts',
|
|
124
|
+
to,
|
|
125
|
+
from,
|
|
126
|
+
value,
|
|
127
|
+
children,
|
|
128
|
+
} as DecoderResult
|
|
129
|
+
return setDataBatchResult
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return undefined
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export default enhanceSetData
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// Re-export standardPlugin and helpers from the new file
|
|
2
|
+
export {
|
|
3
|
+
createAggregationKey,
|
|
4
|
+
standardPlugin,
|
|
5
|
+
standardSchemaPlugin,
|
|
6
|
+
} from './standardPlugin'
|
|
7
|
+
|
|
8
|
+
import burntPix from './enhanceBurntPix'
|
|
9
|
+
// Import plugins - now standardPlugin is available from ./standardPlugin
|
|
10
|
+
import graffiti from './enhanceGraffiti'
|
|
11
|
+
import profile from './enhanceLSP0ERC725Account'
|
|
12
|
+
import keyManager from './enhanceLSP6KeyManager'
|
|
13
|
+
import lsp7 from './enhanceLSP7DigitalAsset'
|
|
14
|
+
import lsp8 from './enhanceLSP8IdentifiableDigitalAsset'
|
|
15
|
+
import lsp9 from './enhanceLSP9Vault'
|
|
16
|
+
import lsp26 from './enhanceLSP26FollowerSystem'
|
|
17
|
+
import abiRetrieve from './enhanceRetrieveAbi'
|
|
18
|
+
import schemaDefaultPlugin from './schemaDefault'
|
|
19
|
+
|
|
20
|
+
// Force evaluation of plugins to ensure they register (prevent tree-shaking)
|
|
21
|
+
// These plugins self-register via standardPlugin when imported
|
|
22
|
+
;[profile, keyManager, lsp7, lsp8, lsp9, lsp26, burntPix].forEach((p) => p)
|
|
23
|
+
|
|
24
|
+
import type { Hex } from 'viem'
|
|
25
|
+
import type {
|
|
26
|
+
DecoderOptions,
|
|
27
|
+
DecoderPlugin,
|
|
28
|
+
Info,
|
|
29
|
+
ResultSetData,
|
|
30
|
+
SchemaPlugin,
|
|
31
|
+
} from '../types'
|
|
32
|
+
import { getArgByName } from '../utils'
|
|
33
|
+
|
|
34
|
+
export const defaultPlugins: ReadonlyArray<DecoderPlugin> = Object.freeze([
|
|
35
|
+
graffiti,
|
|
36
|
+
keyManager,
|
|
37
|
+
profile,
|
|
38
|
+
lsp7,
|
|
39
|
+
lsp8,
|
|
40
|
+
lsp9,
|
|
41
|
+
lsp26,
|
|
42
|
+
abiRetrieve,
|
|
43
|
+
burntPix,
|
|
44
|
+
])
|
|
45
|
+
|
|
46
|
+
export const defaultSchemaPlugins: ReadonlyArray<SchemaPlugin> = Object.freeze([
|
|
47
|
+
schemaDefaultPlugin,
|
|
48
|
+
])
|
|
49
|
+
|
|
50
|
+
export default defaultPlugins
|
|
51
|
+
|
|
52
|
+
export async function decodeKeyValue(
|
|
53
|
+
result: ResultSetData,
|
|
54
|
+
options: DecoderOptions
|
|
55
|
+
): Promise<Info | undefined> {
|
|
56
|
+
const key: Hex = (getArgByName(result.args, 'key') as Hex) ?? '0x'
|
|
57
|
+
const value: Hex = (getArgByName(result.args, 'value') as Hex) ?? '0x'
|
|
58
|
+
return await decodeKeyValueRaw(key, value, options)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function decodeKeyValueRaw(
|
|
62
|
+
key: Hex,
|
|
63
|
+
value: Hex,
|
|
64
|
+
options: DecoderOptions
|
|
65
|
+
): Promise<Info | undefined> {
|
|
66
|
+
for (const schemaPlugin of options.schemaPlugins) {
|
|
67
|
+
try {
|
|
68
|
+
const output = await schemaPlugin(key, value)
|
|
69
|
+
if (output) {
|
|
70
|
+
return output
|
|
71
|
+
}
|
|
72
|
+
} catch {}
|
|
73
|
+
}
|
|
74
|
+
return undefined
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Import registry and register default plugins when this module loads
|
|
78
|
+
import { pluginRegistry } from '../registry'
|
|
79
|
+
|
|
80
|
+
// Register graffiti manually since it doesn't use standardPlugin
|
|
81
|
+
pluginRegistry.register('graffiti', graffiti, {
|
|
82
|
+
priority: 100,
|
|
83
|
+
required: false,
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// Register abiRetrieve manually with async flag
|
|
87
|
+
pluginRegistry.register('abiRetrieve', abiRetrieve, {
|
|
88
|
+
priority: 1,
|
|
89
|
+
required: false,
|
|
90
|
+
usesAsync: true,
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// Register default schema plugin
|
|
94
|
+
pluginRegistry.registerSchema('default-schema', schemaDefaultPlugin, {
|
|
95
|
+
priority: 100,
|
|
96
|
+
required: false,
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// Note: Other plugins using standardPlugin will auto-register when imported
|