diff --git a/.changeset/transaction-block-timestamp.md b/.changeset/transaction-block-timestamp.md new file mode 100644 index 00000000..39ccde38 --- /dev/null +++ b/.changeset/transaction-block-timestamp.md @@ -0,0 +1,5 @@ +--- +"ox": patch +--- + +Added `blockTimestamp` support to transaction RPC conversions. diff --git a/src/core/Transaction.ts b/src/core/Transaction.ts index 87508d93..a6383c82 100644 --- a/src/core/Transaction.ts +++ b/src/core/Transaction.ts @@ -49,6 +49,8 @@ export type Base< blockHash: pending extends true ? null : Hex.Hex /** Number of block containing this transaction or `null` if pending */ blockNumber: pending extends true ? null : bigintType + /** Timestamp of the block containing this transaction, or `null` if pending. */ + blockTimestamp?: pending extends true ? null : bigintType | undefined /** Chain ID that this transaction is valid on. */ chainId: numberType /** @alias `input` Added for TransactionEnvelope - Transaction compatibility. */ @@ -289,6 +291,12 @@ export function fromRpc< transaction_.blockNumber = transaction.blockNumber ? BigInt(transaction.blockNumber) : null + if ('blockTimestamp' in transaction) + transaction_.blockTimestamp = transaction.blockTimestamp + ? BigInt(transaction.blockTimestamp) + : transaction.blockTimestamp === null + ? null + : undefined transaction_.data = transaction.input transaction_.gas = BigInt(transaction.gas ?? 0n) transaction_.nonce = BigInt(transaction.nonce ?? 0n) @@ -371,6 +379,9 @@ export function toRpc( typeof transaction.blockNumber === 'bigint' ? Hex.fromNumber(transaction.blockNumber) : null + if (typeof transaction.blockTimestamp === 'bigint') + rpc.blockTimestamp = Hex.fromNumber(transaction.blockTimestamp) + else if (transaction.blockTimestamp === null) rpc.blockTimestamp = null rpc.from = transaction.from rpc.gas = Hex.fromNumber(transaction.gas ?? 0n) rpc.hash = transaction.hash diff --git a/src/tempo/Transaction.test.ts b/src/tempo/Transaction.test.ts index 4923f070..8c56682b 100644 --- a/src/tempo/Transaction.test.ts +++ b/src/tempo/Transaction.test.ts @@ -19,6 +19,7 @@ describe('fromRpc', () => { blockHash: '0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b', blockNumber: '0x12f296f', + blockTimestamp: '0x66434e07', transactionIndex: '0x2', feeToken: '0x20c0000000000000000000000000000000000000', from: '0x814e5e0e31016b9a7f138c76b7e7b2bb5c1ab6a6', @@ -39,6 +40,7 @@ describe('fromRpc', () => { "accessList": [], "blockHash": "0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b", "blockNumber": 19868015n, + "blockTimestamp": 1715686919n, "calls": [ { "data": "0xdeadbeef", @@ -269,6 +271,7 @@ describe('toRpc', () => { blockHash: '0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b', blockNumber: 19868015n, + blockTimestamp: 1715686919n, calls: [ { data: '0xdeadbeef', @@ -302,6 +305,7 @@ describe('toRpc', () => { "accessList": [], "blockHash": "0xc350d807505fb835650f0013632c5515592987ba169bbc6626d9fc54d91f0f0b", "blockNumber": "0x12f296f", + "blockTimestamp": "0x66434e07", "calls": [ { "data": "0xdeadbeef", diff --git a/src/tempo/e2e.test.ts b/src/tempo/e2e.test.ts index 1ba617a1..e6869396 100644 --- a/src/tempo/e2e.test.ts +++ b/src/tempo/e2e.test.ts @@ -79,6 +79,7 @@ test('behavior: default (secp256k1)', async () => { const { blockNumber, blockHash, + blockTimestamp, chainId, hash, feeToken: _, @@ -94,6 +95,7 @@ test('behavior: default (secp256k1)', async () => { expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(chainId).toBe(chainId) expect(hash).toBe(receipt.transactionHash) expect(from).toBe(address) @@ -288,6 +290,7 @@ test('behavior: default (p256)', async () => { const { blockNumber, blockHash, + blockTimestamp, chainId, feeToken: _, from, @@ -303,6 +306,7 @@ test('behavior: default (p256)', async () => { expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(chainId).toBe(chainId) expect(from).toBe(address) expect(hash).toBe(receipt.transactionHash) @@ -429,6 +433,7 @@ test('behavior: default (p256 - webcrypto)', async () => { const { blockNumber, blockHash, + blockTimestamp, chainId, feeToken: _, from, @@ -440,10 +445,11 @@ test('behavior: default (p256 - webcrypto)', async () => { signature, transactionIndex, ...rest - } = response as any + } = response expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(chainId).toBeDefined() expect(from).toBeDefined() expect(hash).toBe(receipt.transactionHash) @@ -577,6 +583,7 @@ test('behavior: default (webauthn)', async () => { const { blockNumber, blockHash, + blockTimestamp, chainId, feeToken: _, from, @@ -592,6 +599,7 @@ test('behavior: default (webauthn)', async () => { expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(chainId).toBe(chainId) expect(from).toBeDefined() expect(hash).toBe(receipt.transactionHash) @@ -956,6 +964,7 @@ describe('behavior: keyAuthorization', () => { const { blockNumber, blockHash, + blockTimestamp, chainId: _, gasPrice, hash, @@ -971,6 +980,7 @@ describe('behavior: keyAuthorization', () => { expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(gasPrice).toBeDefined() expect(maxFeePerGas).toBeDefined() expect(maxPriorityFeePerGas).toBeDefined() @@ -1173,6 +1183,7 @@ describe('behavior: keyAuthorization', () => { const { blockNumber, blockHash, + blockTimestamp, chainId: _, gasPrice, hash, @@ -1188,6 +1199,7 @@ describe('behavior: keyAuthorization', () => { expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(gasPrice).toBeDefined() expect(hash).toBe(receipt.transactionHash) expect(from).toBe(root.address) @@ -1392,6 +1404,7 @@ describe('behavior: keyAuthorization', () => { const { blockNumber, blockHash, + blockTimestamp, chainId: _, gasPrice, hash, @@ -1407,6 +1420,7 @@ describe('behavior: keyAuthorization', () => { expect(blockNumber).toBeDefined() expect(blockHash).toBeDefined() + expect(blockTimestamp).toBeDefined() expect(gasPrice).toBeDefined() expect(hash).toBe(receipt.transactionHash) expect(from).toBe(root.address)