ox 1.0.0-beta.21 → 1.0.0-beta.22
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/erc4337/EntryPoint.d.ts +1072 -1
- package/dist/erc4337/EntryPoint.d.ts.map +1 -1
- package/dist/erc4337/EntryPoint.js +872 -0
- package/dist/erc4337/EntryPoint.js.map +1 -1
- package/dist/erc4337/RpcSchema.d.ts +2 -2
- package/dist/erc4337/RpcSchema.d.ts.map +1 -1
- package/dist/erc4337/UserOperation.d.ts +39 -10
- package/dist/erc4337/UserOperation.d.ts.map +1 -1
- package/dist/erc4337/UserOperation.js +62 -48
- package/dist/erc4337/UserOperation.js.map +1 -1
- package/dist/erc4337/UserOperationGas.d.ts +9 -5
- package/dist/erc4337/UserOperationGas.d.ts.map +1 -1
- package/dist/erc4337/UserOperationGas.js +17 -15
- package/dist/erc4337/UserOperationGas.js.map +1 -1
- package/dist/erc4337/UserOperationReceipt.d.ts +4 -4
- package/dist/erc4337/UserOperationReceipt.d.ts.map +1 -1
- package/dist/erc4337/UserOperationReceipt.js.map +1 -1
- package/package.json +1 -1
- package/src/erc4337/EntryPoint.ts +875 -1
- package/src/erc4337/RpcSchema.ts +4 -2
- package/src/erc4337/UserOperation.ts +130 -60
- package/src/erc4337/UserOperationGas.ts +36 -28
- package/src/erc4337/UserOperationReceipt.ts +15 -7
- package/src/erc4337/_test/EntryPoint.test.ts +48 -0
- package/src/erc4337/_test/RpcSchema.test-d.ts +56 -0
- package/src/erc4337/_test/UserOperation.snap-d.ts +31 -0
- package/src/erc4337/_test/UserOperation.test.ts +221 -5
- package/src/erc4337/_test/UserOperationGas.test.ts +30 -1
- package/src/version.ts +1 -1
|
@@ -215,6 +215,52 @@ describe('getSignPayload', () => {
|
|
|
215
215
|
})
|
|
216
216
|
|
|
217
217
|
describe('hash', () => {
|
|
218
|
+
describe('v0.9', () => {
|
|
219
|
+
const userOperation = {
|
|
220
|
+
callData: '0x',
|
|
221
|
+
callGasLimit: 6942069n,
|
|
222
|
+
maxFeePerGas: 69420n,
|
|
223
|
+
maxPriorityFeePerGas: 69n,
|
|
224
|
+
nonce: 0n,
|
|
225
|
+
paymaster: '0x1234567890123456789012345678901234567890',
|
|
226
|
+
paymasterData: '0xdeadbeef',
|
|
227
|
+
paymasterPostOpGasLimit: 6942069n,
|
|
228
|
+
paymasterVerificationGasLimit: 6942069n,
|
|
229
|
+
preVerificationGas: 6942069n,
|
|
230
|
+
sender: '0x1234567890123456789012345678901234567890',
|
|
231
|
+
signature: '0x',
|
|
232
|
+
verificationGasLimit: 6942069n,
|
|
233
|
+
} as const satisfies UserOperation.UserOperation<'0.9', true>
|
|
234
|
+
|
|
235
|
+
test('args: paymasterSignature', () => {
|
|
236
|
+
const options = {
|
|
237
|
+
chainId: 1,
|
|
238
|
+
entryPointAddress: '0x433709009B8330FDa32311DF1C2AFA402eD8D009',
|
|
239
|
+
entryPointVersion: '0.9',
|
|
240
|
+
} as const
|
|
241
|
+
|
|
242
|
+
expect(
|
|
243
|
+
UserOperation.hash(
|
|
244
|
+
{ ...userOperation, paymasterSignature: '0xcafebabe' },
|
|
245
|
+
options,
|
|
246
|
+
),
|
|
247
|
+
).toMatchInlineSnapshot(
|
|
248
|
+
`"0x802c25af5d98cd349b2118227faa93172fb791c4130a482272095cec45c4fc6e"`,
|
|
249
|
+
)
|
|
250
|
+
expect(
|
|
251
|
+
UserOperation.hash(
|
|
252
|
+
{ ...userOperation, paymasterSignature: '0xdeadbeef' },
|
|
253
|
+
options,
|
|
254
|
+
),
|
|
255
|
+
).toMatchInlineSnapshot(
|
|
256
|
+
`"0x802c25af5d98cd349b2118227faa93172fb791c4130a482272095cec45c4fc6e"`,
|
|
257
|
+
)
|
|
258
|
+
expect(UserOperation.hash(userOperation, options)).toMatchInlineSnapshot(
|
|
259
|
+
`"0xde381ae0368b77df677808c3a2da72abd68a07eab11ef31c35923f56a75bbe6d"`,
|
|
260
|
+
)
|
|
261
|
+
})
|
|
262
|
+
})
|
|
263
|
+
|
|
218
264
|
describe('v0.8', () => {
|
|
219
265
|
test('default', () => {
|
|
220
266
|
expect(
|
|
@@ -818,6 +864,54 @@ describe('toPacked', () => {
|
|
|
818
864
|
}
|
|
819
865
|
`)
|
|
820
866
|
})
|
|
867
|
+
|
|
868
|
+
describe('v0.9 paymasterSignature', () => {
|
|
869
|
+
const userOperation = {
|
|
870
|
+
callData: '0x',
|
|
871
|
+
callGasLimit: 6942069n,
|
|
872
|
+
maxFeePerGas: 69420n,
|
|
873
|
+
maxPriorityFeePerGas: 69n,
|
|
874
|
+
nonce: 0n,
|
|
875
|
+
paymaster: '0x1234567890123456789012345678901234567890',
|
|
876
|
+
paymasterData: '0xdeadbeef',
|
|
877
|
+
paymasterPostOpGasLimit: 6942069n,
|
|
878
|
+
paymasterSignature: '0xcafebabe',
|
|
879
|
+
paymasterVerificationGasLimit: 6942069n,
|
|
880
|
+
preVerificationGas: 6942069n,
|
|
881
|
+
sender: '0x1234567890123456789012345678901234567890',
|
|
882
|
+
signature: '0x',
|
|
883
|
+
verificationGasLimit: 6942069n,
|
|
884
|
+
} as const satisfies UserOperation.UserOperation<'0.9', true>
|
|
885
|
+
|
|
886
|
+
test('default', () => {
|
|
887
|
+
expect(
|
|
888
|
+
UserOperation.toPacked(userOperation).paymasterAndData,
|
|
889
|
+
).toMatchInlineSnapshot(
|
|
890
|
+
`"0x12345678901234567890123456789012345678900000000000000000000000000069ed750000000000000000000000000069ed75deadbeefcafebabe000422e325a297439656"`,
|
|
891
|
+
)
|
|
892
|
+
})
|
|
893
|
+
|
|
894
|
+
test('options: forHash', () => {
|
|
895
|
+
expect(
|
|
896
|
+
UserOperation.toPacked(userOperation, { forHash: true })
|
|
897
|
+
.paymasterAndData,
|
|
898
|
+
).toMatchInlineSnapshot(
|
|
899
|
+
`"0x12345678901234567890123456789012345678900000000000000000000000000069ed750000000000000000000000000069ed75deadbeef22e325a297439656"`,
|
|
900
|
+
)
|
|
901
|
+
})
|
|
902
|
+
|
|
903
|
+
test('encodes a uint16 signature length', () => {
|
|
904
|
+
const paymasterSignature = Hex.fromBytes(new Uint8Array(65).fill(0x11))
|
|
905
|
+
const paymasterAndData = UserOperation.toPacked({
|
|
906
|
+
...userOperation,
|
|
907
|
+
paymasterSignature,
|
|
908
|
+
}).paymasterAndData
|
|
909
|
+
|
|
910
|
+
expect(
|
|
911
|
+
Hex.slice(paymasterAndData, Hex.size(paymasterAndData) - 10),
|
|
912
|
+
).toMatchInlineSnapshot(`"0x004122e325a297439656"`)
|
|
913
|
+
})
|
|
914
|
+
})
|
|
821
915
|
})
|
|
822
916
|
|
|
823
917
|
describe('toInitCode', () => {
|
|
@@ -1170,6 +1264,96 @@ describe('toRpc', () => {
|
|
|
1170
1264
|
}
|
|
1171
1265
|
`)
|
|
1172
1266
|
})
|
|
1267
|
+
|
|
1268
|
+
test('v0.6 preserves paymasterAndData', () => {
|
|
1269
|
+
expect(
|
|
1270
|
+
UserOperation.toRpc({
|
|
1271
|
+
callData: '0x',
|
|
1272
|
+
callGasLimit: 0n,
|
|
1273
|
+
maxFeePerGas: 0n,
|
|
1274
|
+
maxPriorityFeePerGas: 0n,
|
|
1275
|
+
nonce: 0n,
|
|
1276
|
+
paymasterAndData: '0x1234567890123456789012345678901234567890deadbeef',
|
|
1277
|
+
preVerificationGas: 0n,
|
|
1278
|
+
sender: '0x1234567890123456789012345678901234567890',
|
|
1279
|
+
signature: '0x',
|
|
1280
|
+
verificationGasLimit: 0n,
|
|
1281
|
+
} satisfies UserOperation.UserOperation<'0.6', true>),
|
|
1282
|
+
).toMatchInlineSnapshot(`
|
|
1283
|
+
{
|
|
1284
|
+
"callData": "0x",
|
|
1285
|
+
"callGasLimit": "0x0",
|
|
1286
|
+
"maxFeePerGas": "0x0",
|
|
1287
|
+
"maxPriorityFeePerGas": "0x0",
|
|
1288
|
+
"nonce": "0x0",
|
|
1289
|
+
"paymasterAndData": "0x1234567890123456789012345678901234567890deadbeef",
|
|
1290
|
+
"preVerificationGas": "0x0",
|
|
1291
|
+
"sender": "0x1234567890123456789012345678901234567890",
|
|
1292
|
+
"signature": "0x",
|
|
1293
|
+
"verificationGasLimit": "0x0",
|
|
1294
|
+
}
|
|
1295
|
+
`)
|
|
1296
|
+
})
|
|
1297
|
+
|
|
1298
|
+
test('v0.6 preserves empty paymasterAndData', () => {
|
|
1299
|
+
expect(
|
|
1300
|
+
UserOperation.toRpc({
|
|
1301
|
+
callData: '0x',
|
|
1302
|
+
callGasLimit: 0n,
|
|
1303
|
+
maxFeePerGas: 0n,
|
|
1304
|
+
maxPriorityFeePerGas: 0n,
|
|
1305
|
+
nonce: 0n,
|
|
1306
|
+
paymasterAndData: '0x',
|
|
1307
|
+
preVerificationGas: 0n,
|
|
1308
|
+
sender: '0x1234567890123456789012345678901234567890',
|
|
1309
|
+
signature: '0x',
|
|
1310
|
+
verificationGasLimit: 0n,
|
|
1311
|
+
} satisfies UserOperation.UserOperation<'0.6', true>),
|
|
1312
|
+
).toMatchInlineSnapshot(`
|
|
1313
|
+
{
|
|
1314
|
+
"callData": "0x",
|
|
1315
|
+
"callGasLimit": "0x0",
|
|
1316
|
+
"maxFeePerGas": "0x0",
|
|
1317
|
+
"maxPriorityFeePerGas": "0x0",
|
|
1318
|
+
"nonce": "0x0",
|
|
1319
|
+
"paymasterAndData": "0x",
|
|
1320
|
+
"preVerificationGas": "0x0",
|
|
1321
|
+
"sender": "0x1234567890123456789012345678901234567890",
|
|
1322
|
+
"signature": "0x",
|
|
1323
|
+
"verificationGasLimit": "0x0",
|
|
1324
|
+
}
|
|
1325
|
+
`)
|
|
1326
|
+
})
|
|
1327
|
+
|
|
1328
|
+
test('v0.9 preserves paymasterSignature', () => {
|
|
1329
|
+
expect(
|
|
1330
|
+
UserOperation.toRpc({
|
|
1331
|
+
callData: '0x',
|
|
1332
|
+
callGasLimit: 0n,
|
|
1333
|
+
maxFeePerGas: 0n,
|
|
1334
|
+
maxPriorityFeePerGas: 0n,
|
|
1335
|
+
nonce: 0n,
|
|
1336
|
+
paymasterSignature: '0xcafebabe',
|
|
1337
|
+
preVerificationGas: 0n,
|
|
1338
|
+
sender: '0x1234567890123456789012345678901234567890',
|
|
1339
|
+
signature: '0x',
|
|
1340
|
+
verificationGasLimit: 0n,
|
|
1341
|
+
} satisfies UserOperation.UserOperation<'0.9', true>),
|
|
1342
|
+
).toMatchInlineSnapshot(`
|
|
1343
|
+
{
|
|
1344
|
+
"callData": "0x",
|
|
1345
|
+
"callGasLimit": "0x0",
|
|
1346
|
+
"maxFeePerGas": "0x0",
|
|
1347
|
+
"maxPriorityFeePerGas": "0x0",
|
|
1348
|
+
"nonce": "0x0",
|
|
1349
|
+
"paymasterSignature": "0xcafebabe",
|
|
1350
|
+
"preVerificationGas": "0x0",
|
|
1351
|
+
"sender": "0x1234567890123456789012345678901234567890",
|
|
1352
|
+
"signature": "0x",
|
|
1353
|
+
"verificationGasLimit": "0x0",
|
|
1354
|
+
}
|
|
1355
|
+
`)
|
|
1356
|
+
})
|
|
1173
1357
|
})
|
|
1174
1358
|
|
|
1175
1359
|
describe('toTypedData', () => {
|
|
@@ -1465,9 +1649,9 @@ describe('v0.8 authorization round-trip', () => {
|
|
|
1465
1649
|
verificationGasLimit: 100_000n,
|
|
1466
1650
|
} as const satisfies UserOperation.UserOperation<'0.8', true>
|
|
1467
1651
|
|
|
1468
|
-
test('toRpc serializes
|
|
1652
|
+
test('toRpc serializes eip7702Auth', () => {
|
|
1469
1653
|
const rpc = UserOperation.toRpc(userOperation) as UserOperation.Rpc<'0.8'>
|
|
1470
|
-
expect(rpc.
|
|
1654
|
+
expect(rpc.eip7702Auth).toMatchInlineSnapshot(`
|
|
1471
1655
|
{
|
|
1472
1656
|
"address": "0x1234567890123456789012345678901234567890",
|
|
1473
1657
|
"chainId": "0x1",
|
|
@@ -1479,7 +1663,7 @@ describe('v0.8 authorization round-trip', () => {
|
|
|
1479
1663
|
`)
|
|
1480
1664
|
})
|
|
1481
1665
|
|
|
1482
|
-
test('fromRpc parses
|
|
1666
|
+
test('fromRpc parses eip7702Auth', () => {
|
|
1483
1667
|
const rpc = UserOperation.toRpc(userOperation) as UserOperation.Rpc<'0.8'>
|
|
1484
1668
|
const parsed = UserOperation.fromRpc(rpc) as UserOperation.UserOperation<
|
|
1485
1669
|
'0.8',
|
|
@@ -1494,9 +1678,41 @@ describe('v0.8 authorization round-trip', () => {
|
|
|
1494
1678
|
expect(parsed).toEqual(userOperation)
|
|
1495
1679
|
})
|
|
1496
1680
|
|
|
1497
|
-
test('toRpc omits
|
|
1681
|
+
test('toRpc omits eip7702Auth when absent', () => {
|
|
1498
1682
|
const { authorization: _omit, ...rest } = userOperation
|
|
1499
1683
|
const rpc = UserOperation.toRpc(rest)
|
|
1500
|
-
expect('
|
|
1684
|
+
expect('eip7702Auth' in rpc).toBe(false)
|
|
1685
|
+
})
|
|
1686
|
+
})
|
|
1687
|
+
|
|
1688
|
+
describe('v0.9 RPC round-trip', () => {
|
|
1689
|
+
test('preserves paymasterSignature and parses eip7702Auth', () => {
|
|
1690
|
+
const userOperation = {
|
|
1691
|
+
authorization: {
|
|
1692
|
+
address: '0x1234567890123456789012345678901234567890',
|
|
1693
|
+
chainId: 1,
|
|
1694
|
+
nonce: 0n,
|
|
1695
|
+
r: '0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
1696
|
+
s: '0x0000000000000000000000000000000000000000000000000000000000000002',
|
|
1697
|
+
yParity: 0,
|
|
1698
|
+
},
|
|
1699
|
+
callData: '0x',
|
|
1700
|
+
callGasLimit: 0n,
|
|
1701
|
+
maxFeePerGas: 0n,
|
|
1702
|
+
maxPriorityFeePerGas: 0n,
|
|
1703
|
+
nonce: 0n,
|
|
1704
|
+
paymasterSignature: '0xcafebabe',
|
|
1705
|
+
preVerificationGas: 0n,
|
|
1706
|
+
sender: '0x1234567890123456789012345678901234567890',
|
|
1707
|
+
signature: '0x',
|
|
1708
|
+
verificationGasLimit: 0n,
|
|
1709
|
+
} as const satisfies UserOperation.UserOperation<'0.9', true>
|
|
1710
|
+
|
|
1711
|
+
const rpc = UserOperation.toRpc(userOperation)
|
|
1712
|
+
const parsed = UserOperation.fromRpc(rpc)
|
|
1713
|
+
|
|
1714
|
+
expect(rpc).toHaveProperty('eip7702Auth')
|
|
1715
|
+
expect(rpc).not.toHaveProperty('authorization')
|
|
1716
|
+
expect(parsed).toEqual(userOperation)
|
|
1501
1717
|
})
|
|
1502
1718
|
})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UserOperationGas } from 'ox/erc4337'
|
|
2
|
-
import { describe, expect, test } from 'vp/test'
|
|
2
|
+
import { describe, expect, expectTypeOf, test } from 'vp/test'
|
|
3
3
|
|
|
4
4
|
describe('fromRpc', () => {
|
|
5
5
|
test('default', () => {
|
|
@@ -91,3 +91,32 @@ describe('v0.8', () => {
|
|
|
91
91
|
expect(parsed).toEqual(v08)
|
|
92
92
|
})
|
|
93
93
|
})
|
|
94
|
+
|
|
95
|
+
describe('v0.9', () => {
|
|
96
|
+
test('round-trips matching v0.8 shape', () => {
|
|
97
|
+
const v09 = {
|
|
98
|
+
callGasLimit: 300_000n,
|
|
99
|
+
paymasterPostOpGasLimit: 100_000n,
|
|
100
|
+
paymasterVerificationGasLimit: 100_000n,
|
|
101
|
+
preVerificationGas: 100_000n,
|
|
102
|
+
verificationGasLimit: 100_000n,
|
|
103
|
+
} as const satisfies UserOperationGas.UserOperationGas<'0.9'>
|
|
104
|
+
|
|
105
|
+
const rpc = UserOperationGas.toRpc<'0.9'>(v09)
|
|
106
|
+
const parsed = UserOperationGas.fromRpc<'0.9'>(rpc)
|
|
107
|
+
|
|
108
|
+
expectTypeOf(rpc).toEqualTypeOf<UserOperationGas.Rpc<'0.9'>>()
|
|
109
|
+
expectTypeOf(parsed).toEqualTypeOf<
|
|
110
|
+
UserOperationGas.UserOperationGas<'0.9'>
|
|
111
|
+
>()
|
|
112
|
+
expect(parsed).toMatchInlineSnapshot(`
|
|
113
|
+
{
|
|
114
|
+
"callGasLimit": 300000n,
|
|
115
|
+
"paymasterPostOpGasLimit": 100000n,
|
|
116
|
+
"paymasterVerificationGasLimit": 100000n,
|
|
117
|
+
"preVerificationGas": 100000n,
|
|
118
|
+
"verificationGasLimit": 100000n,
|
|
119
|
+
}
|
|
120
|
+
`)
|
|
121
|
+
})
|
|
122
|
+
})
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal */
|
|
2
|
-
export const version = '1.0.0-beta.
|
|
2
|
+
export const version = '1.0.0-beta.22'
|