viem 2.0.10 → 2.1.1
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/CHANGELOG.md +20 -0
- package/_cjs/chains/definitions/baseSepolia.js +4 -0
- package/_cjs/chains/definitions/baseSepolia.js.map +1 -1
- package/_cjs/chains/definitions/holesky.js +6 -0
- package/_cjs/chains/definitions/holesky.js.map +1 -1
- package/_cjs/chains/definitions/lightlinkPegasus.js +30 -0
- package/_cjs/chains/definitions/lightlinkPegasus.js.map +1 -0
- package/_cjs/chains/definitions/lightlinkPhoenix.js +30 -0
- package/_cjs/chains/definitions/lightlinkPhoenix.js.map +1 -0
- package/_cjs/chains/definitions/neonMainnet.js +6 -1
- package/_cjs/chains/definitions/neonMainnet.js.map +1 -1
- package/_cjs/chains/definitions/palm.js +32 -0
- package/_cjs/chains/definitions/palm.js.map +1 -0
- package/_cjs/chains/definitions/palmTestnet.js +33 -0
- package/_cjs/chains/definitions/palmTestnet.js.map +1 -0
- package/_cjs/chains/index.js +11 -3
- package/_cjs/chains/index.js.map +1 -1
- package/_cjs/errors/cursor.js +13 -1
- package/_cjs/errors/cursor.js.map +1 -1
- package/_cjs/errors/version.js +1 -1
- package/_cjs/errors/version.js.map +1 -1
- package/_cjs/utils/abi/decodeAbiParameters.js +117 -126
- package/_cjs/utils/abi/decodeAbiParameters.js.map +1 -1
- package/_cjs/utils/abi/decodeEventLog.js +7 -4
- package/_cjs/utils/abi/decodeEventLog.js.map +1 -1
- package/_cjs/utils/cursor.js +40 -3
- package/_cjs/utils/cursor.js.map +1 -1
- package/_cjs/utils/encoding/fromBytes.js +2 -2
- package/_cjs/utils/encoding/fromBytes.js.map +1 -1
- package/_cjs/utils/encoding/fromRlp.js +1 -1
- package/_cjs/utils/encoding/fromRlp.js.map +1 -1
- package/_esm/chains/definitions/baseSepolia.js +4 -0
- package/_esm/chains/definitions/baseSepolia.js.map +1 -1
- package/_esm/chains/definitions/holesky.js +6 -0
- package/_esm/chains/definitions/holesky.js.map +1 -1
- package/_esm/chains/definitions/lightlinkPegasus.js +27 -0
- package/_esm/chains/definitions/lightlinkPegasus.js.map +1 -0
- package/_esm/chains/definitions/lightlinkPhoenix.js +27 -0
- package/_esm/chains/definitions/lightlinkPhoenix.js.map +1 -0
- package/_esm/chains/definitions/neonMainnet.js +6 -1
- package/_esm/chains/definitions/neonMainnet.js.map +1 -1
- package/_esm/chains/definitions/palm.js +29 -0
- package/_esm/chains/definitions/palm.js.map +1 -0
- package/_esm/chains/definitions/palmTestnet.js +30 -0
- package/_esm/chains/definitions/palmTestnet.js.map +1 -0
- package/_esm/chains/index.js +4 -0
- package/_esm/chains/index.js.map +1 -1
- package/_esm/errors/cursor.js +11 -0
- package/_esm/errors/cursor.js.map +1 -1
- package/_esm/errors/version.js +1 -1
- package/_esm/errors/version.js.map +1 -1
- package/_esm/utils/abi/decodeAbiParameters.js +145 -140
- package/_esm/utils/abi/decodeAbiParameters.js.map +1 -1
- package/_esm/utils/abi/decodeEventLog.js +7 -4
- package/_esm/utils/abi/decodeEventLog.js.map +1 -1
- package/_esm/utils/cursor.js +41 -4
- package/_esm/utils/cursor.js.map +1 -1
- package/_esm/utils/encoding/fromBytes.js +2 -2
- package/_esm/utils/encoding/fromBytes.js.map +1 -1
- package/_esm/utils/encoding/fromRlp.js +1 -1
- package/_esm/utils/encoding/fromRlp.js.map +1 -1
- package/_types/chains/definitions/baseSepolia.d.ts +4 -0
- package/_types/chains/definitions/baseSepolia.d.ts.map +1 -1
- package/_types/chains/definitions/holesky.d.ts +5 -11
- package/_types/chains/definitions/holesky.d.ts.map +1 -1
- package/_types/chains/definitions/lightlinkPegasus.d.ts +35 -0
- package/_types/chains/definitions/lightlinkPegasus.d.ts.map +1 -0
- package/_types/chains/definitions/lightlinkPhoenix.d.ts +35 -0
- package/_types/chains/definitions/lightlinkPhoenix.d.ts.map +1 -0
- package/_types/chains/definitions/neonMainnet.d.ts +6 -1
- package/_types/chains/definitions/neonMainnet.d.ts.map +1 -1
- package/_types/chains/definitions/palm.d.ts +33 -0
- package/_types/chains/definitions/palm.d.ts.map +1 -0
- package/_types/chains/definitions/palmTestnet.d.ts +33 -0
- package/_types/chains/definitions/palmTestnet.d.ts.map +1 -0
- package/_types/chains/index.d.ts +4 -0
- package/_types/chains/index.d.ts.map +1 -1
- package/_types/errors/cursor.d.ts +10 -0
- package/_types/errors/cursor.d.ts.map +1 -1
- package/_types/errors/version.d.ts +1 -1
- package/_types/errors/version.d.ts.map +1 -1
- package/_types/utils/abi/decodeAbiParameters.d.ts +18 -19
- package/_types/utils/abi/decodeAbiParameters.d.ts.map +1 -1
- package/_types/utils/abi/decodeEventLog.d.ts.map +1 -1
- package/_types/utils/cursor.d.ts +13 -3
- package/_types/utils/cursor.d.ts.map +1 -1
- package/chains/definitions/baseSepolia.ts +4 -0
- package/chains/definitions/holesky.ts +6 -0
- package/chains/definitions/lightlinkPegasus.ts +27 -0
- package/chains/definitions/lightlinkPhoenix.ts +27 -0
- package/chains/definitions/neonMainnet.ts +6 -1
- package/chains/definitions/palm.ts +29 -0
- package/chains/definitions/palmTestnet.ts +30 -0
- package/chains/index.ts +4 -0
- package/errors/cursor.ts +13 -0
- package/errors/version.ts +1 -1
- package/package.json +1 -1
- package/utils/abi/decodeAbiParameters.ts +226 -249
- package/utils/abi/decodeEventLog.ts +9 -4
- package/utils/cursor.ts +53 -6
- package/utils/encoding/fromBytes.ts +2 -2
- package/utils/encoding/fromRlp.ts +1 -1
@@ -1,341 +1,284 @@
|
|
1
|
-
import type {
|
2
|
-
|
3
|
-
|
4
|
-
AbiParametersToPrimitiveTypes,
|
5
|
-
} from 'abitype'
|
1
|
+
import type { AbiParameter, AbiParametersToPrimitiveTypes } from 'abitype'
|
2
|
+
|
3
|
+
import type { ByteArray, Hex } from '../../types/misc.js'
|
6
4
|
|
7
5
|
import {
|
8
6
|
AbiDecodingDataSizeTooSmallError,
|
9
|
-
type AbiDecodingDataSizeTooSmallErrorType,
|
10
|
-
AbiDecodingOffsetOutOfBoundsError,
|
11
7
|
AbiDecodingZeroDataError,
|
12
|
-
type AbiDecodingZeroDataErrorType,
|
13
8
|
InvalidAbiDecodingTypeError,
|
14
9
|
type InvalidAbiDecodingTypeErrorType,
|
15
10
|
} from '../../errors/abi.js'
|
16
|
-
import type {
|
11
|
+
import type { ErrorType } from '../../errors/utils.js'
|
17
12
|
import {
|
18
13
|
type ChecksumAddressErrorType,
|
19
14
|
checksumAddress,
|
20
15
|
} from '../address/getAddress.js'
|
16
|
+
import { type Cursor, createCursor } from '../cursor.js'
|
21
17
|
import { type SizeErrorType, size } from '../data/size.js'
|
22
|
-
import { type
|
18
|
+
import { type SliceBytesErrorType, sliceBytes } from '../data/slice.js'
|
23
19
|
import { type TrimErrorType, trim } from '../data/trim.js'
|
24
20
|
import {
|
25
|
-
type
|
26
|
-
type
|
27
|
-
type
|
28
|
-
type
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
} from '../encoding/
|
34
|
-
|
35
|
-
import type
|
36
|
-
import {
|
37
|
-
type GetArrayComponentsErrorType,
|
38
|
-
getArrayComponents,
|
39
|
-
} from './encodeAbiParameters.js'
|
21
|
+
type BytesToBigIntErrorType,
|
22
|
+
type BytesToBoolErrorType,
|
23
|
+
type BytesToNumberErrorType,
|
24
|
+
type BytesToStringErrorType,
|
25
|
+
bytesToBigInt,
|
26
|
+
bytesToBool,
|
27
|
+
bytesToNumber,
|
28
|
+
bytesToString,
|
29
|
+
} from '../encoding/fromBytes.js'
|
30
|
+
import { type HexToBytesErrorType, hexToBytes } from '../encoding/toBytes.js'
|
31
|
+
import { type BytesToHexErrorType, bytesToHex } from '../encoding/toHex.js'
|
32
|
+
import { getArrayComponents } from './encodeAbiParameters.js'
|
40
33
|
|
41
34
|
export type DecodeAbiParametersReturnType<
|
42
|
-
TParams extends
|
43
|
-
| readonly AbiParameter[]
|
44
|
-
| readonly unknown[] = readonly AbiParameter[],
|
35
|
+
TParams extends readonly AbiParameter[] = readonly AbiParameter[],
|
45
36
|
> = AbiParametersToPrimitiveTypes<
|
46
37
|
TParams extends readonly AbiParameter[] ? TParams : AbiParameter[]
|
47
38
|
>
|
48
39
|
|
49
40
|
export type DecodeAbiParametersErrorType =
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
| HexToBytesErrorType
|
42
|
+
| BytesToHexErrorType
|
43
|
+
| DecodeParameterErrorType
|
53
44
|
| SizeErrorType
|
54
45
|
| ErrorType
|
55
46
|
|
56
47
|
export function decodeAbiParameters<
|
57
|
-
const TParams extends readonly AbiParameter[]
|
58
|
-
>(
|
59
|
-
|
48
|
+
const TParams extends readonly AbiParameter[],
|
49
|
+
>(
|
50
|
+
params: TParams,
|
51
|
+
data: ByteArray | Hex,
|
52
|
+
): DecodeAbiParametersReturnType<TParams> {
|
53
|
+
const bytes = typeof data === 'string' ? hexToBytes(data) : data
|
54
|
+
const cursor = createCursor(bytes)
|
55
|
+
|
56
|
+
if (size(bytes) === 0 && params.length > 0)
|
60
57
|
throw new AbiDecodingZeroDataError()
|
61
58
|
if (size(data) && size(data) < 32)
|
62
59
|
throw new AbiDecodingDataSizeTooSmallError({
|
63
|
-
data,
|
60
|
+
data: typeof data === 'string' ? data : bytesToHex(data),
|
64
61
|
params: params as readonly AbiParameter[],
|
65
62
|
size: size(data),
|
66
63
|
})
|
67
|
-
return decodeParams({
|
68
|
-
data,
|
69
|
-
params: params as readonly AbiParameter[],
|
70
|
-
}) as unknown as DecodeAbiParametersReturnType<TParams>
|
71
|
-
}
|
72
|
-
|
73
|
-
////////////////////////////////////////////////////////////////////
|
74
|
-
|
75
|
-
type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] }
|
76
|
-
|
77
|
-
type DecodeParamsErrorType = DecodeParamErrorType | SizeErrorType | ErrorType
|
78
|
-
|
79
|
-
function decodeParams<const TParams extends readonly AbiParameter[]>({
|
80
|
-
data,
|
81
|
-
params,
|
82
|
-
}: { data: Hex; params: TParams }) {
|
83
|
-
const decodedValues: unknown[] = []
|
84
|
-
let position = 0
|
85
|
-
|
86
|
-
for (let i = 0; i < params.length; i++) {
|
87
|
-
if (position >= size(data))
|
88
|
-
throw new AbiDecodingDataSizeTooSmallError({
|
89
|
-
data,
|
90
|
-
params,
|
91
|
-
size: size(data),
|
92
|
-
})
|
93
64
|
|
65
|
+
let consumed = 0
|
66
|
+
const values = []
|
67
|
+
for (let i = 0; i < params.length; ++i) {
|
94
68
|
const param = params[i]
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
69
|
+
cursor.setPosition(consumed)
|
70
|
+
const [data, consumed_] = decodeParameter(cursor, param, {
|
71
|
+
staticPosition: 0,
|
72
|
+
})
|
73
|
+
consumed += consumed_
|
74
|
+
values.push(data)
|
99
75
|
}
|
100
|
-
|
101
|
-
return decodedValues as unknown as AbiParametersToPrimitiveTypes<TParams>
|
76
|
+
return values as DecodeAbiParametersReturnType<TParams>
|
102
77
|
}
|
103
78
|
|
104
|
-
type
|
79
|
+
type DecodeParameterErrorType =
|
105
80
|
| DecodeArrayErrorType
|
106
81
|
| DecodeTupleErrorType
|
107
|
-
| DecodeStringErrorType
|
108
|
-
| DecodeBytesErrorType
|
109
|
-
| DecodeNumberErrorType
|
110
82
|
| DecodeAddressErrorType
|
111
83
|
| DecodeBoolErrorType
|
84
|
+
| DecodeBytesErrorType
|
85
|
+
| DecodeNumberErrorType
|
86
|
+
| DecodeStringErrorType
|
112
87
|
| InvalidAbiDecodingTypeErrorType
|
113
|
-
| ErrorType
|
114
88
|
|
115
|
-
function
|
116
|
-
|
117
|
-
param,
|
118
|
-
|
119
|
-
|
120
|
-
consumed: number
|
121
|
-
value: any
|
122
|
-
} {
|
89
|
+
function decodeParameter(
|
90
|
+
cursor: Cursor,
|
91
|
+
param: AbiParameter,
|
92
|
+
{ staticPosition }: { staticPosition: number },
|
93
|
+
) {
|
123
94
|
const arrayComponents = getArrayComponents(param.type)
|
124
95
|
if (arrayComponents) {
|
125
96
|
const [length, type] = arrayComponents
|
126
|
-
return decodeArray(
|
127
|
-
length,
|
128
|
-
param: { ...param, type: type } as AbiParameter,
|
129
|
-
position,
|
130
|
-
})
|
131
|
-
}
|
132
|
-
if (param.type === 'tuple') {
|
133
|
-
return decodeTuple(data, { param: param as TupleAbiParameter, position })
|
134
|
-
}
|
135
|
-
if (param.type === 'string') {
|
136
|
-
return decodeString(data, { position })
|
137
|
-
}
|
138
|
-
if (param.type.startsWith('bytes')) {
|
139
|
-
return decodeBytes(data, { param, position })
|
140
|
-
}
|
141
|
-
|
142
|
-
const value = slice(data, position, position + 32, { strict: true }) as Hex
|
143
|
-
if (param.type.startsWith('uint') || param.type.startsWith('int')) {
|
144
|
-
return decodeNumber(value, { param })
|
145
|
-
}
|
146
|
-
if (param.type === 'address') {
|
147
|
-
return decodeAddress(value)
|
148
|
-
}
|
149
|
-
if (param.type === 'bool') {
|
150
|
-
return decodeBool(value)
|
97
|
+
return decodeArray(cursor, { ...param, type }, { length, staticPosition })
|
151
98
|
}
|
99
|
+
if (param.type === 'tuple')
|
100
|
+
return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition })
|
101
|
+
|
102
|
+
if (param.type === 'address') return decodeAddress(cursor)
|
103
|
+
if (param.type === 'bool') return decodeBool(cursor)
|
104
|
+
if (param.type.startsWith('bytes'))
|
105
|
+
return decodeBytes(cursor, param, { staticPosition })
|
106
|
+
if (param.type.startsWith('uint') || param.type.startsWith('int'))
|
107
|
+
return decodeNumber(cursor, param)
|
108
|
+
if (param.type === 'string') return decodeString(cursor, { staticPosition })
|
152
109
|
throw new InvalidAbiDecodingTypeError(param.type, {
|
153
110
|
docsPath: '/docs/contract/decodeAbiParameters',
|
154
111
|
})
|
155
112
|
}
|
156
113
|
|
157
114
|
////////////////////////////////////////////////////////////////////
|
115
|
+
// Type Decoders
|
116
|
+
|
117
|
+
const sizeOfLength = 32
|
118
|
+
const sizeOfOffset = 32
|
158
119
|
|
159
120
|
type DecodeAddressErrorType =
|
160
121
|
| ChecksumAddressErrorType
|
161
|
-
|
|
122
|
+
| BytesToHexErrorType
|
123
|
+
| SliceBytesErrorType
|
162
124
|
| ErrorType
|
163
125
|
|
164
|
-
function decodeAddress(
|
165
|
-
|
126
|
+
function decodeAddress(cursor: Cursor) {
|
127
|
+
const value = cursor.readBytes(32)
|
128
|
+
return [checksumAddress(bytesToHex(sliceBytes(value, -20))), 32]
|
166
129
|
}
|
167
130
|
|
168
|
-
type DecodeArrayErrorType =
|
169
|
-
|
170
|
-
function decodeArray
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
length,
|
175
|
-
position,
|
176
|
-
}: {
|
177
|
-
param: TParam
|
178
|
-
length: number | null
|
179
|
-
position: number
|
180
|
-
},
|
131
|
+
type DecodeArrayErrorType = BytesToNumberErrorType | ErrorType
|
132
|
+
|
133
|
+
function decodeArray(
|
134
|
+
cursor: Cursor,
|
135
|
+
param: AbiParameter,
|
136
|
+
{ length, staticPosition }: { length: number | null; staticPosition: number },
|
181
137
|
) {
|
182
138
|
// If the length of the array is not known in advance (dynamic array),
|
183
|
-
// we will need to
|
139
|
+
// this means we will need to wonder off to the pointer and decode.
|
184
140
|
if (!length) {
|
185
|
-
//
|
186
|
-
const offset =
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
141
|
+
// Dealing with a dynamic type, so get the offset of the array data.
|
142
|
+
const offset = bytesToNumber(cursor.readBytes(sizeOfOffset))
|
143
|
+
|
144
|
+
// Start is the static position of current slot + offset.
|
145
|
+
const start = staticPosition + offset
|
146
|
+
const startOfData = start + sizeOfLength
|
191
147
|
|
192
148
|
// Get the length of the array from the offset.
|
193
|
-
|
194
|
-
|
195
|
-
|
149
|
+
cursor.setPosition(start)
|
150
|
+
const length = bytesToNumber(cursor.readBytes(sizeOfLength))
|
151
|
+
|
152
|
+
// Check if the array has any dynamic children.
|
153
|
+
const dynamicChild = hasDynamicChild(param)
|
196
154
|
|
197
155
|
let consumed = 0
|
198
|
-
const value:
|
156
|
+
const value: unknown[] = []
|
199
157
|
for (let i = 0; i < length; ++i) {
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
158
|
+
// If any of the children is dynamic, then all elements will be offset pointer, thus size of one slot (32 bytes).
|
159
|
+
// Otherwise, elements will be the size of their encoding (consumed bytes).
|
160
|
+
cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed))
|
161
|
+
const [data, consumed_] = decodeParameter(cursor, param, {
|
162
|
+
staticPosition: startOfData,
|
204
163
|
})
|
205
|
-
consumed +=
|
206
|
-
value.push(
|
164
|
+
consumed += consumed_
|
165
|
+
value.push(data)
|
207
166
|
}
|
208
|
-
|
167
|
+
|
168
|
+
// As we have gone wondering, restore to the original position + next slot.
|
169
|
+
cursor.setPosition(staticPosition + 32)
|
170
|
+
return [value, 32]
|
209
171
|
}
|
210
172
|
|
211
173
|
// If the length of the array is known in advance,
|
212
174
|
// and the length of an element deeply nested in the array is not known,
|
213
175
|
// we need to decode the offset of the array data.
|
214
176
|
if (hasDynamicChild(param)) {
|
215
|
-
//
|
216
|
-
const
|
217
|
-
// If the child type is not known, the array is dynamic.
|
218
|
-
const dynamicChild = !arrayComponents?.[0]
|
177
|
+
// Dealing with dynamic types, so get the offset of the array data.
|
178
|
+
const offset = bytesToNumber(cursor.readBytes(sizeOfOffset))
|
219
179
|
|
220
|
-
|
221
|
-
const
|
180
|
+
// Start is the static position of current slot + offset.
|
181
|
+
const start = staticPosition + offset
|
182
|
+
|
183
|
+
const value: unknown[] = []
|
222
184
|
for (let i = 0; i < length; ++i) {
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
data: slice(data, offset),
|
228
|
-
param,
|
229
|
-
position: dynamicChild ? consumed : i * 32,
|
185
|
+
// Move cursor along to the next slot (next offset pointer).
|
186
|
+
cursor.setPosition(start + i * 32)
|
187
|
+
const [data] = decodeParameter(cursor, param, {
|
188
|
+
staticPosition: start,
|
230
189
|
})
|
231
|
-
|
232
|
-
value.push(decodedChild.value)
|
190
|
+
value.push(data)
|
233
191
|
}
|
234
|
-
|
192
|
+
|
193
|
+
// As we have gone wondering, restore to the original position + next slot.
|
194
|
+
cursor.setPosition(staticPosition + 32)
|
195
|
+
return [value, 32]
|
235
196
|
}
|
236
197
|
|
237
|
-
// If the length of the array is known in advance,
|
238
|
-
//
|
239
|
-
// the array data is encoded contiguously after the array.
|
198
|
+
// If the length of the array is known in advance and the array is deeply static,
|
199
|
+
// then we can just decode each element in sequence.
|
240
200
|
let consumed = 0
|
241
|
-
const value:
|
201
|
+
const value: unknown[] = []
|
242
202
|
for (let i = 0; i < length; ++i) {
|
243
|
-
const
|
244
|
-
|
245
|
-
param,
|
246
|
-
position: position + consumed,
|
203
|
+
const [data, consumed_] = decodeParameter(cursor, param, {
|
204
|
+
staticPosition: staticPosition + consumed,
|
247
205
|
})
|
248
|
-
consumed +=
|
249
|
-
value.push(
|
206
|
+
consumed += consumed_
|
207
|
+
value.push(data)
|
250
208
|
}
|
251
|
-
return
|
209
|
+
return [value, consumed]
|
252
210
|
}
|
253
211
|
|
254
|
-
type DecodeBoolErrorType =
|
212
|
+
type DecodeBoolErrorType = BytesToBoolErrorType | ErrorType
|
255
213
|
|
256
|
-
function decodeBool(
|
257
|
-
return {
|
214
|
+
function decodeBool(cursor: Cursor) {
|
215
|
+
return [bytesToBool(cursor.readBytes(32), { size: 32 }), 32]
|
258
216
|
}
|
259
217
|
|
260
|
-
type DecodeBytesErrorType =
|
218
|
+
type DecodeBytesErrorType =
|
219
|
+
| BytesToNumberErrorType
|
220
|
+
| BytesToHexErrorType
|
221
|
+
| ErrorType
|
261
222
|
|
262
|
-
function decodeBytes
|
263
|
-
|
264
|
-
|
223
|
+
function decodeBytes(
|
224
|
+
cursor: Cursor,
|
225
|
+
param: AbiParameter,
|
226
|
+
{ staticPosition }: { staticPosition: number },
|
265
227
|
) {
|
266
228
|
const [_, size] = param.type.split('bytes')
|
267
229
|
if (!size) {
|
268
|
-
//
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
)
|
273
|
-
|
274
|
-
|
275
|
-
|
230
|
+
// Dealing with dynamic types, so get the offset of the bytes data.
|
231
|
+
const offset = bytesToNumber(cursor.readBytes(32))
|
232
|
+
|
233
|
+
// Set position of the cursor to start of bytes data.
|
234
|
+
cursor.setPosition(staticPosition + offset)
|
235
|
+
|
236
|
+
const length = bytesToNumber(cursor.readBytes(32))
|
237
|
+
|
276
238
|
// If there is no length, we have zero data.
|
277
|
-
if (length === 0)
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
239
|
+
if (length === 0) {
|
240
|
+
// As we have gone wondering, restore to the original position + next slot.
|
241
|
+
cursor.setPosition(staticPosition + 32)
|
242
|
+
return ['0x', 32]
|
243
|
+
}
|
244
|
+
|
245
|
+
const data = cursor.readBytes(length)
|
246
|
+
|
247
|
+
// As we have gone wondering, restore to the original position + next slot.
|
248
|
+
cursor.setPosition(staticPosition + 32)
|
249
|
+
return [bytesToHex(data), 32]
|
282
250
|
}
|
283
251
|
|
284
|
-
const value =
|
285
|
-
|
286
|
-
})
|
287
|
-
return { consumed: 32, value }
|
252
|
+
const value = bytesToHex(cursor.readBytes(parseInt(size), 32))
|
253
|
+
return [value, 32]
|
288
254
|
}
|
289
255
|
|
290
256
|
type DecodeNumberErrorType =
|
291
|
-
|
|
292
|
-
|
|
257
|
+
| BytesToNumberErrorType
|
258
|
+
| BytesToBigIntErrorType
|
293
259
|
| ErrorType
|
294
260
|
|
295
|
-
function decodeNumber
|
296
|
-
value: Hex,
|
297
|
-
{ param }: { param: TParam },
|
298
|
-
) {
|
261
|
+
function decodeNumber(cursor: Cursor, param: AbiParameter) {
|
299
262
|
const signed = param.type.startsWith('int')
|
300
263
|
const size = parseInt(param.type.split('int')[1] || '256')
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
264
|
+
const value = cursor.readBytes(32)
|
265
|
+
return [
|
266
|
+
size > 48
|
267
|
+
? bytesToBigInt(value, { signed })
|
268
|
+
: bytesToNumber(value, { signed }),
|
269
|
+
32,
|
270
|
+
]
|
308
271
|
}
|
309
272
|
|
310
|
-
type
|
311
|
-
| HexToNumberErrorType
|
312
|
-
| HexToStringErrorType
|
313
|
-
| SliceErrorType
|
314
|
-
| TrimErrorType
|
315
|
-
| ErrorType
|
273
|
+
type TupleAbiParameter = AbiParameter & { components: readonly AbiParameter[] }
|
316
274
|
|
317
|
-
|
318
|
-
const offset = hexToNumber(
|
319
|
-
slice(data, position, position + 32, { strict: true }),
|
320
|
-
)
|
321
|
-
const length = hexToNumber(slice(data, offset, offset + 32, { strict: true }))
|
322
|
-
// If there is no length, we have zero data (empty string).
|
323
|
-
if (length === 0) return { consumed: 32, value: '' }
|
324
|
-
const value = hexToString(
|
325
|
-
trim(slice(data, offset + 32, offset + 32 + length, { strict: true })),
|
326
|
-
)
|
327
|
-
return { consumed: 32, value }
|
328
|
-
}
|
275
|
+
type DecodeTupleErrorType = BytesToNumberErrorType | ErrorType
|
329
276
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
function decodeTuple<
|
337
|
-
const TParam extends AbiParameter & { components: readonly AbiParameter[] },
|
338
|
-
>(data: Hex, { param, position }: { param: TParam; position: number }) {
|
277
|
+
function decodeTuple(
|
278
|
+
cursor: Cursor,
|
279
|
+
param: TupleAbiParameter,
|
280
|
+
{ staticPosition }: { staticPosition: number },
|
281
|
+
) {
|
339
282
|
// Tuples can have unnamed components (i.e. they are arrays), so we must
|
340
283
|
// determine whether the tuple is named or unnamed. In the case of a named
|
341
284
|
// tuple, the value will be an object where each property is the name of the
|
@@ -351,39 +294,73 @@ function decodeTuple<
|
|
351
294
|
// If the tuple has a dynamic child, we must first decode the offset to the
|
352
295
|
// tuple data.
|
353
296
|
if (hasDynamicChild(param)) {
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
//
|
297
|
+
// Dealing with dynamic types, so get the offset of the tuple data.
|
298
|
+
const offset = bytesToNumber(cursor.readBytes(sizeOfOffset))
|
299
|
+
|
300
|
+
// Start is the static position of referencing slot + offset.
|
301
|
+
const start = staticPosition + offset
|
302
|
+
|
358
303
|
for (let i = 0; i < param.components.length; ++i) {
|
359
304
|
const component = param.components[i]
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
position: consumed,
|
305
|
+
cursor.setPosition(start + consumed)
|
306
|
+
const [data, consumed_] = decodeParameter(cursor, component, {
|
307
|
+
staticPosition: start,
|
364
308
|
})
|
365
|
-
consumed +=
|
366
|
-
value[hasUnnamedChild ? i : component?.name!] =
|
309
|
+
consumed += consumed_
|
310
|
+
value[hasUnnamedChild ? i : component?.name!] = data
|
367
311
|
}
|
368
|
-
|
312
|
+
|
313
|
+
// As we have gone wondering, restore to the original position + next slot.
|
314
|
+
cursor.setPosition(staticPosition + 32)
|
315
|
+
return [value, 32]
|
369
316
|
}
|
370
317
|
|
371
318
|
// If the tuple has static children, we can just decode each component
|
372
319
|
// in sequence.
|
373
320
|
for (let i = 0; i < param.components.length; ++i) {
|
374
321
|
const component = param.components[i]
|
375
|
-
const
|
376
|
-
|
377
|
-
param: component,
|
378
|
-
position: position + consumed,
|
322
|
+
const [data, consumed_] = decodeParameter(cursor, component, {
|
323
|
+
staticPosition,
|
379
324
|
})
|
380
|
-
|
381
|
-
|
325
|
+
value[hasUnnamedChild ? i : component?.name!] = data
|
326
|
+
consumed += consumed_
|
382
327
|
}
|
383
|
-
return
|
328
|
+
return [value, consumed]
|
384
329
|
}
|
385
330
|
|
386
|
-
type
|
331
|
+
type DecodeStringErrorType =
|
332
|
+
| BytesToNumberErrorType
|
333
|
+
| BytesToStringErrorType
|
334
|
+
| TrimErrorType
|
335
|
+
| ErrorType
|
336
|
+
|
337
|
+
function decodeString(
|
338
|
+
cursor: Cursor,
|
339
|
+
{ staticPosition }: { staticPosition: number },
|
340
|
+
) {
|
341
|
+
// Get offset to start of string data.
|
342
|
+
const offset = bytesToNumber(cursor.readBytes(32))
|
343
|
+
|
344
|
+
// Start is the static position of current slot + offset.
|
345
|
+
const start = staticPosition + offset
|
346
|
+
cursor.setPosition(start)
|
347
|
+
|
348
|
+
const length = bytesToNumber(cursor.readBytes(32))
|
349
|
+
|
350
|
+
// If there is no length, we have zero data (empty string).
|
351
|
+
if (length === 0) {
|
352
|
+
cursor.setPosition(staticPosition + 32)
|
353
|
+
return ['', 32]
|
354
|
+
}
|
355
|
+
|
356
|
+
const data = cursor.readBytes(length, 32)
|
357
|
+
const value = bytesToString(trim(data))
|
358
|
+
|
359
|
+
// As we have gone wondering, restore to the original position + next slot.
|
360
|
+
cursor.setPosition(staticPosition + 32)
|
361
|
+
|
362
|
+
return [value, 32]
|
363
|
+
}
|
387
364
|
|
388
365
|
function hasDynamicChild(param: AbiParameter) {
|
389
366
|
const { type } = param
|
@@ -24,11 +24,13 @@ import type {
|
|
24
24
|
Prettify,
|
25
25
|
UnionEvaluate,
|
26
26
|
} from '../../types/utils.js'
|
27
|
+
import { size } from '../data/size.js'
|
27
28
|
import {
|
28
29
|
type GetEventSelectorErrorType,
|
29
30
|
getEventSelector,
|
30
31
|
} from '../hash/getEventSelector.js'
|
31
32
|
|
33
|
+
import { PositionOutOfBoundsError } from '../../errors/cursor.js'
|
32
34
|
import {
|
33
35
|
type DecodeAbiParametersErrorType,
|
34
36
|
decodeAbiParameters,
|
@@ -156,12 +158,15 @@ export function decodeEventLog<
|
|
156
158
|
}
|
157
159
|
} catch (err) {
|
158
160
|
if (strict) {
|
159
|
-
if (
|
161
|
+
if (
|
162
|
+
err instanceof AbiDecodingDataSizeTooSmallError ||
|
163
|
+
err instanceof PositionOutOfBoundsError
|
164
|
+
)
|
160
165
|
throw new DecodeLogDataMismatch({
|
161
166
|
abiItem,
|
162
|
-
data:
|
163
|
-
params:
|
164
|
-
size:
|
167
|
+
data: data,
|
168
|
+
params: nonIndexedInputs,
|
169
|
+
size: size(data),
|
165
170
|
})
|
166
171
|
throw err
|
167
172
|
}
|