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,78 @@
|
|
|
1
|
+
import * as Frame from './Frame.js'
|
|
2
|
+
import type { Compute, PartialBy } from './internal/types.js'
|
|
3
|
+
|
|
4
|
+
/** A frame request whose omitted gas limits are estimated by the node. */
|
|
5
|
+
export type FrameRequest<bigintType = bigint> = Frame.Frame<bigintType>
|
|
6
|
+
|
|
7
|
+
/** JSON-RPC frame request. Only the execution mode is required. */
|
|
8
|
+
export type Rpc = Compute<
|
|
9
|
+
PartialBy<Frame.Rpc, Exclude<keyof Frame.Rpc, 'mode'>>
|
|
10
|
+
>
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts an RPC frame request, preserving omitted gas limits for node estimation.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts twoslash
|
|
17
|
+
* import { FrameRequest } from 'ox'
|
|
18
|
+
*
|
|
19
|
+
* const frame = FrameRequest.fromRpc({
|
|
20
|
+
* mode: '0x2',
|
|
21
|
+
* stateGas: '0x0'
|
|
22
|
+
* })
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @param frame - The RPC frame request.
|
|
26
|
+
* @returns The decoded request with omitted gas limits preserved.
|
|
27
|
+
*/
|
|
28
|
+
export function fromRpc(frame: Rpc): FrameRequest {
|
|
29
|
+
const { executionGas, stateGas, ...rest } = Frame.fromRpc({
|
|
30
|
+
...frame,
|
|
31
|
+
data: frame.data ?? '0x',
|
|
32
|
+
executionGas: frame.executionGas ?? '0x0',
|
|
33
|
+
flags: frame.flags ?? '0x0',
|
|
34
|
+
stateGas: frame.stateGas ?? '0x0',
|
|
35
|
+
value: frame.value ?? '0x0',
|
|
36
|
+
})
|
|
37
|
+
return {
|
|
38
|
+
...rest,
|
|
39
|
+
...(frame.executionGas === undefined ? {} : { executionGas }),
|
|
40
|
+
...(frame.stateGas === undefined ? {} : { stateGas }),
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare namespace fromRpc {
|
|
45
|
+
type ErrorType = Frame.fromRpc.ErrorType
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Converts a frame request to RPC fields without filling omitted gas limits.
|
|
50
|
+
*
|
|
51
|
+
* Explicit zero limits remain zero. Omitted mode, flags, value, and data use frame defaults.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts twoslash
|
|
55
|
+
* import { FrameRequest } from 'ox'
|
|
56
|
+
*
|
|
57
|
+
* const frame = FrameRequest.toRpc({
|
|
58
|
+
* mode: 'sender',
|
|
59
|
+
* stateGas: 0n
|
|
60
|
+
* })
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @param frame - The frame request. Gas and value accept hex, bigint, or number values.
|
|
64
|
+
* @returns The RPC request with omitted gas limits preserved.
|
|
65
|
+
*/
|
|
66
|
+
export function toRpc(frame: toRpc.Input): Rpc {
|
|
67
|
+
const { executionGas, stateGas, ...rest } = Frame.toRpc(frame)
|
|
68
|
+
return {
|
|
69
|
+
...rest,
|
|
70
|
+
...(frame.executionGas === undefined ? {} : { executionGas }),
|
|
71
|
+
...(frame.stateGas === undefined ? {} : { stateGas }),
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export declare namespace toRpc {
|
|
76
|
+
type Input = Frame.toRpc.Input
|
|
77
|
+
type ErrorType = Frame.toRpc.ErrorType
|
|
78
|
+
}
|
|
@@ -26,19 +26,19 @@ export type Arbitrary = {
|
|
|
26
26
|
signer?: undefined
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/** A
|
|
29
|
+
/** A secp256k1 signature entry. */
|
|
30
30
|
export type Secp256k1 = {
|
|
31
31
|
/** Explicit nonzero digest. Omit or use empty bytes for the transaction signing hash. */
|
|
32
32
|
payload?: Hex.Hex | undefined
|
|
33
33
|
/** secp256k1 verification scheme. */
|
|
34
34
|
scheme: 1 | 'secp256k1'
|
|
35
|
-
/** Recovered signature. Omit for an unsigned entry. */
|
|
36
|
-
signature?: Signature.Signature | undefined
|
|
35
|
+
/** Recovered signature or `Signature.toHex` bytes. Omit or use `0x` for an unsigned entry. */
|
|
36
|
+
signature?: Hex.Hex | Signature.Signature | undefined
|
|
37
37
|
/** Signer address. Omit to use the transaction sender. */
|
|
38
38
|
signer?: Address.Address | undefined
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
/** A
|
|
41
|
+
/** A P-256 signature entry. */
|
|
42
42
|
export type P256 = {
|
|
43
43
|
/** Explicit nonzero digest. Omit or use empty bytes for the transaction signing hash. */
|
|
44
44
|
payload?: Hex.Hex | undefined
|
|
@@ -50,14 +50,14 @@ export type P256 = {
|
|
|
50
50
|
| {
|
|
51
51
|
/** Uncompressed P-256 public key. */
|
|
52
52
|
publicKey: PublicKey.PublicKey
|
|
53
|
-
/** P-256 signature. */
|
|
54
|
-
signature: Signature.Signature<false>
|
|
53
|
+
/** P-256 signature or `Signature.toHex` bytes. */
|
|
54
|
+
signature: Hex.Hex | Signature.Signature<false>
|
|
55
55
|
}
|
|
56
56
|
| {
|
|
57
57
|
/** Public key, if already known. Empty wire signatures do not retain it. */
|
|
58
58
|
publicKey?: PublicKey.PublicKey | undefined
|
|
59
|
-
/** Omit for an unsigned entry. */
|
|
60
|
-
signature?: undefined
|
|
59
|
+
/** Omit or use `0x` for an unsigned entry. */
|
|
60
|
+
signature?: '0x' | undefined
|
|
61
61
|
}
|
|
62
62
|
)
|
|
63
63
|
|
|
@@ -67,13 +67,13 @@ export type FrameSignature = Arbitrary | Secp256k1 | P256
|
|
|
67
67
|
/** JSON-RPC representation of a frame signature. */
|
|
68
68
|
export type Rpc = {
|
|
69
69
|
/** Explicit digest, or empty bytes for the transaction signing hash. */
|
|
70
|
-
msg
|
|
70
|
+
msg?: Hex.Hex | undefined
|
|
71
71
|
/** Signature verification scheme. */
|
|
72
|
-
scheme:
|
|
72
|
+
scheme: '0x0' | '0x1' | '0x2'
|
|
73
73
|
/** Encoded signature bytes. */
|
|
74
|
-
signature
|
|
74
|
+
signature?: Hex.Hex | undefined
|
|
75
75
|
/** Signer address; absent for the transaction sender. */
|
|
76
|
-
signer?: Address.Address |
|
|
76
|
+
signer?: Address.Address | '0x' | undefined
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/** RLP-ready signature entry. The payload occupies the specification's `msg` field. */
|
|
@@ -164,24 +164,34 @@ export function assert(
|
|
|
164
164
|
throw new InvalidError('Public key coordinates must fit in 32 bytes.')
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
-
if (
|
|
167
|
+
if (
|
|
168
|
+
entry.signature !== undefined &&
|
|
169
|
+
entry.signature !== '0x' &&
|
|
170
|
+
entry.publicKey === undefined
|
|
171
|
+
)
|
|
168
172
|
throw new InvalidError('P-256 signatures require a public key.')
|
|
169
173
|
}
|
|
170
|
-
if (entry.signature === undefined) {
|
|
174
|
+
if (entry.signature === undefined || entry.signature === '0x') {
|
|
171
175
|
if (options.signed) throw new InvalidError('Signature is required.')
|
|
172
176
|
return
|
|
173
177
|
}
|
|
174
|
-
|
|
175
|
-
|
|
178
|
+
if (typeof entry.signature === 'string')
|
|
179
|
+
Hex.assert(entry.signature, { strict: true })
|
|
180
|
+
const signature =
|
|
181
|
+
typeof entry.signature === 'string'
|
|
182
|
+
? Signature.fromHex(entry.signature)
|
|
183
|
+
: entry.signature
|
|
184
|
+
Hex.assert(signature.r, { strict: true })
|
|
185
|
+
Hex.assert(signature.s, { strict: true })
|
|
176
186
|
if (
|
|
177
|
-
(scheme === 1 ||
|
|
178
|
-
|
|
179
|
-
|
|
187
|
+
(scheme === 1 || signature.yParity !== undefined) &&
|
|
188
|
+
signature.yParity !== 0 &&
|
|
189
|
+
signature.yParity !== 1
|
|
180
190
|
)
|
|
181
191
|
throw new InvalidError('Signature parity must be 0 or 1.')
|
|
182
|
-
Signature.assert(
|
|
183
|
-
const r = Hex.toBigInt(
|
|
184
|
-
const s = Hex.toBigInt(
|
|
192
|
+
Signature.assert(signature, { recovered: scheme === 1 })
|
|
193
|
+
const r = Hex.toBigInt(signature.r)
|
|
194
|
+
const s = Hex.toBigInt(signature.s)
|
|
185
195
|
const order = scheme === 1 ? secp256k1N : p256N
|
|
186
196
|
if (
|
|
187
197
|
r === 0n ||
|
|
@@ -210,13 +220,15 @@ export declare namespace assert {
|
|
|
210
220
|
| Hex.toBigInt.ErrorType
|
|
211
221
|
| PublicKey.assert.ErrorType
|
|
212
222
|
| Signature.assert.ErrorType
|
|
223
|
+
| Signature.fromHex.ErrorType
|
|
213
224
|
| Errors.GlobalErrorType
|
|
214
225
|
}
|
|
215
226
|
|
|
216
227
|
/**
|
|
217
228
|
* Coerces a value into a {@link ox#FrameSignature.FrameSignature}.
|
|
218
229
|
*
|
|
219
|
-
* Accepts arbitrary signature bytes or a
|
|
230
|
+
* Accepts arbitrary signature bytes or a signature entry. Protocol signatures accept
|
|
231
|
+
* structured objects or `Signature.toHex` bytes. P-256 entries still require a public key. Omitted
|
|
220
232
|
* `scheme` and `payload` default to `'arbitrary'` and `'0x'`, respectively.
|
|
221
233
|
* An empty payload selects the canonical transaction signing hash; an explicit
|
|
222
234
|
* payload must be a nonzero 32-byte digest.
|
|
@@ -340,7 +352,7 @@ export declare namespace from {
|
|
|
340
352
|
*
|
|
341
353
|
* const entry = FrameSignature.fromRpc({
|
|
342
354
|
* msg: '0x',
|
|
343
|
-
* scheme:
|
|
355
|
+
* scheme: '0x0',
|
|
344
356
|
* signature: '0xdeadbeef'
|
|
345
357
|
* })
|
|
346
358
|
* ```
|
|
@@ -350,15 +362,20 @@ export declare namespace from {
|
|
|
350
362
|
*/
|
|
351
363
|
export function fromRpc(entry: Rpc): FrameSignature {
|
|
352
364
|
return fromTuple([
|
|
353
|
-
entry.scheme ===
|
|
365
|
+
entry.scheme === '0x0'
|
|
366
|
+
? '0x'
|
|
367
|
+
: Hex.fromNumber(Hex.toNumber(entry.scheme), { size: 1 }),
|
|
354
368
|
entry.signer ?? '0x',
|
|
355
|
-
entry.msg,
|
|
356
|
-
entry.signature,
|
|
369
|
+
entry.msg ?? '0x',
|
|
370
|
+
entry.signature ?? '0x',
|
|
357
371
|
])
|
|
358
372
|
}
|
|
359
373
|
|
|
360
374
|
export declare namespace fromRpc {
|
|
361
|
-
type ErrorType =
|
|
375
|
+
type ErrorType =
|
|
376
|
+
| fromTuple.ErrorType
|
|
377
|
+
| Hex.fromNumber.ErrorType
|
|
378
|
+
| Hex.toNumber.ErrorType
|
|
362
379
|
}
|
|
363
380
|
|
|
364
381
|
/**
|
|
@@ -381,8 +398,10 @@ export function toRpc(entry: FrameSignature): Rpc {
|
|
|
381
398
|
const [scheme, signer, msg, signature] = toTuple(entry)
|
|
382
399
|
return {
|
|
383
400
|
msg,
|
|
384
|
-
scheme: (scheme === '0x'
|
|
385
|
-
|
|
401
|
+
scheme: (scheme === '0x'
|
|
402
|
+
? '0x0'
|
|
403
|
+
: Hex.fromNumber(Hex.toNumber(scheme))) as Rpc['scheme'],
|
|
404
|
+
...(signature === '0x' && scheme !== '0x' ? {} : { signature }),
|
|
386
405
|
...(signer === '0x' ? {} : { signer }),
|
|
387
406
|
}
|
|
388
407
|
}
|
|
@@ -509,13 +528,24 @@ export function toTuple(entry: FrameSignature): Tuple {
|
|
|
509
528
|
return entry.signature
|
|
510
529
|
case 1:
|
|
511
530
|
case 'secp256k1':
|
|
512
|
-
return entry.signature === undefined
|
|
531
|
+
return entry.signature === undefined || entry.signature === '0x'
|
|
513
532
|
? '0x'
|
|
514
|
-
: Hex.fromBytes(
|
|
533
|
+
: Hex.fromBytes(
|
|
534
|
+
Signature.toRecoveredBytes(
|
|
535
|
+
typeof entry.signature === 'string'
|
|
536
|
+
? Signature.fromHex(entry.signature)
|
|
537
|
+
: entry.signature,
|
|
538
|
+
),
|
|
539
|
+
)
|
|
515
540
|
case 2:
|
|
516
541
|
case 'p256': {
|
|
517
|
-
if (entry.signature === undefined
|
|
518
|
-
|
|
542
|
+
if (entry.signature === undefined || entry.signature === '0x')
|
|
543
|
+
return '0x'
|
|
544
|
+
const publicKey = entry.publicKey!
|
|
545
|
+
const signature =
|
|
546
|
+
typeof entry.signature === 'string'
|
|
547
|
+
? Signature.fromHex(entry.signature)
|
|
548
|
+
: entry.signature
|
|
519
549
|
const s = Hex.toBigInt(signature.s)
|
|
520
550
|
return Hex.concat(
|
|
521
551
|
Hex.fromNumber(Hex.toBigInt(signature.r), { size: 32 }),
|
package/src/core/Siwe.ts
CHANGED
|
@@ -21,7 +21,7 @@ export const prefixRegex =
|
|
|
21
21
|
|
|
22
22
|
// https://regexr.com/80gf9
|
|
23
23
|
export const suffixRegex =
|
|
24
|
-
/(?:URI: (?<uri>.+))\n(?:Version: (?<version>.+))\n(?:Chain ID: (?<chainId>\d+))\n(?:Nonce: (?<nonce>[a-zA-Z0-9]+))\n(?:Issued At: (?<issuedAt>.+))(?:\nExpiration Time: (?<expirationTime>.+))?(?:\nNot Before: (?<notBefore>.+))?(?:\nRequest ID: (?<requestId
|
|
24
|
+
/(?:URI: (?<uri>.+))\n(?:Version: (?<version>.+))\n(?:Chain ID: (?<chainId>\d+))\n(?:Nonce: (?<nonce>[a-zA-Z0-9]+))\n(?:Issued At: (?<issuedAt>.+))(?:\nExpiration Time: (?<expirationTime>.+))?(?:\nNot Before: (?<notBefore>.+))?(?:\nRequest ID: (?<requestId>.*))?(?:\nResources:(?<resources>(?:\n- .+)*))?/
|
|
25
25
|
|
|
26
26
|
const siweDateTimeRegex =
|
|
27
27
|
/^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])[Tt]([01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d+)?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/
|
|
@@ -421,18 +421,26 @@ export function parseMessage(message: string): ExactPartial<Message> {
|
|
|
421
421
|
scheme?: string
|
|
422
422
|
statement?: string
|
|
423
423
|
}
|
|
424
|
-
const {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
424
|
+
const {
|
|
425
|
+
chainId,
|
|
426
|
+
expirationTime,
|
|
427
|
+
issuedAt,
|
|
428
|
+
notBefore,
|
|
429
|
+
requestId,
|
|
430
|
+
resources: resources_,
|
|
431
|
+
...suffix
|
|
432
|
+
} = (message.match(suffixRegex)?.groups ?? {}) as {
|
|
433
|
+
chainId: string
|
|
434
|
+
expirationTime?: string
|
|
435
|
+
issuedAt?: string
|
|
436
|
+
nonce: string
|
|
437
|
+
notBefore?: string
|
|
438
|
+
requestId?: string
|
|
439
|
+
resources?: string
|
|
440
|
+
uri: string
|
|
441
|
+
version: '1'
|
|
442
|
+
}
|
|
443
|
+
const resources = resources_?.split('\n- ').slice(1)
|
|
436
444
|
return {
|
|
437
445
|
...prefix,
|
|
438
446
|
...suffix,
|
package/src/core/Transaction.ts
CHANGED
|
@@ -5,8 +5,14 @@ import type * as Errors from './Errors.js'
|
|
|
5
5
|
import * as Frame from './Frame.js'
|
|
6
6
|
import * as FrameSignature from './FrameSignature.js'
|
|
7
7
|
import * as Hex from './Hex.js'
|
|
8
|
+
import * as FrameNonce from './internal/frameNonce.js'
|
|
8
9
|
import * as Quantity from './internal/quantity.js'
|
|
9
|
-
import type {
|
|
10
|
+
import type {
|
|
11
|
+
Compute,
|
|
12
|
+
ExactPartial,
|
|
13
|
+
OneOf,
|
|
14
|
+
UnionCompute,
|
|
15
|
+
} from './internal/types.js'
|
|
10
16
|
import * as Signature from './Signature.js'
|
|
11
17
|
|
|
12
18
|
/**
|
|
@@ -197,29 +203,37 @@ export type Eip8141<
|
|
|
197
203
|
> = Compute<
|
|
198
204
|
Omit<
|
|
199
205
|
Base<type, pending, bigintType, numberType>,
|
|
200
|
-
'chainId' | 'r' | 's' | 'v' | 'yParity'
|
|
201
|
-
> &
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
:
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
:
|
|
222
|
-
|
|
206
|
+
'chainId' | 'gas' | 'input' | 'to' | 'value' | 'r' | 's' | 'v' | 'yParity'
|
|
207
|
+
> &
|
|
208
|
+
ExactPartial<
|
|
209
|
+
Pick<
|
|
210
|
+
Base<type, pending, bigintType, numberType>,
|
|
211
|
+
'gas' | 'input' | 'to' | 'value'
|
|
212
|
+
>
|
|
213
|
+
> & {
|
|
214
|
+
/** Versioned blob hashes. */
|
|
215
|
+
blobVersionedHashes: readonly Hex.Hex[]
|
|
216
|
+
/** Chain ID, retaining bigint precision when needed. */
|
|
217
|
+
chainId: numberType | bigintType
|
|
218
|
+
/** Frames in execution order. */
|
|
219
|
+
frames: readonly ([bigintType] extends [Hex.Hex]
|
|
220
|
+
? Frame.Rpc
|
|
221
|
+
: Frame.Frame<bigintType>)[]
|
|
222
|
+
/** Effective gas price. */
|
|
223
|
+
gasPrice?: bigintType | undefined
|
|
224
|
+
/** Maximum fee per blob gas. */
|
|
225
|
+
maxFeePerBlobGas: bigintType
|
|
226
|
+
/** Maximum fee per gas. */
|
|
227
|
+
maxFeePerGas: bigintType
|
|
228
|
+
/** Maximum priority fee per gas. */
|
|
229
|
+
maxPriorityFeePerGas: bigintType
|
|
230
|
+
/** EIP-8250 domains sharing the transaction's `nonce` sequence. */
|
|
231
|
+
nonceKeys?: readonly bigintType[] | undefined
|
|
232
|
+
/** Frame signature entries. */
|
|
233
|
+
signatures: readonly ([bigintType] extends [Hex.Hex]
|
|
234
|
+
? FrameSignature.Rpc
|
|
235
|
+
: FrameSignature.FrameSignature)[]
|
|
236
|
+
}
|
|
223
237
|
>
|
|
224
238
|
|
|
225
239
|
/** An EIP-8141 RPC transaction. */
|
|
@@ -366,6 +380,16 @@ export function fromRpc<
|
|
|
366
380
|
? chainId
|
|
367
381
|
: Number(chainId)
|
|
368
382
|
}
|
|
383
|
+
if (transaction.type === '0x6' && transaction.nonceKeys !== undefined) {
|
|
384
|
+
if (transaction.nonce === undefined)
|
|
385
|
+
throw new FrameNonce.InvalidError(
|
|
386
|
+
'A keyed transaction result requires nonce.',
|
|
387
|
+
)
|
|
388
|
+
transaction_.nonceKeys = FrameNonce.fromRpc(
|
|
389
|
+
transaction.nonceKeys,
|
|
390
|
+
transaction.nonce,
|
|
391
|
+
)
|
|
392
|
+
}
|
|
369
393
|
if (transaction.type === '0x6' && transaction.frames) {
|
|
370
394
|
transaction_.frames = transaction.frames.map(Frame.fromRpc)
|
|
371
395
|
transaction_.signatures = (transaction.signatures ?? []).map(
|
|
@@ -402,6 +426,7 @@ export declare namespace fromRpc {
|
|
|
402
426
|
|
|
403
427
|
type ErrorType =
|
|
404
428
|
| Signature.extract.ErrorType
|
|
429
|
+
| FrameNonce.InvalidError
|
|
405
430
|
| Frame.fromRpc.ErrorType
|
|
406
431
|
| FrameSignature.fromRpc.ErrorType
|
|
407
432
|
| Errors.GlobalErrorType
|
|
@@ -469,6 +494,8 @@ export function toRpc<pending extends boolean = false>(
|
|
|
469
494
|
rpc.type = (toRpcType as any)[transaction.type] ?? transaction.type
|
|
470
495
|
rpc.value = Quantity.fromNumberish(transaction.value ?? 0n)
|
|
471
496
|
|
|
497
|
+
if (transaction.type === 'eip8141' && transaction.nonceKeys !== undefined)
|
|
498
|
+
rpc.nonceKeys = FrameNonce.toRpc(transaction.nonceKeys, transaction.nonce)
|
|
472
499
|
if (transaction.type === 'eip8141' && transaction.frames) {
|
|
473
500
|
rpc.frames = transaction.frames.map(Frame.toRpc)
|
|
474
501
|
rpc.signatures = transaction.signatures.map(FrameSignature.toRpc)
|
|
@@ -516,6 +543,7 @@ export declare namespace toRpc {
|
|
|
516
543
|
|
|
517
544
|
type ErrorType =
|
|
518
545
|
| Signature.extract.ErrorType
|
|
546
|
+
| FrameNonce.InvalidError
|
|
519
547
|
| Frame.toRpc.ErrorType
|
|
520
548
|
| FrameSignature.toRpc.ErrorType
|
|
521
549
|
| Errors.GlobalErrorType
|
|
@@ -3,9 +3,10 @@ import type * as Address from './Address.js'
|
|
|
3
3
|
import * as Authorization from './Authorization.js'
|
|
4
4
|
import * as Blobs from './Blobs.js'
|
|
5
5
|
import * as Errors from './Errors.js'
|
|
6
|
-
import * as
|
|
6
|
+
import * as FrameRequest from './FrameRequest.js'
|
|
7
7
|
import * as FrameSignature from './FrameSignature.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 { Compute } from './internal/types.js'
|
|
11
12
|
import type * as Kzg from './Kzg.js'
|
|
@@ -19,7 +20,9 @@ export type TransactionRequest<
|
|
|
19
20
|
bigintType = bigint,
|
|
20
21
|
numberType = number,
|
|
21
22
|
type extends string = string,
|
|
22
|
-
frame = [bigintType] extends [Hex.Hex]
|
|
23
|
+
frame = [bigintType] extends [Hex.Hex]
|
|
24
|
+
? FrameRequest.Rpc
|
|
25
|
+
: FrameRequest.FrameRequest<bigintType>,
|
|
23
26
|
signature = [bigintType] extends [Hex.Hex]
|
|
24
27
|
? FrameSignature.Rpc
|
|
25
28
|
: FrameSignature.FrameSignature,
|
|
@@ -56,6 +59,8 @@ export type TransactionRequest<
|
|
|
56
59
|
maxPriorityFeePerGas?: bigintType | undefined
|
|
57
60
|
/** Unique number identifying this transaction */
|
|
58
61
|
nonce?: bigintType | undefined
|
|
62
|
+
/** EIP-8250 nonce domains. `nonce` is their shared sequence; omitted keys preserve EIP-8141 encoding. */
|
|
63
|
+
nonceKeys?: readonly bigintType[] | undefined
|
|
59
64
|
/** Frame signature entries for EIP-8141 transactions. */
|
|
60
65
|
signatures?: readonly signature[] | undefined
|
|
61
66
|
/** Transaction recipient */
|
|
@@ -79,7 +84,7 @@ export type Rpc = TransactionRequest<
|
|
|
79
84
|
Hex.Hex,
|
|
80
85
|
Hex.Hex,
|
|
81
86
|
string,
|
|
82
|
-
|
|
87
|
+
FrameRequest.Rpc,
|
|
83
88
|
FrameSignature.Rpc
|
|
84
89
|
>
|
|
85
90
|
|
|
@@ -109,7 +114,7 @@ export function fromRpc(request: Rpc): TransactionRequest {
|
|
|
109
114
|
if (typeof request.chainId !== 'undefined')
|
|
110
115
|
request_.chainId = Hex.toNumber(request.chainId)
|
|
111
116
|
if (request.frames !== undefined)
|
|
112
|
-
request_.frames = request.frames.map(
|
|
117
|
+
request_.frames = request.frames.map(FrameRequest.fromRpc)
|
|
113
118
|
if (request.signatures !== undefined)
|
|
114
119
|
request_.signatures = request.signatures.map(FrameSignature.fromRpc)
|
|
115
120
|
if (typeof request.gas !== 'undefined')
|
|
@@ -124,6 +129,8 @@ export function fromRpc(request: Rpc): TransactionRequest {
|
|
|
124
129
|
request_.maxPriorityFeePerGas = Hex.toBigInt(request.maxPriorityFeePerGas)
|
|
125
130
|
if (typeof request.nonce !== 'undefined')
|
|
126
131
|
request_.nonce = Hex.toBigInt(request.nonce)
|
|
132
|
+
if (request.nonceKeys !== undefined)
|
|
133
|
+
request_.nonceKeys = FrameNonce.fromRpc(request.nonceKeys, request.nonce)
|
|
127
134
|
if (typeof request.type !== 'undefined')
|
|
128
135
|
request_.type =
|
|
129
136
|
Transaction.fromRpcType[
|
|
@@ -141,7 +148,8 @@ export function fromRpc(request: Rpc): TransactionRequest {
|
|
|
141
148
|
export declare namespace fromRpc {
|
|
142
149
|
export type ErrorType =
|
|
143
150
|
| Authorization.fromRpcList.ErrorType
|
|
144
|
-
|
|
|
151
|
+
| FrameNonce.InvalidError
|
|
152
|
+
| FrameRequest.fromRpc.ErrorType
|
|
145
153
|
| FrameSignature.fromRpc.ErrorType
|
|
146
154
|
| Hex.toNumber.ErrorType
|
|
147
155
|
| Hex.toBigInt.ErrorType
|
|
@@ -210,7 +218,7 @@ export function toRpc(request: toRpc.Input): Rpc {
|
|
|
210
218
|
request_rpc.input = request.input
|
|
211
219
|
}
|
|
212
220
|
if (request.frames !== undefined)
|
|
213
|
-
request_rpc.frames = request.frames.map(
|
|
221
|
+
request_rpc.frames = request.frames.map(FrameRequest.toRpc)
|
|
214
222
|
if (request.signatures !== undefined)
|
|
215
223
|
request_rpc.signatures = request.signatures.map(FrameSignature.toRpc)
|
|
216
224
|
if (typeof request.from !== 'undefined') request_rpc.from = request.from
|
|
@@ -230,6 +238,8 @@ export function toRpc(request: toRpc.Input): Rpc {
|
|
|
230
238
|
)
|
|
231
239
|
if (typeof request.nonce !== 'undefined')
|
|
232
240
|
request_rpc.nonce = Quantity.fromNumberish(request.nonce)
|
|
241
|
+
if (request.nonceKeys !== undefined)
|
|
242
|
+
request_rpc.nonceKeys = FrameNonce.toRpc(request.nonceKeys, request.nonce)
|
|
233
243
|
if (typeof request.to !== 'undefined') request_rpc.to = request.to
|
|
234
244
|
if (typeof request.type !== 'undefined')
|
|
235
245
|
request_rpc.type =
|
|
@@ -258,7 +268,8 @@ export declare namespace toRpc {
|
|
|
258
268
|
|
|
259
269
|
export type ErrorType =
|
|
260
270
|
| Authorization.toRpcList.ErrorType
|
|
261
|
-
|
|
|
271
|
+
| FrameNonce.InvalidError
|
|
272
|
+
| FrameRequest.toRpc.ErrorType
|
|
262
273
|
| FrameSignature.toRpc.ErrorType
|
|
263
274
|
| Hex.fromNumber.ErrorType
|
|
264
275
|
| Errors.GlobalErrorType
|
|
@@ -400,6 +411,9 @@ export function toEnvelope(
|
|
|
400
411
|
maxFeePerGas: request.maxFeePerGas,
|
|
401
412
|
maxPriorityFeePerGas: request.maxPriorityFeePerGas,
|
|
402
413
|
nonce: request.nonce,
|
|
414
|
+
...(request.nonceKeys !== undefined
|
|
415
|
+
? { nonceKeys: request.nonceKeys }
|
|
416
|
+
: {}),
|
|
403
417
|
sender: request.from,
|
|
404
418
|
sidecars,
|
|
405
419
|
signatures: request.signatures,
|
package/src/core/TxEnvelope.ts
CHANGED
|
@@ -242,7 +242,9 @@ export declare namespace deserialize {
|
|
|
242
242
|
*
|
|
243
243
|
* const envelope = TransactionEnvelope.from({
|
|
244
244
|
* chainId: 1,
|
|
245
|
-
* frames: [
|
|
245
|
+
* frames: [
|
|
246
|
+
* Frame.from({ executionGas: 50_000n, mode: 'sender' })
|
|
247
|
+
* ],
|
|
246
248
|
* sender: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8'
|
|
247
249
|
* })
|
|
248
250
|
* ```
|
|
@@ -410,7 +412,10 @@ export function getType<const envelope extends Typeable>(
|
|
|
410
412
|
return type as never
|
|
411
413
|
}
|
|
412
414
|
|
|
413
|
-
if (
|
|
415
|
+
if (
|
|
416
|
+
('frames' in envelope && envelope.frames !== undefined) ||
|
|
417
|
+
('nonceKeys' in envelope && envelope.nonceKeys !== undefined)
|
|
418
|
+
)
|
|
414
419
|
return 'eip8141' as never
|
|
415
420
|
if (
|
|
416
421
|
'authorizationList' in envelope &&
|
|
@@ -444,7 +449,9 @@ export declare namespace getType {
|
|
|
444
449
|
type: infer type extends string
|
|
445
450
|
}
|
|
446
451
|
? type
|
|
447
|
-
:
|
|
452
|
+
: true extends
|
|
453
|
+
| HasDefined<envelope, 'frames'>
|
|
454
|
+
| HasDefined<envelope, 'nonceKeys'>
|
|
448
455
|
? TxEnvelopeEip8141.Type
|
|
449
456
|
: HasDefined<envelope, 'authorizationList'> extends true
|
|
450
457
|
? TxEnvelopeEip7702.Type
|
|
@@ -779,6 +786,12 @@ export function toTransactionRequest(
|
|
|
779
786
|
...rest,
|
|
780
787
|
...(sidecars ? { blobs: sidecars.blobs } : {}),
|
|
781
788
|
chainId: Hex.toNumber(Hex.fromNumber(rest.chainId)),
|
|
789
|
+
// Envelopes commit to zero defaults; request omission would trigger estimation.
|
|
790
|
+
frames: rest.frames.map((frame) => ({
|
|
791
|
+
...frame,
|
|
792
|
+
executionGas: frame.executionGas ?? 0n,
|
|
793
|
+
stateGas: frame.stateGas ?? 0n,
|
|
794
|
+
})),
|
|
782
795
|
from: sender,
|
|
783
796
|
}
|
|
784
797
|
}
|