ox 1.8.10 → 1.8.13
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 +30 -0
- package/dist/core/Authorization.d.ts.map +1 -1
- package/dist/core/Authorization.js +44 -6
- package/dist/core/Authorization.js.map +1 -1
- package/dist/core/Siwe.d.ts.map +1 -1
- package/dist/core/Siwe.js +1 -1
- package/dist/core/Siwe.js.map +1 -1
- package/dist/core/TxEnvelope.d.ts.map +1 -1
- package/dist/core/TxEnvelope.js +5 -3
- package/dist/core/TxEnvelope.js.map +1 -1
- package/dist/core/TxEnvelopeEip1559.d.ts.map +1 -1
- package/dist/core/TxEnvelopeEip1559.js +6 -2
- package/dist/core/TxEnvelopeEip1559.js.map +1 -1
- package/dist/core/TxEnvelopeEip4844.d.ts.map +1 -1
- package/dist/core/TxEnvelopeEip4844.js +4 -0
- package/dist/core/TxEnvelopeEip4844.js.map +1 -1
- package/dist/core/TxEnvelopeEip7702.d.ts.map +1 -1
- package/dist/core/TxEnvelopeEip7702.js +4 -0
- package/dist/core/TxEnvelopeEip7702.js.map +1 -1
- package/dist/core/TypedData.d.ts +8 -1
- package/dist/core/TypedData.d.ts.map +1 -1
- package/dist/core/TypedData.js +51 -14
- package/dist/core/TypedData.js.map +1 -1
- package/dist/core/internal/abiItem.d.ts.map +1 -1
- package/dist/core/internal/abiItem.js +44 -13
- package/dist/core/internal/abiItem.js.map +1 -1
- package/dist/core/internal/abiParameters.d.ts +2 -2
- package/dist/core/internal/abiParameters.d.ts.map +1 -1
- package/dist/core/internal/abiParameters.js +24 -7
- package/dist/core/internal/abiParameters.js.map +1 -1
- package/dist/core/internal/rpcSchemas/eth.d.ts +3 -2
- package/dist/core/internal/rpcSchemas/eth.d.ts.map +1 -1
- package/dist/tempo/AccountConfig.d.ts +7 -17
- package/dist/tempo/AccountConfig.d.ts.map +1 -1
- package/dist/tempo/AccountConfig.js +8 -26
- package/dist/tempo/AccountConfig.js.map +1 -1
- package/dist/tempo/AccountOperation.d.ts +1 -1
- package/dist/tempo/AccountOperation.js +1 -1
- package/dist/tempo/KeyAuthorization.d.ts +21 -6
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/KeyAuthorization.js +7 -4
- package/dist/tempo/KeyAuthorization.js.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.js +6 -2
- package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
- package/dist/tempo/index.d.ts +1 -3
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +1 -3
- package/dist/tempo/index.js.map +1 -1
- package/dist/zod/Authorization.d.ts.map +1 -1
- package/dist/zod/Authorization.js +6 -9
- package/dist/zod/Authorization.js.map +1 -1
- package/package.json +5 -2
- package/src/core/Authorization.ts +43 -6
- package/src/core/Siwe.ts +1 -1
- package/src/core/TxEnvelope.ts +5 -3
- package/src/core/TxEnvelopeEip1559.ts +8 -2
- package/src/core/TxEnvelopeEip4844.ts +6 -0
- package/src/core/TxEnvelopeEip7702.ts +6 -0
- package/src/core/TypedData.ts +57 -13
- package/src/core/_test/AbiItem.test.ts +238 -4
- package/src/core/_test/AbiParameters.decode.test.ts +140 -1
- package/src/core/_test/Authorization.test.ts +166 -0
- package/src/core/_test/RpcSchema.test-d.ts +23 -1
- package/src/core/_test/Siwe.test.ts +53 -0
- package/src/core/_test/TransactionEnvelopeEip1559.test.ts +24 -0
- package/src/core/_test/TransactionEnvelopeEip4844.test.ts +13 -0
- package/src/core/_test/TransactionEnvelopeEip7702.test.ts +79 -0
- package/src/core/_test/TypedData.test.ts +188 -1
- package/src/core/internal/abiItem.ts +48 -17
- package/src/core/internal/abiParameters.ts +26 -8
- package/src/core/internal/rpcSchemas/eth.ts +2 -1
- package/src/tempo/AccountConfig.test.ts +34 -47
- package/src/tempo/AccountConfig.ts +9 -37
- package/src/tempo/AccountOperation.test.ts +36 -37
- package/src/tempo/AccountOperation.ts +1 -1
- package/src/tempo/KeyAuthorization.test.ts +6 -4
- package/src/tempo/KeyAuthorization.ts +26 -8
- package/src/tempo/SignatureEnvelope.test.ts +1 -3
- package/src/tempo/TxEnvelopeTempo.test.ts +26 -0
- package/src/tempo/TxEnvelopeTempo.ts +8 -2
- package/src/tempo/configurableAccounts.e2e.test.ts +1 -2
- package/src/tempo/e2e.test.ts +73 -17
- package/src/tempo/index.ts +1 -3
- package/src/version.ts +1 -1
- package/src/zod/Authorization.ts +6 -24
- package/src/zod/_test/Authorization.test.ts +35 -2
- package/src/zod/_test/TransactionRequest.test.ts +1 -1
|
@@ -1021,7 +1021,201 @@ describe('fromAbi', () => {
|
|
|
1021
1021
|
`)
|
|
1022
1022
|
})
|
|
1023
1023
|
|
|
1024
|
+
test('behavior: overloads: bytes32 vs bytes', () => {
|
|
1025
|
+
expect(() =>
|
|
1026
|
+
AbiItem.fromAbi(
|
|
1027
|
+
Abi.from([
|
|
1028
|
+
'function isValidSignature(bytes32 hash, bytes signature)',
|
|
1029
|
+
'function isValidSignature(bytes data, bytes signature)',
|
|
1030
|
+
]),
|
|
1031
|
+
'isValidSignature',
|
|
1032
|
+
{
|
|
1033
|
+
args: [
|
|
1034
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
1035
|
+
'0x1234',
|
|
1036
|
+
],
|
|
1037
|
+
},
|
|
1038
|
+
),
|
|
1039
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
|
1040
|
+
[AbiItem.AmbiguityError: Found ambiguous types in overloaded ABI Items.
|
|
1041
|
+
|
|
1042
|
+
\`bytes\` in \`isValidSignature(bytes,bytes)\`, and
|
|
1043
|
+
\`bytes32\` in \`isValidSignature(bytes32,bytes)\`
|
|
1044
|
+
|
|
1045
|
+
These types encode differently and cannot be distinguished at runtime.
|
|
1046
|
+
Remove one of the ambiguous items in the ABI.]
|
|
1047
|
+
`)
|
|
1048
|
+
})
|
|
1049
|
+
|
|
1050
|
+
test('behavior: overloads: uint256 vs int256', () => {
|
|
1051
|
+
expect(() =>
|
|
1052
|
+
AbiItem.fromAbi(
|
|
1053
|
+
Abi.from(['function foo(uint256 x)', 'function foo(int256 x)']),
|
|
1054
|
+
'foo',
|
|
1055
|
+
{ args: [1n] },
|
|
1056
|
+
),
|
|
1057
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
|
1058
|
+
[AbiItem.AmbiguityError: Found ambiguous types in overloaded ABI Items.
|
|
1059
|
+
|
|
1060
|
+
\`int256\` in \`foo(int256)\`, and
|
|
1061
|
+
\`uint256\` in \`foo(uint256)\`
|
|
1062
|
+
|
|
1063
|
+
These types encode differently and cannot be distinguished at runtime.
|
|
1064
|
+
Remove one of the ambiguous items in the ABI.]
|
|
1065
|
+
`)
|
|
1066
|
+
|
|
1067
|
+
expect(
|
|
1068
|
+
AbiItem.fromAbi(
|
|
1069
|
+
Abi.from(['function foo(uint256 x)', 'function foo(int256 x)']),
|
|
1070
|
+
'foo',
|
|
1071
|
+
{ args: [-1n] },
|
|
1072
|
+
).inputs,
|
|
1073
|
+
).toMatchInlineSnapshot(`
|
|
1074
|
+
[
|
|
1075
|
+
{
|
|
1076
|
+
"name": "x",
|
|
1077
|
+
"type": "int256",
|
|
1078
|
+
},
|
|
1079
|
+
]
|
|
1080
|
+
`)
|
|
1081
|
+
})
|
|
1082
|
+
|
|
1083
|
+
test('behavior: overloads: uint256[] vs uint256[2]', () => {
|
|
1084
|
+
expect(() =>
|
|
1085
|
+
AbiItem.fromAbi(
|
|
1086
|
+
Abi.from(['function foo(uint256[] x)', 'function foo(uint256[2] x)']),
|
|
1087
|
+
'foo',
|
|
1088
|
+
{ args: [[1n, 1n]] },
|
|
1089
|
+
),
|
|
1090
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
|
1091
|
+
[AbiItem.AmbiguityError: Found ambiguous types in overloaded ABI Items.
|
|
1092
|
+
|
|
1093
|
+
\`uint256[2]\` in \`foo(uint256[2])\`, and
|
|
1094
|
+
\`uint256[]\` in \`foo(uint256[])\`
|
|
1095
|
+
|
|
1096
|
+
These types encode differently and cannot be distinguished at runtime.
|
|
1097
|
+
Remove one of the ambiguous items in the ABI.]
|
|
1098
|
+
`)
|
|
1099
|
+
|
|
1100
|
+
expect(
|
|
1101
|
+
AbiItem.fromAbi(
|
|
1102
|
+
Abi.from(['function foo(uint256[] x)', 'function foo(uint256[2] x)']),
|
|
1103
|
+
'foo',
|
|
1104
|
+
{ args: [[1n, 1n, 1n]] },
|
|
1105
|
+
).inputs,
|
|
1106
|
+
).toMatchInlineSnapshot(`
|
|
1107
|
+
[
|
|
1108
|
+
{
|
|
1109
|
+
"name": "x",
|
|
1110
|
+
"type": "uint256[]",
|
|
1111
|
+
},
|
|
1112
|
+
]
|
|
1113
|
+
`)
|
|
1114
|
+
})
|
|
1115
|
+
|
|
1116
|
+
test('behavior: overloads: uint256[2][] vs uint256[][2]', () => {
|
|
1117
|
+
expect(() =>
|
|
1118
|
+
AbiItem.fromAbi(
|
|
1119
|
+
Abi.from([
|
|
1120
|
+
'function foo(uint256[2][] x)',
|
|
1121
|
+
'function foo(uint256[][2] x)',
|
|
1122
|
+
]),
|
|
1123
|
+
'foo',
|
|
1124
|
+
{
|
|
1125
|
+
args: [
|
|
1126
|
+
[
|
|
1127
|
+
[1n, 1n],
|
|
1128
|
+
[1n, 1n],
|
|
1129
|
+
],
|
|
1130
|
+
],
|
|
1131
|
+
},
|
|
1132
|
+
),
|
|
1133
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
|
1134
|
+
[AbiItem.AmbiguityError: Found ambiguous types in overloaded ABI Items.
|
|
1135
|
+
|
|
1136
|
+
\`uint256[]\` in \`foo(uint256[][2])\`, and
|
|
1137
|
+
\`uint256[2]\` in \`foo(uint256[2][])\`
|
|
1138
|
+
|
|
1139
|
+
These types encode differently and cannot be distinguished at runtime.
|
|
1140
|
+
Remove one of the ambiguous items in the ABI.]
|
|
1141
|
+
`)
|
|
1142
|
+
})
|
|
1143
|
+
|
|
1144
|
+
test('behavior: overloads: selector chooses one of two matches', () => {
|
|
1145
|
+
expect(
|
|
1146
|
+
AbiItem.fromAbi(
|
|
1147
|
+
Abi.from([
|
|
1148
|
+
'function isValidSignature(bytes32 hash, bytes signature)',
|
|
1149
|
+
'function isValidSignature(bytes data, bytes signature)',
|
|
1150
|
+
]),
|
|
1151
|
+
'0x1626ba7e',
|
|
1152
|
+
{
|
|
1153
|
+
args: [
|
|
1154
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
1155
|
+
'0x1234',
|
|
1156
|
+
],
|
|
1157
|
+
},
|
|
1158
|
+
).inputs,
|
|
1159
|
+
).toMatchInlineSnapshot(`
|
|
1160
|
+
[
|
|
1161
|
+
{
|
|
1162
|
+
"name": "hash",
|
|
1163
|
+
"type": "bytes32",
|
|
1164
|
+
},
|
|
1165
|
+
{
|
|
1166
|
+
"name": "signature",
|
|
1167
|
+
"type": "bytes",
|
|
1168
|
+
},
|
|
1169
|
+
]
|
|
1170
|
+
`)
|
|
1171
|
+
})
|
|
1172
|
+
|
|
1024
1173
|
describe('getAmbiguousTypes', () => {
|
|
1174
|
+
test('bytes', () => {
|
|
1175
|
+
expect(
|
|
1176
|
+
getAmbiguousTypes(
|
|
1177
|
+
AbiParameters.from('bytes32'),
|
|
1178
|
+
AbiParameters.from('bytes'),
|
|
1179
|
+
[
|
|
1180
|
+
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
1181
|
+
],
|
|
1182
|
+
),
|
|
1183
|
+
).toMatchInlineSnapshot(`
|
|
1184
|
+
[
|
|
1185
|
+
"bytes32",
|
|
1186
|
+
"bytes",
|
|
1187
|
+
]
|
|
1188
|
+
`)
|
|
1189
|
+
})
|
|
1190
|
+
|
|
1191
|
+
test('integers', () => {
|
|
1192
|
+
expect(
|
|
1193
|
+
getAmbiguousTypes(
|
|
1194
|
+
AbiParameters.from('uint256'),
|
|
1195
|
+
AbiParameters.from('int256'),
|
|
1196
|
+
[1n],
|
|
1197
|
+
),
|
|
1198
|
+
).toMatchInlineSnapshot(`
|
|
1199
|
+
[
|
|
1200
|
+
"uint256",
|
|
1201
|
+
"int256",
|
|
1202
|
+
]
|
|
1203
|
+
`)
|
|
1204
|
+
|
|
1205
|
+
expect(
|
|
1206
|
+
getAmbiguousTypes(
|
|
1207
|
+
AbiParameters.from('uint256'),
|
|
1208
|
+
AbiParameters.from('uint128'),
|
|
1209
|
+
[69420n],
|
|
1210
|
+
),
|
|
1211
|
+
).toMatchInlineSnapshot(`
|
|
1212
|
+
[
|
|
1213
|
+
"uint256",
|
|
1214
|
+
"uint128",
|
|
1215
|
+
]
|
|
1216
|
+
`)
|
|
1217
|
+
})
|
|
1218
|
+
|
|
1025
1219
|
test('string/address', () => {
|
|
1026
1220
|
expect(
|
|
1027
1221
|
getAmbiguousTypes(
|
|
@@ -1163,7 +1357,7 @@ describe('fromAbi', () => {
|
|
|
1163
1357
|
expect(
|
|
1164
1358
|
getAmbiguousTypes(
|
|
1165
1359
|
AbiParameters.from('uint256, (address)'),
|
|
1166
|
-
AbiParameters.from('
|
|
1360
|
+
AbiParameters.from('uint256, (bytes20)'),
|
|
1167
1361
|
[69420n, ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e']],
|
|
1168
1362
|
),
|
|
1169
1363
|
).toMatchInlineSnapshot(`
|
|
@@ -1175,7 +1369,7 @@ describe('fromAbi', () => {
|
|
|
1175
1369
|
expect(
|
|
1176
1370
|
getAmbiguousTypes(
|
|
1177
1371
|
AbiParameters.from('uint256, (string, (address))'),
|
|
1178
|
-
AbiParameters.from('
|
|
1372
|
+
AbiParameters.from('uint256, (string, (bytes20))'),
|
|
1179
1373
|
[69420n, ['foo', ['0xA0Cf798816D4b9b9866b5330EEa46a18382f251e']]],
|
|
1180
1374
|
),
|
|
1181
1375
|
).toMatchInlineSnapshot(`
|
|
@@ -1187,7 +1381,7 @@ describe('fromAbi', () => {
|
|
|
1187
1381
|
expect(
|
|
1188
1382
|
getAmbiguousTypes(
|
|
1189
1383
|
AbiParameters.from('uint256, (string, (address, bytes))'),
|
|
1190
|
-
AbiParameters.from('
|
|
1384
|
+
AbiParameters.from('uint256, (string, (bytes20, address))'),
|
|
1191
1385
|
[
|
|
1192
1386
|
123n,
|
|
1193
1387
|
[
|
|
@@ -1360,7 +1554,19 @@ describe('fromAbi', () => {
|
|
|
1360
1554
|
{ arg: 'true', abiParameter: { type: 'bool' }, expected: false },
|
|
1361
1555
|
// bytes
|
|
1362
1556
|
{ arg: 'foo', abiParameter: { type: 'bytes' }, expected: true },
|
|
1363
|
-
{ arg: 'foo', abiParameter: { type: 'bytes32' }, expected:
|
|
1557
|
+
{ arg: 'foo', abiParameter: { type: 'bytes32' }, expected: false },
|
|
1558
|
+
{ arg: '0x1234', abiParameter: { type: 'bytes2' }, expected: true },
|
|
1559
|
+
{ arg: '0x1234', abiParameter: { type: 'bytes4' }, expected: false },
|
|
1560
|
+
{
|
|
1561
|
+
arg: Bytes.fromString('foo'),
|
|
1562
|
+
abiParameter: { type: 'bytes3' },
|
|
1563
|
+
expected: true,
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
arg: Bytes.fromString('foo'),
|
|
1567
|
+
abiParameter: { type: 'bytes4' },
|
|
1568
|
+
expected: false,
|
|
1569
|
+
},
|
|
1364
1570
|
{
|
|
1365
1571
|
arg: Bytes.fromString('foo'),
|
|
1366
1572
|
abiParameter: { type: 'bytes' },
|
|
@@ -1381,6 +1587,34 @@ describe('fromAbi', () => {
|
|
|
1381
1587
|
{ arg: 1, abiParameter: { type: 'uint256' }, expected: true },
|
|
1382
1588
|
{ arg: 1, abiParameter: { type: 'int69' }, expected: false },
|
|
1383
1589
|
{ arg: 1, abiParameter: { type: 'uint69' }, expected: false },
|
|
1590
|
+
{ arg: -129, abiParameter: { type: 'int8' }, expected: false },
|
|
1591
|
+
{ arg: -128, abiParameter: { type: 'int8' }, expected: true },
|
|
1592
|
+
{ arg: 127, abiParameter: { type: 'int8' }, expected: true },
|
|
1593
|
+
{ arg: 128, abiParameter: { type: 'int8' }, expected: false },
|
|
1594
|
+
{ arg: -1n, abiParameter: { type: 'uint8' }, expected: false },
|
|
1595
|
+
{ arg: 0n, abiParameter: { type: 'uint8' }, expected: true },
|
|
1596
|
+
{ arg: 255n, abiParameter: { type: 'uint8' }, expected: true },
|
|
1597
|
+
{ arg: 256n, abiParameter: { type: 'uint8' }, expected: false },
|
|
1598
|
+
{ arg: 2n ** 256n - 1n, abiParameter: { type: 'uint256' }, expected: true },
|
|
1599
|
+
{ arg: 2n ** 256n, abiParameter: { type: 'uint256' }, expected: false },
|
|
1600
|
+
{ arg: -(2n ** 255n), abiParameter: { type: 'int256' }, expected: true },
|
|
1601
|
+
{
|
|
1602
|
+
arg: -(2n ** 255n) - 1n,
|
|
1603
|
+
abiParameter: { type: 'int256' },
|
|
1604
|
+
expected: false,
|
|
1605
|
+
},
|
|
1606
|
+
{ arg: Number.NaN, abiParameter: { type: 'uint256' }, expected: false },
|
|
1607
|
+
{
|
|
1608
|
+
arg: Number.POSITIVE_INFINITY,
|
|
1609
|
+
abiParameter: { type: 'uint256' },
|
|
1610
|
+
expected: false,
|
|
1611
|
+
},
|
|
1612
|
+
{ arg: 1.5, abiParameter: { type: 'uint256' }, expected: false },
|
|
1613
|
+
{
|
|
1614
|
+
arg: Number.MAX_SAFE_INTEGER + 1,
|
|
1615
|
+
abiParameter: { type: 'uint256' },
|
|
1616
|
+
expected: true,
|
|
1617
|
+
},
|
|
1384
1618
|
// string
|
|
1385
1619
|
{ arg: 'foo', abiParameter: { type: 'string' }, expected: true },
|
|
1386
1620
|
{ arg: 1, abiParameter: { type: 'string' }, expected: false },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbiItem, AbiParameters,
|
|
1
|
+
import { AbiItem, AbiParameters, Address, Bytes, Hex } from 'ox'
|
|
2
2
|
import { assertType, describe, expect, test } from 'vp/test'
|
|
3
3
|
|
|
4
4
|
import {
|
|
@@ -1887,3 +1887,142 @@ describe('zero-width types', () => {
|
|
|
1887
1887
|
}
|
|
1888
1888
|
})
|
|
1889
1889
|
})
|
|
1890
|
+
|
|
1891
|
+
describe('integer range', () => {
|
|
1892
|
+
test('uint8: max', () => {
|
|
1893
|
+
expect(
|
|
1894
|
+
AbiParameters.decode(
|
|
1895
|
+
AbiParameters.from('uint8'),
|
|
1896
|
+
'0x00000000000000000000000000000000000000000000000000000000000000ff',
|
|
1897
|
+
),
|
|
1898
|
+
).toEqual([255])
|
|
1899
|
+
})
|
|
1900
|
+
|
|
1901
|
+
test('uint8: above max', () => {
|
|
1902
|
+
expect(() =>
|
|
1903
|
+
AbiParameters.decode(
|
|
1904
|
+
AbiParameters.from('uint8'),
|
|
1905
|
+
'0x0000000000000000000000000000000000000000000000000000000000000100',
|
|
1906
|
+
),
|
|
1907
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1908
|
+
`[Hex.IntegerOutOfRangeError: Number \`256\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
1909
|
+
)
|
|
1910
|
+
})
|
|
1911
|
+
|
|
1912
|
+
test('int8: -1', () => {
|
|
1913
|
+
expect(
|
|
1914
|
+
AbiParameters.decode(
|
|
1915
|
+
AbiParameters.from('int8'),
|
|
1916
|
+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
|
|
1917
|
+
),
|
|
1918
|
+
).toEqual([-1])
|
|
1919
|
+
})
|
|
1920
|
+
|
|
1921
|
+
test('int8: missing sign extension', () => {
|
|
1922
|
+
expect(() =>
|
|
1923
|
+
AbiParameters.decode(
|
|
1924
|
+
AbiParameters.from('int8'),
|
|
1925
|
+
'0x0000000000000000000000000000000000000000000000000000000000000080',
|
|
1926
|
+
),
|
|
1927
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1928
|
+
`[Hex.IntegerOutOfRangeError: Number \`128\` is not in safe 8-bit signed integer range (\`-128\` to \`127\`)]`,
|
|
1929
|
+
)
|
|
1930
|
+
})
|
|
1931
|
+
|
|
1932
|
+
test('int8: below min', () => {
|
|
1933
|
+
expect(() =>
|
|
1934
|
+
AbiParameters.decode(
|
|
1935
|
+
AbiParameters.from('int8'),
|
|
1936
|
+
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
|
|
1937
|
+
),
|
|
1938
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1939
|
+
`[Hex.IntegerOutOfRangeError: Number \`-129\` is not in safe 8-bit signed integer range (\`-128\` to \`127\`)]`,
|
|
1940
|
+
)
|
|
1941
|
+
})
|
|
1942
|
+
|
|
1943
|
+
test('uint8[]: element above max', () => {
|
|
1944
|
+
expect(() =>
|
|
1945
|
+
AbiParameters.decode(
|
|
1946
|
+
AbiParameters.from('uint8[]'),
|
|
1947
|
+
'0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100',
|
|
1948
|
+
),
|
|
1949
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1950
|
+
`[Hex.IntegerOutOfRangeError: Number \`256\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
1951
|
+
)
|
|
1952
|
+
})
|
|
1953
|
+
|
|
1954
|
+
test('uint16: 2^64', () => {
|
|
1955
|
+
expect(() =>
|
|
1956
|
+
AbiParameters.decode(
|
|
1957
|
+
AbiParameters.from('uint16'),
|
|
1958
|
+
'0x0000000000000000000000000000000000000000000000010000000000000000',
|
|
1959
|
+
),
|
|
1960
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
1961
|
+
`[Hex.IntegerOutOfRangeError: Number \`18446744073709551616\` is not in safe 16-bit unsigned integer range (\`0\` to \`65535\`)]`,
|
|
1962
|
+
)
|
|
1963
|
+
})
|
|
1964
|
+
|
|
1965
|
+
test('every size: min and max round-trip, out of range throws', () => {
|
|
1966
|
+
for (let size = 8; size <= 256; size += 8) {
|
|
1967
|
+
for (const signed of [false, true]) {
|
|
1968
|
+
const type = (signed ? 'int' : 'uint') + size
|
|
1969
|
+
const parameters = AbiParameters.from(type)
|
|
1970
|
+
const max = (1n << BigInt(signed ? size - 1 : size)) - 1n
|
|
1971
|
+
const min = signed ? -max - 1n : 0n
|
|
1972
|
+
const cast = (value: bigint) => (size > 48 ? value : Number(value))
|
|
1973
|
+
|
|
1974
|
+
for (const value of [min, max])
|
|
1975
|
+
expect(
|
|
1976
|
+
AbiParameters.decode(
|
|
1977
|
+
parameters,
|
|
1978
|
+
AbiParameters.encode(parameters, [cast(value)] as never),
|
|
1979
|
+
),
|
|
1980
|
+
).toEqual([cast(value)])
|
|
1981
|
+
|
|
1982
|
+
if (size === 256) continue
|
|
1983
|
+
const word = (value: bigint) =>
|
|
1984
|
+
Hex.fromNumber(BigInt.asUintN(256, value), { size: 32 })
|
|
1985
|
+
expect(() => AbiParameters.decode(parameters, word(max + 1n))).toThrow(
|
|
1986
|
+
Hex.IntegerOutOfRangeError,
|
|
1987
|
+
)
|
|
1988
|
+
if (signed)
|
|
1989
|
+
expect(() =>
|
|
1990
|
+
AbiParameters.decode(parameters, word(min - 1n)),
|
|
1991
|
+
).toThrow(Hex.IntegerOutOfRangeError)
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
})
|
|
1995
|
+
})
|
|
1996
|
+
|
|
1997
|
+
describe('address padding', () => {
|
|
1998
|
+
test('dirty high bytes', () => {
|
|
1999
|
+
expect(() =>
|
|
2000
|
+
AbiParameters.decode(
|
|
2001
|
+
AbiParameters.from('address'),
|
|
2002
|
+
'0x00000000000000000000000114dc79964da2c08b23698b3d3cc7ca32193d9955',
|
|
2003
|
+
),
|
|
2004
|
+
).toThrowErrorMatchingInlineSnapshot(`
|
|
2005
|
+
[Address.InvalidAddressError: Address "0x00000000000000000000000114dc79964da2c08b23698b3d3cc7ca32193d9955" is invalid.
|
|
2006
|
+
|
|
2007
|
+
Details: Address is not a 20 byte (40 hexadecimal character) value.]
|
|
2008
|
+
`)
|
|
2009
|
+
})
|
|
2010
|
+
|
|
2011
|
+
test('dirty first byte', () => {
|
|
2012
|
+
expect(() =>
|
|
2013
|
+
AbiParameters.decode(
|
|
2014
|
+
AbiParameters.from('address'),
|
|
2015
|
+
'0xff000000000000000000000014dc79964da2c08b23698b3d3cc7ca32193d9955',
|
|
2016
|
+
),
|
|
2017
|
+
).toThrow(Address.InvalidAddressError)
|
|
2018
|
+
})
|
|
2019
|
+
|
|
2020
|
+
test('address[2]: second element dirty', () => {
|
|
2021
|
+
expect(() =>
|
|
2022
|
+
AbiParameters.decode(
|
|
2023
|
+
AbiParameters.from('address[2]'),
|
|
2024
|
+
'0x00000000000000000000000014dc79964da2c08b23698b3d3cc7ca32193d99550000000000000000000000ff14dc79964da2c08b23698b3d3cc7ca32193d9955',
|
|
2025
|
+
),
|
|
2026
|
+
).toThrow(Address.InvalidAddressError)
|
|
2027
|
+
})
|
|
2028
|
+
})
|
|
@@ -151,6 +151,43 @@ describe('fromRpc', () => {
|
|
|
151
151
|
}
|
|
152
152
|
`)
|
|
153
153
|
})
|
|
154
|
+
|
|
155
|
+
test('behavior: yParity above 1', () => {
|
|
156
|
+
expect(
|
|
157
|
+
Authorization.fromRpc({
|
|
158
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
159
|
+
chainId: '0x0',
|
|
160
|
+
nonce: '0x6',
|
|
161
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
162
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
163
|
+
yParity: '0x1c',
|
|
164
|
+
}),
|
|
165
|
+
).toMatchInlineSnapshot(`
|
|
166
|
+
{
|
|
167
|
+
"address": "0xc498cea4bfedbb8de856491bdd9967e677775f4f",
|
|
168
|
+
"chainId": 0,
|
|
169
|
+
"nonce": 6n,
|
|
170
|
+
"r": "0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512",
|
|
171
|
+
"s": "0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191",
|
|
172
|
+
"yParity": 28,
|
|
173
|
+
}
|
|
174
|
+
`)
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
test('error: yParity above 2**8 - 1', () => {
|
|
178
|
+
expect(() =>
|
|
179
|
+
Authorization.fromRpc({
|
|
180
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
181
|
+
chainId: '0x0',
|
|
182
|
+
nonce: '0x6',
|
|
183
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
184
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
185
|
+
yParity: '0x100',
|
|
186
|
+
}),
|
|
187
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
188
|
+
`[Hex.IntegerOutOfRangeError: Number \`256\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
189
|
+
)
|
|
190
|
+
})
|
|
154
191
|
})
|
|
155
192
|
|
|
156
193
|
describe('fromRpcList', () => {
|
|
@@ -251,6 +288,44 @@ describe('fromTuple', () => {
|
|
|
251
288
|
}
|
|
252
289
|
`)
|
|
253
290
|
})
|
|
291
|
+
|
|
292
|
+
test('behavior: yParity above 1', () => {
|
|
293
|
+
const tuple = [
|
|
294
|
+
'0x',
|
|
295
|
+
'0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
296
|
+
'0x06',
|
|
297
|
+
'0x1c',
|
|
298
|
+
'0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
299
|
+
'0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
300
|
+
] as const satisfies Authorization.Tuple
|
|
301
|
+
const authorization = Authorization.fromTuple(tuple)
|
|
302
|
+
expect(authorization).toMatchInlineSnapshot(`
|
|
303
|
+
{
|
|
304
|
+
"address": "0xc498cea4bfedbb8de856491bdd9967e677775f4f",
|
|
305
|
+
"chainId": 0,
|
|
306
|
+
"nonce": 6n,
|
|
307
|
+
"r": "0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512",
|
|
308
|
+
"s": "0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191",
|
|
309
|
+
"yParity": 28,
|
|
310
|
+
}
|
|
311
|
+
`)
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
test('error: yParity above 2**8 - 1', () => {
|
|
315
|
+
const tuple = [
|
|
316
|
+
'0x',
|
|
317
|
+
'0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
318
|
+
'0x06',
|
|
319
|
+
'0x0100',
|
|
320
|
+
'0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
321
|
+
'0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
322
|
+
] as const satisfies Authorization.Tuple
|
|
323
|
+
expect(() =>
|
|
324
|
+
Authorization.fromTuple(tuple),
|
|
325
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
326
|
+
`[Hex.IntegerOutOfRangeError: Number \`256\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
327
|
+
)
|
|
328
|
+
})
|
|
254
329
|
})
|
|
255
330
|
|
|
256
331
|
describe('fromTupleList', () => {
|
|
@@ -454,6 +529,43 @@ describe('toRpc', () => {
|
|
|
454
529
|
expect(fromBigint).toEqual(fromNumber)
|
|
455
530
|
expect(fromBigint).toEqual(fromHex)
|
|
456
531
|
})
|
|
532
|
+
|
|
533
|
+
test('behavior: yParity above 1', () => {
|
|
534
|
+
expect(
|
|
535
|
+
Authorization.toRpc({
|
|
536
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
537
|
+
chainId: 0,
|
|
538
|
+
nonce: 6n,
|
|
539
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
540
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
541
|
+
yParity: 28,
|
|
542
|
+
}),
|
|
543
|
+
).toMatchInlineSnapshot(`
|
|
544
|
+
{
|
|
545
|
+
"address": "0xc498cea4bfedbb8de856491bdd9967e677775f4f",
|
|
546
|
+
"chainId": "0x0",
|
|
547
|
+
"nonce": "0x6",
|
|
548
|
+
"r": "0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512",
|
|
549
|
+
"s": "0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191",
|
|
550
|
+
"yParity": "0x1c",
|
|
551
|
+
}
|
|
552
|
+
`)
|
|
553
|
+
})
|
|
554
|
+
|
|
555
|
+
test('error: yParity above 2**8 - 1', () => {
|
|
556
|
+
expect(() =>
|
|
557
|
+
Authorization.toRpc({
|
|
558
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
559
|
+
chainId: 0,
|
|
560
|
+
nonce: 6n,
|
|
561
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
562
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
563
|
+
yParity: 256,
|
|
564
|
+
}),
|
|
565
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
566
|
+
`[Hex.IntegerOutOfRangeError: Number \`256\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
567
|
+
)
|
|
568
|
+
})
|
|
457
569
|
})
|
|
458
570
|
|
|
459
571
|
describe('toRpcList', () => {
|
|
@@ -540,6 +652,60 @@ describe('toTuple', () => {
|
|
|
540
652
|
`)
|
|
541
653
|
}
|
|
542
654
|
})
|
|
655
|
+
|
|
656
|
+
test('behavior: yParity above 1', () => {
|
|
657
|
+
const authorization = Authorization.from({
|
|
658
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
659
|
+
chainId: 0,
|
|
660
|
+
nonce: 6n,
|
|
661
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
662
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
663
|
+
yParity: 28,
|
|
664
|
+
})
|
|
665
|
+
const tuple = Authorization.toTuple(authorization)
|
|
666
|
+
expect(tuple).toMatchInlineSnapshot(`
|
|
667
|
+
[
|
|
668
|
+
"0x",
|
|
669
|
+
"0xc498cea4bfedbb8de856491bdd9967e677775f4f",
|
|
670
|
+
"0x6",
|
|
671
|
+
"0x1c",
|
|
672
|
+
"0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512",
|
|
673
|
+
"0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191",
|
|
674
|
+
]
|
|
675
|
+
`)
|
|
676
|
+
})
|
|
677
|
+
|
|
678
|
+
test('error: yParity above 2**8 - 1', () => {
|
|
679
|
+
const authorization = Authorization.from({
|
|
680
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
681
|
+
chainId: 0,
|
|
682
|
+
nonce: 6n,
|
|
683
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
684
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
685
|
+
yParity: 256,
|
|
686
|
+
})
|
|
687
|
+
expect(() =>
|
|
688
|
+
Authorization.toTuple(authorization),
|
|
689
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
690
|
+
`[Hex.IntegerOutOfRangeError: Number \`256\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
691
|
+
)
|
|
692
|
+
})
|
|
693
|
+
|
|
694
|
+
test('error: yParity not an integer', () => {
|
|
695
|
+
const authorization = Authorization.from({
|
|
696
|
+
address: '0xc498cea4bfedbb8de856491bdd9967e677775f4f',
|
|
697
|
+
chainId: 0,
|
|
698
|
+
nonce: 6n,
|
|
699
|
+
r: '0x44754b7f217808e21f1935cfa450380e17a3ab8f2c6996c0190d678f0c14a512',
|
|
700
|
+
s: '0x27a6b869798cbbbd8d538dbc95b9bb28783bf08f8ef88ad6bb82552d0b47b191',
|
|
701
|
+
yParity: Number.NaN,
|
|
702
|
+
})
|
|
703
|
+
expect(() =>
|
|
704
|
+
Authorization.toTuple(authorization),
|
|
705
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
706
|
+
`[Hex.IntegerOutOfRangeError: Number \`NaN\` is not in safe 8-bit unsigned integer range (\`0\` to \`255\`)]`,
|
|
707
|
+
)
|
|
708
|
+
})
|
|
543
709
|
})
|
|
544
710
|
|
|
545
711
|
describe('toTupleList', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RpcSchema } from 'ox'
|
|
1
|
+
import { type Frame, RpcSchema } from 'ox'
|
|
2
2
|
import { z } from 'ox/zod'
|
|
3
3
|
import { describe, expectTypeOf, test } from 'vp/test'
|
|
4
4
|
|
|
@@ -246,6 +246,28 @@ test('frame fill responses do not require raw bytes or lookup metadata', () => {
|
|
|
246
246
|
expectTypeOf(filled).toExtend<Filled>()
|
|
247
247
|
})
|
|
248
248
|
|
|
249
|
+
test('fill responses expose fields not shared by every envelope as optional', () => {
|
|
250
|
+
type Tx = Extract<
|
|
251
|
+
RpcSchema.Eth,
|
|
252
|
+
{ Request: { method: 'eth_fillTransaction' } }
|
|
253
|
+
>['ReturnType']['tx']
|
|
254
|
+
expectTypeOf<Tx['from']>().toEqualTypeOf<`0x${string}`>()
|
|
255
|
+
expectTypeOf<Tx['gas']>().toEqualTypeOf<`0x${string}` | undefined>()
|
|
256
|
+
expectTypeOf<Tx['frames']>().toEqualTypeOf<readonly Frame.Rpc[] | undefined>()
|
|
257
|
+
|
|
258
|
+
type Eip1559 = Extract<Tx, { type: '0x2' }>
|
|
259
|
+
expectTypeOf<Eip1559['gas']>().toEqualTypeOf<`0x${string}` | undefined>()
|
|
260
|
+
expectTypeOf<Eip1559['gasPrice']>().toEqualTypeOf<undefined>()
|
|
261
|
+
expectTypeOf<Eip1559['maxFeePerGas']>().toEqualTypeOf<
|
|
262
|
+
`0x${string}` | undefined
|
|
263
|
+
>()
|
|
264
|
+
expectTypeOf<Eip1559['frames']>().toEqualTypeOf<undefined>()
|
|
265
|
+
|
|
266
|
+
type Eip8141 = Extract<Tx, { type: '0x6' }>
|
|
267
|
+
expectTypeOf<Eip8141['frames']>().toEqualTypeOf<readonly Frame.Rpc[]>()
|
|
268
|
+
expectTypeOf<Eip8141['gas']>().toEqualTypeOf<undefined>()
|
|
269
|
+
})
|
|
270
|
+
|
|
249
271
|
test('frame simulation results expose payer and frame results', () => {
|
|
250
272
|
type Result = Extract<
|
|
251
273
|
RpcSchema.Eth,
|