ox 0.4.1 → 0.4.3

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.
@@ -73,9 +73,12 @@ export function decode<
73
73
  export function decode(
74
74
  parameters: AbiParameters,
75
75
  data: Bytes.Bytes | Hex.Hex,
76
- options: { as?: 'Array' | 'Object' | undefined } = {},
76
+ options: {
77
+ as?: 'Array' | 'Object' | undefined
78
+ checksumAddress?: boolean | undefined
79
+ } = {},
77
80
  ): readonly unknown[] | Record<string, unknown> {
78
- const { as = 'Array' } = options
81
+ const { as = 'Array', checksumAddress = false } = options
79
82
 
80
83
  const bytes = typeof data === 'string' ? Bytes.fromHex(data) : data
81
84
  const cursor = Cursor.create(bytes)
@@ -95,6 +98,7 @@ export function decode(
95
98
  const param = parameters[i] as Parameter
96
99
  cursor.setPosition(consumed)
97
100
  const [data, consumed_] = internal.decodeParameter(cursor, param, {
101
+ checksumAddress,
98
102
  staticPosition: 0,
99
103
  })
100
104
  consumed += consumed_
@@ -112,6 +116,12 @@ export declare namespace decode {
112
116
  * @default "Array"
113
117
  */
114
118
  as?: as | 'Object' | 'Array' | undefined
119
+ /**
120
+ * Whether decoded addresses should be checksummed.
121
+ *
122
+ * @default false
123
+ */
124
+ checksumAddress?: boolean | undefined
115
125
  }
116
126
 
117
127
  type ReturnType<
@@ -175,7 +185,10 @@ export function encode<
175
185
  values: parameters extends AbiParameters
176
186
  ? internal.ToPrimitiveTypes<parameters>
177
187
  : never,
188
+ options?: encode.Options,
178
189
  ): Hex.Hex {
190
+ const { checksumAddress = false } = options ?? {}
191
+
179
192
  if (parameters.length !== values.length)
180
193
  throw new LengthMismatchError({
181
194
  expectedLength: parameters.length as number,
@@ -183,6 +196,7 @@ export function encode<
183
196
  })
184
197
  // Prepare the parameters to determine dynamic types to encode.
185
198
  const preparedParameters = internal.prepareParameters({
199
+ checksumAddress,
186
200
  parameters: parameters as readonly Parameter[],
187
201
  values: values as any,
188
202
  })
@@ -197,6 +211,15 @@ export declare namespace encode {
197
211
  | internal.encode.ErrorType
198
212
  | internal.prepareParameters.ErrorType
199
213
  | Errors.GlobalErrorType
214
+
215
+ type Options = {
216
+ /**
217
+ * Whether addresses should be checked against their checksum.
218
+ *
219
+ * @default false
220
+ */
221
+ checksumAddress?: boolean | undefined
222
+ }
200
223
  }
201
224
 
202
225
  /**
@@ -63,17 +63,25 @@ export type Tuple = ParameterToPrimitiveType<TupleAbiParameter>
63
63
  export function decodeParameter(
64
64
  cursor: Cursor.Cursor,
65
65
  param: AbiParameters.Parameter,
66
- { staticPosition }: { staticPosition: number },
66
+ options: { checksumAddress?: boolean | undefined; staticPosition: number },
67
67
  ) {
68
+ const { checksumAddress, staticPosition } = options
68
69
  const arrayComponents = getArrayComponents(param.type)
69
70
  if (arrayComponents) {
70
71
  const [length, type] = arrayComponents
71
- return decodeArray(cursor, { ...param, type }, { length, staticPosition })
72
+ return decodeArray(
73
+ cursor,
74
+ { ...param, type },
75
+ { checksumAddress, length, staticPosition },
76
+ )
72
77
  }
73
78
  if (param.type === 'tuple')
74
- return decodeTuple(cursor, param as TupleAbiParameter, { staticPosition })
75
-
76
- if (param.type === 'address') return decodeAddress(cursor)
79
+ return decodeTuple(cursor, param as TupleAbiParameter, {
80
+ checksumAddress,
81
+ staticPosition,
82
+ })
83
+ if (param.type === 'address')
84
+ return decodeAddress(cursor, { checksum: checksumAddress })
77
85
  if (param.type === 'bool') return decodeBool(cursor)
78
86
  if (param.type.startsWith('bytes'))
79
87
  return decodeBytes(cursor, param, { staticPosition })
@@ -100,9 +108,15 @@ const sizeOfLength = 32
100
108
  const sizeOfOffset = 32
101
109
 
102
110
  /** @internal */
103
- export function decodeAddress(cursor: Cursor.Cursor) {
111
+ export function decodeAddress(
112
+ cursor: Cursor.Cursor,
113
+ options: { checksum?: boolean | undefined } = {},
114
+ ) {
115
+ const { checksum = false } = options
104
116
  const value = cursor.readBytes(32)
105
- return [Hex.fromBytes(Bytes.slice(value, -20)), 32]
117
+ const wrap = (address: Hex.Hex) =>
118
+ checksum ? Address.checksum(address) : address
119
+ return [wrap(Hex.fromBytes(Bytes.slice(value, -20))), 32]
106
120
  }
107
121
 
108
122
  export declare namespace decodeAddress {
@@ -116,8 +130,14 @@ export declare namespace decodeAddress {
116
130
  export function decodeArray(
117
131
  cursor: Cursor.Cursor,
118
132
  param: AbiParameters.Parameter,
119
- { length, staticPosition }: { length: number | null; staticPosition: number },
133
+ options: {
134
+ checksumAddress?: boolean | undefined
135
+ length: number | null
136
+ staticPosition: number
137
+ },
120
138
  ) {
139
+ const { checksumAddress, length, staticPosition } = options
140
+
121
141
  // If the length of the array is not known in advance (dynamic array),
122
142
  // this means we will need to wonder off to the pointer and decode.
123
143
  if (!length) {
@@ -142,6 +162,7 @@ export function decodeArray(
142
162
  // Otherwise, elements will be the size of their encoding (consumed bytes).
143
163
  cursor.setPosition(startOfData + (dynamicChild ? i * 32 : consumed))
144
164
  const [data, consumed_] = decodeParameter(cursor, param, {
165
+ checksumAddress,
145
166
  staticPosition: startOfData,
146
167
  })
147
168
  consumed += consumed_
@@ -168,6 +189,7 @@ export function decodeArray(
168
189
  // Move cursor along to the next slot (next offset pointer).
169
190
  cursor.setPosition(start + i * 32)
170
191
  const [data] = decodeParameter(cursor, param, {
192
+ checksumAddress,
171
193
  staticPosition: start,
172
194
  })
173
195
  value.push(data)
@@ -184,6 +206,7 @@ export function decodeArray(
184
206
  const value: unknown[] = []
185
207
  for (let i = 0; i < length; ++i) {
186
208
  const [data, consumed_] = decodeParameter(cursor, param, {
209
+ checksumAddress,
187
210
  staticPosition: staticPosition + consumed,
188
211
  })
189
212
  consumed += consumed_
@@ -278,8 +301,10 @@ export type TupleAbiParameter = AbiParameters.Parameter & {
278
301
  export function decodeTuple(
279
302
  cursor: Cursor.Cursor,
280
303
  param: TupleAbiParameter,
281
- { staticPosition }: { staticPosition: number },
304
+ options: { checksumAddress?: boolean | undefined; staticPosition: number },
282
305
  ) {
306
+ const { checksumAddress, staticPosition } = options
307
+
283
308
  // Tuples can have unnamed components (i.e. they are arrays), so we must
284
309
  // determine whether the tuple is named or unnamed. In the case of a named
285
310
  // tuple, the value will be an object where each property is the name of the
@@ -305,6 +330,7 @@ export function decodeTuple(
305
330
  const component = param.components[i]!
306
331
  cursor.setPosition(start + consumed)
307
332
  const [data, consumed_] = decodeParameter(cursor, component, {
333
+ checksumAddress,
308
334
  staticPosition: start,
309
335
  })
310
336
  consumed += consumed_
@@ -321,6 +347,7 @@ export function decodeTuple(
321
347
  for (let i = 0; i < param.components.length; ++i) {
322
348
  const component = param.components[i]!
323
349
  const [data, consumed_] = decodeParameter(cursor, component, {
350
+ checksumAddress,
324
351
  staticPosition,
325
352
  })
326
353
  value[hasUnnamedChild ? i : component?.name!] = data
@@ -374,9 +401,11 @@ export declare namespace decodeString {
374
401
  export function prepareParameters<
375
402
  const parameters extends AbiParameters.AbiParameters,
376
403
  >({
404
+ checksumAddress,
377
405
  parameters,
378
406
  values,
379
407
  }: {
408
+ checksumAddress?: boolean | undefined
380
409
  parameters: parameters
381
410
  values: parameters extends AbiParameters.AbiParameters
382
411
  ? ToPrimitiveTypes<parameters>
@@ -385,7 +414,11 @@ export function prepareParameters<
385
414
  const preparedParameters: PreparedParameter[] = []
386
415
  for (let i = 0; i < parameters.length; i++) {
387
416
  preparedParameters.push(
388
- prepareParameter({ parameter: parameters[i]!, value: values[i] }),
417
+ prepareParameter({
418
+ checksumAddress,
419
+ parameter: parameters[i]!,
420
+ value: values[i],
421
+ }),
389
422
  )
390
423
  }
391
424
  return preparedParameters
@@ -400,6 +433,7 @@ export declare namespace prepareParameters {
400
433
  export function prepareParameter<
401
434
  const parameter extends AbiParameters.Parameter,
402
435
  >({
436
+ checksumAddress = false,
403
437
  parameter: parameter_,
404
438
  value,
405
439
  }: {
@@ -407,6 +441,7 @@ export function prepareParameter<
407
441
  value: parameter extends AbiParameters.Parameter
408
442
  ? ParameterToPrimitiveType<parameter>
409
443
  : never
444
+ checksumAddress?: boolean | undefined
410
445
  }): PreparedParameter {
411
446
  const parameter = parameter_ as AbiParameters.Parameter
412
447
 
@@ -414,6 +449,7 @@ export function prepareParameter<
414
449
  if (arrayComponents) {
415
450
  const [length, type] = arrayComponents
416
451
  return encodeArray(value, {
452
+ checksumAddress,
417
453
  length,
418
454
  parameter: {
419
455
  ...parameter,
@@ -423,11 +459,14 @@ export function prepareParameter<
423
459
  }
424
460
  if (parameter.type === 'tuple') {
425
461
  return encodeTuple(value as unknown as Tuple, {
462
+ checksumAddress,
426
463
  parameter: parameter as TupleAbiParameter,
427
464
  })
428
465
  }
429
466
  if (parameter.type === 'address') {
430
- return encodeAddress(value as unknown as Hex.Hex)
467
+ return encodeAddress(value as unknown as Hex.Hex, {
468
+ checksum: checksumAddress,
469
+ })
431
470
  }
432
471
  if (parameter.type === 'bool') {
433
472
  return encodeBoolean(value as unknown as boolean)
@@ -503,8 +542,12 @@ export declare namespace encode {
503
542
  }
504
543
 
505
544
  /** @internal */
506
- export function encodeAddress(value: Hex.Hex): PreparedParameter {
507
- Address.assert(value, { strict: false })
545
+ export function encodeAddress(
546
+ value: Hex.Hex,
547
+ options: { checksum: boolean },
548
+ ): PreparedParameter {
549
+ const { checksum = false } = options
550
+ Address.assert(value, { strict: checksum })
508
551
  return {
509
552
  dynamic: false,
510
553
  encoded: Hex.padLeft(value.toLowerCase() as Hex.Hex),
@@ -522,14 +565,14 @@ export declare namespace encodeAddress {
522
565
  /** @internal */
523
566
  export function encodeArray<const parameter extends AbiParameters.Parameter>(
524
567
  value: ParameterToPrimitiveType<parameter>,
525
- {
526
- length,
527
- parameter,
528
- }: {
568
+ options: {
569
+ checksumAddress?: boolean | undefined
529
570
  length: number | null
530
571
  parameter: parameter
531
572
  },
532
573
  ): PreparedParameter {
574
+ const { checksumAddress, length, parameter } = options
575
+
533
576
  const dynamic = length === null
534
577
 
535
578
  if (!Array.isArray(value)) throw new AbiParameters.InvalidArrayError(value)
@@ -543,7 +586,11 @@ export function encodeArray<const parameter extends AbiParameters.Parameter>(
543
586
  let dynamicChild = false
544
587
  const preparedParameters: PreparedParameter[] = []
545
588
  for (let i = 0; i < value.length; i++) {
546
- const preparedParam = prepareParameter({ parameter, value: value[i] })
589
+ const preparedParam = prepareParameter({
590
+ checksumAddress,
591
+ parameter,
592
+ value: value[i],
593
+ })
547
594
  if (preparedParam.dynamic) dynamicChild = true
548
595
  preparedParameters.push(preparedParam)
549
596
  }
@@ -697,14 +744,20 @@ export function encodeTuple<
697
744
  },
698
745
  >(
699
746
  value: ParameterToPrimitiveType<parameter>,
700
- { parameter }: { parameter: parameter },
747
+ options: {
748
+ checksumAddress?: boolean | undefined
749
+ parameter: parameter
750
+ },
701
751
  ): PreparedParameter {
752
+ const { checksumAddress, parameter } = options
753
+
702
754
  let dynamic = false
703
755
  const preparedParameters: PreparedParameter[] = []
704
756
  for (let i = 0; i < parameter.components.length; i++) {
705
757
  const param_ = parameter.components[i]!
706
758
  const index = Array.isArray(value) ? i : param_.name
707
759
  const preparedParam = prepareParameter({
760
+ checksumAddress,
708
761
  parameter: param_,
709
762
  value: (value as any)[index!] as readonly unknown[],
710
763
  })
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "types": "../_types/erc6492/WrappedSignature.d.ts",
4
- "main": "../_cjs/erc6492/WrappedSignature.js",
5
- "module": "../_esm/erc6492/WrappedSignature.js"
3
+ "types": "../../_types/erc6492/WrappedSignature.d.ts",
4
+ "main": "../../_cjs/erc6492/WrappedSignature.js",
5
+ "module": "../../_esm/erc6492/WrappedSignature.js"
6
6
  }
@@ -1,3 +1,4 @@
1
+ import type * as Abi from '../core/Abi.js'
1
2
  import * as AbiParameters from '../core/AbiParameters.js'
2
3
  import type * as Address from '../core/Address.js'
3
4
  import * as Errors from '../core/Errors.js'
@@ -20,6 +21,62 @@ export type WrappedSignature = {
20
21
  export const magicBytes =
21
22
  '0x6492649264926492649264926492649264926492649264926492649264926492' as const
22
23
 
24
+ /**
25
+ * Deployless ERC-6492 signature verification bytecode.
26
+ */
27
+ export const universalSignatureValidatorBytecode =
28
+ '0x608060405234801561001057600080fd5b5060405161069438038061069483398101604081905261002f9161051e565b600061003c848484610048565b9050806000526001601ff35b60007f64926492649264926492649264926492649264926492649264926492649264926100748361040c565b036101e7576000606080848060200190518101906100929190610577565b60405192955090935091506000906001600160a01b038516906100b69085906105dd565b6000604051808303816000865af19150503d80600081146100f3576040519150601f19603f3d011682016040523d82523d6000602084013e6100f8565b606091505b50509050876001600160a01b03163b60000361016057806101605760405162461bcd60e51b815260206004820152601e60248201527f5369676e617475726556616c696461746f723a206465706c6f796d656e74000060448201526064015b60405180910390fd5b604051630b135d3f60e11b808252906001600160a01b038a1690631626ba7e90610190908b9087906004016105f9565b602060405180830381865afa1580156101ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d19190610633565b6001600160e01b03191614945050505050610405565b6001600160a01b0384163b1561027a57604051630b135d3f60e11b808252906001600160a01b03861690631626ba7e9061022790879087906004016105f9565b602060405180830381865afa158015610244573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102689190610633565b6001600160e01b031916149050610405565b81516041146102df5760405162461bcd60e51b815260206004820152603a602482015260008051602061067483398151915260448201527f3a20696e76616c6964207369676e6174757265206c656e6774680000000000006064820152608401610157565b6102e7610425565b5060208201516040808401518451859392600091859190811061030c5761030c61065d565b016020015160f81c9050601b811480159061032b57508060ff16601c14155b1561038c5760405162461bcd60e51b815260206004820152603b602482015260008051602061067483398151915260448201527f3a20696e76616c6964207369676e617475726520762076616c756500000000006064820152608401610157565b60408051600081526020810180835289905260ff83169181019190915260608101849052608081018390526001600160a01b0389169060019060a0016020604051602081039080840390855afa1580156103ea573d6000803e3d6000fd5b505050602060405103516001600160a01b0316149450505050505b9392505050565b600060208251101561041d57600080fd5b508051015190565b60405180606001604052806003906020820280368337509192915050565b6001600160a01b038116811461045857600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561048c578181015183820152602001610474565b50506000910152565b600082601f8301126104a657600080fd5b81516001600160401b038111156104bf576104bf61045b565b604051601f8201601f19908116603f011681016001600160401b03811182821017156104ed576104ed61045b565b60405281815283820160200185101561050557600080fd5b610516826020830160208701610471565b949350505050565b60008060006060848603121561053357600080fd5b835161053e81610443565b6020850151604086015191945092506001600160401b0381111561056157600080fd5b61056d86828701610495565b9150509250925092565b60008060006060848603121561058c57600080fd5b835161059781610443565b60208501519093506001600160401b038111156105b357600080fd5b6105bf86828701610495565b604086015190935090506001600160401b0381111561056157600080fd5b600082516105ef818460208701610471565b9190910192915050565b828152604060208201526000825180604084015261061e816060850160208701610471565b601f01601f1916919091016060019392505050565b60006020828403121561064557600080fd5b81516001600160e01b03198116811461040557600080fd5b634e487b7160e01b600052603260045260246000fdfe5369676e617475726556616c696461746f72237265636f7665725369676e6572'
29
+
30
+ /**
31
+ * ABI for the ERC-6492 universal deployless signature validator contract.
32
+ *
33
+ * Constructor return value is `0x1` (valid) or `0x0` (invalid).
34
+ */
35
+ export const universalSignatureValidatorAbi = [
36
+ {
37
+ inputs: [
38
+ {
39
+ name: '_signer',
40
+ type: 'address',
41
+ },
42
+ {
43
+ name: '_hash',
44
+ type: 'bytes32',
45
+ },
46
+ {
47
+ name: '_signature',
48
+ type: 'bytes',
49
+ },
50
+ ],
51
+ stateMutability: 'nonpayable',
52
+ type: 'constructor',
53
+ },
54
+ {
55
+ inputs: [
56
+ {
57
+ name: '_signer',
58
+ type: 'address',
59
+ },
60
+ {
61
+ name: '_hash',
62
+ type: 'bytes32',
63
+ },
64
+ {
65
+ name: '_signature',
66
+ type: 'bytes',
67
+ },
68
+ ],
69
+ outputs: [
70
+ {
71
+ type: 'bool',
72
+ },
73
+ ],
74
+ stateMutability: 'nonpayable',
75
+ type: 'function',
76
+ name: 'isValidSig',
77
+ },
78
+ ] as const satisfies Abi.Abi
79
+
23
80
  /**
24
81
  * Asserts that the wrapped signature is valid.
25
82
  *
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "types": "../_types/index.docs.d.ts",
4
- "main": "../_cjs/index.docs.js",
5
- "module": "../_esm/index.docs.js"
3
+ "types": "../_types/undefined/index.docs.d.ts",
4
+ "main": "../_cjs/undefined/index.docs.js",
5
+ "module": "../_esm/undefined/index.docs.js"
6
6
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ox",
3
3
  "description": "Ethereum Standard Library",
4
- "version": "0.4.1",
4
+ "version": "0.4.3",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
7
7
  "types": "./_types/index.d.ts",
@@ -388,11 +388,6 @@
388
388
  "import": "./_esm/trusted-setups/index.js",
389
389
  "default": "./_cjs/trusted-setups/index.js"
390
390
  },
391
- "./version": {
392
- "types": "./_types/version.d.ts",
393
- "import": "./_esm/version.js",
394
- "default": "./_cjs/version.js"
395
- },
396
391
  "./window": {
397
392
  "types": "./_types/window/index.d.ts",
398
393
  "import": "./_esm/window/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "types": "../_types/trusted-setups/Paths.d.ts",
4
- "main": "../_cjs/trusted-setups/Paths.js",
5
- "module": "../_esm/trusted-setups/Paths.js"
3
+ "types": "../../_types/trusted-setups/Paths.d.ts",
4
+ "main": "../../_cjs/trusted-setups/Paths.js",
5
+ "module": "../../_esm/trusted-setups/Paths.js"
6
6
  }
package/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** @internal */
2
- export const version = '0.4.1'
2
+ export const version = '0.4.3'
@@ -1,6 +0,0 @@
1
- {
2
- "type": "module",
3
- "types": "../_types/version.d.ts",
4
- "main": "../_cjs/version.js",
5
- "module": "../_esm/version.js"
6
- }