ox 1.8.3 → 1.8.4
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 +18 -0
- package/dist/core/Transaction.d.ts +5 -2
- package/dist/core/Transaction.d.ts.map +1 -1
- package/dist/core/Transaction.js +8 -0
- package/dist/core/Transaction.js.map +1 -1
- package/dist/core/TransactionRequest.d.ts +5 -2
- package/dist/core/TransactionRequest.d.ts.map +1 -1
- package/dist/core/TransactionRequest.js +8 -0
- package/dist/core/TransactionRequest.js.map +1 -1
- package/dist/core/TxEnvelope.d.ts +1 -1
- package/dist/core/TxEnvelope.d.ts.map +1 -1
- package/dist/core/TxEnvelope.js +2 -1
- package/dist/core/TxEnvelope.js.map +1 -1
- package/dist/core/TxEnvelopeEip8141.d.ts +18 -7
- package/dist/core/TxEnvelopeEip8141.d.ts.map +1 -1
- package/dist/core/TxEnvelopeEip8141.js +37 -8
- package/dist/core/TxEnvelopeEip8141.js.map +1 -1
- package/dist/core/internal/frameNonce.d.ts +10 -0
- package/dist/core/internal/frameNonce.d.ts.map +1 -0
- package/dist/core/internal/frameNonce.js +45 -0
- package/dist/core/internal/frameNonce.js.map +1 -0
- package/dist/zod/Block.d.ts +3 -0
- package/dist/zod/Block.d.ts.map +1 -1
- package/dist/zod/RpcSchema.d.ts +23 -0
- package/dist/zod/RpcSchema.d.ts.map +1 -1
- package/dist/zod/Transaction.d.ts +6 -0
- package/dist/zod/Transaction.d.ts.map +1 -1
- package/dist/zod/Transaction.js +18 -11
- package/dist/zod/Transaction.js.map +1 -1
- package/dist/zod/TransactionEnvelope.d.ts +10 -0
- package/dist/zod/TransactionEnvelope.d.ts.map +1 -1
- package/dist/zod/TransactionRequest.d.ts +2 -0
- package/dist/zod/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/TransactionRequest.js +9 -3
- package/dist/zod/TransactionRequest.js.map +1 -1
- package/dist/zod/TxEnvelopeEip8141.d.ts +7 -0
- package/dist/zod/TxEnvelopeEip8141.d.ts.map +1 -1
- package/dist/zod/TxEnvelopeEip8141.js +2 -0
- package/dist/zod/TxEnvelopeEip8141.js.map +1 -1
- package/dist/zod/internal/Frame.d.ts +8 -0
- package/dist/zod/internal/Frame.d.ts.map +1 -1
- package/dist/zod/internal/Frame.js +29 -0
- package/dist/zod/internal/Frame.js.map +1 -1
- package/dist/zod/internal/rpcSchemas/Eth.d.ts +23 -0
- package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
- package/dist/zod/internal/rpcSchemas/Wallet.d.ts +2 -0
- package/dist/zod/internal/rpcSchemas/Wallet.d.ts.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +4 -0
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +3 -0
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/Transaction.ts +17 -0
- package/src/core/TransactionRequest.ts +12 -0
- package/src/core/TxEnvelope.ts +7 -2
- package/src/core/TxEnvelopeEip8141.ts +61 -13
- package/src/core/_test/TransactionEnvelope.test-d.ts +27 -0
- package/src/core/_test/TransactionEnvelope.test.ts +26 -0
- package/src/core/_test/TransactionRequest.test.ts +28 -0
- package/src/core/_test/TxEnvelopeEip8141.test-d.ts +27 -0
- package/src/core/_test/TxEnvelopeEip8141.test.ts +456 -2
- package/src/core/internal/frameNonce.ts +61 -0
- package/src/version.ts +1 -1
- package/src/zod/Transaction.ts +42 -23
- package/src/zod/TransactionRequest.ts +32 -17
- package/src/zod/TxEnvelopeEip8141.ts +2 -0
- package/src/zod/_test/TxEnvelopeEip8141.nonce.test.ts +174 -0
- package/src/zod/_test/TxEnvelopeEip8141.test-d.ts +29 -0
- package/src/zod/internal/Frame.ts +45 -0
|
@@ -6,12 +6,18 @@ import * as Frame from './Frame.js'
|
|
|
6
6
|
import * as FrameSignature from './FrameSignature.js'
|
|
7
7
|
import * as Hash from './Hash.js'
|
|
8
8
|
import * as Hex from './Hex.js'
|
|
9
|
+
import * as FrameNonce from './internal/frameNonce.js'
|
|
9
10
|
import * as Quantity from './internal/quantity.js'
|
|
10
11
|
import type { Assign, Compute, PartialBy } from './internal/types.js'
|
|
11
12
|
import * as Rlp from './Rlp.js'
|
|
12
13
|
import type * as TxEnvelopeEip4844 from './TxEnvelopeEip4844.js'
|
|
13
14
|
|
|
14
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* An EIP-8141 transaction containing independently budgeted call frames.
|
|
17
|
+
*
|
|
18
|
+
* Omitted `nonceKeys` preserves the original EIP-8141 encoding. Supplying keys,
|
|
19
|
+
* including `[0n]`, selects EIP-8250 encoding and changes the signing hash.
|
|
20
|
+
*/
|
|
15
21
|
export type TxEnvelopeEip8141 = {
|
|
16
22
|
/** Versioned blob hashes. @default [] */
|
|
17
23
|
blobVersionedHashes?: readonly Hex.Hex[] | undefined
|
|
@@ -25,8 +31,10 @@ export type TxEnvelopeEip8141 = {
|
|
|
25
31
|
maxFeePerGas?: bigint | undefined
|
|
26
32
|
/** Maximum priority fee per gas, in wei. @default 0n */
|
|
27
33
|
maxPriorityFeePerGas?: bigint | undefined
|
|
28
|
-
/** Sender nonce. @default 0n */
|
|
34
|
+
/** Sender nonce or shared sequence. With `nonceKeys`, the sequence must be less than 2^64 - 1. @default 0n */
|
|
29
35
|
nonce?: bigint | undefined
|
|
36
|
+
/** EIP-8250 domains: 1–16 strictly increasing uint256 keys. `[0n]` selects the legacy account nonce; zero cannot accompany other keys. */
|
|
37
|
+
nonceKeys?: readonly bigint[] | undefined
|
|
30
38
|
/** Account authorizing execution. */
|
|
31
39
|
sender: Address.Address
|
|
32
40
|
/** PeerDAS sidecars. Excluded from transaction and signing hashes. */
|
|
@@ -53,8 +61,10 @@ export type Rpc = {
|
|
|
53
61
|
maxFeePerGas: Hex.Hex
|
|
54
62
|
/** Maximum priority fee per gas. */
|
|
55
63
|
maxPriorityFeePerGas: Hex.Hex
|
|
56
|
-
/** Sender nonce. */
|
|
64
|
+
/** Sender nonce or shared EIP-8250 sequence. */
|
|
57
65
|
nonce: Hex.Hex
|
|
66
|
+
/** EIP-8250 domains. Omitted for the original EIP-8141 encoding. */
|
|
67
|
+
nonceKeys?: readonly Hex.Hex[] | undefined
|
|
58
68
|
/** Frame signature entries. */
|
|
59
69
|
signatures: readonly FrameSignature.Rpc[]
|
|
60
70
|
/** RPC transaction type. */
|
|
@@ -106,6 +116,7 @@ export function assert(envelope: PartialBy<TxEnvelopeEip8141, 'type'>): void {
|
|
|
106
116
|
maxFeePerGas = 0n,
|
|
107
117
|
maxPriorityFeePerGas = 0n,
|
|
108
118
|
nonce = 0n,
|
|
119
|
+
nonceKeys,
|
|
109
120
|
sender,
|
|
110
121
|
signatures = [],
|
|
111
122
|
} = envelope
|
|
@@ -118,6 +129,7 @@ export function assert(envelope: PartialBy<TxEnvelopeEip8141, 'type'>): void {
|
|
|
118
129
|
throw new InvalidError(
|
|
119
130
|
'chainId must be an unsigned 256-bit integer; use bigint for large IDs.',
|
|
120
131
|
)
|
|
132
|
+
if (nonceKeys !== undefined) FrameNonce.assert(nonceKeys, nonce)
|
|
121
133
|
Address.assert(sender, { strict: false })
|
|
122
134
|
for (const [field, value, bits] of [
|
|
123
135
|
['maxFeePerBlobGas', maxFeePerBlobGas, 256n],
|
|
@@ -157,6 +169,18 @@ export function assert(envelope: PartialBy<TxEnvelopeEip8141, 'type'>): void {
|
|
|
157
169
|
for (const byte of Hex.toBytes(data)) tokens += byte === 0 ? 1n : 4n
|
|
158
170
|
size += BigInt(Hex.size(data))
|
|
159
171
|
}
|
|
172
|
+
if (nonceKeys !== undefined) {
|
|
173
|
+
count(
|
|
174
|
+
Rlp.fromHex(
|
|
175
|
+
nonceKeys.map((key) =>
|
|
176
|
+
key === 0n ? '0x' : Hex.fromBytes(Bytes.fromNumber(key)),
|
|
177
|
+
),
|
|
178
|
+
),
|
|
179
|
+
)
|
|
180
|
+
count(
|
|
181
|
+
Rlp.fromHex(nonce === 0n ? '0x' : Hex.fromBytes(Bytes.fromNumber(nonce))),
|
|
182
|
+
)
|
|
183
|
+
}
|
|
160
184
|
for (const [index, frame] of (frames as readonly Frame.Frame[]).entries()) {
|
|
161
185
|
Frame.assert(frame)
|
|
162
186
|
const flags =
|
|
@@ -221,6 +245,7 @@ export function assert(envelope: PartialBy<TxEnvelopeEip8141, 'type'>): void {
|
|
|
221
245
|
export declare namespace assert {
|
|
222
246
|
type ErrorType =
|
|
223
247
|
| InvalidError
|
|
248
|
+
| FrameNonce.InvalidError
|
|
224
249
|
| Frame.assert.ErrorType
|
|
225
250
|
| FrameSignature.toTuple.ErrorType
|
|
226
251
|
| Address.assert.ErrorType
|
|
@@ -258,9 +283,14 @@ export function deserialize(serialized: Serialized): TxEnvelopeEip8141 {
|
|
|
258
283
|
throw new InvalidError('Expected a transaction list.')
|
|
259
284
|
const wrapped = Array.isArray(decoded[0])
|
|
260
285
|
const body = wrapped ? decoded[0] : decoded
|
|
261
|
-
if (!Array.isArray(body) || body.length !== 7)
|
|
262
|
-
throw new InvalidError('Expected seven transaction fields.')
|
|
263
|
-
const
|
|
286
|
+
if (!Array.isArray(body) || (body.length !== 7 && body.length !== 8))
|
|
287
|
+
throw new InvalidError('Expected seven or eight transaction fields.')
|
|
288
|
+
const keyed = body.length === 8
|
|
289
|
+
const [chainId, ...fields] = body
|
|
290
|
+
const keys = keyed ? fields.shift() : undefined
|
|
291
|
+
if (keyed && !Array.isArray(keys))
|
|
292
|
+
throw new InvalidError('Expected a nonce key list.')
|
|
293
|
+
const [nonce, sender, frames, signatures, fees, hashes] = fields
|
|
264
294
|
if (
|
|
265
295
|
typeof sender !== 'string' ||
|
|
266
296
|
!Array.isArray(frames) ||
|
|
@@ -288,6 +318,7 @@ export function deserialize(serialized: Serialized): TxEnvelopeEip8141 {
|
|
|
288
318
|
maxFeePerGas: integer(fees[1]),
|
|
289
319
|
maxPriorityFeePerGas: integer(fees[0]),
|
|
290
320
|
nonce: integer(nonce),
|
|
321
|
+
...(Array.isArray(keys) ? { nonceKeys: keys.map(integer) } : {}),
|
|
291
322
|
sender: sender as Address.Address,
|
|
292
323
|
signatures: signatures.map((entry) =>
|
|
293
324
|
FrameSignature.fromTuple(entry as FrameSignature.Tuple),
|
|
@@ -403,6 +434,9 @@ export function fromRpc(envelope: Rpc): TxEnvelopeEip8141 {
|
|
|
403
434
|
maxFeePerGas: Hex.toBigInt(envelope.maxFeePerGas),
|
|
404
435
|
maxPriorityFeePerGas: Hex.toBigInt(envelope.maxPriorityFeePerGas),
|
|
405
436
|
nonce: Hex.toBigInt(envelope.nonce),
|
|
437
|
+
...(envelope.nonceKeys !== undefined
|
|
438
|
+
? { nonceKeys: FrameNonce.fromRpc(envelope.nonceKeys, envelope.nonce) }
|
|
439
|
+
: {}),
|
|
406
440
|
sender: envelope.from,
|
|
407
441
|
signatures: envelope.signatures.map(FrameSignature.fromRpc),
|
|
408
442
|
})
|
|
@@ -410,6 +444,7 @@ export function fromRpc(envelope: Rpc): TxEnvelopeEip8141 {
|
|
|
410
444
|
|
|
411
445
|
export declare namespace fromRpc {
|
|
412
446
|
type ErrorType =
|
|
447
|
+
| FrameNonce.InvalidError
|
|
413
448
|
| from.ErrorType
|
|
414
449
|
| Frame.fromRpc.ErrorType
|
|
415
450
|
| FrameSignature.fromRpc.ErrorType
|
|
@@ -448,6 +483,9 @@ export function toRpc(envelope: toRpc.Input): Rpc {
|
|
|
448
483
|
envelope.maxPriorityFeePerGas ?? 0n,
|
|
449
484
|
),
|
|
450
485
|
nonce: Quantity.fromNumberish(envelope.nonce ?? 0n),
|
|
486
|
+
...(envelope.nonceKeys !== undefined
|
|
487
|
+
? { nonceKeys: FrameNonce.toRpc(envelope.nonceKeys, envelope.nonce) }
|
|
488
|
+
: {}),
|
|
451
489
|
signatures: (envelope.signatures ?? []).map(FrameSignature.toRpc),
|
|
452
490
|
type: '0x6',
|
|
453
491
|
}
|
|
@@ -462,6 +500,7 @@ export declare namespace toRpc {
|
|
|
462
500
|
| 'maxFeePerGas'
|
|
463
501
|
| 'maxPriorityFeePerGas'
|
|
464
502
|
| 'nonce'
|
|
503
|
+
| 'nonceKeys'
|
|
465
504
|
| 'type'
|
|
466
505
|
> & {
|
|
467
506
|
chainId: Hex.Hex | bigint | number
|
|
@@ -470,9 +509,11 @@ export declare namespace toRpc {
|
|
|
470
509
|
maxFeePerGas?: Hex.Hex | bigint | number | undefined
|
|
471
510
|
maxPriorityFeePerGas?: Hex.Hex | bigint | number | undefined
|
|
472
511
|
nonce?: Hex.Hex | bigint | number | undefined
|
|
512
|
+
nonceKeys?: readonly (Hex.Hex | bigint | number)[] | undefined
|
|
473
513
|
type?: Type | undefined
|
|
474
514
|
}
|
|
475
515
|
type ErrorType =
|
|
516
|
+
| FrameNonce.InvalidError
|
|
476
517
|
| Frame.toRpc.ErrorType
|
|
477
518
|
| FrameSignature.toRpc.ErrorType
|
|
478
519
|
| Hex.fromNumber.ErrorType
|
|
@@ -560,10 +601,12 @@ export function hash(
|
|
|
560
601
|
): Hex.Hex {
|
|
561
602
|
assert(envelope)
|
|
562
603
|
const body = toTuple(envelope)
|
|
563
|
-
if (options.presign)
|
|
564
|
-
body[
|
|
565
|
-
|
|
566
|
-
|
|
604
|
+
if (options.presign) {
|
|
605
|
+
const signatures = body.length === 8 ? body[5] : body[4]
|
|
606
|
+
for (const [index, entry] of signatures.entries())
|
|
607
|
+
if (entry[2] === '0x')
|
|
608
|
+
signatures[index] = [entry[0], entry[1], entry[2], '0x']
|
|
609
|
+
}
|
|
567
610
|
return Hash.keccak256(Hex.concat(serializedType, Rlp.fromHex(body)))
|
|
568
611
|
}
|
|
569
612
|
export declare namespace hash {
|
|
@@ -690,8 +733,7 @@ export class InvalidError extends Errors.BaseError {
|
|
|
690
733
|
function toTuple(envelope: PartialBy<TxEnvelopeEip8141, 'type'>) {
|
|
691
734
|
const quantity = (value: bigint | number | undefined): Hex.Hex =>
|
|
692
735
|
value ? Hex.fromBytes(Bytes.fromNumber(value)) : '0x'
|
|
693
|
-
|
|
694
|
-
quantity(envelope.chainId),
|
|
736
|
+
const fields = [
|
|
695
737
|
quantity(envelope.nonce),
|
|
696
738
|
envelope.sender,
|
|
697
739
|
envelope.frames.map((frame) => Frame.toTuple(frame)),
|
|
@@ -703,7 +745,6 @@ function toTuple(envelope: PartialBy<TxEnvelopeEip8141, 'type'>) {
|
|
|
703
745
|
],
|
|
704
746
|
envelope.blobVersionedHashes ?? [],
|
|
705
747
|
] satisfies [
|
|
706
|
-
Hex.Hex,
|
|
707
748
|
Hex.Hex,
|
|
708
749
|
Address.Address,
|
|
709
750
|
Frame.Tuple[],
|
|
@@ -711,4 +752,11 @@ function toTuple(envelope: PartialBy<TxEnvelopeEip8141, 'type'>) {
|
|
|
711
752
|
Hex.Hex[],
|
|
712
753
|
readonly Hex.Hex[],
|
|
713
754
|
]
|
|
755
|
+
return envelope.nonceKeys === undefined
|
|
756
|
+
? ([quantity(envelope.chainId), ...fields] as const)
|
|
757
|
+
: ([
|
|
758
|
+
quantity(envelope.chainId),
|
|
759
|
+
envelope.nonceKeys.map(quantity),
|
|
760
|
+
...fields,
|
|
761
|
+
] as const)
|
|
714
762
|
}
|
|
@@ -10,6 +10,33 @@ import {
|
|
|
10
10
|
import { describe, expectTypeOf, test } from 'vp/test'
|
|
11
11
|
|
|
12
12
|
describe('getType', () => {
|
|
13
|
+
test('infers frame transactions from nonce keys', () => {
|
|
14
|
+
expectTypeOf(
|
|
15
|
+
TransactionEnvelope.getType({ nonceKeys: [1n] }),
|
|
16
|
+
).toEqualTypeOf<'eip8141'>()
|
|
17
|
+
expectTypeOf(
|
|
18
|
+
TransactionEnvelope.getType({ nonceKeys: [0n] }),
|
|
19
|
+
).toEqualTypeOf<'eip8141'>()
|
|
20
|
+
expectTypeOf(
|
|
21
|
+
TransactionEnvelope.getType({ nonceKeys: [] }),
|
|
22
|
+
).toEqualTypeOf<'eip8141'>()
|
|
23
|
+
expectTypeOf(
|
|
24
|
+
TransactionEnvelope.getType({
|
|
25
|
+
nonceKeys: [1n],
|
|
26
|
+
frames: undefined,
|
|
27
|
+
authorizationList: [],
|
|
28
|
+
blobVersionedHashes: [],
|
|
29
|
+
gasPrice: 1n,
|
|
30
|
+
}),
|
|
31
|
+
).toEqualTypeOf<'eip8141'>()
|
|
32
|
+
expectTypeOf(
|
|
33
|
+
TransactionEnvelope.getType({ nonceKeys: undefined, maxFeePerGas: 1n }),
|
|
34
|
+
).toEqualTypeOf<'eip1559'>()
|
|
35
|
+
expectTypeOf(
|
|
36
|
+
TransactionEnvelope.getType({ nonceKeys: [1n], type: 'eip1559' }),
|
|
37
|
+
).toEqualTypeOf<'eip1559'>()
|
|
38
|
+
})
|
|
39
|
+
|
|
13
40
|
test('behavior: infers explicit transaction types', () => {
|
|
14
41
|
expectTypeOf(
|
|
15
42
|
TransactionEnvelope.getType({ type: 'legacy' }),
|
|
@@ -99,6 +99,32 @@ test('exports', () => {
|
|
|
99
99
|
})
|
|
100
100
|
|
|
101
101
|
describe('getType', () => {
|
|
102
|
+
test('infers frame transactions from nonce keys', () => {
|
|
103
|
+
expect([
|
|
104
|
+
TransactionEnvelope.getType({ nonceKeys: [1n] }),
|
|
105
|
+
TransactionEnvelope.getType({ nonceKeys: [0n] }),
|
|
106
|
+
TransactionEnvelope.getType({ nonceKeys: [] }),
|
|
107
|
+
TransactionEnvelope.getType({
|
|
108
|
+
nonceKeys: [1n],
|
|
109
|
+
frames: undefined,
|
|
110
|
+
authorizationList: [],
|
|
111
|
+
blobVersionedHashes: [],
|
|
112
|
+
gasPrice: 1n,
|
|
113
|
+
}),
|
|
114
|
+
TransactionEnvelope.getType({ nonceKeys: undefined, maxFeePerGas: 1n }),
|
|
115
|
+
TransactionEnvelope.getType({ nonceKeys: [1n], type: 'eip1559' }),
|
|
116
|
+
]).toMatchInlineSnapshot(`
|
|
117
|
+
[
|
|
118
|
+
"eip8141",
|
|
119
|
+
"eip8141",
|
|
120
|
+
"eip8141",
|
|
121
|
+
"eip8141",
|
|
122
|
+
"eip1559",
|
|
123
|
+
"eip1559",
|
|
124
|
+
]
|
|
125
|
+
`)
|
|
126
|
+
})
|
|
127
|
+
|
|
102
128
|
test('frame fields take precedence over blobs and fees', () => {
|
|
103
129
|
expect(
|
|
104
130
|
TransactionEnvelope.getType({
|
|
@@ -13,6 +13,21 @@ import { kzg } from '../../../test/kzg.js'
|
|
|
13
13
|
import { anvilMainnet } from '../../../test/prool.js'
|
|
14
14
|
|
|
15
15
|
describe('toRpc', () => {
|
|
16
|
+
test('preserves nonce keys without type or frames', () => {
|
|
17
|
+
const request = { nonceKeys: [1n, 2n], nonce: 0n }
|
|
18
|
+
const rpc = TransactionRequest.toRpc(request)
|
|
19
|
+
expect(rpc).toMatchInlineSnapshot(`
|
|
20
|
+
{
|
|
21
|
+
"nonce": "0x0",
|
|
22
|
+
"nonceKeys": [
|
|
23
|
+
"0x1",
|
|
24
|
+
"0x2",
|
|
25
|
+
],
|
|
26
|
+
}
|
|
27
|
+
`)
|
|
28
|
+
expect(TransactionRequest.fromRpc(rpc)).toEqual(request)
|
|
29
|
+
})
|
|
30
|
+
|
|
16
31
|
test('default', () => {
|
|
17
32
|
const request = TransactionRequest.toRpc({
|
|
18
33
|
to: '0x0000000000000000000000000000000000000000',
|
|
@@ -439,6 +454,19 @@ test('exports', () => {
|
|
|
439
454
|
})
|
|
440
455
|
|
|
441
456
|
describe('frame transactions', () => {
|
|
457
|
+
test('requires frames when nonce keys select a frame envelope', () => {
|
|
458
|
+
expect(() =>
|
|
459
|
+
TransactionRequest.toEnvelope({
|
|
460
|
+
chainId: 1,
|
|
461
|
+
from: '0x1111111111111111111111111111111111111111',
|
|
462
|
+
nonceKeys: [1n],
|
|
463
|
+
nonce: 0n,
|
|
464
|
+
}),
|
|
465
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
466
|
+
'[Quantity.MissingFieldError: Missing required field `frames` on `TransactionRequest`.]',
|
|
467
|
+
)
|
|
468
|
+
})
|
|
469
|
+
|
|
442
470
|
test('derives frame blob sidecars and replaces stale hashes', () => {
|
|
443
471
|
const blobs = Blobs.from('0xdeadbeef')
|
|
444
472
|
const request = {
|
|
@@ -42,3 +42,30 @@ test('unsigned signature', () => {
|
|
|
42
42
|
}>()
|
|
43
43
|
expectTypeOf(envelope).toMatchTypeOf<TxEnvelopeEip8141.TxEnvelopeEip8141>()
|
|
44
44
|
})
|
|
45
|
+
|
|
46
|
+
test('keyed nonce literals and numberish RPC input', () => {
|
|
47
|
+
const envelope = TxEnvelopeEip8141.from({
|
|
48
|
+
chainId: 1,
|
|
49
|
+
frames: [{}],
|
|
50
|
+
sender: '0x1111111111111111111111111111111111111111',
|
|
51
|
+
nonceKeys: [1n, 2n],
|
|
52
|
+
nonce: 3n,
|
|
53
|
+
})
|
|
54
|
+
expectTypeOf(envelope.nonceKeys).toEqualTypeOf<readonly [1n, 2n]>()
|
|
55
|
+
expectTypeOf(envelope.nonce).toEqualTypeOf<3n>()
|
|
56
|
+
expectTypeOf(TxEnvelopeEip8141.toRpc(envelope).nonceKeys).toEqualTypeOf<
|
|
57
|
+
readonly `0x${string}`[] | undefined
|
|
58
|
+
>()
|
|
59
|
+
expectTypeOf(
|
|
60
|
+
TxEnvelopeEip8141.toRpc({
|
|
61
|
+
...envelope,
|
|
62
|
+
nonceKeys: ['0x1', 2],
|
|
63
|
+
nonce: '0x3',
|
|
64
|
+
}),
|
|
65
|
+
).toEqualTypeOf<TxEnvelopeEip8141.Rpc>()
|
|
66
|
+
// @ts-expect-error decoded nonce keys are bigint
|
|
67
|
+
TxEnvelopeEip8141.from({ ...envelope, nonceKeys: [1] })
|
|
68
|
+
expectTypeOf<keyof TxEnvelopeEip8141.Rpc>()
|
|
69
|
+
.exclude<'nonceSeq'>()
|
|
70
|
+
.toEqualTypeOf<keyof TxEnvelopeEip8141.Rpc>()
|
|
71
|
+
})
|