ox 1.7.4 → 1.8.0

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.
Files changed (237) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/core/AbiEvent.d.ts.map +1 -1
  3. package/dist/core/AbiEvent.js +10 -9
  4. package/dist/core/AbiEvent.js.map +1 -1
  5. package/dist/core/Blobs.d.ts.map +1 -1
  6. package/dist/core/Blobs.js +6 -2
  7. package/dist/core/Blobs.js.map +1 -1
  8. package/dist/core/Frame.d.ts +290 -0
  9. package/dist/core/Frame.d.ts.map +1 -0
  10. package/dist/core/Frame.js +306 -0
  11. package/dist/core/Frame.js.map +1 -0
  12. package/dist/core/FrameReceipt.d.ts +92 -0
  13. package/dist/core/FrameReceipt.d.ts.map +1 -0
  14. package/dist/core/FrameReceipt.js +72 -0
  15. package/dist/core/FrameReceipt.js.map +1 -0
  16. package/dist/core/FrameSignature.d.ts +357 -0
  17. package/dist/core/FrameSignature.d.ts.map +1 -0
  18. package/dist/core/FrameSignature.js +411 -0
  19. package/dist/core/FrameSignature.js.map +1 -0
  20. package/dist/core/Signature.d.ts +6 -5
  21. package/dist/core/Signature.d.ts.map +1 -1
  22. package/dist/core/Signature.js +17 -7
  23. package/dist/core/Signature.js.map +1 -1
  24. package/dist/core/Siwe.d.ts.map +1 -1
  25. package/dist/core/Siwe.js +21 -1
  26. package/dist/core/Siwe.js.map +1 -1
  27. package/dist/core/Transaction.d.ts +29 -4
  28. package/dist/core/Transaction.d.ts.map +1 -1
  29. package/dist/core/Transaction.js +25 -4
  30. package/dist/core/Transaction.js.map +1 -1
  31. package/dist/core/TransactionReceipt.d.ts +13 -4
  32. package/dist/core/TransactionReceipt.d.ts.map +1 -1
  33. package/dist/core/TransactionReceipt.js +14 -0
  34. package/dist/core/TransactionReceipt.js.map +1 -1
  35. package/dist/core/TransactionRequest.d.ts +15 -7
  36. package/dist/core/TransactionRequest.d.ts.map +1 -1
  37. package/dist/core/TransactionRequest.js +47 -1
  38. package/dist/core/TransactionRequest.js.map +1 -1
  39. package/dist/core/TxEnvelope.d.ts +35 -21
  40. package/dist/core/TxEnvelope.d.ts.map +1 -1
  41. package/dist/core/TxEnvelope.js +46 -6
  42. package/dist/core/TxEnvelope.js.map +1 -1
  43. package/dist/core/TxEnvelopeEip8141.d.ts +341 -0
  44. package/dist/core/TxEnvelopeEip8141.d.ts.map +1 -0
  45. package/dist/core/TxEnvelopeEip8141.js +485 -0
  46. package/dist/core/TxEnvelopeEip8141.js.map +1 -0
  47. package/dist/core/internal/curves.d.ts +2 -0
  48. package/dist/core/internal/curves.d.ts.map +1 -1
  49. package/dist/core/internal/curves.js +2 -0
  50. package/dist/core/internal/curves.js.map +1 -1
  51. package/dist/index.d.ts +73 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +73 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/tempo/KeyAuthorization.d.ts +42 -38
  56. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  57. package/dist/tempo/KeyAuthorization.js +24 -4
  58. package/dist/tempo/KeyAuthorization.js.map +1 -1
  59. package/dist/tempo/MultisigConfig.d.ts +18 -15
  60. package/dist/tempo/MultisigConfig.d.ts.map +1 -1
  61. package/dist/tempo/MultisigConfig.js +49 -20
  62. package/dist/tempo/MultisigConfig.js.map +1 -1
  63. package/dist/tempo/MultisigOperation.d.ts +3 -2
  64. package/dist/tempo/MultisigOperation.d.ts.map +1 -1
  65. package/dist/tempo/MultisigOperation.js +20 -100
  66. package/dist/tempo/MultisigOperation.js.map +1 -1
  67. package/dist/tempo/MultisigSimulation.d.ts +2 -49
  68. package/dist/tempo/MultisigSimulation.d.ts.map +1 -1
  69. package/dist/tempo/MultisigSimulation.js +18 -46
  70. package/dist/tempo/MultisigSimulation.js.map +1 -1
  71. package/dist/tempo/SignatureEnvelope.d.ts +72 -140
  72. package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
  73. package/dist/tempo/SignatureEnvelope.js +130 -181
  74. package/dist/tempo/SignatureEnvelope.js.map +1 -1
  75. package/dist/tempo/Transaction.d.ts +2 -0
  76. package/dist/tempo/Transaction.d.ts.map +1 -1
  77. package/dist/tempo/TransactionReceipt.d.ts +2 -0
  78. package/dist/tempo/TransactionReceipt.d.ts.map +1 -1
  79. package/dist/tempo/TransactionRequest.d.ts +4 -2
  80. package/dist/tempo/TransactionRequest.d.ts.map +1 -1
  81. package/dist/tempo/TransactionRequest.js +6 -1
  82. package/dist/tempo/TransactionRequest.js.map +1 -1
  83. package/dist/tempo/index.d.ts +3 -1
  84. package/dist/tempo/index.d.ts.map +1 -1
  85. package/dist/tempo/index.js +3 -1
  86. package/dist/tempo/index.js.map +1 -1
  87. package/dist/zod/Block.d.ts +123 -0
  88. package/dist/zod/Block.d.ts.map +1 -1
  89. package/dist/zod/Frame.d.ts +73 -0
  90. package/dist/zod/Frame.d.ts.map +1 -0
  91. package/dist/zod/Frame.js +74 -0
  92. package/dist/zod/Frame.js.map +1 -0
  93. package/dist/zod/FrameReceipt.d.ts +50 -0
  94. package/dist/zod/FrameReceipt.d.ts.map +1 -0
  95. package/dist/zod/FrameReceipt.js +37 -0
  96. package/dist/zod/FrameReceipt.js.map +1 -0
  97. package/dist/zod/FrameSignature.d.ts +63 -0
  98. package/dist/zod/FrameSignature.d.ts.map +1 -0
  99. package/dist/zod/FrameSignature.js +66 -0
  100. package/dist/zod/FrameSignature.js.map +1 -0
  101. package/dist/zod/RpcSchema.d.ts +806 -11
  102. package/dist/zod/RpcSchema.d.ts.map +1 -1
  103. package/dist/zod/Transaction.d.ts +252 -0
  104. package/dist/zod/Transaction.d.ts.map +1 -1
  105. package/dist/zod/Transaction.js +54 -0
  106. package/dist/zod/Transaction.js.map +1 -1
  107. package/dist/zod/TransactionEnvelope.d.ts +233 -4
  108. package/dist/zod/TransactionEnvelope.d.ts.map +1 -1
  109. package/dist/zod/TransactionEnvelope.js +9 -0
  110. package/dist/zod/TransactionEnvelope.js.map +1 -1
  111. package/dist/zod/TransactionReceipt.d.ts +48 -0
  112. package/dist/zod/TransactionReceipt.d.ts.map +1 -1
  113. package/dist/zod/TransactionReceipt.js +8 -3
  114. package/dist/zod/TransactionReceipt.js.map +1 -1
  115. package/dist/zod/TransactionRequest.d.ts +50 -2
  116. package/dist/zod/TransactionRequest.d.ts.map +1 -1
  117. package/dist/zod/TransactionRequest.js +10 -4
  118. package/dist/zod/TransactionRequest.js.map +1 -1
  119. package/dist/zod/TxEnvelopeEip8141.d.ts +166 -0
  120. package/dist/zod/TxEnvelopeEip8141.d.ts.map +1 -0
  121. package/dist/zod/TxEnvelopeEip8141.js +76 -0
  122. package/dist/zod/TxEnvelopeEip8141.js.map +1 -0
  123. package/dist/zod/internal/Frame.d.ts +4 -0
  124. package/dist/zod/internal/Frame.d.ts.map +1 -0
  125. package/dist/zod/internal/Frame.js +17 -0
  126. package/dist/zod/internal/Frame.js.map +1 -0
  127. package/dist/zod/internal/rpcSchemas/Eth.d.ts +842 -11
  128. package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
  129. package/dist/zod/internal/rpcSchemas/Wallet.d.ts +56 -2
  130. package/dist/zod/internal/rpcSchemas/Wallet.d.ts.map +1 -1
  131. package/dist/zod/tempo/AuthorizationTempo.d.ts +350 -10
  132. package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
  133. package/dist/zod/tempo/KeyAuthorization.d.ts +242 -422
  134. package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
  135. package/dist/zod/tempo/KeyAuthorization.js +29 -31
  136. package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
  137. package/dist/zod/tempo/MultisigSimulation.d.ts +8 -76
  138. package/dist/zod/tempo/MultisigSimulation.d.ts.map +1 -1
  139. package/dist/zod/tempo/MultisigSimulation.js +3 -37
  140. package/dist/zod/tempo/MultisigSimulation.js.map +1 -1
  141. package/dist/zod/tempo/RpcSchemaTempo.d.ts +424 -228
  142. package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
  143. package/dist/zod/tempo/SignatureEnvelope.d.ts +105 -3
  144. package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
  145. package/dist/zod/tempo/SignatureEnvelope.js +21 -9
  146. package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
  147. package/dist/zod/tempo/Transaction.d.ts +783 -432
  148. package/dist/zod/tempo/Transaction.d.ts.map +1 -1
  149. package/dist/zod/tempo/TransactionRequest.d.ts +590 -473
  150. package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
  151. package/dist/zod/tempo/TransactionRequest.js +8 -0
  152. package/dist/zod/tempo/TransactionRequest.js.map +1 -1
  153. package/dist/zod/tempo/TxEnvelopeTempo.d.ts +327 -213
  154. package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
  155. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +105 -3
  156. package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
  157. package/dist/zod/z.d.ts +4 -0
  158. package/dist/zod/z.d.ts.map +1 -1
  159. package/dist/zod/z.js +4 -0
  160. package/dist/zod/z.js.map +1 -1
  161. package/package.json +41 -1
  162. package/src/core/AbiEvent.ts +11 -9
  163. package/src/core/Blobs.ts +6 -2
  164. package/src/core/Frame.ts +443 -0
  165. package/src/core/FrameReceipt.ts +117 -0
  166. package/src/core/FrameSignature.ts +593 -0
  167. package/src/core/Signature.ts +41 -11
  168. package/src/core/Siwe.ts +20 -1
  169. package/src/core/Transaction.ts +82 -5
  170. package/src/core/TransactionReceipt.ts +41 -3
  171. package/src/core/TransactionRequest.ts +71 -4
  172. package/src/core/TxEnvelope.ts +159 -90
  173. package/src/core/TxEnvelopeEip8141.ts +715 -0
  174. package/src/core/_test/AbiEvent.test.ts +45 -0
  175. package/src/core/_test/Blobs.test.ts +22 -0
  176. package/src/core/_test/Frame.test-d.ts +96 -0
  177. package/src/core/_test/Frame.test.ts +267 -0
  178. package/src/core/_test/FrameReceipt.test.ts +86 -0
  179. package/src/core/_test/FrameSignature.test-d.ts +93 -0
  180. package/src/core/_test/FrameSignature.test.ts +554 -0
  181. package/src/core/_test/Signature.test.ts +166 -0
  182. package/src/core/_test/Siwe.test.ts +100 -1
  183. package/src/core/_test/Transaction.test.ts +33 -0
  184. package/src/core/_test/TransactionEnvelope.test-d.ts +74 -0
  185. package/src/core/_test/TransactionEnvelope.test.ts +107 -0
  186. package/src/core/_test/TransactionReceipt.test.ts +59 -0
  187. package/src/core/_test/TransactionRequest.test-d.ts +50 -0
  188. package/src/core/_test/TransactionRequest.test.ts +88 -1
  189. package/src/core/_test/TxEnvelopeEip8141.test-d.ts +44 -0
  190. package/src/core/_test/TxEnvelopeEip8141.test.ts +1775 -0
  191. package/src/core/_test/curves.test.ts +6 -1
  192. package/src/core/_test/index.test.ts +4 -0
  193. package/src/core/internal/curves.ts +4 -0
  194. package/src/index.ts +77 -0
  195. package/src/tempo/AuthorizationTempo.test.ts +8 -4
  196. package/src/tempo/KeyAuthorization.test-d.ts +16 -63
  197. package/src/tempo/KeyAuthorization.test.ts +69 -11
  198. package/src/tempo/KeyAuthorization.ts +107 -63
  199. package/src/tempo/MultisigConfig.test.ts +44 -20
  200. package/src/tempo/MultisigConfig.ts +65 -23
  201. package/src/tempo/MultisigOperation.test.ts +79 -550
  202. package/src/tempo/MultisigOperation.ts +31 -146
  203. package/src/tempo/MultisigSimulation.test-d.ts +2 -2
  204. package/src/tempo/MultisigSimulation.test.ts +21 -110
  205. package/src/tempo/MultisigSimulation.ts +25 -99
  206. package/src/tempo/SignatureEnvelope.test-d.ts +29 -47
  207. package/src/tempo/SignatureEnvelope.test.ts +328 -541
  208. package/src/tempo/SignatureEnvelope.ts +196 -291
  209. package/src/tempo/Transaction.test.ts +4 -4
  210. package/src/tempo/TransactionRequest.test.ts +17 -80
  211. package/src/tempo/TransactionRequest.ts +19 -2
  212. package/src/tempo/index.ts +3 -1
  213. package/src/tempo/multisig.e2e.test.ts +321 -860
  214. package/src/version.ts +1 -1
  215. package/src/zod/Frame.ts +82 -0
  216. package/src/zod/FrameReceipt.ts +48 -0
  217. package/src/zod/FrameSignature.ts +78 -0
  218. package/src/zod/Transaction.ts +63 -0
  219. package/src/zod/TransactionEnvelope.ts +33 -0
  220. package/src/zod/TransactionReceipt.ts +14 -3
  221. package/src/zod/TransactionRequest.ts +18 -3
  222. package/src/zod/TxEnvelopeEip8141.ts +102 -0
  223. package/src/zod/_test/Frame.test-d.ts +41 -0
  224. package/src/zod/_test/Frame.test.ts +54 -0
  225. package/src/zod/_test/FrameReceipt.test.ts +75 -0
  226. package/src/zod/_test/FrameSignature.test.ts +94 -0
  227. package/src/zod/_test/TxEnvelopeEip8141.test.ts +116 -0
  228. package/src/zod/internal/Frame.ts +26 -0
  229. package/src/zod/tempo/KeyAuthorization.ts +50 -39
  230. package/src/zod/tempo/MultisigSimulation.ts +3 -48
  231. package/src/zod/tempo/SignatureEnvelope.ts +46 -35
  232. package/src/zod/tempo/TransactionRequest.ts +14 -0
  233. package/src/zod/tempo/_test/KeyAuthorization.test.ts +69 -20
  234. package/src/zod/tempo/_test/MultisigSimulation.test.ts +6 -31
  235. package/src/zod/tempo/_test/SignatureEnvelope.test.ts +118 -85
  236. package/src/zod/tempo/_test/TransactionRequest.test.ts +9 -19
  237. package/src/zod/z.ts +4 -0
