ox 1.8.1 → 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 +53 -0
- package/dist/core/Frame.d.ts +23 -20
- package/dist/core/Frame.d.ts.map +1 -1
- package/dist/core/Frame.js +28 -23
- package/dist/core/Frame.js.map +1 -1
- package/dist/core/FrameReceipt.d.ts +23 -14
- package/dist/core/FrameReceipt.d.ts.map +1 -1
- package/dist/core/FrameReceipt.js +15 -11
- package/dist/core/FrameReceipt.js.map +1 -1
- package/dist/core/FrameRequest.d.ts +50 -0
- package/dist/core/FrameRequest.d.ts.map +1 -0
- package/dist/core/FrameRequest.js +59 -0
- package/dist/core/FrameRequest.js.map +1 -0
- package/dist/core/FrameSignature.d.ts +17 -16
- package/dist/core/FrameSignature.d.ts.map +1 -1
- package/dist/core/FrameSignature.js +38 -21
- package/dist/core/FrameSignature.js.map +1 -1
- package/dist/core/Siwe.d.ts.map +1 -1
- package/dist/core/Siwe.js +3 -3
- package/dist/core/Siwe.js.map +1 -1
- package/dist/core/Transaction.d.ts +7 -4
- 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 +8 -5
- package/dist/core/TransactionRequest.d.ts.map +1 -1
- package/dist/core/TransactionRequest.js +11 -3
- package/dist/core/TransactionRequest.js.map +1 -1
- package/dist/core/TxEnvelope.d.ts +4 -2
- package/dist/core/TxEnvelope.d.ts.map +1 -1
- package/dist/core/TxEnvelope.js +11 -2
- package/dist/core/TxEnvelope.js.map +1 -1
- package/dist/core/TxEnvelopeEip8141.d.ts +22 -11
- package/dist/core/TxEnvelopeEip8141.d.ts.map +1 -1
- package/dist/core/TxEnvelopeEip8141.js +45 -16
- 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/core/internal/rpcSchemas/eth.d.ts +16 -4
- package/dist/core/internal/rpcSchemas/eth.d.ts.map +1 -1
- package/dist/index.d.ts +21 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -5
- package/dist/index.js.map +1 -1
- package/dist/zod/Block.d.ts +52 -37
- package/dist/zod/Block.d.ts.map +1 -1
- package/dist/zod/Frame.d.ts +14 -14
- package/dist/zod/Frame.js +5 -5
- package/dist/zod/Frame.js.map +1 -1
- package/dist/zod/FrameReceipt.d.ts +42 -2
- package/dist/zod/FrameReceipt.d.ts.map +1 -1
- package/dist/zod/FrameReceipt.js +11 -1
- package/dist/zod/FrameReceipt.js.map +1 -1
- package/dist/zod/FrameRequest.d.ts +40 -0
- package/dist/zod/FrameRequest.d.ts.map +1 -0
- package/dist/zod/FrameRequest.js +37 -0
- package/dist/zod/FrameRequest.js.map +1 -0
- package/dist/zod/FrameSignature.d.ts +21 -13
- package/dist/zod/FrameSignature.d.ts.map +1 -1
- package/dist/zod/FrameSignature.js +10 -7
- package/dist/zod/FrameSignature.js.map +1 -1
- package/dist/zod/RpcSchema.d.ts +470 -265
- package/dist/zod/RpcSchema.d.ts.map +1 -1
- package/dist/zod/Transaction.d.ts +104 -74
- package/dist/zod/Transaction.d.ts.map +1 -1
- package/dist/zod/Transaction.js +22 -15
- package/dist/zod/Transaction.js.map +1 -1
- package/dist/zod/TransactionEnvelope.d.ts +60 -34
- package/dist/zod/TransactionEnvelope.d.ts.map +1 -1
- package/dist/zod/TransactionReceipt.d.ts +42 -2
- package/dist/zod/TransactionReceipt.d.ts.map +1 -1
- package/dist/zod/TransactionRequest.d.ts +31 -21
- package/dist/zod/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/TransactionRequest.js +10 -4
- package/dist/zod/TransactionRequest.js.map +1 -1
- package/dist/zod/TxEnvelopeEip8141.d.ts +44 -25
- 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 +472 -267
- package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
- package/dist/zod/internal/rpcSchemas/Eth.js +9 -0
- package/dist/zod/internal/rpcSchemas/Eth.js.map +1 -1
- package/dist/zod/internal/rpcSchemas/Wallet.d.ts +51 -21
- package/dist/zod/internal/rpcSchemas/Wallet.d.ts.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +68 -48
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +52 -37
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/z.d.ts +1 -0
- package/dist/zod/z.d.ts.map +1 -1
- package/dist/zod/z.js +1 -0
- package/dist/zod/z.js.map +1 -1
- package/package.json +11 -1
- package/src/core/Frame.ts +41 -33
- package/src/core/FrameReceipt.ts +30 -16
- package/src/core/FrameRequest.ts +78 -0
- package/src/core/FrameSignature.ts +64 -34
- package/src/core/Siwe.ts +21 -13
- package/src/core/Transaction.ts +52 -24
- package/src/core/TransactionRequest.ts +21 -7
- package/src/core/TxEnvelope.ts +16 -3
- package/src/core/TxEnvelopeEip8141.ts +69 -21
- package/src/core/_test/AbiConstructor.test.ts +2 -0
- package/src/core/_test/Frame.test-d.ts +16 -7
- package/src/core/_test/Frame.test.ts +52 -24
- package/src/core/_test/FrameReceipt.test.ts +15 -9
- package/src/core/_test/FrameRequest.test-d.ts +16 -0
- package/src/core/_test/FrameRequest.test.ts +41 -0
- package/src/core/_test/FrameRpc.test.ts +131 -0
- package/src/core/_test/FrameSignature.test-d.ts +20 -0
- package/src/core/_test/FrameSignature.test.ts +132 -11
- package/src/core/_test/RpcSchema.test-d.ts +45 -0
- package/src/core/_test/Siwe.test.ts +147 -0
- package/src/core/_test/TransactionEnvelope.test-d.ts +27 -0
- package/src/core/_test/TransactionEnvelope.test.ts +27 -1
- package/src/core/_test/TransactionReceipt.test.ts +32 -6
- package/src/core/_test/TransactionRequest.test-d.ts +10 -1
- package/src/core/_test/TransactionRequest.test.ts +31 -2
- package/src/core/_test/TxEnvelopeEip8141.test-d.ts +29 -2
- package/src/core/_test/TxEnvelopeEip8141.test.ts +548 -55
- package/src/core/_test/index.test.ts +1 -0
- package/src/core/internal/frameNonce.ts +61 -0
- package/src/core/internal/rpcSchemas/eth.ts +13 -4
- package/src/index.ts +22 -5
- package/src/version.ts +1 -1
- package/src/zod/Frame.ts +5 -5
- package/src/zod/FrameReceipt.ts +11 -1
- package/src/zod/FrameRequest.ts +46 -0
- package/src/zod/FrameSignature.ts +10 -7
- package/src/zod/Transaction.ts +46 -27
- package/src/zod/TransactionRequest.ts +33 -18
- package/src/zod/TxEnvelopeEip8141.ts +2 -0
- package/src/zod/_test/Frame.test.ts +13 -11
- package/src/zod/_test/FrameReceipt.test.ts +11 -4
- package/src/zod/_test/FrameRequest.test-d.ts +15 -0
- package/src/zod/_test/FrameRequest.test.ts +44 -0
- package/src/zod/_test/FrameSignature.test.ts +73 -9
- package/src/zod/_test/RpcSchema.test.ts +106 -0
- package/src/zod/_test/TransactionRequest.test.ts +61 -0
- package/src/zod/_test/TxEnvelopeEip8141.nonce.test.ts +174 -0
- package/src/zod/_test/TxEnvelopeEip8141.test-d.ts +29 -0
- package/src/zod/_test/TxEnvelopeEip8141.test.ts +3 -3
- package/src/zod/internal/Frame.ts +45 -0
- package/src/zod/internal/rpcSchemas/Eth.ts +20 -0
- package/src/zod/z.ts +1 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as Errors from '../Errors.js'
|
|
2
|
+
import * as Hex from '../Hex.js'
|
|
3
|
+
import * as Quantity from './quantity.js'
|
|
4
|
+
|
|
5
|
+
export function assert(keys: readonly bigint[], nonce?: bigint): void {
|
|
6
|
+
if (!Array.isArray(keys) || keys.length < 1 || keys.length > 16)
|
|
7
|
+
throw new InvalidError('Expected between 1 and 16 nonce keys.')
|
|
8
|
+
for (const [index, key] of keys.entries()) {
|
|
9
|
+
if (typeof key !== 'bigint' || key < 0n || key >= 2n ** 256n)
|
|
10
|
+
throw new InvalidError('Nonce keys must be unsigned 256-bit integers.')
|
|
11
|
+
if (index > 0 && key <= keys[index - 1]!)
|
|
12
|
+
throw new InvalidError('Nonce keys must be strictly increasing.')
|
|
13
|
+
}
|
|
14
|
+
if (keys.length > 1 && keys[0] === 0n)
|
|
15
|
+
throw new InvalidError(
|
|
16
|
+
'The zero nonce key cannot be combined with other keys.',
|
|
17
|
+
)
|
|
18
|
+
if (
|
|
19
|
+
nonce !== undefined &&
|
|
20
|
+
(typeof nonce !== 'bigint' || nonce < 0n || nonce >= 2n ** 64n - 1n)
|
|
21
|
+
)
|
|
22
|
+
throw new InvalidError('Nonce must be less than 2^64 - 1 and nonnegative.')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function fromRpc(
|
|
26
|
+
keys: readonly Hex.Hex[],
|
|
27
|
+
nonce?: Hex.Hex,
|
|
28
|
+
): readonly bigint[] {
|
|
29
|
+
if (!Array.isArray(keys)) throw new InvalidError('Expected a nonce key list.')
|
|
30
|
+
const integer = (value: Hex.Hex): bigint => {
|
|
31
|
+
if (
|
|
32
|
+
typeof value !== 'string' ||
|
|
33
|
+
!/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/.test(value)
|
|
34
|
+
)
|
|
35
|
+
throw new InvalidError('Expected a canonical RPC nonce quantity.')
|
|
36
|
+
return Hex.toBigInt(value)
|
|
37
|
+
}
|
|
38
|
+
const decoded = keys.map(integer)
|
|
39
|
+
assert(decoded, nonce === undefined ? undefined : integer(nonce))
|
|
40
|
+
return decoded
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function toRpc(
|
|
44
|
+
keys: readonly (Hex.Hex | bigint | number)[],
|
|
45
|
+
nonce?: Hex.Hex | bigint | number,
|
|
46
|
+
): readonly Hex.Hex[] {
|
|
47
|
+
if (!Array.isArray(keys)) throw new InvalidError('Expected a nonce key list.')
|
|
48
|
+
const encoded = keys.map((key) => Quantity.fromNumberish(key))
|
|
49
|
+
fromRpc(
|
|
50
|
+
encoded,
|
|
51
|
+
nonce === undefined ? undefined : Quantity.fromNumberish(nonce),
|
|
52
|
+
)
|
|
53
|
+
return encoded
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class InvalidError extends Errors.BaseError {
|
|
57
|
+
override readonly name = 'FrameNonce.InvalidError'
|
|
58
|
+
constructor(reason: string) {
|
|
59
|
+
super(reason)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -4,6 +4,7 @@ import type * as Block from '../../Block.js'
|
|
|
4
4
|
import type * as BlockOverrides from '../../BlockOverrides.js'
|
|
5
5
|
import type * as Fee from '../../Fee.js'
|
|
6
6
|
import type * as Filter from '../../Filter.js'
|
|
7
|
+
import type * as FrameReceipt from '../../FrameReceipt.js'
|
|
7
8
|
import type * as Hex from '../../Hex.js'
|
|
8
9
|
import type * as Log from '../../Log.js'
|
|
9
10
|
import type * as RpcSchema from '../../RpcSchema.js'
|
|
@@ -11,6 +12,7 @@ import type * as StateOverrides from '../../StateOverrides.js'
|
|
|
11
12
|
import type * as Transaction from '../../Transaction.js'
|
|
12
13
|
import type * as TransactionReceipt from '../../TransactionReceipt.js'
|
|
13
14
|
import type * as TransactionRequest from '../../TransactionRequest.js'
|
|
15
|
+
import type * as TxEnvelope from '../../TxEnvelope.js'
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* Union of all JSON-RPC Methods for the `eth_` namespace.
|
|
@@ -219,12 +221,12 @@ export type Eth = RpcSchema.From<
|
|
|
219
221
|
ReturnType: Fee.FeeHistoryRpc
|
|
220
222
|
}
|
|
221
223
|
/**
|
|
222
|
-
* Fills
|
|
224
|
+
* Fills transaction defaults and returns the unsigned transaction.
|
|
223
225
|
*
|
|
224
226
|
* @example
|
|
225
227
|
* ```
|
|
226
228
|
* request({ method: 'eth_fillTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] })
|
|
227
|
-
* // {
|
|
229
|
+
* // { tx: { ... } }
|
|
228
230
|
* ```
|
|
229
231
|
*/
|
|
230
232
|
| {
|
|
@@ -234,8 +236,8 @@ export type Eth = RpcSchema.From<
|
|
|
234
236
|
}
|
|
235
237
|
ReturnType: {
|
|
236
238
|
capabilities?: Record<string, unknown> | undefined
|
|
237
|
-
raw
|
|
238
|
-
tx:
|
|
239
|
+
raw?: Hex.Hex | undefined
|
|
240
|
+
tx: TxEnvelope.Rpc & { from: Address.Address }
|
|
239
241
|
}
|
|
240
242
|
}
|
|
241
243
|
/**
|
|
@@ -769,6 +771,13 @@ export type Eth = RpcSchema.From<
|
|
|
769
771
|
message: string
|
|
770
772
|
}
|
|
771
773
|
| undefined
|
|
774
|
+
frameResults?:
|
|
775
|
+
| readonly (FrameReceipt.Rpc & {
|
|
776
|
+
error?: { code: number; message: string } | undefined
|
|
777
|
+
returnData: Hex.Hex
|
|
778
|
+
})[]
|
|
779
|
+
| undefined
|
|
780
|
+
payer?: Address.Address | undefined
|
|
772
781
|
logs?: readonly Log.Rpc[] | undefined
|
|
773
782
|
gasUsed: Hex.Hex
|
|
774
783
|
returnData: Hex.Hex
|
package/src/index.ts
CHANGED
|
@@ -1618,13 +1618,13 @@ export * as Filter from './core/Filter.js'
|
|
|
1618
1618
|
* import { Frame } from 'ox'
|
|
1619
1619
|
*
|
|
1620
1620
|
* const frame = Frame.from({
|
|
1621
|
+
* executionGas: 50_000n,
|
|
1621
1622
|
* flags: 'approveExecutionAndPayment',
|
|
1622
|
-
* gas: 50_000n,
|
|
1623
1623
|
* mode: 'verify'
|
|
1624
1624
|
* })
|
|
1625
1625
|
* ```
|
|
1626
1626
|
*
|
|
1627
|
-
* @category
|
|
1627
|
+
* @category Frames (EIP-8141)
|
|
1628
1628
|
*/
|
|
1629
1629
|
export * as Frame from './core/Frame.js'
|
|
1630
1630
|
|
|
@@ -1633,10 +1633,27 @@ export * as Frame from './core/Frame.js'
|
|
|
1633
1633
|
*
|
|
1634
1634
|
* Frame receipts include execution gas, state gas, logs, and execution status.
|
|
1635
1635
|
*
|
|
1636
|
-
* @category
|
|
1636
|
+
* @category Frames (EIP-8141)
|
|
1637
1637
|
*/
|
|
1638
1638
|
export * as FrameReceipt from './core/FrameReceipt.js'
|
|
1639
1639
|
|
|
1640
|
+
/**
|
|
1641
|
+
* Convert EIP-8141 frame requests while preserving omitted gas limits for node estimation.
|
|
1642
|
+
*
|
|
1643
|
+
* @example
|
|
1644
|
+
* ```ts twoslash
|
|
1645
|
+
* import { FrameRequest } from 'ox'
|
|
1646
|
+
*
|
|
1647
|
+
* const frame = FrameRequest.toRpc({
|
|
1648
|
+
* mode: 'sender',
|
|
1649
|
+
* stateGas: 0n
|
|
1650
|
+
* })
|
|
1651
|
+
* ```
|
|
1652
|
+
*
|
|
1653
|
+
* @category Frames (EIP-8141)
|
|
1654
|
+
*/
|
|
1655
|
+
export * as FrameRequest from './core/FrameRequest.js'
|
|
1656
|
+
|
|
1640
1657
|
/**
|
|
1641
1658
|
* Utilities for constructing, validating, and encoding [EIP-8141](https://eips.ethereum.org/EIPS/eip-8141) signature entries.
|
|
1642
1659
|
*
|
|
@@ -1656,7 +1673,7 @@ export * as FrameReceipt from './core/FrameReceipt.js'
|
|
|
1656
1673
|
* // @log: { payload: '0x', scheme: 'arbitrary', signature: '0xaabb' }
|
|
1657
1674
|
* ```
|
|
1658
1675
|
*
|
|
1659
|
-
* @category
|
|
1676
|
+
* @category Frames (EIP-8141)
|
|
1660
1677
|
*/
|
|
1661
1678
|
export * as FrameSignature from './core/FrameSignature.js'
|
|
1662
1679
|
|
|
@@ -3580,7 +3597,7 @@ export * as TxEnvelopeEip7702 from './core/TxEnvelopeEip7702.js'
|
|
|
3580
3597
|
*
|
|
3581
3598
|
* const envelope = TxEnvelopeEip8141.from({
|
|
3582
3599
|
* chainId: 1,
|
|
3583
|
-
* frames: [{
|
|
3600
|
+
* frames: [{ executionGas: 50_000n, mode: 'sender' }],
|
|
3584
3601
|
* sender: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8'
|
|
3585
3602
|
* })
|
|
3586
3603
|
* ```
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal */
|
|
2
|
-
export const version = '1.8.
|
|
2
|
+
export const version = '1.8.4'
|
package/src/zod/Frame.ts
CHANGED
|
@@ -25,10 +25,10 @@ export const Decoded: z.ZodMiniType<core_Frame.Frame, core_Frame.Frame> = z
|
|
|
25
25
|
export const Rpc = z
|
|
26
26
|
.object({
|
|
27
27
|
data: z_Hex.Hex,
|
|
28
|
-
|
|
29
|
-
flags:
|
|
30
|
-
mode:
|
|
31
|
-
|
|
28
|
+
executionGas: z_Hex.Hex,
|
|
29
|
+
flags: z_Hex.Hex,
|
|
30
|
+
mode: z_Hex.Hex,
|
|
31
|
+
stateGas: z_Hex.Hex,
|
|
32
32
|
target: z.optional(z.nullable(z_Address.Address)),
|
|
33
33
|
value: z_Hex.Hex,
|
|
34
34
|
})
|
|
@@ -72,8 +72,8 @@ export const FrameToRpc = z.codec(Rpc, DecodedToRpc, {
|
|
|
72
72
|
function fields<uint extends z.ZodMiniType>(uint: uint) {
|
|
73
73
|
return {
|
|
74
74
|
data: z.optional(z_Hex.Hex),
|
|
75
|
+
executionGas: z.optional(uint),
|
|
75
76
|
flags: z.optional(Flags),
|
|
76
|
-
gas: z.optional(uint),
|
|
77
77
|
mode: z.optional(Mode),
|
|
78
78
|
stateGas: z.optional(uint),
|
|
79
79
|
to: z.optional(z_Address.Address),
|
package/src/zod/FrameReceipt.ts
CHANGED
|
@@ -11,17 +11,26 @@ import * as z from 'zod/mini'
|
|
|
11
11
|
|
|
12
12
|
const frameLog = z.object({
|
|
13
13
|
address: z_Address.Address,
|
|
14
|
+
blockHash: z.optional(z_Hex.Hex),
|
|
15
|
+
blockNumber: z.optional(quantityHex()),
|
|
16
|
+
blockTimestamp: z.optional(quantityHex()),
|
|
14
17
|
data: z_Hex.Hex,
|
|
18
|
+
logIndex: z.optional(quantityHex()),
|
|
19
|
+
removed: z.optional(z.boolean()),
|
|
15
20
|
topics: z.array(z_Hex.Hex),
|
|
21
|
+
transactionHash: z.optional(z_Hex.Hex),
|
|
22
|
+
transactionIndex: z.optional(quantityHex()),
|
|
16
23
|
})
|
|
17
24
|
|
|
18
25
|
const frameReceiptRpc = z.object({
|
|
19
26
|
executionGasUsed: quantityHex(),
|
|
27
|
+
gasUsed: quantityHex(),
|
|
20
28
|
logs: z.readonly(z.array(frameLog)),
|
|
21
29
|
stateGasUsed: quantityHex(),
|
|
22
|
-
status: z.
|
|
30
|
+
status: z.enum(['0x0', '0x1', '0x2']),
|
|
23
31
|
})
|
|
24
32
|
const frameReceiptDecoded = z.object({
|
|
33
|
+
executionGasUsed: uintBigint(),
|
|
25
34
|
gasUsed: uintBigint(),
|
|
26
35
|
logs: z.readonly(z.array(frameLog)),
|
|
27
36
|
stateGasUsed: uintBigint(),
|
|
@@ -38,6 +47,7 @@ export const FrameReceipt = z.codec(frameReceiptRpc, frameReceiptDecoded, {
|
|
|
38
47
|
export const FrameReceiptToRpc = z.codec(
|
|
39
48
|
frameReceiptRpc,
|
|
40
49
|
z.extend(frameReceiptDecoded, {
|
|
50
|
+
executionGasUsed: uintBigintNumberish(),
|
|
41
51
|
gasUsed: uintBigintNumberish(),
|
|
42
52
|
stateGasUsed: uintBigintNumberish(),
|
|
43
53
|
}),
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* eslint-disable jsdoc-js/require-jsdoc, jsdoc-js/require-description, jsdoc-js/require-example */
|
|
2
|
+
import * as core_FrameRequest from '../core/FrameRequest.js'
|
|
3
|
+
import * as z_Address from './Address.js'
|
|
4
|
+
import * as z_Frame from './Frame.js'
|
|
5
|
+
import * as z_Hex from './Hex.js'
|
|
6
|
+
import * as z from 'zod/mini'
|
|
7
|
+
|
|
8
|
+
const quantity = z_Hex.Hex.check(
|
|
9
|
+
z.refine(
|
|
10
|
+
(value) => /^0x(0|[1-9a-f][0-9a-f]*)$/.test(value),
|
|
11
|
+
'Invalid RPC quantity',
|
|
12
|
+
),
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const rpc = z
|
|
16
|
+
.object({
|
|
17
|
+
data: z.optional(z_Hex.Hex),
|
|
18
|
+
executionGas: z.optional(quantity),
|
|
19
|
+
flags: z.optional(z_Hex.Hex),
|
|
20
|
+
mode: z_Hex.Hex,
|
|
21
|
+
stateGas: z.optional(quantity),
|
|
22
|
+
target: z.optional(z.nullable(z_Address.Address)),
|
|
23
|
+
value: z.optional(quantity),
|
|
24
|
+
})
|
|
25
|
+
.check(
|
|
26
|
+
z.refine((value) => {
|
|
27
|
+
try {
|
|
28
|
+
core_FrameRequest.fromRpc(value)
|
|
29
|
+
return true
|
|
30
|
+
} catch {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
}, 'Invalid frame request'),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
/** Codec between RPC and decoded frame requests, preserving omitted gas limits. */
|
|
37
|
+
export const FrameRequest = z.codec(rpc, z_Frame.Decoded, {
|
|
38
|
+
decode: core_FrameRequest.fromRpc,
|
|
39
|
+
encode: core_FrameRequest.toRpc,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
/** Encode-only frame request codec accepting numberish gas and value. */
|
|
43
|
+
export const FrameRequestToRpc = z.codec(rpc, z_Frame.DecodedToRpc, {
|
|
44
|
+
decode: core_FrameRequest.fromRpc,
|
|
45
|
+
encode: core_FrameRequest.toRpc,
|
|
46
|
+
})
|
|
@@ -24,7 +24,10 @@ export const Secp256k1 = z.object({
|
|
|
24
24
|
payload: z.optional(z_Hex.Hex),
|
|
25
25
|
scheme: z.union([z.literal(1), z.literal('secp256k1')]),
|
|
26
26
|
signature: z.optional(
|
|
27
|
-
z.
|
|
27
|
+
z.union([
|
|
28
|
+
z_Hex.Hex,
|
|
29
|
+
z.object({ r: z_Hex.Hex, s: z_Hex.Hex, yParity: z.number() }),
|
|
30
|
+
]),
|
|
28
31
|
),
|
|
29
32
|
signer: z.optional(z_Address.Address),
|
|
30
33
|
})
|
|
@@ -36,11 +39,11 @@ const p256 = {
|
|
|
36
39
|
}
|
|
37
40
|
/** P-256 frame signature schema, including unsigned placeholders. */
|
|
38
41
|
export const P256 = z.union([
|
|
39
|
-
z.object({ ...p256, publicKey, signature }),
|
|
42
|
+
z.object({ ...p256, publicKey, signature: z.union([z_Hex.Hex, signature]) }),
|
|
40
43
|
z.object({
|
|
41
44
|
...p256,
|
|
42
45
|
publicKey: z.optional(publicKey),
|
|
43
|
-
signature: z.optional(z.
|
|
46
|
+
signature: z.optional(z.literal('0x')),
|
|
44
47
|
}),
|
|
45
48
|
])
|
|
46
49
|
|
|
@@ -55,10 +58,10 @@ export const Decoded: z.ZodMiniType<
|
|
|
55
58
|
/** RPC frame signature schema. */
|
|
56
59
|
export const Rpc = z
|
|
57
60
|
.object({
|
|
58
|
-
msg: z_Hex.Hex,
|
|
59
|
-
scheme: z.
|
|
60
|
-
signature: z_Hex.Hex,
|
|
61
|
-
signer: z.optional(z.
|
|
61
|
+
msg: z.optional(z_Hex.Hex),
|
|
62
|
+
scheme: z.enum(['0x0', '0x1', '0x2']),
|
|
63
|
+
signature: z.optional(z_Hex.Hex),
|
|
64
|
+
signer: z.optional(z.union([z.literal('0x'), z_Address.Address])),
|
|
62
65
|
})
|
|
63
66
|
.check(
|
|
64
67
|
z.refine((value) => {
|
package/src/zod/Transaction.ts
CHANGED
|
@@ -4,7 +4,13 @@ import * as z_Address from './Address.js'
|
|
|
4
4
|
import * as z_Authorization from './Authorization.js'
|
|
5
5
|
import * as z_Frame from './Frame.js'
|
|
6
6
|
import * as z_FrameSignature from './FrameSignature.js'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
chainId,
|
|
9
|
+
chainIdToRpc,
|
|
10
|
+
nonceKeys,
|
|
11
|
+
nonceKeysToRpc,
|
|
12
|
+
validNonce,
|
|
13
|
+
} from './internal/Frame.js'
|
|
8
14
|
import * as z_Hex from './Hex.js'
|
|
9
15
|
import * as z_Number from './Number.js'
|
|
10
16
|
import * as z_Uint from './Uint.js'
|
|
@@ -142,55 +148,68 @@ export const PendingEip7702 = z.object(
|
|
|
142
148
|
const Eip8141Type = type('0x6', 'eip8141')
|
|
143
149
|
|
|
144
150
|
/** EIP-8141 transaction schema. */
|
|
145
|
-
export const Eip8141 = z
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
export const Eip8141 = z
|
|
152
|
+
.object({
|
|
153
|
+
...eip8141Fields(z_Uint.Uint, chainId, z_Frame.Frame, nonceKeys),
|
|
154
|
+
blockHash: z_Hex.Hex,
|
|
155
|
+
blockNumber: z_Uint.Uint,
|
|
156
|
+
blockTimestamp: z.optional(z_Uint.Uint),
|
|
157
|
+
transactionIndex: z_Number.Number,
|
|
158
|
+
})
|
|
159
|
+
.check(z.refine(validNonce, 'Invalid keyed nonce'))
|
|
152
160
|
|
|
153
161
|
/** Encode-only EIP-8141 transaction schema accepting numberish values. */
|
|
154
|
-
export const Eip8141ToRpc = z
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
export const Eip8141ToRpc = z
|
|
163
|
+
.object({
|
|
164
|
+
...eip8141Fields(
|
|
165
|
+
z_Uint.UintToRpc,
|
|
166
|
+
chainIdToRpc,
|
|
167
|
+
z_Frame.FrameToRpc,
|
|
168
|
+
nonceKeysToRpc,
|
|
169
|
+
),
|
|
170
|
+
blockHash: z_Hex.Hex,
|
|
171
|
+
blockNumber: z_Uint.UintToRpc,
|
|
172
|
+
blockTimestamp: z.optional(z_Uint.UintToRpc),
|
|
173
|
+
transactionIndex: z_Number.NumberToRpc,
|
|
174
|
+
})
|
|
175
|
+
.check(z.refine(validNonce, 'Invalid keyed nonce'))
|
|
161
176
|
|
|
162
177
|
/** Pending EIP-8141 transaction schema. */
|
|
163
|
-
export const PendingEip8141 = z
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
178
|
+
export const PendingEip8141 = z
|
|
179
|
+
.object({
|
|
180
|
+
...eip8141Fields(z_Uint.Uint, chainId, z_Frame.Frame, nonceKeys),
|
|
181
|
+
blockHash: z.null(),
|
|
182
|
+
blockNumber: z.null(),
|
|
183
|
+
blockTimestamp: z.optional(z.null()),
|
|
184
|
+
transactionIndex: z.null(),
|
|
185
|
+
})
|
|
186
|
+
.check(z.refine(validNonce, 'Invalid keyed nonce'))
|
|
170
187
|
|
|
171
188
|
function eip8141Fields<
|
|
172
189
|
uint extends z.ZodMiniType,
|
|
173
190
|
num extends z.ZodMiniType,
|
|
174
191
|
frame extends z.ZodMiniType,
|
|
175
|
-
|
|
192
|
+
keys extends z.ZodMiniType,
|
|
193
|
+
>(uint: uint, num: num, frame: frame, keys: keys) {
|
|
176
194
|
return {
|
|
177
195
|
blobVersionedHashes: z.readonly(z.array(z_Hex.Hex)),
|
|
178
196
|
chainId: num,
|
|
179
197
|
data: z.optional(z_Hex.Hex),
|
|
180
198
|
frames: z.readonly(z.array(frame)),
|
|
181
199
|
from: z_Address.Address,
|
|
182
|
-
gas: uint,
|
|
200
|
+
gas: z.optional(uint),
|
|
183
201
|
gasPrice: z.optional(uint),
|
|
184
202
|
hash: z_Hex.Hex,
|
|
185
|
-
input: z_Hex.Hex,
|
|
203
|
+
input: z.optional(z_Hex.Hex),
|
|
186
204
|
maxFeePerBlobGas: uint,
|
|
187
205
|
maxFeePerGas: uint,
|
|
188
206
|
maxPriorityFeePerGas: uint,
|
|
189
207
|
nonce: uint,
|
|
208
|
+
nonceKeys: z.optional(keys),
|
|
190
209
|
signatures: z.readonly(z.array(z_FrameSignature.FrameSignature)),
|
|
191
|
-
to: z.nullable(z_Address.Address),
|
|
210
|
+
to: z.optional(z.nullable(z_Address.Address)),
|
|
192
211
|
type: Eip8141Type,
|
|
193
|
-
value: uint,
|
|
212
|
+
value: z.optional(uint),
|
|
194
213
|
}
|
|
195
214
|
}
|
|
196
215
|
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import * as z_AccessList from './AccessList.js'
|
|
3
3
|
import * as z_Address from './Address.js'
|
|
4
4
|
import * as z_Authorization from './Authorization.js'
|
|
5
|
-
import * as
|
|
5
|
+
import * as z_FrameRequest from './FrameRequest.js'
|
|
6
6
|
import * as z_FrameSignature from './FrameSignature.js'
|
|
7
7
|
import * as z_Hex from './Hex.js'
|
|
8
|
+
import { nonceKeys, nonceKeysToRpc, validNonce } from './internal/Frame.js'
|
|
8
9
|
import * as z_Number from './Number.js'
|
|
9
10
|
import * as z_Uint from './Uint.js'
|
|
10
11
|
import * as z from 'zod/mini'
|
|
@@ -33,31 +34,44 @@ const type = z.codec(z.string(), z.string(), {
|
|
|
33
34
|
})
|
|
34
35
|
|
|
35
36
|
/** Transaction request schema. */
|
|
36
|
-
export const TransactionRequest = z
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
export const TransactionRequest = z
|
|
38
|
+
.object(
|
|
39
|
+
fields(
|
|
40
|
+
z_Uint.Uint,
|
|
41
|
+
z_Number.Number,
|
|
42
|
+
z_Authorization.ListSigned,
|
|
43
|
+
z_FrameRequest.FrameRequest,
|
|
44
|
+
nonceKeys,
|
|
45
|
+
),
|
|
46
|
+
)
|
|
47
|
+
.check(z.refine(validNonce, 'Invalid keyed nonce'))
|
|
44
48
|
|
|
45
49
|
/** Encode-only transaction request schema accepting numberish `toRpc` inputs. */
|
|
46
|
-
export const TransactionRequestToRpc = z
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
export const TransactionRequestToRpc = z
|
|
51
|
+
.object(
|
|
52
|
+
fields(
|
|
53
|
+
z_Uint.UintToRpc,
|
|
54
|
+
z_Number.NumberToRpc,
|
|
55
|
+
z_Authorization.ListSignedToRpc,
|
|
56
|
+
z_FrameRequest.FrameRequestToRpc,
|
|
57
|
+
nonceKeysToRpc,
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
.check(z.refine(validNonce, 'Invalid keyed nonce'))
|
|
54
61
|
|
|
55
62
|
function fields<
|
|
56
63
|
uint extends z.ZodMiniType,
|
|
57
64
|
num extends z.ZodMiniType,
|
|
58
65
|
authorizationList extends z.ZodMiniType,
|
|
59
66
|
frame extends z.ZodMiniType,
|
|
60
|
-
|
|
67
|
+
keys extends z.ZodMiniType,
|
|
68
|
+
>(
|
|
69
|
+
uint: uint,
|
|
70
|
+
num: num,
|
|
71
|
+
authorizationList: authorizationList,
|
|
72
|
+
frame: frame,
|
|
73
|
+
keys: keys,
|
|
74
|
+
) {
|
|
61
75
|
return {
|
|
62
76
|
accessList: z.optional(z_AccessList.AccessList),
|
|
63
77
|
authorizationList: z.optional(authorizationList),
|
|
@@ -74,6 +88,7 @@ function fields<
|
|
|
74
88
|
maxFeePerGas: z.optional(uint),
|
|
75
89
|
maxPriorityFeePerGas: z.optional(uint),
|
|
76
90
|
nonce: z.optional(uint),
|
|
91
|
+
nonceKeys: z.optional(keys),
|
|
77
92
|
signatures: z.optional(
|
|
78
93
|
z.readonly(z.array(z_FrameSignature.FrameSignature)),
|
|
79
94
|
),
|
|
@@ -25,6 +25,7 @@ export const Rpc = z
|
|
|
25
25
|
maxFeePerGas: z_Hex.Hex,
|
|
26
26
|
maxPriorityFeePerGas: z_Hex.Hex,
|
|
27
27
|
nonce: z_Hex.Hex,
|
|
28
|
+
nonceKeys: z.optional(z.readonly(z.array(z_Hex.Hex))),
|
|
28
29
|
signatures: z.readonly(z.array(z_FrameSignature.Rpc)),
|
|
29
30
|
type: z.literal('0x6'),
|
|
30
31
|
})
|
|
@@ -94,6 +95,7 @@ function fields<
|
|
|
94
95
|
maxFeePerGas: z.optional(uint),
|
|
95
96
|
maxPriorityFeePerGas: z.optional(uint),
|
|
96
97
|
nonce: z.optional(uint),
|
|
98
|
+
nonceKeys: z.optional(z.readonly(z.array(uint))),
|
|
97
99
|
sender: z_Address.Address,
|
|
98
100
|
sidecars: z.optional(z_TxEnvelopeEip4844.Sidecars),
|
|
99
101
|
signatures: z.optional(z.readonly(z.array(z_FrameSignature.Decoded))),
|
|
@@ -5,25 +5,25 @@ import { describe, expect, test } from 'vp/test'
|
|
|
5
5
|
describe('Frame', () => {
|
|
6
6
|
test('decodes RPC budgets and encodes named flags', () => {
|
|
7
7
|
const frame = Frame.from({
|
|
8
|
+
executionGas: 50_000n,
|
|
8
9
|
flags: 'approveExecutionAndPayment',
|
|
9
|
-
gas: 50_000n,
|
|
10
10
|
mode: 'verify',
|
|
11
11
|
to: '0x1111111111111111111111111111111111111111',
|
|
12
12
|
})
|
|
13
13
|
const rpc = z.encode(z.Frame.Frame, frame)
|
|
14
14
|
expect(rpc).toEqual({
|
|
15
15
|
data: '0x',
|
|
16
|
-
|
|
17
|
-
flags:
|
|
18
|
-
mode:
|
|
19
|
-
|
|
16
|
+
executionGas: '0xc350',
|
|
17
|
+
flags: '0x3',
|
|
18
|
+
mode: '0x1',
|
|
19
|
+
stateGas: '0x0',
|
|
20
20
|
target: '0x1111111111111111111111111111111111111111',
|
|
21
21
|
value: '0x0',
|
|
22
22
|
})
|
|
23
23
|
expect(z.decode(z.Frame.Frame, rpc)).toEqual({
|
|
24
24
|
data: '0x',
|
|
25
|
+
executionGas: 50_000n,
|
|
25
26
|
flags: 3,
|
|
26
|
-
gas: 50_000n,
|
|
27
27
|
mode: 1,
|
|
28
28
|
stateGas: 0n,
|
|
29
29
|
to: '0x1111111111111111111111111111111111111111',
|
|
@@ -32,12 +32,14 @@ describe('Frame', () => {
|
|
|
32
32
|
})
|
|
33
33
|
test('rejects invalid mode and budget', () => {
|
|
34
34
|
expect(z.safeParse(z.Frame.Decoded, { mode: 3 }).success).toBe(false)
|
|
35
|
-
expect(z.safeParse(z.Frame.Decoded, {
|
|
35
|
+
expect(z.safeParse(z.Frame.Decoded, { executionGas: -1n }).success).toBe(
|
|
36
|
+
false,
|
|
37
|
+
)
|
|
36
38
|
})
|
|
37
39
|
test('encodes numberish values', () => {
|
|
38
40
|
expect(
|
|
39
|
-
z.encode(z.Frame.FrameToRpc, {
|
|
40
|
-
.
|
|
41
|
+
z.encode(z.Frame.FrameToRpc, { executionGas: '0xc350', stateGas: 0 })
|
|
42
|
+
.executionGas,
|
|
41
43
|
).toBe('0xc350')
|
|
42
44
|
})
|
|
43
45
|
})
|
|
@@ -46,9 +48,9 @@ describe('FrameToRpc validation', () => {
|
|
|
46
48
|
test.each([
|
|
47
49
|
{ mode: 3 },
|
|
48
50
|
{ flags: 8 },
|
|
49
|
-
{
|
|
51
|
+
{ executionGas: 2n ** 64n },
|
|
50
52
|
{ stateGas: -1 },
|
|
51
|
-
{
|
|
53
|
+
{ executionGas: '0x10000000000000000' },
|
|
52
54
|
])('rejects invalid frame %#', (frame) => {
|
|
53
55
|
expect(
|
|
54
56
|
z.safeEncode(z.Frame.FrameToRpc, frame as Frame.toRpc.Input).success,
|