@lukso/transaction-decoder 1.3.6-dev.4a582bd → 1.3.6-dev.637d4ef
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 +203 -13
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js +4 -4
- package/dist/cdn/transaction-decoder.global.js +75 -75
- package/dist/cdn/transaction-decoder.global.js.map +1 -1
- package/dist/{chunk-FKBKAWB3.js → chunk-HFBAO6YR.js} +2 -2
- package/dist/{chunk-T4H2HHIB.js → chunk-MGPLCACC.js} +198 -8
- package/dist/chunk-MGPLCACC.js.map +1 -0
- package/dist/{chunk-SSY7TTU2.js → chunk-MSTGEOTX.js} +4 -4
- package/dist/{chunk-NDBDNXBI.js → chunk-RYQVLCCC.js} +2 -2
- package/dist/data.cjs +197 -7
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.cts +3 -3
- package/dist/data.d.ts +3 -3
- package/dist/data.js +2 -2
- package/dist/{index-BzXh7poJ.d.ts → index-BWD9DaG6.d.cts} +6 -1
- package/dist/{index-BzXh7poJ.d.cts → index-BWD9DaG6.d.ts} +6 -1
- package/dist/index.cjs +203 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -4
- package/dist/server.cjs +197 -7
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +2 -2
- package/dist/{utils-De_c6fUK.d.ts → utils-4Qdavg8r.d.ts} +2 -2
- package/dist/{utils-BEpSreRR.d.cts → utils-OR-XzeYG.d.cts} +2 -2
- package/package.json +8 -8
- package/src/decoder/lsp7Mint.test.ts +18 -11
- package/src/decoder/plugins/enhanceLSP0ERC725Account.ts +39 -2
- package/src/decoder/plugins/universalReceiverTypeIds.ts +277 -0
- package/src/decoder/types.ts +2 -0
- package/dist/chunk-T4H2HHIB.js.map +0 -1
- /package/dist/{chunk-FKBKAWB3.js.map → chunk-HFBAO6YR.js.map} +0 -0
- /package/dist/{chunk-SSY7TTU2.js.map → chunk-MSTGEOTX.js.map} +0 -0
- /package/dist/{chunk-NDBDNXBI.js.map → chunk-RYQVLCCC.js.map} +0 -0
package/dist/server.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Chain, Abi } from 'viem';
|
|
2
|
-
import {
|
|
2
|
+
import { c as DecoderResult, b as DataKey, E as EnhancedInfo, e as Info } from './index-BWD9DaG6.cjs';
|
|
3
3
|
import '@preact/signals-core';
|
|
4
4
|
import '@erc725/erc725.js';
|
|
5
5
|
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Chain, Abi } from 'viem';
|
|
2
|
-
import {
|
|
2
|
+
import { c as DecoderResult, b as DataKey, E as EnhancedInfo, e as Info } from './index-BWD9DaG6.js';
|
|
3
3
|
import '@preact/signals-core';
|
|
4
4
|
import '@erc725/erc725.js';
|
|
5
5
|
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
fetchMultipleAddresses
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HFBAO6YR.js";
|
|
4
4
|
import {
|
|
5
5
|
__name,
|
|
6
6
|
collectDataKeys,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
decodeTransaction,
|
|
9
9
|
needsEnhancement,
|
|
10
10
|
pluginRegistry
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MGPLCACC.js";
|
|
12
12
|
|
|
13
13
|
// src/server/addressResolver.ts
|
|
14
14
|
var ServerAddressResolver = class {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as IDataModelConsumer, I as IDataModel,
|
|
1
|
+
import { g as IDataModelConsumer, I as IDataModel, b as DataKey, c as DecoderResult, T as TransactionState, h as DecoderOptions, P as PluginOptions, i as EnhancerCallback, j as DecodeEventCallback, k as EnhancerAggregationKeyCallback, l as EnhancerSummarizeCallback, m as Aggregation, n as DecoderPlugin, e as Info, S as SchemaPlugin, o as ResultSetData, A as ArrayArgs, C as CustomDecodeFunctionDataReturn, E as EnhancedInfo } from './index-BWD9DaG6.js';
|
|
2
2
|
import { Signal } from '@preact/signals-core';
|
|
3
3
|
import { Transaction, Abi, Hex, AbiParameter, DecodeFunctionDataParameters, Address, Chain, PublicClient } from 'viem';
|
|
4
4
|
import { ERC725JSONSchema } from '@erc725/erc725.js';
|
|
@@ -105,4 +105,4 @@ declare function getPublicClient(chain: Chain): PublicClient;
|
|
|
105
105
|
*/
|
|
106
106
|
declare function needsEnhancement(result: DecoderResult): boolean;
|
|
107
107
|
|
|
108
|
-
export { type AddressResolver as A, type TransactionDecoderResult as T,
|
|
108
|
+
export { type AddressResolver as A, type TransactionDecoderResult as T, customDecodeFunctionData as a, decodeKeyValue as b, createNamedArgs as c, dataModel as d, decodeKeyValueRaw as e, decodeTransaction as f, extractAddress as g, getPublicClient as h, consumerModel as i, createAggregationKey as j, createGlobalInstance as k, decodeTransactionAsync as l, defaultPlugins as m, defaultSchemaPlugins as n, getArgByName as o, needsEnhancement as p, standardPlugin as q, standardSchemaPlugin as s };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as IDataModelConsumer, I as IDataModel,
|
|
1
|
+
import { g as IDataModelConsumer, I as IDataModel, b as DataKey, c as DecoderResult, T as TransactionState, h as DecoderOptions, P as PluginOptions, i as EnhancerCallback, j as DecodeEventCallback, k as EnhancerAggregationKeyCallback, l as EnhancerSummarizeCallback, m as Aggregation, n as DecoderPlugin, e as Info, S as SchemaPlugin, o as ResultSetData, A as ArrayArgs, C as CustomDecodeFunctionDataReturn, E as EnhancedInfo } from './index-BWD9DaG6.cjs';
|
|
2
2
|
import { Signal } from '@preact/signals-core';
|
|
3
3
|
import { Transaction, Abi, Hex, AbiParameter, DecodeFunctionDataParameters, Address, Chain, PublicClient } from 'viem';
|
|
4
4
|
import { ERC725JSONSchema } from '@erc725/erc725.js';
|
|
@@ -105,4 +105,4 @@ declare function getPublicClient(chain: Chain): PublicClient;
|
|
|
105
105
|
*/
|
|
106
106
|
declare function needsEnhancement(result: DecoderResult): boolean;
|
|
107
107
|
|
|
108
|
-
export { type AddressResolver as A, type TransactionDecoderResult as T,
|
|
108
|
+
export { type AddressResolver as A, type TransactionDecoderResult as T, customDecodeFunctionData as a, decodeKeyValue as b, createNamedArgs as c, dataModel as d, decodeKeyValueRaw as e, decodeTransaction as f, extractAddress as g, getPublicClient as h, consumerModel as i, createAggregationKey as j, createGlobalInstance as k, decodeTransactionAsync as l, defaultPlugins as m, defaultSchemaPlugins as n, getArgByName as o, needsEnhancement as p, standardPlugin as q, standardSchemaPlugin as s };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukso/transaction-decoder",
|
|
3
|
-
"version": "1.3.6-dev.
|
|
3
|
+
"version": "1.3.6-dev.637d4ef",
|
|
4
4
|
"description": "Transaction decoder for LUKSO blockchain with reactive state management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -47,19 +47,19 @@
|
|
|
47
47
|
"@lukso/lsp8-contracts": "0.16.7",
|
|
48
48
|
"@lukso/lsp9-contracts": "0.15.5",
|
|
49
49
|
"@lukso/universalprofile-contracts": "0.15.5",
|
|
50
|
-
"@preact/signals-core": "^1.
|
|
50
|
+
"@preact/signals-core": "^1.13.0",
|
|
51
51
|
"graphql-request": "^7.4.0",
|
|
52
|
-
"graphql-ws": "^6.0.
|
|
53
|
-
"lru-cache": "^11.2.
|
|
54
|
-
"viem": "^2.
|
|
52
|
+
"graphql-ws": "^6.0.7",
|
|
53
|
+
"lru-cache": "^11.2.6",
|
|
54
|
+
"viem": "^2.46.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@biomejs/biome": "^2.
|
|
57
|
+
"@biomejs/biome": "^2.4.2",
|
|
58
58
|
"@types/debug": "^4.1.12",
|
|
59
|
-
"@types/node": "^25.
|
|
59
|
+
"@types/node": "^25.2.3",
|
|
60
60
|
"tsup": "^8.5.1",
|
|
61
61
|
"typescript": "^5.9.3",
|
|
62
|
-
"vitest": "^4.0.
|
|
62
|
+
"vitest": "^4.0.18"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"viem": "^2.0.0"
|
|
@@ -145,24 +145,31 @@ describe('LSP7 Mint Transaction Decoding', () => {
|
|
|
145
145
|
expect(dataChangedLogs.length).toBeGreaterThan(0)
|
|
146
146
|
console.log(`\nFound ${dataChangedLogs.length} DataChanged events`)
|
|
147
147
|
|
|
148
|
-
// Look for
|
|
149
|
-
// UniversalReceiver
|
|
150
|
-
const
|
|
151
|
-
(log: any) =>
|
|
148
|
+
// Look for unwrapped URDTokensReceived event from UniversalReceiver (confirms the mint was received)
|
|
149
|
+
// The UniversalReceiver event is now unwrapped into URDTokensReceived with standard: LSP7DigitalAsset
|
|
150
|
+
const unwrappedTransferLog = result?.logs?.find(
|
|
151
|
+
(log: any) =>
|
|
152
|
+
log.eventName === 'URDTokensReceived' &&
|
|
153
|
+
log.standard === 'LSP7DigitalAsset'
|
|
152
154
|
)
|
|
153
|
-
expect(
|
|
154
|
-
expect(
|
|
155
|
+
expect(unwrappedTransferLog).toBeDefined()
|
|
156
|
+
expect(unwrappedTransferLog?.address).toBe(
|
|
155
157
|
'0xda9b727f1718f128008ad025828e7fecfaa8a37b'
|
|
156
158
|
) // LSP7 token contract
|
|
157
159
|
|
|
158
|
-
// Verify the UniversalReceiver
|
|
159
|
-
|
|
160
|
-
expect(
|
|
160
|
+
// Verify the original UniversalReceiver is preserved in wrappers
|
|
161
|
+
const wrapper = (unwrappedTransferLog as any)?.wrappers?.[0]
|
|
162
|
+
expect(wrapper).toBeDefined()
|
|
163
|
+
expect(wrapper?.eventName).toBe('UniversalReceiver')
|
|
164
|
+
|
|
165
|
+
// Verify the UniversalReceiver typeId indicates this is a mint recipient notification
|
|
166
|
+
// typeId 0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c = _TYPEID_LSP7_TOKENSRECIPIENT
|
|
167
|
+
expect(wrapper?.args?.[2]?.value).toBe(
|
|
161
168
|
'0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c'
|
|
162
169
|
)
|
|
163
170
|
|
|
164
|
-
// Verify the 'from' address in
|
|
165
|
-
expect(
|
|
171
|
+
// Verify the 'from' address in the wrapper (the minter, which is the UP)
|
|
172
|
+
expect(wrapper?.args?.[0]?.value).toBe(
|
|
166
173
|
'0x81A904879F657142d9b5C7e875c786717e2125c0'
|
|
167
174
|
)
|
|
168
175
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { universalProfileAbi as UniversalProfile } from '@lukso/universalprofile-contracts/abi'
|
|
2
|
-
import type { Address } from 'viem'
|
|
2
|
+
import type { Address, Hex, Log } from 'viem'
|
|
3
3
|
import { decodeEvent } from '../events'
|
|
4
4
|
import { decodeTransaction } from '../transaction'
|
|
5
5
|
import type {
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
import { createNamedArgs } from '../utils'
|
|
16
16
|
import { standardPlugin } from '.'
|
|
17
17
|
import { enhanceSetData } from './enhanceSetData'
|
|
18
|
+
import { unwrapUniversalReceiver } from './universalReceiverTypeIds'
|
|
18
19
|
|
|
19
20
|
export const enhanceLSP0ERC725AccountPlugin = standardPlugin(
|
|
20
21
|
UniversalProfile,
|
|
@@ -26,7 +27,43 @@ export const enhanceLSP0ERC725AccountPlugin = standardPlugin(
|
|
|
26
27
|
{
|
|
27
28
|
enhance: enhanceLSP0ERC725Account,
|
|
28
29
|
decodeEvent: async (log: DecodeEventResult, options: DecoderOptions) => {
|
|
29
|
-
|
|
30
|
+
const decoded = decodeEvent(options.chain, UniversalProfile, log)
|
|
31
|
+
if (!decoded || decoded.eventName !== 'UniversalReceiver') {
|
|
32
|
+
return decoded
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Extract UniversalReceiver args
|
|
36
|
+
const typeId = decoded.args.find((a) => a.name === 'typeId')?.value as Hex
|
|
37
|
+
const receivedData = decoded.args.find((a) => a.name === 'receivedData')
|
|
38
|
+
?.value as Hex
|
|
39
|
+
const from = decoded.args.find((a) => a.name === 'from')?.value as Address
|
|
40
|
+
const profileAddress = (decoded as unknown as Log).address as Address
|
|
41
|
+
|
|
42
|
+
if (!typeId || !receivedData || !from) {
|
|
43
|
+
return decoded
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Unwrap based on typeId (always succeeds — falls back to generic Notification)
|
|
47
|
+
const unwrapped = unwrapUniversalReceiver(
|
|
48
|
+
typeId,
|
|
49
|
+
receivedData,
|
|
50
|
+
from,
|
|
51
|
+
profileAddress
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// Rewrite the event: inner event becomes the main event,
|
|
55
|
+
// original UniversalReceiver goes into wrappers.
|
|
56
|
+
// Topics and data are rewritten to match the inner event's ABI.
|
|
57
|
+
const { wrappers: _w, standard: _s, ...logBase } = decoded
|
|
58
|
+
return {
|
|
59
|
+
...logBase,
|
|
60
|
+
eventName: unwrapped.eventName,
|
|
61
|
+
args: unwrapped.args,
|
|
62
|
+
standard: unwrapped.standard,
|
|
63
|
+
topics: unwrapped.topics,
|
|
64
|
+
data: unwrapped.data,
|
|
65
|
+
wrappers: [logBase],
|
|
66
|
+
} as DecodeEventResult
|
|
30
67
|
},
|
|
31
68
|
}
|
|
32
69
|
)
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type { AbiParameter, Address, Hex } from 'viem'
|
|
2
|
+
import {
|
|
3
|
+
decodeAbiParameters,
|
|
4
|
+
encodeAbiParameters,
|
|
5
|
+
getAddress,
|
|
6
|
+
keccak256,
|
|
7
|
+
slice,
|
|
8
|
+
toHex,
|
|
9
|
+
} from 'viem'
|
|
10
|
+
import type { ArrayArgs } from '../types'
|
|
11
|
+
import { createNamedArgs } from '../utils'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Result of unwrapping a UniversalReceiver event based on its typeId.
|
|
15
|
+
* Contains the inner event that was wrapped by the UniversalReceiver notification,
|
|
16
|
+
* including rewritten topics and data fields matching the inner event's ABI.
|
|
17
|
+
*/
|
|
18
|
+
export type UnwrapResult = {
|
|
19
|
+
eventName: string
|
|
20
|
+
args: ArrayArgs
|
|
21
|
+
standard?: string
|
|
22
|
+
topics: [Hex, ...Hex[]]
|
|
23
|
+
data: Hex
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type UnwrapFn = (
|
|
27
|
+
receivedData: Hex,
|
|
28
|
+
from: Address,
|
|
29
|
+
profileAddress: Address,
|
|
30
|
+
eventName: string
|
|
31
|
+
) => UnwrapResult | undefined
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Compute topic0 (event signature hash) and ABI-encode the data field
|
|
35
|
+
* for an event with all non-indexed parameters.
|
|
36
|
+
*/
|
|
37
|
+
function encodeEventLog(
|
|
38
|
+
eventName: string,
|
|
39
|
+
params: AbiParameter[],
|
|
40
|
+
values: unknown[]
|
|
41
|
+
): { topics: [Hex, ...Hex[]]; data: Hex } {
|
|
42
|
+
const sig = `${eventName}(${params.map((p) => p.type).join(',')})`
|
|
43
|
+
const topic0 = keccak256(toHex(sig))
|
|
44
|
+
const data = encodeAbiParameters(params, values)
|
|
45
|
+
return { topics: [topic0], data }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// --- LSP26 FollowerSystem ---
|
|
49
|
+
|
|
50
|
+
// keccak256('LSP26FollowerSystem_FollowNotification')
|
|
51
|
+
const TYPEID_LSP26_FOLLOW: Hex =
|
|
52
|
+
'0x71e02f9f05bcd5816ec4f3134aa2e5a916669537ec6c77fe66ea595fabc2d51a'
|
|
53
|
+
|
|
54
|
+
// keccak256('LSP26FollowerSystem_UnfollowNotification')
|
|
55
|
+
const TYPEID_LSP26_UNFOLLOW: Hex =
|
|
56
|
+
'0x9d3c0b4012b69658977b099bdaa51eff0f0460f421fba96d15669506c00d1c4f'
|
|
57
|
+
|
|
58
|
+
// --- LSP7 DigitalAsset ---
|
|
59
|
+
|
|
60
|
+
// keccak256('LSP7Tokens_SenderNotification')
|
|
61
|
+
const TYPEID_LSP7_TOKENSSENDER: Hex =
|
|
62
|
+
'0x429ac7a06903dbc9c13dfcb3c9d11df8194581fa047c96d7a4171fc7402958ea'
|
|
63
|
+
|
|
64
|
+
// keccak256('LSP7Tokens_RecipientNotification')
|
|
65
|
+
const TYPEID_LSP7_TOKENSRECIPIENT: Hex =
|
|
66
|
+
'0x20804611b3e2ea21c480dc465142210acf4a2485947541770ec1fb87dee4a55c'
|
|
67
|
+
|
|
68
|
+
// --- LSP8 IdentifiableDigitalAsset ---
|
|
69
|
+
|
|
70
|
+
// keccak256('LSP8Tokens_SenderNotification')
|
|
71
|
+
const TYPEID_LSP8_TOKENSSENDER: Hex =
|
|
72
|
+
'0xb23eae7e6d1564b295b4c3e3be402d9a2f0776c57bdf365903496f6fa481ab00'
|
|
73
|
+
|
|
74
|
+
// keccak256('LSP8Tokens_RecipientNotification')
|
|
75
|
+
const TYPEID_LSP8_TOKENSRECIPIENT: Hex =
|
|
76
|
+
'0x0b084a55ebf70fd3c06fd755269dac2212c4d3f0f4d09079780bfa50c1b2984d'
|
|
77
|
+
|
|
78
|
+
// --- Event parameter definitions ---
|
|
79
|
+
|
|
80
|
+
const followParams: AbiParameter[] = [
|
|
81
|
+
{ name: 'follower', type: 'address' },
|
|
82
|
+
{ name: 'addr', type: 'address' },
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
const unfollowParams: AbiParameter[] = [
|
|
86
|
+
{ name: 'unfollower', type: 'address' },
|
|
87
|
+
{ name: 'addr', type: 'address' },
|
|
88
|
+
]
|
|
89
|
+
|
|
90
|
+
const lsp7TransferParams: AbiParameter[] = [
|
|
91
|
+
{ name: 'operator', type: 'address' },
|
|
92
|
+
{ name: 'from', type: 'address' },
|
|
93
|
+
{ name: 'to', type: 'address' },
|
|
94
|
+
{ name: 'amount', type: 'uint256' },
|
|
95
|
+
{ name: 'force', type: 'bool' },
|
|
96
|
+
{ name: 'data', type: 'bytes' },
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
const lsp8TransferParams: AbiParameter[] = [
|
|
100
|
+
{ name: 'operator', type: 'address' },
|
|
101
|
+
{ name: 'from', type: 'address' },
|
|
102
|
+
{ name: 'to', type: 'address' },
|
|
103
|
+
{ name: 'tokenId', type: 'bytes32' },
|
|
104
|
+
{ name: 'force', type: 'bool' },
|
|
105
|
+
{ name: 'data', type: 'bytes' },
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
const notificationParams: AbiParameter[] = [
|
|
109
|
+
{ name: 'from', type: 'address' },
|
|
110
|
+
{ name: 'typeId', type: 'bytes32' },
|
|
111
|
+
{ name: 'data', type: 'bytes' },
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Decode LSP26 Follow notification.
|
|
116
|
+
* receivedData is abi.encodePacked(followerAddress) — raw 20 bytes.
|
|
117
|
+
*/
|
|
118
|
+
function unwrapLSP26Follow(
|
|
119
|
+
receivedData: Hex,
|
|
120
|
+
_from: Address,
|
|
121
|
+
profileAddress: Address,
|
|
122
|
+
_eventName: string
|
|
123
|
+
): UnwrapResult | undefined {
|
|
124
|
+
if (!receivedData || receivedData.length < 42) {
|
|
125
|
+
return undefined
|
|
126
|
+
}
|
|
127
|
+
const followerAddress = getAddress(slice(receivedData, 0, 20))
|
|
128
|
+
const values = [followerAddress, profileAddress]
|
|
129
|
+
return {
|
|
130
|
+
eventName: 'URDFollow',
|
|
131
|
+
...createNamedArgs(values, followParams),
|
|
132
|
+
...encodeEventLog('URDFollow', followParams, values),
|
|
133
|
+
standard: 'LSP26FollowerSystem',
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Decode LSP26 Unfollow notification.
|
|
139
|
+
* receivedData is abi.encodePacked(unfollowerAddress) — raw 20 bytes.
|
|
140
|
+
*/
|
|
141
|
+
function unwrapLSP26Unfollow(
|
|
142
|
+
receivedData: Hex,
|
|
143
|
+
_from: Address,
|
|
144
|
+
profileAddress: Address,
|
|
145
|
+
_eventName: string
|
|
146
|
+
): UnwrapResult | undefined {
|
|
147
|
+
if (!receivedData || receivedData.length < 42) {
|
|
148
|
+
return undefined
|
|
149
|
+
}
|
|
150
|
+
const unfollowerAddress = getAddress(slice(receivedData, 0, 20))
|
|
151
|
+
const values = [unfollowerAddress, profileAddress]
|
|
152
|
+
return {
|
|
153
|
+
eventName: 'URDUnfollow',
|
|
154
|
+
...createNamedArgs(values, unfollowParams),
|
|
155
|
+
...encodeEventLog('URDUnfollow', unfollowParams, values),
|
|
156
|
+
standard: 'LSP26FollowerSystem',
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Decode LSP7 token transfer notification.
|
|
162
|
+
* receivedData is abi.encode(operator, from, to, amount, data).
|
|
163
|
+
*/
|
|
164
|
+
function unwrapLSP7Transfer(
|
|
165
|
+
receivedData: Hex,
|
|
166
|
+
_from: Address,
|
|
167
|
+
_profileAddress: Address,
|
|
168
|
+
eventName: string
|
|
169
|
+
): UnwrapResult | undefined {
|
|
170
|
+
try {
|
|
171
|
+
const [operator, sender, recipient, amount, data] = decodeAbiParameters(
|
|
172
|
+
[
|
|
173
|
+
{ name: 'operator', type: 'address' },
|
|
174
|
+
{ name: 'from', type: 'address' },
|
|
175
|
+
{ name: 'to', type: 'address' },
|
|
176
|
+
{ name: 'amount', type: 'uint256' },
|
|
177
|
+
{ name: 'data', type: 'bytes' },
|
|
178
|
+
],
|
|
179
|
+
receivedData
|
|
180
|
+
)
|
|
181
|
+
const values = [operator, sender, recipient, amount, true, data]
|
|
182
|
+
return {
|
|
183
|
+
eventName,
|
|
184
|
+
...createNamedArgs(values, lsp7TransferParams),
|
|
185
|
+
...encodeEventLog(eventName, lsp7TransferParams, values),
|
|
186
|
+
standard: 'LSP7DigitalAsset',
|
|
187
|
+
}
|
|
188
|
+
} catch {
|
|
189
|
+
return undefined
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Decode LSP8 token transfer notification.
|
|
195
|
+
* receivedData is abi.encode(operator, from, to, tokenId, data).
|
|
196
|
+
*/
|
|
197
|
+
function unwrapLSP8Transfer(
|
|
198
|
+
receivedData: Hex,
|
|
199
|
+
_from: Address,
|
|
200
|
+
_profileAddress: Address,
|
|
201
|
+
eventName: string
|
|
202
|
+
): UnwrapResult | undefined {
|
|
203
|
+
try {
|
|
204
|
+
const [operator, sender, recipient, tokenId, data] = decodeAbiParameters(
|
|
205
|
+
[
|
|
206
|
+
{ name: 'operator', type: 'address' },
|
|
207
|
+
{ name: 'from', type: 'address' },
|
|
208
|
+
{ name: 'to', type: 'address' },
|
|
209
|
+
{ name: 'tokenId', type: 'bytes32' },
|
|
210
|
+
{ name: 'data', type: 'bytes' },
|
|
211
|
+
],
|
|
212
|
+
receivedData
|
|
213
|
+
)
|
|
214
|
+
const values = [operator, sender, recipient, tokenId, true, data]
|
|
215
|
+
return {
|
|
216
|
+
eventName,
|
|
217
|
+
...createNamedArgs(values, lsp8TransferParams),
|
|
218
|
+
...encodeEventLog(eventName, lsp8TransferParams, values),
|
|
219
|
+
standard: 'LSP8IdentifiableDigitalAsset',
|
|
220
|
+
}
|
|
221
|
+
} catch {
|
|
222
|
+
return undefined
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Registry mapping typeId → unwrap function.
|
|
228
|
+
*/
|
|
229
|
+
const typeIdUnwrappers: Record<Hex, { fn: UnwrapFn; eventName: string }> = {
|
|
230
|
+
[TYPEID_LSP26_FOLLOW]: { fn: unwrapLSP26Follow, eventName: 'Follow' },
|
|
231
|
+
[TYPEID_LSP26_UNFOLLOW]: { fn: unwrapLSP26Unfollow, eventName: 'Unfollow' },
|
|
232
|
+
[TYPEID_LSP7_TOKENSSENDER]: {
|
|
233
|
+
fn: unwrapLSP7Transfer,
|
|
234
|
+
eventName: 'URDTokensSent',
|
|
235
|
+
},
|
|
236
|
+
[TYPEID_LSP7_TOKENSRECIPIENT]: {
|
|
237
|
+
fn: unwrapLSP7Transfer,
|
|
238
|
+
eventName: 'URDTokensReceived',
|
|
239
|
+
},
|
|
240
|
+
[TYPEID_LSP8_TOKENSSENDER]: {
|
|
241
|
+
fn: unwrapLSP8Transfer,
|
|
242
|
+
eventName: 'URDTokensSent',
|
|
243
|
+
},
|
|
244
|
+
[TYPEID_LSP8_TOKENSRECIPIENT]: {
|
|
245
|
+
fn: unwrapLSP8Transfer,
|
|
246
|
+
eventName: 'URDTokensReceived',
|
|
247
|
+
},
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Unwrap a UniversalReceiver event based on its typeId.
|
|
252
|
+
* For known typeIds, decodes receivedData into specific event args.
|
|
253
|
+
* For unknown typeIds, returns a generic Notification with raw receivedData.
|
|
254
|
+
* Always rewrites topics and data to match the inner event's ABI.
|
|
255
|
+
*/
|
|
256
|
+
export function unwrapUniversalReceiver(
|
|
257
|
+
typeId: Hex,
|
|
258
|
+
receivedData: Hex,
|
|
259
|
+
from: Address,
|
|
260
|
+
profileAddress: Address
|
|
261
|
+
): UnwrapResult {
|
|
262
|
+
const entry = typeIdUnwrappers[typeId]
|
|
263
|
+
if (entry) {
|
|
264
|
+
const result = entry.fn(receivedData, from, profileAddress, entry.eventName)
|
|
265
|
+
if (result) {
|
|
266
|
+
return result
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Fallback: generic notification with raw data
|
|
271
|
+
const values = [from, typeId, receivedData]
|
|
272
|
+
return {
|
|
273
|
+
eventName: 'URDNotification',
|
|
274
|
+
...createNamedArgs(values, notificationParams),
|
|
275
|
+
...encodeEventLog('Notification', notificationParams, values),
|
|
276
|
+
}
|
|
277
|
+
}
|