@@ -0,0 +1,443 @@
1
+ import * as Address from './Address.js'
2
+ import * as Bytes from './Bytes.js'
3
+ import * as Errors from './Errors.js'
4
+ import * as Hex from './Hex.js'
5
+ import * as Quantity from './internal/quantity.js'
6
+
7
+ /** An EIP-8141 call frame. */
8
+ export type Frame<bigintType = bigint> = {
9
+ /**
10
+ * Frame calldata.
11
+ * @default '0x'
12
+ */
13
+ data?: Hex.Hex | undefined
14
+ /**
15
+ * Approval scope and atomic batching bits.
16
+ * @default 0
17
+ */
18
+ flags?: Flags | undefined
19
+ /**
20
+ * Execution gas budget.
21
+ * @default 0n
22
+ */
23
+ gas?: bigintType | undefined
24
+ /**
25
+ * Execution context: default, verify, or sender.
26
+ * @default 0
27
+ */
28
+ mode?: Mode | undefined
29
+ /**
30
+ * State gas budget.
31
+ * @default 0n
32
+ */
33
+ stateGas?: bigintType | undefined
34
+ /** Target address. Omit to target the transaction sender. */
35
+ target?: Address.Address | undefined
36
+ /**
37
+ * Value transferred by a sender frame, in wei.
38
+ * @default 0n
39
+ */
40
+ value?: bigintType | undefined
41
+ }
42
+
43
+ /** JSON-RPC representation of a frame. */
44
+ export type Rpc = {
45
+ /** Frame calldata. */
46
+ data: Hex.Hex
47
+ /** Execution gas budget. */
48
+ executionGasLimit: Hex.Hex
49
+ /** Approval scope and batching bits. */
50
+ flags: number
51
+ /** Execution mode. */
52
+ mode: number
53
+ /** State gas budget. */
54
+ stateGasLimit: Hex.Hex
55
+ /** Target address; absent for the transaction sender. */
56
+ target?: Address.Address | null | undefined
57
+ /** Value transferred in wei. */
58
+ value: Hex.Hex
59
+ }
60
+
61
+ /** Frame execution modes. */
62
+ export const modes = { default: 0, sender: 2, verify: 1 } as const
63
+
64
+ /** A numeric or named frame execution mode. */
65
+ export type Mode = number | keyof typeof modes
66
+
67
+ /** Approval and atomic batching flags. */
68
+ export const flags = {
69
+ approveExecution: 2,
70
+ approveExecutionAndPayment: 3,
71
+ approvePayment: 1,
72
+ atomicBatch: 4,
73
+ none: 0,
74
+ } as const
75
+
76
+ /** Numeric approval and batching bits, or a named flag value. */
77
+ export type Flags = number | keyof typeof flags
78
+
79
+ /** RLP-ready frame tuple. Empty target bytes refer to the transaction sender. */
80
+ export type Tuple = readonly [
81
+ mode: Hex.Hex,
82
+ flags: Hex.Hex,
83
+ target: Hex.Hex,
84
+ limits: readonly [execution: Hex.Hex, state: Hex.Hex],
85
+ value: Hex.Hex,
86
+ data: Hex.Hex,
87
+ ]
88
+
89
+ /**
90
+ * Asserts that a {@link ox#Frame.Frame} satisfies frame-local constraints.
91
+ *
92
+ * Sender-dependent approval, batch adjacency, expiry, and transaction-wide gas
93
+ * constraints require the enclosing transaction.
94
+ *
95
+ * @example
96
+ * ### Basic Usage
97
+ *
98
+ * Check a verification frame before including it in a transaction.
99
+ *
100
+ * ```ts twoslash
101
+ * import { Frame } from 'ox'
102
+ *
103
+ * Frame.assert({
104
+ * flags: 'approveExecutionAndPayment',
105
+ * gas: 50_000n,
106
+ * mode: 'verify'
107
+ * })
108
+ * ```
109
+ *
110
+ * @param frame - The frame to assert.
111
+ */
112
+ export function assert(frame: Frame): void {
113
+ const {
114
+ data = '0x',
115
+ flags: flagsValue = 0,
116
+ gas = 0n,
117
+ mode: modeValue = 0,
118
+ stateGas = 0n,
119
+ value = 0n,
120
+ } = frame
121
+ const mode = typeof modeValue === 'string' ? modes[modeValue] : modeValue
122
+ if (!Number.isInteger(mode) || mode < 0 || mode > 2)
123
+ throw new InvalidError('mode must be a supported name or 0, 1, or 2.')
124
+ const flags_ = typeof flagsValue === 'string' ? flags[flagsValue] : flagsValue
125
+ if (!Number.isInteger(flags_) || flags_ < 0 || flags_ > 7)
126
+ throw new InvalidError(
127
+ 'flags must be a supported name or an integer from 0 to 7.',
128
+ )
129
+ if (flags_ & flags.atomicBatch) {
130
+ if (mode === modes.verify)
131
+ throw new InvalidError('VERIFY frames cannot belong to an atomic batch.')
132
+ if (flags_ & flags.approveExecutionAndPayment)
133
+ throw new InvalidError(
134
+ 'Atomic batch frames cannot approve execution or payment.',
135
+ )
136
+ }
137
+ if (frame.target !== undefined)
138
+ Address.assert(frame.target, { strict: false })
139
+ for (const [field, limit] of [
140
+ ['gas', gas],
141
+ ['stateGas', stateGas],
142
+ ] as const)
143
+ if (typeof limit !== 'bigint' || limit < 0n || limit >= 2n ** 64n)
144
+ throw new InvalidError(`${field} must be an unsigned 64-bit integer.`)
145
+ if (gas + stateGas >= 2n ** 64n)
146
+ throw new InvalidError('Combined frame gas must be less than 2^64.')
147
+ if (typeof value !== 'bigint' || value < 0n || value >= 2n ** 256n)
148
+ throw new InvalidError('value must be an unsigned 256-bit integer.')
149
+ if (mode !== modes.sender && value !== 0n)
150
+ throw new InvalidError('Only SENDER frames can transfer value.')
151
+ Hex.assert(data, { strict: true })
152
+ if (data.length % 2 !== 0)
153
+ throw new InvalidError('data must contain whole bytes.')
154
+ }
155
+
156
+ export declare namespace assert {
157
+ type ErrorType =
158
+ | InvalidError
159
+ | Address.assert.ErrorType
160
+ | Hex.assert.ErrorType
161
+ | Errors.GlobalErrorType
162
+ }
163
+
164
+ /**
165
+ * Coerces a frame object into a {@link ox#Frame.Frame}.
166
+ *
167
+ * Validates the frame and returns a copy, preserving literal types and the supplied
168
+ * numeric or named mode and flags. Omitted fields stay omitted;
169
+ * {@link ox#Frame.(toTuple:function)} supplies their defaults when encoding.
170
+ *
171
+ * @example
172
+ * ### Basic Usage
173
+ *
174
+ * Construct a verification frame that approves execution and payment.
175
+ *
176
+ * ```ts twoslash
177
+ * import { Frame } from 'ox'
178
+ *
179
+ * const frame = Frame.from({
180
+ * flags: 'approveExecutionAndPayment',
181
+ * gas: 50_000n,
182
+ * mode: 'verify'
183
+ * })
184
+ * ```
185
+ *
186
+ * @param frame - The frame object to convert.
187
+ * @returns The validated frame.
188
+ */
189
+ export function from<const frame extends Frame>(frame: frame | Frame): frame {
190
+ assert(frame)
191
+ return { ...frame } as frame
192
+ }
193
+
194
+ export declare namespace from {
195
+ type ErrorType = assert.ErrorType
196
+ }
197
+
198
+ /**
199
+ * Converts an RPC frame to a frame.
200
+ *
201
+ * @example
202
+ * ### Basic Usage
203
+ *
204
+ * ```ts twoslash
205
+ * import { Frame } from 'ox'
206
+ *
207
+ * const frame = Frame.fromRpc({
208
+ * data: '0x',
209
+ * executionGasLimit: '0xc350',
210
+ * flags: 3,
211
+ * mode: 1,
212
+ * stateGasLimit: '0x0',
213
+ * value: '0x0'
214
+ * })
215
+ * ```
216
+ *
217
+ * @param frame - The value to convert.
218
+ * @returns The converted value.
219
+ */
220
+ export function fromRpc(frame: Rpc): Frame {
221
+ return from({
222
+ data: frame.data,
223
+ flags: frame.flags,
224
+ gas: Hex.toBigInt(frame.executionGasLimit),
225
+ mode: frame.mode,
226
+ stateGas: Hex.toBigInt(frame.stateGasLimit),
227
+ ...(frame.target == null ? {} : { target: frame.target }),
228
+ value: Hex.toBigInt(frame.value),
229
+ })
230
+ }
231
+
232
+ export declare namespace fromRpc {
233
+ type ErrorType = from.ErrorType | Hex.toBigInt.ErrorType
234
+ }
235
+
236
+ /**
237
+ * Converts a frame to its JSON-RPC representation.
238
+ *
239
+ * @example
240
+ * ### Basic Usage
241
+ *
242
+ * ```ts twoslash
243
+ * import { Frame } from 'ox'
244
+ *
245
+ * const frame = Frame.from({ gas: 50_000n, mode: 'verify' })
246
+ * const rpc = Frame.toRpc(frame)
247
+ * ```
248
+ *
249
+ * @param frame - The value to convert.
250
+ * @returns The converted value.
251
+ */
252
+ export function toRpc(frame: toRpc.Input): Rpc {
253
+ const { flags: flags_ = 0, mode = 0 } = frame
254
+ return {
255
+ data: frame.data ?? '0x',
256
+ executionGasLimit: Quantity.fromNumberish(frame.gas ?? 0n),
257
+ flags: typeof flags_ === 'string' ? flags[flags_] : flags_,
258
+ mode: typeof mode === 'string' ? modes[mode] : mode,
259
+ stateGasLimit: Quantity.fromNumberish(frame.stateGas ?? 0n),
260
+ ...(frame.target === undefined ? {} : { target: frame.target }),
261
+ value: Quantity.fromNumberish(frame.value ?? 0n),
262
+ }
263
+ }
264
+
265
+ export declare namespace toRpc {
266
+ type Input = Frame<Hex.Hex | bigint | number>
267
+ type ErrorType = Hex.fromNumber.ErrorType | Errors.GlobalErrorType
268
+ }
269
+
270
+ /**
271
+ * Converts a {@link ox#Frame.Tuple} to a {@link ox#Frame.Frame}.
272
+ *
273
+ * Returns numeric mode and flags. An empty target becomes an omitted `target`.
274
+ * Integer fields must use minimal whole-byte encodings, with empty bytes for zero.
275
+ *
276
+ * @example
277
+ * ### Basic Usage
278
+ *
279
+ * Decode a frame tuple with separate execution and state gas limits.
280
+ *
281
+ * ```ts twoslash
282
+ * import { Frame } from 'ox'
283
+ *
284
+ * const frame = Frame.fromTuple([
285
+ * '0x01',
286
+ * '0x03',
287
+ * '0x',
288
+ * ['0xc350', '0x'],
289
+ * '0x',
290
+ * '0x'
291
+ * ])
292
+ * // @log: {
293
+ * // @log: data: '0x',
294
+ * // @log: flags: 3,
295
+ * // @log: gas: 50000n,
296
+ * // @log: mode: 1,
297
+ * // @log: stateGas: 0n,
298
+ * // @log: value: 0n
299
+ * // @log: }
300
+ * ```
301
+ *
302
+ * @param tuple - The frame tuple to convert.
303
+ * @returns The decoded frame.
304
+ */
305
+ export function fromTuple(tuple: Tuple): Frame {
306
+ if (
307
+ !Array.isArray(tuple) ||
308
+ tuple.length !== 6 ||
309
+ !Array.isArray(tuple[3]) ||
310
+ tuple[3].length !== 2
311
+ )
312
+ throw new InvalidError(
313
+ 'Expected [mode, flags, target, [execution, state], value, data].',
314
+ )
315
+ const [mode, flags, target, [execution, state], value, data] = tuple
316
+ Hex.assert(target, { strict: true })
317
+ Hex.assert(data, { strict: true })
318
+ const quantities = [mode, flags, execution, state, value]
319
+ for (const quantity of quantities) {
320
+ Hex.assert(quantity, { strict: true })
321
+ if (quantity.length % 2 !== 0 || quantity.startsWith('0x00'))
322
+ throw new InvalidError(
323
+ 'Integers must use minimal whole-byte encodings, with empty bytes for zero.',
324
+ )
325
+ }
326
+ const frame = {
327
+ ...(target === '0x' ? {} : { target }),
328
+ data,
329
+ flags: flags === '0x' ? 0 : Hex.toNumber(flags),
330
+ gas: execution === '0x' ? 0n : Hex.toBigInt(execution),
331
+ mode: mode === '0x' ? 0 : Hex.toNumber(mode),
332
+ stateGas: state === '0x' ? 0n : Hex.toBigInt(state),
333
+ value: value === '0x' ? 0n : Hex.toBigInt(value),
334
+ }
335
+ assert(frame)
336
+ return frame
337
+ }
338
+
339
+ export declare namespace fromTuple {
340
+ type ErrorType =
341
+ | assert.ErrorType
342
+ | Hex.toNumber.ErrorType
343
+ | Hex.toBigInt.ErrorType
344
+ }
345
+
346
+ /**
347
+ * Converts a {@link ox#Frame.Frame} to its RLP-ready {@link ox#Frame.Tuple}.
348
+ *
349
+ * Named mode and flags are encoded as integers. An omitted target and zero integer
350
+ * fields are encoded as empty bytes. Omitted mode and flags default to zero;
351
+ * omitted gas limits and value default to `0n`, and data defaults to `'0x'`.
352
+ *
353
+ * @example
354
+ * ### Basic Usage
355
+ *
356
+ * Encode a verification frame in the field order required by EIP-8141.
357
+ *
358
+ * ```ts twoslash
359
+ * import { Frame } from 'ox'
360
+ *
361
+ * const tuple = Frame.toTuple({
362
+ * flags: 'approveExecutionAndPayment',
363
+ * gas: 50_000n,
364
+ * mode: 'verify'
365
+ * })
366
+ * // @log: ['0x01', '0x03', '0x', ['0xc350', '0x'], '0x', '0x']
367
+ * ```
368
+ *
369
+ * @param frame - The frame to convert.
370
+ * @returns The encoded frame tuple.
371
+ */
372
+ export function toTuple(frame: Frame): Tuple {
373
+ assert(frame)
374
+ const mode =
375
+ typeof frame.mode === 'string' ? modes[frame.mode] : (frame.mode ?? 0)
376
+ const flags_ =
377
+ typeof frame.flags === 'string' ? flags[frame.flags] : (frame.flags ?? 0)
378
+ return [
379
+ mode ? Hex.fromBytes(Bytes.fromNumber(mode)) : '0x',
380
+ flags_ ? Hex.fromBytes(Bytes.fromNumber(flags_)) : '0x',
381
+ frame.target ?? '0x',
382
+ [
383
+ frame.gas ? Hex.fromBytes(Bytes.fromNumber(frame.gas)) : '0x',
384
+ frame.stateGas ? Hex.fromBytes(Bytes.fromNumber(frame.stateGas)) : '0x',
385
+ ],
386
+ frame.value ? Hex.fromBytes(Bytes.fromNumber(frame.value)) : '0x',
387
+ frame.data ?? '0x',
388
+ ]
389
+ }
390
+
391
+ export declare namespace toTuple {
392
+ type ErrorType =
393
+ | assert.ErrorType
394
+ | Bytes.fromNumber.ErrorType
395
+ | Hex.fromBytes.ErrorType
396
+ }
397
+
398
+ /**
399
+ * Returns whether a {@link ox#Frame.Frame} satisfies frame-local constraints.
400
+ *
401
+ * Performs the same checks as {@link ox#Frame.(assert:function)}, returning `false`
402
+ * instead of throwing when the frame is invalid.
403
+ *
404
+ * @example
405
+ * ### Basic Usage
406
+ *
407
+ * Check whether a frame is structurally valid.
408
+ *
409
+ * ```ts twoslash
410
+ * import { Frame } from 'ox'
411
+ *
412
+ * const valid = Frame.validate({
413
+ * flags: 'approveExecutionAndPayment',
414
+ * gas: 50_000n,
415
+ * mode: 'verify'
416
+ * })
417
+ * // @log: true
418
+ * ```
419
+ *
420
+ * @param frame - The frame to validate.
421
+ * @returns Whether the frame satisfies frame-local constraints.
422
+ */
423
+ export function validate(frame: Frame): boolean {
424
+ try {
425
+ assert(frame)
426
+ return true
427
+ } catch {
428
+ return false
429
+ }
430
+ }
431
+
432
+ export declare namespace validate {
433
+ type ErrorType = Errors.GlobalErrorType
434
+ }
435
+
436
+ /** Thrown when an EIP-8141 frame is structurally invalid. */
437
+ export class InvalidError extends Errors.BaseError {
438
+ override readonly name = 'Frame.InvalidError'
439
+
440
+ constructor(details: string) {
441
+ super('Invalid frame.', { details })
442
+ }
443
+ }
@@ -0,0 +1,117 @@
1
+ import type * as Errors from './Errors.js'
2
+ import * as Hex from './Hex.js'
3
+ import * as Quantity from './internal/quantity.js'
4
+ import type * as Log from './Log.js'
5
+
6
+ /** Receipt for one frame. Frame logs contain only address, data, and topics. */
7
+ export type FrameReceipt<bigintType = bigint> = {
8
+ /** Execution gas used before transaction-level refunds. */
9
+ gasUsed: bigintType
10
+ /** Logs emitted by this frame. */
11
+ logs: readonly Pick<Log.Log, 'address' | 'data' | 'topics'>[]
12
+ /** Final state gas after refills and rollbacks. */
13
+ stateGasUsed: bigintType
14
+ /** Frame execution result. */
15
+ status: Status
16
+ }
17
+
18
+ /** JSON-RPC receipt for one frame. */
19
+ export type Rpc = {
20
+ /** Execution gas used. */
21
+ executionGasUsed: Hex.Hex
22
+ /** Logs emitted by this frame. */
23
+ logs: readonly Pick<Log.Log, 'address' | 'data' | 'topics'>[]
24
+ /** Final state gas used. */
25
+ stateGasUsed: Hex.Hex
26
+ /** Zero for failure, one for success, or two for a skipped frame. */
27
+ status: RpcStatus
28
+ }
29
+
30
+ /** Frame execution status. */
31
+ export type Status = 'reverted' | 'skipped' | 'success'
32
+
33
+ /** Numeric JSON-RPC frame execution status. */
34
+ export type RpcStatus = 0 | 1 | 2
35
+
36
+ /** RPC status to status mapping. */
37
+ export const fromRpcStatus = {
38
+ 0: 'reverted',
39
+ 1: 'success',
40
+ 2: 'skipped',
41
+ } as const
42
+
43
+ /** Status to RPC status mapping. */
44
+ export const toRpcStatus = {
45
+ reverted: 0,
46
+ skipped: 2,
47
+ success: 1,
48
+ } as const
49
+
50
+ /**
51
+ * Converts an RPC frame receipt to a {@link ox#FrameReceipt.FrameReceipt}.
52
+ *
53
+ * @example
54
+ * ### Basic Usage
55
+ *
56
+ * ```ts twoslash
57
+ * import { FrameReceipt } from 'ox'
58
+ *
59
+ * const receipt = FrameReceipt.fromRpc({
60
+ * executionGasUsed: '0x5208',
61
+ * logs: [],
62
+ * stateGasUsed: '0x0',
63
+ * status: 1
64
+ * })
65
+ * ```
66
+ *
67
+ * @param receipt - The RPC frame receipt.
68
+ * @returns The frame receipt with bigint gas and a named status.
69
+ */
70
+ export function fromRpc(receipt: Rpc): FrameReceipt {
71
+ return {
72
+ gasUsed: Hex.toBigInt(receipt.executionGasUsed),
73
+ logs: receipt.logs,
74
+ stateGasUsed: Hex.toBigInt(receipt.stateGasUsed),
75
+ status: fromRpcStatus[receipt.status],
76
+ }
77
+ }
78
+
79
+ export declare namespace fromRpc {
80
+ type ErrorType = Hex.toBigInt.ErrorType | Errors.GlobalErrorType
81
+ }
82
+
83
+ /**
84
+ * Converts a {@link ox#FrameReceipt.FrameReceipt} to an RPC frame receipt.
85
+ *
86
+ * @example
87
+ * ### Basic Usage
88
+ *
89
+ * ```ts twoslash
90
+ * import { FrameReceipt } from 'ox'
91
+ *
92
+ * const receipt = FrameReceipt.fromRpc({
93
+ * executionGasUsed: '0x5208',
94
+ * logs: [],
95
+ * stateGasUsed: '0x0',
96
+ * status: 1
97
+ * })
98
+ * const rpc = FrameReceipt.toRpc(receipt)
99
+ * ```
100
+ *
101
+ * @param receipt - The frame receipt. Gas accepts hex, bigint, or number values.
102
+ * @returns The RPC frame receipt with hex gas and a numeric status.
103
+ */
104
+ export function toRpc(receipt: toRpc.Input): Rpc {
105
+ return {
106
+ executionGasUsed: Quantity.fromNumberish(receipt.gasUsed),
107
+ logs: receipt.logs,
108
+ stateGasUsed: Quantity.fromNumberish(receipt.stateGasUsed),
109
+ status: toRpcStatus[receipt.status],
110
+ }
111
+ }
112
+
113
+ export declare namespace toRpc {
114
+ type Input = FrameReceipt<Hex.Hex | bigint | number>
115
+
116
+ type ErrorType = Hex.fromNumber.ErrorType | Errors.GlobalErrorType
117
+ }