ox 1.0.0-beta.9 → 1.0.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.
- package/CHANGELOG.md +1143 -0
- package/dist/core/AbiParameters.d.ts.map +1 -1
- package/dist/core/AbiParameters.js +4 -1
- package/dist/core/AbiParameters.js.map +1 -1
- package/dist/core/Rlp.d.ts +27 -5
- package/dist/core/Rlp.d.ts.map +1 -1
- package/dist/core/Rlp.js +40 -4
- package/dist/core/Rlp.js.map +1 -1
- package/dist/core/RpcSchema.d.ts +1 -1
- package/dist/core/internal/abiParameters.d.ts.map +1 -1
- package/dist/core/internal/abiParameters.js +21 -3
- package/dist/core/internal/abiParameters.js.map +1 -1
- package/dist/core/internal/rpcSchemas/eth.d.ts +36 -0
- package/dist/core/internal/rpcSchemas/eth.d.ts.map +1 -1
- package/dist/erc4337/EntryPoint.d.ts +1072 -1
- package/dist/erc4337/EntryPoint.d.ts.map +1 -1
- package/dist/erc4337/EntryPoint.js +872 -0
- package/dist/erc4337/EntryPoint.js.map +1 -1
- package/dist/erc4337/RpcSchema.d.ts +2 -2
- package/dist/erc4337/RpcSchema.d.ts.map +1 -1
- package/dist/erc4337/UserOperation.d.ts +39 -10
- package/dist/erc4337/UserOperation.d.ts.map +1 -1
- package/dist/erc4337/UserOperation.js +62 -48
- package/dist/erc4337/UserOperation.js.map +1 -1
- package/dist/erc4337/UserOperationGas.d.ts +9 -5
- package/dist/erc4337/UserOperationGas.d.ts.map +1 -1
- package/dist/erc4337/UserOperationGas.js +17 -15
- package/dist/erc4337/UserOperationGas.js.map +1 -1
- package/dist/erc4337/UserOperationReceipt.d.ts +4 -4
- package/dist/erc4337/UserOperationReceipt.d.ts.map +1 -1
- package/dist/erc4337/UserOperationReceipt.js.map +1 -1
- package/dist/tempo/Channel.d.ts +8 -14
- package/dist/tempo/Channel.d.ts.map +1 -1
- package/dist/tempo/Channel.js +4 -8
- package/dist/tempo/Channel.js.map +1 -1
- package/dist/tempo/KeyAuthorization.d.ts +5 -5
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/KeyAuthorization.js +4 -4
- package/dist/tempo/KeyAuthorization.js.map +1 -1
- package/dist/tempo/MultisigConfig.d.ts +37 -85
- package/dist/tempo/MultisigConfig.d.ts.map +1 -1
- package/dist/tempo/MultisigConfig.js +39 -83
- package/dist/tempo/MultisigConfig.js.map +1 -1
- package/dist/tempo/PoolId.d.ts +8 -7
- package/dist/tempo/PoolId.d.ts.map +1 -1
- package/dist/tempo/PoolId.js +10 -6
- package/dist/tempo/PoolId.js.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +32 -30
- package/dist/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/tempo/SignatureEnvelope.js +56 -51
- package/dist/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/tempo/Transaction.d.ts +16 -5
- package/dist/tempo/Transaction.d.ts.map +1 -1
- package/dist/tempo/Transaction.js +34 -7
- package/dist/tempo/Transaction.js.map +1 -1
- package/dist/tempo/TransactionReceipt.d.ts +3 -3
- package/dist/tempo/TransactionReceipt.d.ts.map +1 -1
- package/dist/tempo/TransactionReceipt.js +8 -1
- package/dist/tempo/TransactionReceipt.js.map +1 -1
- package/dist/tempo/TransactionRequest.d.ts +15 -2
- package/dist/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/tempo/TransactionRequest.js +65 -29
- package/dist/tempo/TransactionRequest.js.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.d.ts +2 -3
- package/dist/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/tempo/TxEnvelopeTempo.js +5 -6
- package/dist/tempo/TxEnvelopeTempo.js.map +1 -1
- package/dist/tempo/index.d.ts +6 -26
- package/dist/tempo/index.d.ts.map +1 -1
- package/dist/tempo/index.js +6 -26
- package/dist/tempo/index.js.map +1 -1
- package/dist/zod/Abi.d.ts +214 -0
- package/dist/zod/Abi.d.ts.map +1 -0
- package/dist/zod/Abi.js +5 -0
- package/dist/zod/Abi.js.map +1 -0
- package/dist/zod/AbiConstructor.d.ts +58 -0
- package/dist/zod/AbiConstructor.d.ts.map +1 -0
- package/dist/zod/AbiConstructor.js +18 -0
- package/dist/zod/AbiConstructor.js.map +1 -0
- package/dist/zod/AbiError.d.ts +20 -0
- package/dist/zod/AbiError.d.ts.map +1 -0
- package/dist/zod/AbiError.js +9 -0
- package/dist/zod/AbiError.js.map +1 -0
- package/dist/zod/AbiEvent.d.ts +23 -0
- package/dist/zod/AbiEvent.d.ts.map +1 -0
- package/dist/zod/AbiEvent.js +11 -0
- package/dist/zod/AbiEvent.js.map +1 -0
- package/dist/zod/AbiFallback.d.ts +16 -0
- package/dist/zod/AbiFallback.d.ts.map +1 -0
- package/dist/zod/AbiFallback.js +16 -0
- package/dist/zod/AbiFallback.js.map +1 -0
- package/dist/zod/AbiFunction.d.ts +109 -0
- package/dist/zod/AbiFunction.d.ts.map +1 -0
- package/dist/zod/AbiFunction.js +26 -0
- package/dist/zod/AbiFunction.js.map +1 -0
- package/dist/zod/AbiItem.d.ts +216 -0
- package/dist/zod/AbiItem.d.ts.map +1 -0
- package/dist/zod/AbiItem.js +26 -0
- package/dist/zod/AbiItem.js.map +1 -0
- package/dist/zod/AbiParameter.d.ts +32 -0
- package/dist/zod/AbiParameter.d.ts.map +1 -0
- package/dist/zod/AbiParameter.js +28 -0
- package/dist/zod/AbiParameter.js.map +1 -0
- package/dist/zod/AbiParameters.d.ts +30 -0
- package/dist/zod/AbiParameters.d.ts.map +1 -0
- package/dist/zod/AbiParameters.js +6 -0
- package/dist/zod/AbiParameters.js.map +1 -0
- package/dist/zod/AbiReceive.d.ts +6 -0
- package/dist/zod/AbiReceive.d.ts.map +1 -0
- package/dist/zod/AbiReceive.js +7 -0
- package/dist/zod/AbiReceive.js.map +1 -0
- package/dist/zod/RpcSchema.d.ts +1 -0
- package/dist/zod/RpcSchema.d.ts.map +1 -1
- package/dist/zod/Solidity.d.ts +15 -0
- package/dist/zod/Solidity.d.ts.map +1 -0
- package/dist/zod/Solidity.js +41 -0
- package/dist/zod/Solidity.js.map +1 -0
- package/dist/zod/TypedData.d.ts +226 -0
- package/dist/zod/TypedData.d.ts.map +1 -0
- package/dist/zod/TypedData.js +84 -0
- package/dist/zod/TypedData.js.map +1 -0
- package/dist/zod/internal/rpcSchemas/Eth.d.ts +1 -0
- package/dist/zod/internal/rpcSchemas/Eth.d.ts.map +1 -1
- package/dist/zod/internal/rpcSchemas/Eth.js +5 -0
- package/dist/zod/internal/rpcSchemas/Eth.js.map +1 -1
- package/dist/zod/tempo/AuthorizationTempo.d.ts +0 -20
- package/dist/zod/tempo/AuthorizationTempo.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.d.ts +503 -67
- package/dist/zod/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/zod/tempo/KeyAuthorization.js +32 -15
- package/dist/zod/tempo/KeyAuthorization.js.map +1 -1
- package/dist/zod/tempo/RpcSchemaTempo.d.ts +216 -34
- package/dist/zod/tempo/RpcSchemaTempo.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.d.ts +0 -6
- package/dist/zod/tempo/SignatureEnvelope.d.ts.map +1 -1
- package/dist/zod/tempo/SignatureEnvelope.js +0 -2
- package/dist/zod/tempo/SignatureEnvelope.js.map +1 -1
- package/dist/zod/tempo/Transaction.d.ts +1479 -333
- package/dist/zod/tempo/Transaction.d.ts.map +1 -1
- package/dist/zod/tempo/Transaction.js +65 -16
- package/dist/zod/tempo/Transaction.js.map +1 -1
- package/dist/zod/tempo/TransactionRequest.d.ts +410 -57
- package/dist/zod/tempo/TransactionRequest.d.ts.map +1 -1
- package/dist/zod/tempo/TransactionRequest.js +81 -18
- package/dist/zod/tempo/TransactionRequest.js.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts +225 -18
- package/dist/zod/tempo/TxEnvelopeTempo.d.ts.map +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.js +1 -1
- package/dist/zod/tempo/TxEnvelopeTempo.js.map +1 -1
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts +0 -3
- package/dist/zod/tempo/ZoneRpcAuthentication.d.ts.map +1 -1
- package/dist/zod/tempo/z.d.ts +0 -1
- package/dist/zod/tempo/z.d.ts.map +1 -1
- package/dist/zod/tempo/z.js +0 -1
- package/dist/zod/tempo/z.js.map +1 -1
- package/dist/zod/z.d.ts +12 -0
- package/dist/zod/z.d.ts.map +1 -1
- package/dist/zod/z.js +12 -0
- package/dist/zod/z.js.map +1 -1
- package/package.json +62 -11
- package/src/core/AbiParameters.ts +3 -1
- package/src/core/Rlp.ts +66 -3
- package/src/core/RpcSchema.ts +1 -1
- package/src/core/_test/AbiParameters.decode.test.ts +88 -12
- package/src/core/_test/AbiParameters.encode.test.ts +68 -0
- package/src/core/_test/Rlp.test.ts +101 -0
- package/src/core/internal/abiParameters.ts +21 -3
- package/src/core/internal/rpcSchemas/eth.ts +36 -0
- package/src/erc4337/EntryPoint.ts +875 -1
- package/src/erc4337/RpcSchema.ts +4 -2
- package/src/erc4337/UserOperation.ts +130 -60
- package/src/erc4337/UserOperationGas.ts +36 -28
- package/src/erc4337/UserOperationReceipt.ts +15 -7
- package/src/erc4337/_test/EntryPoint.test.ts +48 -0
- package/src/erc4337/_test/RpcSchema.test-d.ts +56 -0
- package/src/erc4337/_test/UserOperation.snap-d.ts +31 -0
- package/src/erc4337/_test/UserOperation.test.ts +221 -5
- package/src/erc4337/_test/UserOperationGas.test.ts +30 -1
- package/src/tempo/Channel.test.ts +2 -23
- package/src/tempo/Channel.ts +10 -22
- package/src/tempo/KeyAuthorization.test.ts +22 -0
- package/src/tempo/KeyAuthorization.ts +9 -9
- package/src/tempo/MultisigConfig.test.ts +54 -37
- package/src/tempo/MultisigConfig.ts +59 -134
- package/src/tempo/PoolId.test.ts +7 -41
- package/src/tempo/PoolId.ts +15 -10
- package/src/tempo/SignatureEnvelope.test.ts +118 -17
- package/src/tempo/SignatureEnvelope.ts +77 -72
- package/src/tempo/Transaction.test.ts +0 -15
- package/src/tempo/Transaction.ts +63 -12
- package/src/tempo/TransactionReceipt.test.ts +76 -0
- package/src/tempo/TransactionReceipt.ts +11 -5
- package/src/tempo/TransactionRequest.test.ts +174 -1
- package/src/tempo/TransactionRequest.ts +84 -32
- package/src/tempo/TxEnvelopeTempo.test.ts +2 -2
- package/src/tempo/TxEnvelopeTempo.ts +7 -7
- package/src/tempo/e2e.test.ts +228 -50
- package/src/tempo/index.ts +6 -26
- package/src/version.ts +1 -1
- package/src/zod/Abi.ts +5 -0
- package/src/zod/AbiConstructor.ts +24 -0
- package/src/zod/AbiError.ts +9 -0
- package/src/zod/AbiEvent.ts +11 -0
- package/src/zod/AbiFallback.ts +22 -0
- package/src/zod/AbiFunction.ts +32 -0
- package/src/zod/AbiItem.ts +28 -0
- package/src/zod/AbiParameter.ts +36 -0
- package/src/zod/AbiParameters.ts +7 -0
- package/src/zod/AbiReceive.ts +7 -0
- package/src/zod/Solidity.ts +83 -0
- package/src/zod/TypedData.ts +111 -0
- package/src/zod/_test/Abi.test-d.ts +46 -0
- package/src/zod/_test/Abi.test.ts +163 -0
- package/src/zod/_test/TypedData.test-d.ts +20 -0
- package/src/zod/_test/TypedData.test.ts +87 -0
- package/src/zod/_test/z.test-d.ts +6 -0
- package/src/zod/_test/z.test.ts +17 -0
- package/src/zod/internal/rpcSchemas/Eth.ts +6 -0
- package/src/zod/tempo/KeyAuthorization.ts +34 -15
- package/src/zod/tempo/SignatureEnvelope.ts +0 -2
- package/src/zod/tempo/Transaction.ts +84 -22
- package/src/zod/tempo/TransactionRequest.ts +86 -20
- package/src/zod/tempo/TxEnvelopeTempo.ts +1 -1
- package/src/zod/tempo/_test/KeyAuthorization.test.ts +53 -0
- package/src/zod/tempo/_test/SignatureEnvelope.test.ts +0 -2
- package/src/zod/tempo/_test/Transaction.test.ts +155 -0
- package/src/zod/tempo/_test/TransactionRequest.test.ts +44 -0
- package/src/zod/tempo/z.ts +0 -1
- package/src/zod/z.ts +12 -0
- package/dist/tempo/TokenId.d.ts +0 -87
- package/dist/tempo/TokenId.d.ts.map +0 -1
- package/dist/tempo/TokenId.js +0 -123
- package/dist/tempo/TokenId.js.map +0 -1
- package/dist/zod/tempo/TokenId.d.ts +0 -6
- package/dist/zod/tempo/TokenId.d.ts.map +0 -1
- package/dist/zod/tempo/TokenId.js +0 -14
- package/dist/zod/tempo/TokenId.js.map +0 -1
- package/src/CHANGELOG.md +0 -820
- package/src/tempo/TokenId.bench.ts +0 -36
- package/src/tempo/TokenId.test.ts +0 -79
- package/src/tempo/TokenId.ts +0 -141
- package/src/zod/tempo/TokenId.ts +0 -15
- package/src/zod/tempo/_test/TokenId.test-d.ts +0 -17
- package/src/zod/tempo/_test/TokenId.test.ts +0 -21
|
@@ -86,7 +86,6 @@ export type GetType<
|
|
|
86
86
|
? 'keychain'
|
|
87
87
|
: envelope extends {
|
|
88
88
|
account: Address.Address
|
|
89
|
-
genesisConfigId: `0x${string}`
|
|
90
89
|
signatures: any
|
|
91
90
|
}
|
|
92
91
|
? 'multisig'
|
|
@@ -162,9 +161,10 @@ export type KeychainRpc = {
|
|
|
162
161
|
/**
|
|
163
162
|
* Native multisig signature (type `0x05`).
|
|
164
163
|
*
|
|
165
|
-
* Wraps a set of
|
|
166
|
-
* multisig owner approval digest. The transaction sender is
|
|
167
|
-
* authorized once the recovered owner weights meet the
|
|
164
|
+
* Wraps a set of owner approvals (secp256k1, p256, webAuthn, or nested
|
|
165
|
+
* multisig) over the multisig owner approval digest. The transaction sender is
|
|
166
|
+
* the derived `account`, authorized once the recovered owner weights meet the
|
|
167
|
+
* configured threshold.
|
|
168
168
|
*
|
|
169
169
|
* [TIP-1061](https://tips.sh/1061)
|
|
170
170
|
*/
|
|
@@ -172,9 +172,11 @@ export type Multisig<numberType = number> = {
|
|
|
172
172
|
type: 'multisig'
|
|
173
173
|
/** Native multisig account address. */
|
|
174
174
|
account: Address.Address
|
|
175
|
-
/**
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Owner approvals over the multisig owner approval digest. Each approval is
|
|
177
|
+
* either a primitive signature or a nested multisig signature (keychain
|
|
178
|
+
* approvals are invalid).
|
|
179
|
+
*/
|
|
178
180
|
signatures: readonly SignatureEnvelope<numberType>[]
|
|
179
181
|
/**
|
|
180
182
|
* Initial native multisig config for bootstrapping this account. Present only on
|
|
@@ -188,14 +190,8 @@ export type MultisigRpc = {
|
|
|
188
190
|
type: 'multisig'
|
|
189
191
|
account: Address.Address
|
|
190
192
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* {@link ox#SignatureEnvelope.Multisig} envelope.
|
|
194
|
-
*/
|
|
195
|
-
configId: Hex.Hex
|
|
196
|
-
/**
|
|
197
|
-
* Encoded primitive owner approvals (raw serialized signatures), matching the
|
|
198
|
-
* node's `Vec<Bytes>` representation.
|
|
193
|
+
* Encoded owner approvals (raw serialized signatures), matching the node's
|
|
194
|
+
* `Vec<Bytes>` representation.
|
|
199
195
|
*/
|
|
200
196
|
signatures: readonly Serialized[]
|
|
201
197
|
init?: MultisigConfig.Config | undefined
|
|
@@ -345,11 +341,24 @@ export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
|
|
|
345
341
|
const multisig = envelope as Multisig
|
|
346
342
|
const missing: string[] = []
|
|
347
343
|
if (!multisig.account) missing.push('account')
|
|
348
|
-
if (!multisig.genesisConfigId) missing.push('genesisConfigId')
|
|
349
344
|
if (!Array.isArray(multisig.signatures)) missing.push('signatures')
|
|
350
345
|
if (missing.length > 0)
|
|
351
346
|
throw new MissingPropertiesError({ envelope, missing, type: 'multisig' })
|
|
352
|
-
|
|
347
|
+
if (getNestingDepth(multisig) > MultisigConfig.maxNestingDepth)
|
|
348
|
+
throw new InvalidMultisigApprovalError({
|
|
349
|
+
reason: `multisig nesting depth exceeds ${MultisigConfig.maxNestingDepth}`,
|
|
350
|
+
})
|
|
351
|
+
for (const inner of multisig.signatures) {
|
|
352
|
+
if (inner.type === 'keychain')
|
|
353
|
+
throw new InvalidMultisigApprovalError({
|
|
354
|
+
reason: 'keychain owner approvals are not allowed',
|
|
355
|
+
})
|
|
356
|
+
if (inner.type === 'multisig' && inner.init)
|
|
357
|
+
throw new InvalidMultisigApprovalError({
|
|
358
|
+
reason: 'nested multisig owner approvals cannot carry `init`',
|
|
359
|
+
})
|
|
360
|
+
assert(inner)
|
|
361
|
+
}
|
|
353
362
|
if (multisig.init) MultisigConfig.assert(multisig.init)
|
|
354
363
|
return
|
|
355
364
|
}
|
|
@@ -358,12 +367,22 @@ export function assert(envelope: PartialBy<SignatureEnvelope, 'type'>): void {
|
|
|
358
367
|
export declare namespace assert {
|
|
359
368
|
type ErrorType =
|
|
360
369
|
| CoercionError
|
|
370
|
+
| InvalidMultisigApprovalError
|
|
361
371
|
| MissingPropertiesError
|
|
362
372
|
| MultisigConfig.assert.ErrorType
|
|
363
373
|
| Signature.assert.ErrorType
|
|
364
374
|
| Errors.GlobalErrorType
|
|
365
375
|
}
|
|
366
376
|
|
|
377
|
+
// Returns the deepest multisig path length within a multisig envelope.
|
|
378
|
+
function getNestingDepth(envelope: Multisig): number {
|
|
379
|
+
let deepest = 0
|
|
380
|
+
for (const inner of envelope.signatures)
|
|
381
|
+
if (inner.type === 'multisig')
|
|
382
|
+
deepest = Math.max(deepest, getNestingDepth(inner))
|
|
383
|
+
return 1 + deepest
|
|
384
|
+
}
|
|
385
|
+
|
|
367
386
|
/**
|
|
368
387
|
* Extracts the address of the signer from a {@link ox#SignatureEnvelope.SignatureEnvelope}.
|
|
369
388
|
*
|
|
@@ -630,24 +649,26 @@ export function deserialize(value: Serialized): SignatureEnvelope {
|
|
|
630
649
|
}
|
|
631
650
|
|
|
632
651
|
if (typeId === serializedMultisigType) {
|
|
633
|
-
// Wire format: `0x05 || rlp([account,
|
|
634
|
-
//
|
|
635
|
-
//
|
|
636
|
-
const [account,
|
|
637
|
-
Hex.Hex,
|
|
652
|
+
// Wire format: `0x05 || rlp([account, signatures, init?])`. `init` is a
|
|
653
|
+
// trailing optional: the bootstrap config list when present, otherwise
|
|
654
|
+
// omitted entirely (the empty `0x80` placeholder is rejected).
|
|
655
|
+
const [account, signatures, init] = Rlp.toHex(data) as [
|
|
638
656
|
Hex.Hex,
|
|
639
657
|
readonly Hex.Hex[],
|
|
640
658
|
(Hex.Hex | MultisigConfig.Tuple)?,
|
|
641
659
|
]
|
|
660
|
+
if (typeof init !== 'undefined' && !Array.isArray(init))
|
|
661
|
+
throw new InvalidSerializedError({
|
|
662
|
+
reason:
|
|
663
|
+
'Invalid multisig `init`: expected the bootstrap config list or an omitted trailing element',
|
|
664
|
+
serialized,
|
|
665
|
+
})
|
|
642
666
|
return {
|
|
643
667
|
type: 'multisig',
|
|
644
668
|
account,
|
|
645
|
-
genesisConfigId,
|
|
646
669
|
signatures: signatures.map((signature) => deserialize(signature)),
|
|
647
|
-
...(init
|
|
648
|
-
? {
|
|
649
|
-
init: MultisigConfig.fromTuple(init as MultisigConfig.Tuple),
|
|
650
|
-
}
|
|
670
|
+
...(init
|
|
671
|
+
? { init: MultisigConfig.fromTuple(init as MultisigConfig.Tuple) }
|
|
651
672
|
: {}),
|
|
652
673
|
} satisfies Multisig
|
|
653
674
|
}
|
|
@@ -786,9 +807,9 @@ export function deserialize(value: Serialized): SignatureEnvelope {
|
|
|
786
807
|
* @example
|
|
787
808
|
* ### Multisig (from genesis config)
|
|
788
809
|
*
|
|
789
|
-
* Pass `genesisConfig` to derive `account`
|
|
790
|
-
*
|
|
791
|
-
*
|
|
810
|
+
* Pass `genesisConfig` to derive `account` automatically. Set `init: true` to
|
|
811
|
+
* opt into bootstrap (uses `genesisConfig` as the bootstrap `init`); omit
|
|
812
|
+
* `init` for subsequent (non-bootstrap) transactions.
|
|
792
813
|
*
|
|
793
814
|
* ```ts twoslash
|
|
794
815
|
* import { Secp256k1 } from 'ox'
|
|
@@ -849,18 +870,12 @@ export function from<const value extends from.Value>(
|
|
|
849
870
|
init?: MultisigConfig.Config | boolean | undefined
|
|
850
871
|
}
|
|
851
872
|
const { genesisConfig, init, ...rest } = multisig
|
|
852
|
-
// Derive `account
|
|
853
|
-
// explicitly.
|
|
873
|
+
// Derive `account` from `genesisConfig` when not provided explicitly.
|
|
854
874
|
const account = (() => {
|
|
855
875
|
if (rest.account) return rest.account
|
|
856
876
|
if (genesisConfig) return MultisigConfig.getAddress(genesisConfig)
|
|
857
877
|
return rest.account
|
|
858
878
|
})()
|
|
859
|
-
const genesisConfigId = (() => {
|
|
860
|
-
if (rest.genesisConfigId) return rest.genesisConfigId
|
|
861
|
-
if (genesisConfig) return MultisigConfig.toId(genesisConfig)
|
|
862
|
-
return rest.genesisConfigId
|
|
863
|
-
})()
|
|
864
879
|
// `init: true` opts into bootstrap using the supplied `genesisConfig`.
|
|
865
880
|
// Otherwise, `init` is treated as the explicit bootstrap config (or
|
|
866
881
|
// omitted).
|
|
@@ -868,7 +883,6 @@ export function from<const value extends from.Value>(
|
|
|
868
883
|
return {
|
|
869
884
|
...rest,
|
|
870
885
|
account,
|
|
871
|
-
genesisConfigId,
|
|
872
886
|
signatures: rest.signatures.map((signature) => from(signature)),
|
|
873
887
|
// Normalize the bootstrap config (sorts owners, defaults the salt) so the
|
|
874
888
|
// in-memory envelope matches what `deserialize` reconstructs.
|
|
@@ -920,9 +934,9 @@ export declare namespace from {
|
|
|
920
934
|
}
|
|
921
935
|
|
|
922
936
|
/**
|
|
923
|
-
* Multisig envelope input variant where `account`
|
|
924
|
-
*
|
|
925
|
-
*
|
|
937
|
+
* Multisig envelope input variant where `account` is derived from the
|
|
938
|
+
* supplied `genesisConfig`. Pass `init: true` to opt into bootstrap (uses
|
|
939
|
+
* `genesisConfig` as the bootstrap `init`); omit `init` for subsequent
|
|
926
940
|
* (non-bootstrap) transactions.
|
|
927
941
|
*/
|
|
928
942
|
type MultisigFromGenesisConfig = {
|
|
@@ -1063,17 +1077,12 @@ export function fromRpc(envelope: SignatureEnvelopeRpc): SignatureEnvelope {
|
|
|
1063
1077
|
|
|
1064
1078
|
if (
|
|
1065
1079
|
envelope.type === 'multisig' ||
|
|
1066
|
-
('account' in envelope &&
|
|
1067
|
-
'configId' in envelope &&
|
|
1068
|
-
'signatures' in envelope)
|
|
1080
|
+
('account' in envelope && 'signatures' in envelope)
|
|
1069
1081
|
) {
|
|
1070
1082
|
const multisig = envelope as MultisigRpc
|
|
1071
1083
|
return {
|
|
1072
1084
|
type: 'multisig',
|
|
1073
1085
|
account: multisig.account,
|
|
1074
|
-
// Map RPC wire field `configId` (TIP-1061 spec name) to the typed
|
|
1075
|
-
// envelope's `genesisConfigId`.
|
|
1076
|
-
genesisConfigId: multisig.configId,
|
|
1077
1086
|
// Owner approvals are raw serialized signatures (node `Vec<Bytes>`).
|
|
1078
1087
|
signatures: multisig.signatures.map((signature) =>
|
|
1079
1088
|
deserialize(signature),
|
|
@@ -1164,8 +1173,7 @@ export function getType<
|
|
|
1164
1173
|
|
|
1165
1174
|
// Detect Multisig signature
|
|
1166
1175
|
if (
|
|
1167
|
-
(
|
|
1168
|
-
'genesisConfig' in envelope) &&
|
|
1176
|
+
('account' in envelope || 'genesisConfig' in envelope) &&
|
|
1169
1177
|
'signatures' in envelope
|
|
1170
1178
|
)
|
|
1171
1179
|
return 'multisig' as never
|
|
@@ -1269,17 +1277,15 @@ export function serialize(
|
|
|
1269
1277
|
|
|
1270
1278
|
if (type === 'multisig') {
|
|
1271
1279
|
const multisig = envelope as Multisig
|
|
1272
|
-
// Format: `0x05 || rlp([account,
|
|
1273
|
-
//
|
|
1274
|
-
// config
|
|
1275
|
-
// placeholder (`0x` → RLP `0x80`).
|
|
1280
|
+
// Format: `0x05 || rlp([account, signatures, init?])`, where each owner
|
|
1281
|
+
// approval is an encoded signature. `init` is a trailing optional: the
|
|
1282
|
+
// bootstrap config list when present, otherwise omitted entirely.
|
|
1276
1283
|
return Hex.concat(
|
|
1277
1284
|
serializedMultisigType,
|
|
1278
1285
|
Rlp.fromHex([
|
|
1279
1286
|
multisig.account,
|
|
1280
|
-
multisig.genesisConfigId,
|
|
1281
1287
|
multisig.signatures.map((signature) => serialize(signature)),
|
|
1282
|
-
multisig.init ? MultisigConfig.toTuple(multisig.init) :
|
|
1288
|
+
...(multisig.init ? [MultisigConfig.toTuple(multisig.init)] : []),
|
|
1283
1289
|
]),
|
|
1284
1290
|
options.magic ? magicBytes : '0x',
|
|
1285
1291
|
)
|
|
@@ -1307,10 +1313,10 @@ export declare namespace serialize {
|
|
|
1307
1313
|
* ({@link ox#MultisigConfig.(getSignPayload:function)}), so the signer of
|
|
1308
1314
|
* every approval is recovered against that digest and the list is sorted by the
|
|
1309
1315
|
* recovered owner address. Works for any owner key type (secp256k1, p256,
|
|
1310
|
-
* webAuthn
|
|
1316
|
+
* webAuthn).
|
|
1311
1317
|
*
|
|
1312
|
-
* Config updates never change `account
|
|
1313
|
-
*
|
|
1318
|
+
* Config updates never change `account`, so the genesis config is the correct
|
|
1319
|
+
* input even for post-update transactions.
|
|
1314
1320
|
*
|
|
1315
1321
|
* @example
|
|
1316
1322
|
* ```ts twoslash
|
|
@@ -1370,12 +1376,7 @@ export function sortMultisigApprovals(
|
|
|
1370
1376
|
const digest = MultisigConfig.getSignPayload(
|
|
1371
1377
|
'genesisConfig' in value && value.genesisConfig
|
|
1372
1378
|
? { payload, genesisConfig: value.genesisConfig }
|
|
1373
|
-
: {
|
|
1374
|
-
payload,
|
|
1375
|
-
account: (value as { account: Address.Address }).account,
|
|
1376
|
-
genesisConfigId: (value as { genesisConfigId: Hex.Hex })
|
|
1377
|
-
.genesisConfigId,
|
|
1378
|
-
},
|
|
1379
|
+
: { payload, account: (value as { account: Address.Address }).account },
|
|
1379
1380
|
)
|
|
1380
1381
|
// Recover each signer once (decorate–sort–undecorate) rather than inside the
|
|
1381
1382
|
// comparator.
|
|
@@ -1392,20 +1393,17 @@ export declare namespace sortMultisigApprovals {
|
|
|
1392
1393
|
type Value = {
|
|
1393
1394
|
/** The inner transaction sign payload (`tx.signature_hash()`). */
|
|
1394
1395
|
payload: Hex.Hex | Bytes.Bytes
|
|
1395
|
-
/** The
|
|
1396
|
+
/** The owner approvals to order. */
|
|
1396
1397
|
signatures: readonly SignatureEnvelope[]
|
|
1397
1398
|
} & OneOf<
|
|
1398
1399
|
| {
|
|
1399
1400
|
/** The native multisig account address. */
|
|
1400
1401
|
account: Address.Address
|
|
1401
|
-
/** The permanent config ID. */
|
|
1402
|
-
genesisConfigId: Hex.Hex
|
|
1403
1402
|
}
|
|
1404
1403
|
| {
|
|
1405
1404
|
/**
|
|
1406
1405
|
* The initial multisig config (the bootstrap config that derived the
|
|
1407
|
-
* permanent `account`
|
|
1408
|
-
* automatically.
|
|
1406
|
+
* permanent `account`). Used to derive the account automatically.
|
|
1409
1407
|
*/
|
|
1410
1408
|
genesisConfig: MultisigConfig.Config
|
|
1411
1409
|
}
|
|
@@ -1493,9 +1491,6 @@ export function toRpc(envelope: toRpc.Input): SignatureEnvelopeRpc {
|
|
|
1493
1491
|
return {
|
|
1494
1492
|
type: 'multisig',
|
|
1495
1493
|
account: multisig.account,
|
|
1496
|
-
// Map the typed envelope's `genesisConfigId` to the RPC wire field
|
|
1497
|
-
// `configId` (TIP-1061 spec name).
|
|
1498
|
-
configId: multisig.genesisConfigId,
|
|
1499
1494
|
// Owner approvals are raw serialized signatures (node `Vec<Bytes>`).
|
|
1500
1495
|
signatures: multisig.signatures.map((signature) => serialize(signature)),
|
|
1501
1496
|
...(multisig.init ? { init: multisig.init } : {}),
|
|
@@ -1780,6 +1775,16 @@ export class InvalidSerializedError extends Errors.BaseError {
|
|
|
1780
1775
|
}
|
|
1781
1776
|
}
|
|
1782
1777
|
|
|
1778
|
+
/**
|
|
1779
|
+
* Error thrown when a native multisig owner approval is invalid.
|
|
1780
|
+
*/
|
|
1781
|
+
export class InvalidMultisigApprovalError extends Errors.BaseError {
|
|
1782
|
+
override readonly name = 'SignatureEnvelope.InvalidMultisigApprovalError'
|
|
1783
|
+
constructor({ reason }: { reason: string }) {
|
|
1784
|
+
super(`Invalid native multisig owner approval: ${reason}.`)
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1783
1788
|
/**
|
|
1784
1789
|
* Error thrown when a signature envelope fails to verify.
|
|
1785
1790
|
*/
|
|
@@ -49,7 +49,6 @@ describe('fromRpc', () => {
|
|
|
49
49
|
},
|
|
50
50
|
],
|
|
51
51
|
"chainId": 1,
|
|
52
|
-
"data": undefined,
|
|
53
52
|
"feeToken": "0x20c0000000000000000000000000000000000000",
|
|
54
53
|
"from": "0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6",
|
|
55
54
|
"gas": 278365n,
|
|
@@ -68,7 +67,6 @@ describe('fromRpc', () => {
|
|
|
68
67
|
},
|
|
69
68
|
"transactionIndex": 2,
|
|
70
69
|
"type": "tempo",
|
|
71
|
-
"value": 0n,
|
|
72
70
|
}
|
|
73
71
|
`)
|
|
74
72
|
})
|
|
@@ -125,7 +123,6 @@ describe('fromRpc', () => {
|
|
|
125
123
|
},
|
|
126
124
|
],
|
|
127
125
|
"chainId": 1,
|
|
128
|
-
"data": undefined,
|
|
129
126
|
"feePayerSignature": {
|
|
130
127
|
"r": "0x12f4d9e9924f62b19de816252efc125006298f43e62d394151e62600e2c2f91e",
|
|
131
128
|
"s": "0x31daa78bb3e95dd22f6370e59617c60d109bf28e55c92b25994ddbed420e2a80",
|
|
@@ -150,7 +147,6 @@ describe('fromRpc', () => {
|
|
|
150
147
|
},
|
|
151
148
|
"transactionIndex": 2,
|
|
152
149
|
"type": "tempo",
|
|
153
|
-
"value": 0n,
|
|
154
150
|
}
|
|
155
151
|
`)
|
|
156
152
|
})
|
|
@@ -219,7 +215,6 @@ describe('fromRpc', () => {
|
|
|
219
215
|
},
|
|
220
216
|
],
|
|
221
217
|
"chainId": 1,
|
|
222
|
-
"data": undefined,
|
|
223
218
|
"feeToken": "0x20c0000000000000000000000000000000000000",
|
|
224
219
|
"from": "0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6",
|
|
225
220
|
"gas": 278365n,
|
|
@@ -258,7 +253,6 @@ describe('fromRpc', () => {
|
|
|
258
253
|
},
|
|
259
254
|
"transactionIndex": 2,
|
|
260
255
|
"type": "tempo",
|
|
261
|
-
"value": 0n,
|
|
262
256
|
}
|
|
263
257
|
`)
|
|
264
258
|
})
|
|
@@ -319,7 +313,6 @@ describe('toRpc', () => {
|
|
|
319
313
|
"gas": "0x43f5d",
|
|
320
314
|
"gasPrice": "0x2ca6ae494",
|
|
321
315
|
"hash": "0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0",
|
|
322
|
-
"input": undefined,
|
|
323
316
|
"maxFeePerGas": "0x2",
|
|
324
317
|
"maxPriorityFeePerGas": "0x1",
|
|
325
318
|
"nonce": "0x357",
|
|
@@ -329,10 +322,8 @@ describe('toRpc', () => {
|
|
|
329
322
|
"type": "secp256k1",
|
|
330
323
|
"yParity": "0x0",
|
|
331
324
|
},
|
|
332
|
-
"to": undefined,
|
|
333
325
|
"transactionIndex": "0x2",
|
|
334
326
|
"type": "0x76",
|
|
335
|
-
"value": "0x0",
|
|
336
327
|
}
|
|
337
328
|
`)
|
|
338
329
|
})
|
|
@@ -401,7 +392,6 @@ describe('toRpc', () => {
|
|
|
401
392
|
"gas": "0x43f5d",
|
|
402
393
|
"gasPrice": "0x2ca6ae494",
|
|
403
394
|
"hash": "0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0",
|
|
404
|
-
"input": undefined,
|
|
405
395
|
"maxFeePerGas": "0x2",
|
|
406
396
|
"maxPriorityFeePerGas": "0x1",
|
|
407
397
|
"nonce": "0x357",
|
|
@@ -411,10 +401,8 @@ describe('toRpc', () => {
|
|
|
411
401
|
"type": "secp256k1",
|
|
412
402
|
"yParity": "0x0",
|
|
413
403
|
},
|
|
414
|
-
"to": undefined,
|
|
415
404
|
"transactionIndex": "0x2",
|
|
416
405
|
"type": "0x76",
|
|
417
|
-
"value": "0x0",
|
|
418
406
|
}
|
|
419
407
|
`)
|
|
420
408
|
})
|
|
@@ -491,7 +479,6 @@ describe('toRpc', () => {
|
|
|
491
479
|
"gas": "0x43f5d",
|
|
492
480
|
"gasPrice": "0x2ca6ae494",
|
|
493
481
|
"hash": "0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0",
|
|
494
|
-
"input": undefined,
|
|
495
482
|
"keyAuthorization": {
|
|
496
483
|
"chainId": "0x1",
|
|
497
484
|
"expiry": "0xffffffffffff",
|
|
@@ -519,10 +506,8 @@ describe('toRpc', () => {
|
|
|
519
506
|
"type": "secp256k1",
|
|
520
507
|
"yParity": "0x0",
|
|
521
508
|
},
|
|
522
|
-
"to": undefined,
|
|
523
509
|
"transactionIndex": "0x2",
|
|
524
510
|
"type": "0x76",
|
|
525
|
-
"value": "0x0",
|
|
526
511
|
}
|
|
527
512
|
`)
|
|
528
513
|
})
|
package/src/tempo/Transaction.ts
CHANGED
|
@@ -103,18 +103,40 @@ export type Tempo<
|
|
|
103
103
|
export type TempoRpc<pending extends boolean = false> = Compute<
|
|
104
104
|
Omit<
|
|
105
105
|
Tempo<pending, Hex.Hex, Hex.Hex, ToRpcType['tempo']>,
|
|
106
|
-
|
|
106
|
+
| 'authorizationList'
|
|
107
|
+
| 'calls'
|
|
108
|
+
| 'feePayerSignature'
|
|
109
|
+
| 'gasPrice'
|
|
110
|
+
| 'keyAuthorization'
|
|
111
|
+
| 'nonceKey'
|
|
112
|
+
| 'signature'
|
|
113
|
+
| 'validAfter'
|
|
114
|
+
| 'validBefore'
|
|
107
115
|
> & {
|
|
108
116
|
aaAuthorizationList?: AuthorizationTempo.ListRpc | undefined
|
|
109
117
|
calls:
|
|
110
118
|
| readonly {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
119
|
+
data?: Hex.Hex | null | undefined
|
|
120
|
+
input?: Hex.Hex | null | undefined
|
|
121
|
+
to?: Hex.Hex | null | undefined
|
|
122
|
+
value?: Hex.Hex | null | undefined
|
|
114
123
|
}[]
|
|
115
124
|
| undefined
|
|
116
|
-
|
|
125
|
+
feePayerSignature?:
|
|
126
|
+
| {
|
|
127
|
+
r: Hex.Hex
|
|
128
|
+
s: Hex.Hex
|
|
129
|
+
v?: Hex.Hex | undefined
|
|
130
|
+
yParity: Hex.Hex
|
|
131
|
+
}
|
|
132
|
+
| null
|
|
133
|
+
| undefined
|
|
134
|
+
gasPrice?: Hex.Hex | null | undefined
|
|
135
|
+
keyAuthorization?: KeyAuthorization.Rpc | null | undefined
|
|
136
|
+
nonceKey?: Hex.Hex | null | undefined
|
|
117
137
|
signature: SignatureEnvelope.SignatureEnvelopeRpc
|
|
138
|
+
validAfter?: Hex.Hex | null | undefined
|
|
139
|
+
validBefore?: Hex.Hex | null | undefined
|
|
118
140
|
}
|
|
119
141
|
>
|
|
120
142
|
|
|
@@ -199,19 +221,26 @@ export function fromRpc<
|
|
|
199
221
|
transaction as ox_Transaction.Rpc<pending>,
|
|
200
222
|
) as Transaction<pending>
|
|
201
223
|
|
|
202
|
-
|
|
224
|
+
if (transaction.type !== '0x76') return transaction_ as never
|
|
225
|
+
|
|
226
|
+
transaction_.type = 'tempo'
|
|
203
227
|
|
|
204
|
-
|
|
228
|
+
// Tempo transactions carry `calls`; scrub the flat call fields the generic
|
|
229
|
+
// decoder fabricates.
|
|
230
|
+
delete (transaction_ as any).data
|
|
231
|
+
delete (transaction_ as any).input
|
|
232
|
+
delete (transaction_ as any).to
|
|
233
|
+
delete (transaction_ as any).value
|
|
234
|
+
|
|
235
|
+
if (transaction.aaAuthorizationList?.length)
|
|
205
236
|
transaction_.authorizationList = AuthorizationTempo.fromRpcList(
|
|
206
237
|
transaction.aaAuthorizationList,
|
|
207
238
|
)
|
|
208
|
-
|
|
209
|
-
}
|
|
239
|
+
delete (transaction_ as any).aaAuthorizationList
|
|
210
240
|
if (transaction.calls)
|
|
211
241
|
transaction_.calls = transaction.calls.map((call) => ({
|
|
212
|
-
to: call.to,
|
|
242
|
+
to: call.to ?? undefined,
|
|
213
243
|
value: call.value && call.value !== '0x' ? BigInt(call.value) : undefined,
|
|
214
|
-
// @ts-expect-error
|
|
215
244
|
data: call.input || call.data || '0x',
|
|
216
245
|
}))
|
|
217
246
|
if (transaction.feeToken) transaction_.feeToken = transaction.feeToken
|
|
@@ -235,6 +264,18 @@ export function fromRpc<
|
|
|
235
264
|
)
|
|
236
265
|
}
|
|
237
266
|
|
|
267
|
+
// The node serializes absent optional fields as `null`; scrub them.
|
|
268
|
+
for (const key of [
|
|
269
|
+
'feePayer',
|
|
270
|
+
'feePayerSignature',
|
|
271
|
+
'gasPrice',
|
|
272
|
+
'keyAuthorization',
|
|
273
|
+
'nonceKey',
|
|
274
|
+
'validAfter',
|
|
275
|
+
'validBefore',
|
|
276
|
+
] as const)
|
|
277
|
+
if ((transaction_ as any)[key] === null) delete (transaction_ as any)[key]
|
|
278
|
+
|
|
238
279
|
return transaction_ as never
|
|
239
280
|
}
|
|
240
281
|
|
|
@@ -300,7 +341,15 @@ export function toRpc<pending extends boolean = false>(
|
|
|
300
341
|
transaction as ox_Transaction.Transaction<pending>,
|
|
301
342
|
) as Rpc<pending>
|
|
302
343
|
|
|
303
|
-
|
|
344
|
+
if (transaction.type !== 'tempo') return rpc
|
|
345
|
+
|
|
346
|
+
rpc.type = '0x76'
|
|
347
|
+
|
|
348
|
+
// Tempo transactions carry `calls`; scrub the flat call fields the generic
|
|
349
|
+
// encoder fabricates.
|
|
350
|
+
delete (rpc as any).input
|
|
351
|
+
delete (rpc as any).to
|
|
352
|
+
delete (rpc as any).value
|
|
304
353
|
|
|
305
354
|
if (transaction.authorizationList)
|
|
306
355
|
rpc.aaAuthorizationList = AuthorizationTempo.toRpcList(
|
|
@@ -323,6 +372,8 @@ export function toRpc<pending extends boolean = false>(
|
|
|
323
372
|
Signature.yParityToV(Number(transaction.feePayerSignature.yParity)),
|
|
324
373
|
)
|
|
325
374
|
}
|
|
375
|
+
if (transaction.nonceKey !== undefined)
|
|
376
|
+
rpc.nonceKey = Quantity.fromNumberish(transaction.nonceKey)
|
|
326
377
|
if (transaction.signature)
|
|
327
378
|
rpc.signature = SignatureEnvelope.toRpc(transaction.signature)
|
|
328
379
|
if (transaction.validAfter !== undefined)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { TransactionReceipt } from 'ox/tempo'
|
|
2
|
+
import { describe, expect, test } from 'vite-plus/test'
|
|
3
|
+
|
|
4
|
+
const rpc = {
|
|
5
|
+
blockHash:
|
|
6
|
+
'0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b',
|
|
7
|
+
blockNumber: '0x12f296f',
|
|
8
|
+
contractAddress: null,
|
|
9
|
+
cumulativeGasUsed: '0x82515',
|
|
10
|
+
effectiveGasPrice: '0x21c2f6c09',
|
|
11
|
+
feePayer: '0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6',
|
|
12
|
+
feeToken: '0x20c0000000000000000000000000000000000001',
|
|
13
|
+
from: '0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6',
|
|
14
|
+
gasUsed: '0x2abba',
|
|
15
|
+
logs: [],
|
|
16
|
+
logsBloom: `0x${'00'.repeat(256)}`,
|
|
17
|
+
status: '0x1',
|
|
18
|
+
to: '0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad',
|
|
19
|
+
transactionHash:
|
|
20
|
+
'0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0',
|
|
21
|
+
transactionIndex: '0x2',
|
|
22
|
+
type: '0x76',
|
|
23
|
+
} as const satisfies TransactionReceipt.Rpc
|
|
24
|
+
|
|
25
|
+
describe('fromRpc', () => {
|
|
26
|
+
test('default', () => {
|
|
27
|
+
const receipt = TransactionReceipt.fromRpc(rpc)
|
|
28
|
+
expect(receipt).toMatchInlineSnapshot(`
|
|
29
|
+
{
|
|
30
|
+
"blobGasPrice": undefined,
|
|
31
|
+
"blobGasUsed": undefined,
|
|
32
|
+
"blockHash": "0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b",
|
|
33
|
+
"blockNumber": 19868015n,
|
|
34
|
+
"contractAddress": null,
|
|
35
|
+
"cumulativeGasUsed": 533781n,
|
|
36
|
+
"effectiveGasPrice": 9062804489n,
|
|
37
|
+
"feePayer": "0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6",
|
|
38
|
+
"feeToken": "0x20c0000000000000000000000000000000000001",
|
|
39
|
+
"from": "0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6",
|
|
40
|
+
"gasUsed": 175034n,
|
|
41
|
+
"logs": [],
|
|
42
|
+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
43
|
+
"status": "success",
|
|
44
|
+
"to": "0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad",
|
|
45
|
+
"transactionHash": "0x353fdfc38a2f26115daadee9f5b8392ce62b84f410957967e2ed56b35338cdd0",
|
|
46
|
+
"transactionIndex": 2,
|
|
47
|
+
"type": "tempo",
|
|
48
|
+
}
|
|
49
|
+
`)
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
test('behavior: non-tempo type passes through the generic mapping', () => {
|
|
53
|
+
const receipt = TransactionReceipt.fromRpc({ ...rpc, type: '0x2' })
|
|
54
|
+
expect(receipt.type).toBe('eip1559')
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('behavior: null', () => {
|
|
58
|
+
expect(TransactionReceipt.fromRpc(null)).toBeNull()
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
describe('toRpc', () => {
|
|
63
|
+
test('default', () => {
|
|
64
|
+
const receipt = TransactionReceipt.fromRpc(rpc)
|
|
65
|
+
const encoded = TransactionReceipt.toRpc(receipt)
|
|
66
|
+
expect(encoded.type).toBe('0x76')
|
|
67
|
+
expect(encoded.feePayer).toBe(rpc.feePayer)
|
|
68
|
+
expect(encoded.feeToken).toBe(rpc.feeToken)
|
|
69
|
+
expect(TransactionReceipt.fromRpc(encoded)).toEqual(receipt)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
test('behavior: non-tempo type passes through the generic mapping', () => {
|
|
73
|
+
const receipt = TransactionReceipt.fromRpc({ ...rpc, type: '0x2' })
|
|
74
|
+
expect(TransactionReceipt.toRpc(receipt).type).toBe('0x2')
|
|
75
|
+
})
|
|
76
|
+
})
|
|
@@ -13,7 +13,7 @@ import * as ox_TransactionReceipt from '../core/TransactionReceipt.js'
|
|
|
13
13
|
*/
|
|
14
14
|
export type TransactionReceipt<
|
|
15
15
|
status = ox_TransactionReceipt.Status,
|
|
16
|
-
type =
|
|
16
|
+
type = Type,
|
|
17
17
|
bigintType = bigint,
|
|
18
18
|
numberType = number,
|
|
19
19
|
> = Compute<
|
|
@@ -32,7 +32,7 @@ export type TransactionReceipt<
|
|
|
32
32
|
|
|
33
33
|
export type Rpc = TransactionReceipt<
|
|
34
34
|
ox_TransactionReceipt.RpcStatus,
|
|
35
|
-
|
|
35
|
+
RpcType,
|
|
36
36
|
Hex.Hex,
|
|
37
37
|
Hex.Hex
|
|
38
38
|
>
|
|
@@ -118,9 +118,14 @@ export const toRpcType = {
|
|
|
118
118
|
export function fromRpc<const receipt extends Rpc | null>(
|
|
119
119
|
receipt: receipt | Rpc | null,
|
|
120
120
|
): receipt extends Rpc ? TransactionReceipt : null {
|
|
121
|
-
|
|
121
|
+
const decoded = ox_TransactionReceipt.fromRpc(
|
|
122
122
|
receipt as ox_TransactionReceipt.Rpc,
|
|
123
|
-
)
|
|
123
|
+
)
|
|
124
|
+
if (!decoded) return null as never
|
|
125
|
+
return {
|
|
126
|
+
...decoded,
|
|
127
|
+
type: (fromRpcType as any)[receipt!.type] ?? receipt!.type,
|
|
128
|
+
} as never
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
export declare namespace fromRpc {
|
|
@@ -192,6 +197,7 @@ export function toRpc(receipt: toRpc.Input): Rpc {
|
|
|
192
197
|
...rpc,
|
|
193
198
|
feePayer: receipt.feePayer,
|
|
194
199
|
feeToken: receipt.feeToken,
|
|
200
|
+
type: (toRpcType as any)[receipt.type] ?? receipt.type,
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
|
|
@@ -199,7 +205,7 @@ export declare namespace toRpc {
|
|
|
199
205
|
/** Numberish input accepted by {@link ox#TransactionReceipt.(toRpc:function)}. */
|
|
200
206
|
export type Input = TransactionReceipt<
|
|
201
207
|
ox_TransactionReceipt.Status,
|
|
202
|
-
|
|
208
|
+
Type,
|
|
203
209
|
Hex.Hex | bigint | number,
|
|
204
210
|
Hex.Hex | number
|
|
205
211
|
>
|