From 233e120d397907a217ae9ce1e111ec4b65f6ee1a Mon Sep 17 00:00:00 2001 From: John Shutt Date: Sat, 5 Sep 2026 13:45:48 -0700 Subject: [PATCH 1/5] add transaction preparer factory and small signing adapter interface Signed-off-by: John Shutt --- packages/ethereum/README.md | 43 ++- packages/ethereum/dist/index.d.ts | 4 +- packages/ethereum/dist/index.js | 1 + packages/ethereum/dist/index.js.map | 2 +- packages/ethereum/dist/logger.js | 4 +- packages/ethereum/dist/logger.js.map | 2 +- packages/ethereum/dist/receipt-utils.js | 7 +- packages/ethereum/dist/receipt-utils.js.map | 2 +- packages/ethereum/dist/receipts.d.ts | 3 +- packages/ethereum/dist/receipts.js | 11 +- packages/ethereum/dist/receipts.js.map | 2 +- packages/ethereum/dist/request-utils.d.ts | 3 +- packages/ethereum/dist/request-utils.js | 8 +- packages/ethereum/dist/request-utils.js.map | 2 +- .../ethereum/dist/transaction-preparer.d.ts | 25 ++ .../ethereum/dist/transaction-preparer.js | 138 ++++++++ .../ethereum/dist/transaction-preparer.js.map | 1 + packages/ethereum/dist/transactions.d.ts | 18 +- packages/ethereum/dist/transactions.js.map | 2 +- packages/ethereum/src/index.ts | 4 + packages/ethereum/src/logger.ts | 3 +- packages/ethereum/src/receipt-utils.ts | 8 +- packages/ethereum/src/receipts.ts | 12 +- packages/ethereum/src/request-utils.ts | 8 + packages/ethereum/src/transaction-preparer.ts | 181 ++++++++++ packages/ethereum/src/transactions.ts | 23 ++ .../test/transaction-preparer-types.test.ts | 43 +++ .../test/transaction-preparer.test.js | 335 ++++++++++++++++++ packages/utils/README.md | 1 + packages/utils/dist/index.d.ts | 2 +- packages/utils/dist/index.js | 2 +- packages/utils/dist/index.js.map | 2 +- packages/utils/dist/validation-utils.d.ts | 3 +- packages/utils/dist/validation-utils.js | 9 +- packages/utils/dist/validation-utils.js.map | 2 +- packages/utils/src/index.ts | 1 + packages/utils/src/validation-utils.ts | 9 + plans/default-transaction-preparer.md | 73 ++++ 38 files changed, 945 insertions(+), 54 deletions(-) create mode 100644 packages/ethereum/dist/transaction-preparer.d.ts create mode 100644 packages/ethereum/dist/transaction-preparer.js create mode 100644 packages/ethereum/dist/transaction-preparer.js.map create mode 100644 packages/ethereum/src/transaction-preparer.ts create mode 100644 packages/ethereum/test/transaction-preparer-types.test.ts create mode 100644 packages/ethereum/test/transaction-preparer.test.js create mode 100644 plans/default-transaction-preparer.md diff --git a/packages/ethereum/README.md b/packages/ethereum/README.md index b8d4449a..10c81a56 100644 --- a/packages/ethereum/README.md +++ b/packages/ethereum/README.md @@ -10,6 +10,7 @@ Ethereum JSON-RPC utilities for Oya kernel code. This package is a hardened kern - `createHttpConfig(options)`: validate explicit HTTP transport settings, re-exported from `@oyaprotocol/utils`. - `requestEthereumJsonRpc(options)`: send one JSON-RPC POST request with explicit config and injected `fetch`, returning the raw `result`, attempt count, id, and parsed response payload. +- `createTransactionPreparer(options)`: configure a reusable EIP-1559 preparer that fetches transaction fields and invokes a host signer, without broadcasting. - `ethSendRawTransaction(options)`: submit a signed raw transaction and return the transaction hash with attempt metadata. Callers may pass `transactionHash` when they already know the hash, allowing the wrapper to verify duplicate-style retry errors with `eth_getTransactionByHash`. - `ethGetTransactionReceipt(options)`: look up a transaction receipt, returning `{ receipt, attemptCount, response }`. The receipt is `null` when unavailable, including pending or unknown transactions. - `ethWaitForTransactionReceipt(options)`: poll for a receipt with an explicit overall deadline, poll interval, and optional cancellation signal. Returns `{ receipt, pollCount, attemptCount, response }` with a non-null receipt. @@ -39,11 +40,51 @@ Hosts own transaction signing, environment configuration, and RPC endpoint disco - `TransactionRequest`: readonly `to`, `data`, `value: bigint` (wei), and optional `signal`. It describes call intent; the host supplies the remaining transaction fields. - `SignedTransaction`: readonly signed `rawTransaction` and its `transactionHash`. +- `UnsignedTransaction`: readonly `to`, `data`, `value`, `type: 2`, `chainId: bigint`, `nonce: number`, `gasLimit: bigint`, `maxFeePerGas: bigint`, and `maxPriorityFeePerGas: bigint`. The access list is empty. There is no embedded cancellation signal. +- `TransactionSigner`: a readonly `address` and `signTransaction(transaction, signal?)` method returning `SignedTransaction`, synchronously or asynchronously. The host implements signing and must preserve all supplied fields, use the advertised account, and return without broadcasting. - `TransactionPreparer`: a callback from `TransactionRequest` to `SignedTransaction`, synchronously or asynchronously, without broadcasting. - `TransactionStage`: `'prepare' | 'submit' | 'receipt' | 'verify'`. Verification means the operation's checks after receiving a receipt, such as execution status and expected events. Logger uses these shared types and always requests `value: 0n`. Other callers can use the same host preparation callback with a nonzero value. These names replace `LoggerTransactionRequest`, `PreparedLoggerTransaction`, `PrepareLoggerTransaction`, and `LogCidStage`; update type imports accordingly. +## Default Transaction Preparation + +`createTransactionPreparer(options)` in `src/transaction-preparer.ts` returns a `TransactionPreparer` compatible with `logCid` and the messages package's `publishAndLogSignedMessage`. The host supplies a `TransactionSigner`; no local wallet adapter, private-key handling, ethers, viem, or new dependency is included. + +```ts +import { createTransactionPreparer, logCid } from '@oyaprotocol/ethereum'; +import type { TransactionSigner } from '@oyaprotocol/ethereum'; + +declare const signer: TransactionSigner; // Implemented by the host's wallet/signing service. +const transactionPreparer = createTransactionPreparer({ + config: rpcConfig, + fetch: rpcFetch, + chainId: 1n, // The operator's expected network. + signer, + gasLimitMarginPercent: 20, // Default: 20% above the estimate, rounded up. + baseFeeMultiplier: 2, // Default: 2 * base fee + suggested priority fee. + limits: { gasLimit: 200_000n, feePerGas: 30_000_000_000n }, // Illustrative operator-chosen caps. + timeoutMs: 30_000, // Default: overall preparation deadline, including signing. + id: 'prepare-42', // Optional; preparation RPCs default to ID 1. +}); + +const logging = await logCid(cid, { + config: rpcConfig, fetch: rpcFetch, loggerContract, + nodeAddress: signer.address, // Direct account call in this example. + transactionPreparer, timeoutMs: 60_000, pollIntervalMs: 1_000, signal, +}); +``` + +Construction validates and snapshots configuration without making RPC calls. Each invocation validates and snapshots the call, checks `eth_chainId` against the configured positive bigint chain ID, reads `eth_getTransactionCount(address, "pending")`, obtains the latest block's base fee and gas limit, and reads `eth_maxPriorityFeePerGas`. It then calls `eth_estimateGas` against pending state with the signing address, recipient, calldata, value, chain ID, nonce, and selected fees. These methods follow the [Ethereum execution API](https://github.com/ethereum/execution-apis/tree/main/src/eth); the fee fields follow [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). + +The gas limit is `ceil(estimate * (100 + gasLimitMarginPercent) / 100)`. The maximum fee per gas is `baseFee * baseFeeMultiplier + suggestedPriorityFee`; the priority fee is the RPC suggestion. The multiplier and margin are policy choices, not protocol requirements. Arithmetic uses bigint, and fee values are in wei per gas. Nonces above `Number.MAX_SAFE_INTEGER` reject before conversion for the signer. Both optional `limits` fields are ceilings: the factory rejects a selected value above a ceiling instead of reducing the gas buffer or fee suggestion. Omitting them adds no operator ceiling; the buffered gas limit must still fit the latest block's gas limit. A configured gas cap must be positive; a fee cap of zero is permitted. Networks without EIP-1559 base-fee data, unsupported RPC methods, malformed quantities, estimation errors, and out-of-range values reject before signing. + +The signer receives a frozen transaction and a separate signal combining caller cancellation with the overall deadline. Each RPC read uses the existing transport timeout/retry policy. The whole preparation has no retries, and the signer is called at most once per invocation. Signer errors propagate; timeout/cancellation stops waiting even when the signer ignores its signal, and late results are discarded. The host should honor the signal where its signing API permits. Aborting cannot undo an external signing request already started. + +The returned result is a frozen snapshot. The factory checks byte formatting, the type-2 prefix, and that the supplied hash equals Keccak-256 of the returned bytes, using the existing `@noble/hashes` dependency. It does not decode the transaction or recover the signing account: the host signer remains responsible for a valid signature, the advertised account, and exact transaction fields. Only ordinary type-2 calls with an empty access list are supported; contract creation, legacy transactions, blobs, and smart-wallet execution wrapping require a custom preparer. A wallet API that only signs and broadcasts together cannot implement this signing contract. + +**The host coordinates nonces across the complete prepare/submit/receipt lifecycle for each account.** Serialize that lifecycle for the initial implementation, including other users of the account, and reconcile uncertain submissions before proceeding. The factory does not reserve, cache, or increment nonces and does not coordinate different processes. It refreshes chain values on every call; preparation alone cannot guarantee unique nonces before submission. Existing submission retries resend retained signed bytes rather than calling the preparer again. The factory's `id` applies to its read RPCs; Logger's optional `id` separately controls submission and receipt requests. + ## Transaction Receipts The host passes the hash returned by `ethSendRawTransaction(...)` to either receipt function, with the same explicit RPC config and injected fetch: @@ -145,7 +186,7 @@ const logging = await logCid(publication.cid, { // logging: { cid, transactionHash, receipt, event } ``` -`transactionPreparer` is a host-supplied `TransactionPreparer` function. It receives a frozen `{ to, data, value: 0n, signal? }` request describing the Logger call and returns `{ rawTransaction, transactionHash }`, synchronously or asynchronously. It must prepare and sign without broadcasting. The host supplies chain ID, nonce, fees, gas, and key or wallet access, and coordinates nonces across concurrent messages. It must return the correct hash for the signed transaction and preserve the requested call, including when routing through a contract wallet. The helper validates the returned hex shapes and checks the RPC's returned hash; it does not parse or independently verify the signed transaction. +`transactionPreparer` is a host-supplied `TransactionPreparer` function, which can be created with `createTransactionPreparer` above. It receives a frozen `{ to, data, value: 0n, signal? }` request describing the Logger call and returns `{ rawTransaction, transactionHash }`, synchronously or asynchronously. It must prepare and sign without broadcasting. The host selects the chain and preparation policy, supplies wallet access, and coordinates nonces across concurrent messages. It must return the correct hash for the signed transaction and preserve the requested call, including when routing through a contract wallet. The Logger helper validates the returned hex shapes and checks the RPC's returned hash; it does not parse or independently verify the signed transaction. The optional `id` accepts a nonempty string or a safe integer, including zero. It uses the existing RPC validation and defaults to `1` when omitted. The same ID is forwarded to submission, retries and recovery lookups, and every receipt poll. Invalid IDs reject before transaction preparation. This identifier is RPC metadata and is separate from the signed transaction's hash. diff --git a/packages/ethereum/dist/index.d.ts b/packages/ethereum/dist/index.d.ts index 3cd608c7..cdfa21f4 100644 --- a/packages/ethereum/dist/index.d.ts +++ b/packages/ethereum/dist/index.d.ts @@ -1,7 +1,9 @@ export { createHttpConfig, HttpStatusError } from '@oyaprotocol/utils'; export type { CreateHttpConfigOptions, HttpConfig, HttpFetchLike, HttpPostFetchLike, HttpPostFetchOptions, HttpStatusErrorOptions, HttpTextResponse, } from '@oyaprotocol/utils'; export { EthereumRawTransactionRecoveryError, ethSendRawTransaction, } from './transactions.js'; -export type { TransactionRequest, SignedTransaction, TransactionPreparer, TransactionStage, EthSendRawTransactionOptions, EthSendRawTransactionResult, } from './transactions.js'; +export type { TransactionRequest, SignedTransaction, UnsignedTransaction, TransactionSigner, TransactionPreparer, TransactionStage, EthSendRawTransactionOptions, EthSendRawTransactionResult, } from './transactions.js'; +export { createTransactionPreparer } from './transaction-preparer.js'; +export type { CreateTransactionPreparerOptions } from './transaction-preparer.js'; export { EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt, } from './receipts.js'; export type { EthGetTransactionReceiptOptions, EthGetTransactionReceiptResult, EthWaitForTransactionReceiptOptions, EthWaitForTransactionReceiptResult, } from './receipts.js'; export type { EthereumReceiptLog, EthereumTransactionReceipt } from './receipt-utils.js'; diff --git a/packages/ethereum/dist/index.js b/packages/ethereum/dist/index.js index 714e6d4e..b6f1b50c 100644 --- a/packages/ethereum/dist/index.js +++ b/packages/ethereum/dist/index.js @@ -1,5 +1,6 @@ export { createHttpConfig, HttpStatusError } from '@oyaprotocol/utils'; export { EthereumRawTransactionRecoveryError, ethSendRawTransaction, } from './transactions.js'; +export { createTransactionPreparer } from './transaction-preparer.js'; export { EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt, } from './receipts.js'; export { encodeLoggerCall, decodeLoggerEvent, hashLoggerCid, logCid, LogCidError } from './logger.js'; export { EthereumJsonRpcError, requestEthereumJsonRpc, } from './request-utils.js'; diff --git a/packages/ethereum/dist/index.js.map b/packages/ethereum/dist/index.js.map index af208883..65470407 100644 --- a/packages/ethereum/dist/index.js.map +++ b/packages/ethereum/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAUvE,OAAO,EACH,mCAAmC,EACnC,qBAAqB,GACxB,MAAM,mBAAmB,CAAC;AAS3B,OAAO,EACH,sCAAsC,EACtC,wBAAwB,EACxB,4BAA4B,GAC/B,MAAM,eAAe,CAAC;AAQvB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAKtG,OAAO,EACH,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,oBAAoB,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAUvE,OAAO,EACH,mCAAmC,EACnC,qBAAqB,GACxB,MAAM,mBAAmB,CAAC;AAW3B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,OAAO,EACH,sCAAsC,EACtC,wBAAwB,EACxB,4BAA4B,GAC/B,MAAM,eAAe,CAAC;AAQvB,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAKtG,OAAO,EACH,oBAAoB,EACpB,sBAAsB,GACzB,MAAM,oBAAoB,CAAC"} \ No newline at end of file diff --git a/packages/ethereum/dist/logger.js b/packages/ethereum/dist/logger.js index 61464c1f..f64a09c6 100644 --- a/packages/ethereum/dist/logger.js +++ b/packages/ethereum/dist/logger.js @@ -1,7 +1,7 @@ import { keccak_256 } from '@noble/hashes/sha3.js'; import { bytesToHex } from '@noble/hashes/utils.js'; -import { assertCanonicalCid, assertHexData, createHttpConfig, invokeWithAbort, isPlainObject, parseBytes, throwIfSignalAborted, } from '@oyaprotocol/utils'; -import { assertTimerMs, ethWaitForTransactionReceipt } from './receipts.js'; +import { assertCanonicalCid, assertHexData, assertTimerMs, createHttpConfig, invokeWithAbort, isPlainObject, parseBytes, throwIfSignalAborted, } from '@oyaprotocol/utils'; +import { ethWaitForTransactionReceipt } from './receipts.js'; import { normalizeJsonRpcId } from './request-utils.js'; import { ethSendRawTransaction } from './transactions.js'; // Verified against contracts/src/Logger.sol with forge inspect and cast keccak. diff --git a/packages/ethereum/dist/logger.js.map b/packages/ethereum/dist/logger.js.map index 4ae0172e..4e4a0104 100644 --- a/packages/ethereum/dist/logger.js.map +++ b/packages/ethereum/dist/logger.js.map @@ -1 +1 @@ -{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/receipt-utils.js b/packages/ethereum/dist/receipt-utils.js index ba565571..fb8c216f 100644 --- a/packages/ethereum/dist/receipt-utils.js +++ b/packages/ethereum/dist/receipt-utils.js @@ -1,10 +1,5 @@ import { isPlainObject, parseBytes } from '@oyaprotocol/utils'; -function parseQuantity(value, name) { - if (typeof value !== 'string' || !/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/.test(value)) { - throw new Error(`${name} must be an Ethereum quantity hex string without leading zeros.`); - } - return BigInt(value); -} +import { parseQuantity } from './request-utils.js'; function assertMatchingHash(actual, expected, name) { if (actual.toLowerCase() !== expected.toLowerCase()) { throw new Error(`${name} did not match the expected hash.`); diff --git a/packages/ethereum/dist/receipt-utils.js.map b/packages/ethereum/dist/receipt-utils.js.map index db63e5fa..5b651a60 100644 --- a/packages/ethereum/dist/receipt-utils.js.map +++ b/packages/ethereum/dist/receipt-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"receipt-utils.js","sourceRoot":"","sources":["../src/receipt-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"receipt-utils.js","sourceRoot":"","sources":["../src/receipt-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/receipts.d.ts b/packages/ethereum/dist/receipts.d.ts index e9ffa3c9..a0136e7f 100644 --- a/packages/ethereum/dist/receipts.d.ts +++ b/packages/ethereum/dist/receipts.d.ts @@ -30,8 +30,7 @@ declare class EthereumTransactionReceiptTimeoutError extends Error { readonly pollCount: number; constructor(transactionHash: string, timeoutMs: number, pollCount: number, options?: ErrorOptions); } -declare function assertTimerMs(value: unknown, name: string): number; declare function ethGetTransactionReceipt({ config, fetch, transactionHash, id, signal, }: EthGetTransactionReceiptOptions): Promise; declare function ethWaitForTransactionReceipt({ config, fetch, transactionHash, id, signal, timeoutMs, pollIntervalMs, }: EthWaitForTransactionReceiptOptions): Promise; -export { assertTimerMs, EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt }; +export { EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt }; export type { EthGetTransactionReceiptOptions, EthGetTransactionReceiptResult, EthWaitForTransactionReceiptOptions, EthWaitForTransactionReceiptResult, }; diff --git a/packages/ethereum/dist/receipts.js b/packages/ethereum/dist/receipts.js index bc7e21ca..3a8fd7bd 100644 --- a/packages/ethereum/dist/receipts.js +++ b/packages/ethereum/dist/receipts.js @@ -1,4 +1,4 @@ -import { assertBytes32HexString, assertPositiveInteger, combineAbortSignals, createTimeoutSignal, throwIfSignalAborted, waitForRetryDelay, } from '@oyaprotocol/utils'; +import { assertBytes32HexString, assertTimerMs, combineAbortSignals, createTimeoutSignal, throwIfSignalAborted, waitForRetryDelay, } from '@oyaprotocol/utils'; import { parseTransactionReceipt } from './receipt-utils.js'; import { requestEthereumJsonRpc } from './request-utils.js'; class EthereumTransactionReceiptTimeoutError extends Error { @@ -13,13 +13,6 @@ class EthereumTransactionReceiptTimeoutError extends Error { this.pollCount = pollCount; } } -function assertTimerMs(value, name) { - const duration = assertPositiveInteger(value, name); - if (duration > 2_147_483_647) { - throw new Error(`${name} must not exceed 2147483647 ms.`); - } - return duration; -} async function ethGetTransactionReceipt({ config, fetch, transactionHash, id, signal, }) { const validatedHash = assertBytes32HexString(transactionHash, 'transactionHash'); const result = await requestEthereumJsonRpc({ @@ -83,5 +76,5 @@ async function ethWaitForTransactionReceipt({ config, fetch, transactionHash, id timeout.cleanup?.(); } } -export { assertTimerMs, EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt }; +export { EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt }; //# sourceMappingURL=receipts.js.map \ No newline at end of file diff --git a/packages/ethereum/dist/receipts.js.map b/packages/ethereum/dist/receipts.js.map index a0fc4ce3..966b0e95 100644 --- a/packages/ethereum/dist/receipts.js.map +++ b/packages/ethereum/dist/receipts.js.map @@ -1 +1 @@ -{"version":3,"file":"receipts.js","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"receipts.js","sourceRoot":"","sources":["../src/receipts.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/request-utils.d.ts b/packages/ethereum/dist/request-utils.d.ts index 3b5195ee..e2885f39 100644 --- a/packages/ethereum/dist/request-utils.d.ts +++ b/packages/ethereum/dist/request-utils.d.ts @@ -32,6 +32,7 @@ declare class EthereumJsonRpcError extends Error { constructor(error: JsonRpcErrorPayload, { method, response, attemptCount }: EthereumJsonRpcErrorOptions); } declare function normalizeJsonRpcId(id: unknown): string | number; +declare function parseQuantity(value: unknown, name: string): bigint; declare function requestEthereumJsonRpcWithCustomRetryPolicy({ config, fetch, method, params, id, signal, }: RequestEthereumJsonRpcOptions, shouldRetryJsonRpcMethod: (method: string) => boolean): Promise>; declare function requestEthereumJsonRpc(options: RequestEthereumJsonRpcOptions): Promise>; -export { EthereumJsonRpcError, normalizeJsonRpcId, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; +export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; diff --git a/packages/ethereum/dist/request-utils.js b/packages/ethereum/dist/request-utils.js index 1bcc652a..096d1065 100644 --- a/packages/ethereum/dist/request-utils.js +++ b/packages/ethereum/dist/request-utils.js @@ -102,6 +102,12 @@ function normalizeJsonRpcId(id) { } throw new Error('id must be a non-empty string or safe integer.'); } +function parseQuantity(value, name) { + if (typeof value !== 'string' || !/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/.test(value)) { + throw new Error(`${name} must be an Ethereum quantity hex string without leading zeros.`); + } + return BigInt(value); +} function buildJsonRpcBody({ id, method, params, }) { try { return JSON.stringify({ @@ -223,5 +229,5 @@ async function requestEthereumJsonRpcWithCustomRetryPolicy({ config, fetch, meth async function requestEthereumJsonRpc(options) { return await requestEthereumJsonRpcWithCustomRetryPolicy(options, shouldRetryMethod); } -export { EthereumJsonRpcError, normalizeJsonRpcId, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; +export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; //# sourceMappingURL=request-utils.js.map \ No newline at end of file diff --git a/packages/ethereum/dist/request-utils.js.map b/packages/ethereum/dist/request-utils.js.map index e6c38ac7..85706f92 100644 --- a/packages/ethereum/dist/request-utils.js.map +++ b/packages/ethereum/dist/request-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"request-utils.js","sourceRoot":"","sources":["../src/request-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"request-utils.js","sourceRoot":"","sources":["../src/request-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/transaction-preparer.d.ts b/packages/ethereum/dist/transaction-preparer.d.ts new file mode 100644 index 00000000..cdc2fe1e --- /dev/null +++ b/packages/ethereum/dist/transaction-preparer.d.ts @@ -0,0 +1,25 @@ +import type { HttpConfig, HttpPostFetchLike } from '@oyaprotocol/utils'; +import type { TransactionPreparer, TransactionSigner } from './transactions.js'; +interface CreateTransactionPreparerOptions { + config: HttpConfig; + fetch: HttpPostFetchLike; + chainId: bigint; + signer: TransactionSigner; + /** Whole percent added to the estimate, rounded up. Default: 20. */ + gasLimitMarginPercent?: number; + /** Integer multiplier for the latest base fee. Default: 2. */ + baseFeeMultiplier?: number; + /** Exceeding either optional ceiling rejects before signing. */ + limits?: { + gasLimit?: bigint; + feePerGas?: bigint; + }; + /** Overall preparation deadline, including signing. Default: 30,000 ms. */ + timeoutMs?: number; + /** JSON-RPC ID for preparation reads. Default: 1. */ + id?: string | number; +} +/** Prepare direct account calls; the host coordinates nonces through submission. */ +declare function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMarginPercent, baseFeeMultiplier, limits, timeoutMs, id, }: CreateTransactionPreparerOptions): TransactionPreparer; +export { createTransactionPreparer }; +export type { CreateTransactionPreparerOptions }; diff --git a/packages/ethereum/dist/transaction-preparer.js b/packages/ethereum/dist/transaction-preparer.js new file mode 100644 index 00000000..211e9947 --- /dev/null +++ b/packages/ethereum/dist/transaction-preparer.js @@ -0,0 +1,138 @@ +import { keccak_256 } from '@noble/hashes/sha3.js'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'; +import { assertTimerMs, createHttpConfig, isPlainObject, parseBytes, runWithRetry, throwIfSignalAborted, } from '@oyaprotocol/utils'; +import { normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc } from './request-utils.js'; +const UINT256_MAX = (1n << 256n) - 1n; +function assertUint256(value, name) { + if (typeof value !== 'bigint' || value < 0n || value > UINT256_MAX) { + throw new Error(`${name} must be a non-negative bigint fitting in 256 bits.`); + } + return value; +} +function parseTransactionQuantity(value, name) { + if (typeof value === 'string' && value.length > 66) { + throw new Error(`${name} must fit in 256 bits.`); + } + return parseQuantity(value, name); +} +/** Prepare direct account calls; the host coordinates nonces through submission. */ +function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMarginPercent = 20, baseFeeMultiplier = 2, limits, timeoutMs = 30_000, id, }) { + const rpcConfig = createHttpConfig(config); + assertTimerMs(rpcConfig.timeoutMs, 'config.timeoutMs'); + const deadlineMs = assertTimerMs(timeoutMs, 'timeoutMs'); + const expectedChainId = assertUint256(chainId, 'chainId'); + if (expectedChainId === 0n) { + throw new Error('chainId must be positive.'); + } + const requestId = normalizeJsonRpcId(id); + if (typeof fetch !== 'function') { + throw new TypeError('fetch must be provided as a function.'); + } + if (signer == null || typeof signer.signTransaction !== 'function') { + throw new TypeError('signer.signTransaction must be provided as a function.'); + } + const signerAddress = parseBytes(signer.address, 'signer.address', 20); + const signTransaction = signer.signTransaction.bind(signer); + if (!Number.isSafeInteger(gasLimitMarginPercent) || gasLimitMarginPercent < 0) { + throw new Error('gasLimitMarginPercent must be a non-negative safe integer.'); + } + if (!Number.isSafeInteger(baseFeeMultiplier) || baseFeeMultiplier < 1) { + throw new Error('baseFeeMultiplier must be a positive safe integer.'); + } + if (limits !== undefined && !isPlainObject(limits)) { + throw new TypeError('limits must be a plain object.'); + } + const gasLimitCap = limits?.gasLimit === undefined + ? undefined : assertUint256(limits.gasLimit, 'limits.gasLimit'); + const feePerGasCap = limits?.feePerGas === undefined + ? undefined : assertUint256(limits.feePerGas, 'limits.feePerGas'); + if (gasLimitCap === 0n) { + throw new Error('limits.gasLimit must be positive.'); + } + return async ({ to, data, value, signal }) => { + const call = { + to: parseBytes(to, 'to', 20), + data: parseBytes(data, 'data'), + value: assertUint256(value, 'value'), + }; + const abortMessage = 'Transaction preparation was aborted by the caller.'; + return await runWithRetry({ + maxRetries: 0, retryDelayMs: 0, timeoutMs: deadlineMs, signal, + abortErrorMessage: abortMessage, + shouldRetry: () => false, + normalizeError: (error) => error instanceof Error + ? error : new Error('Transaction preparation failed.', { cause: error }), + run: async ({ signal: operationSignal }) => { + const rpc = async (method, params = []) => { + const response = await requestEthereumJsonRpc({ + config: rpcConfig, fetch, method, params, id: requestId, + ...(operationSignal === undefined ? {} : { signal: operationSignal }), + }); + return response.result; + }; + const actualChainId = parseTransactionQuantity(await rpc('eth_chainId'), 'eth_chainId result'); + if (actualChainId !== expectedChainId) { + throw new Error(`RPC chain ID ${actualChainId} did not match configured chainId ${expectedChainId}.`); + } + const nonce = parseTransactionQuantity(await rpc('eth_getTransactionCount', [signerAddress, 'pending']), 'eth_getTransactionCount result'); + if (nonce > BigInt(Number.MAX_SAFE_INTEGER)) { + throw new Error('Transaction nonce must fit in a safe integer.'); + } + const block = await rpc('eth_getBlockByNumber', ['latest', false]); + if (!isPlainObject(block) || block.baseFeePerGas === undefined || block.baseFeePerGas === null) { + throw new Error('Latest block must include baseFeePerGas for EIP-1559 transaction preparation.'); + } + const baseFee = parseTransactionQuantity(block.baseFeePerGas, 'block.baseFeePerGas'); + const blockGasLimit = parseTransactionQuantity(block.gasLimit, 'block.gasLimit'); + if (blockGasLimit === 0n) { + throw new Error('block.gasLimit must be positive.'); + } + const maxPriorityFeePerGas = parseTransactionQuantity(await rpc('eth_maxPriorityFeePerGas'), 'eth_maxPriorityFeePerGas result'); + const maxFeePerGas = assertUint256(baseFee * BigInt(baseFeeMultiplier) + maxPriorityFeePerGas, 'maxFeePerGas'); + if (feePerGasCap !== undefined && maxFeePerGas > feePerGasCap) { + throw new Error('Calculated maxFeePerGas exceeds limits.feePerGas.'); + } + const estimate = parseTransactionQuantity(await rpc('eth_estimateGas', [{ + from: signerAddress, to: call.to, data: call.data, + value: `0x${call.value.toString(16)}`, + type: '0x2', chainId: `0x${expectedChainId.toString(16)}`, + nonce: `0x${nonce.toString(16)}`, + maxFeePerGas: `0x${maxFeePerGas.toString(16)}`, + maxPriorityFeePerGas: `0x${maxPriorityFeePerGas.toString(16)}`, + }, 'pending']), 'eth_estimateGas result'); + if (estimate === 0n) { + throw new Error('eth_estimateGas result must be positive.'); + } + const gasLimit = (estimate * (100n + BigInt(gasLimitMarginPercent)) + 99n) / 100n; + if (gasLimit > blockGasLimit) { + throw new Error('Buffered gas limit exceeds the latest block gas limit.'); + } + if (gasLimitCap !== undefined && gasLimit > gasLimitCap) { + throw new Error('Buffered gas limit exceeds limits.gasLimit.'); + } + const transaction = Object.freeze({ + ...call, type: 2, chainId: expectedChainId, nonce: Number(nonce), + gasLimit, maxFeePerGas, maxPriorityFeePerGas, + }); + throwIfSignalAborted(operationSignal, abortMessage, operationSignal?.reason); + const signed = await signTransaction(transaction, operationSignal); + throwIfSignalAborted(operationSignal, abortMessage, operationSignal?.reason); + if (!isPlainObject(signed)) { + throw new TypeError('signer.signTransaction must return a plain object.'); + } + const rawTransaction = parseBytes(signed.rawTransaction, 'rawTransaction'); + const transactionHash = parseBytes(signed.transactionHash, 'transactionHash', 32); + if (!rawTransaction.startsWith('0x02') || rawTransaction.length <= 4) { + throw new Error('rawTransaction must contain a signed EIP-1559 type-2 transaction.'); + } + const computedHash = `0x${bytesToHex(keccak_256(hexToBytes(rawTransaction.slice(2))))}`; + if (computedHash !== transactionHash.toLowerCase()) { + throw new Error('transactionHash did not match the signed rawTransaction bytes.'); + } + return Object.freeze({ rawTransaction, transactionHash }); + }, + }); + }; +} +export { createTransactionPreparer }; +//# sourceMappingURL=transaction-preparer.js.map \ No newline at end of file diff --git a/packages/ethereum/dist/transaction-preparer.js.map b/packages/ethereum/dist/transaction-preparer.js.map new file mode 100644 index 00000000..999498dc --- /dev/null +++ b/packages/ethereum/dist/transaction-preparer.js.map @@ -0,0 +1 @@ +{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/transactions.d.ts b/packages/ethereum/dist/transactions.d.ts index 902776db..54096a67 100644 --- a/packages/ethereum/dist/transactions.d.ts +++ b/packages/ethereum/dist/transactions.d.ts @@ -12,6 +12,22 @@ interface SignedTransaction { readonly rawTransaction: string; readonly transactionHash: string; } +/** Fully specified EIP-1559 call with an empty access list. */ +interface UnsignedTransaction extends Omit { + readonly type: 2; + readonly chainId: bigint; + /** Nonces outside the safe integer range are rejected before signing. */ + readonly nonce: number; + readonly gasLimit: bigint; + readonly maxFeePerGas: bigint; + readonly maxPriorityFeePerGas: bigint; +} +interface TransactionSigner { + /** Account signing the outer Ethereum transaction. */ + readonly address: string; + /** Preserve all supplied fields and sign without broadcasting. */ + signTransaction(transaction: Readonly, signal?: AbortSignal): SignedTransaction | PromiseLike; +} /** Prepare and sign the requested call without broadcasting it. */ type TransactionPreparer = (request: TransactionRequest) => SignedTransaction | PromiseLike; /** Verify covers operation-specific checks after receipt observation. */ @@ -45,4 +61,4 @@ declare class EthereumRawTransactionRecoveryError extends Error { } declare function ethSendRawTransaction({ config, fetch, rawTransaction, transactionHash, id, signal, }: EthSendRawTransactionOptions): Promise; export { EthereumRawTransactionRecoveryError, ethSendRawTransaction, }; -export type { TransactionRequest, SignedTransaction, TransactionPreparer, TransactionStage, EthSendRawTransactionOptions, EthSendRawTransactionResult, }; +export type { TransactionRequest, SignedTransaction, UnsignedTransaction, TransactionSigner, TransactionPreparer, TransactionStage, EthSendRawTransactionOptions, EthSendRawTransactionResult, }; diff --git a/packages/ethereum/dist/transactions.js.map b/packages/ethereum/dist/transactions.js.map index 78a22655..b15c60f3 100644 --- a/packages/ethereum/dist/transactions.js.map +++ b/packages/ethereum/dist/transactions.js.map @@ -1 +1 @@ -{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/src/index.ts b/packages/ethereum/src/index.ts index d84caa8d..3316d0da 100644 --- a/packages/ethereum/src/index.ts +++ b/packages/ethereum/src/index.ts @@ -15,11 +15,15 @@ export { export type { TransactionRequest, SignedTransaction, + UnsignedTransaction, + TransactionSigner, TransactionPreparer, TransactionStage, EthSendRawTransactionOptions, EthSendRawTransactionResult, } from './transactions.js'; +export { createTransactionPreparer } from './transaction-preparer.js'; +export type { CreateTransactionPreparerOptions } from './transaction-preparer.js'; export { EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, diff --git a/packages/ethereum/src/logger.ts b/packages/ethereum/src/logger.ts index eaa8a2de..3b90631b 100644 --- a/packages/ethereum/src/logger.ts +++ b/packages/ethereum/src/logger.ts @@ -3,6 +3,7 @@ import { bytesToHex } from '@noble/hashes/utils.js'; import { assertCanonicalCid, assertHexData, + assertTimerMs, createHttpConfig, invokeWithAbort, isPlainObject, @@ -11,7 +12,7 @@ import { } from '@oyaprotocol/utils'; import type { EthereumReceiptLog, EthereumTransactionReceipt } from './receipt-utils.js'; -import { assertTimerMs, ethWaitForTransactionReceipt } from './receipts.js'; +import { ethWaitForTransactionReceipt } from './receipts.js'; import type { EthWaitForTransactionReceiptOptions } from './receipts.js'; import { normalizeJsonRpcId } from './request-utils.js'; import { ethSendRawTransaction } from './transactions.js'; diff --git a/packages/ethereum/src/receipt-utils.ts b/packages/ethereum/src/receipt-utils.ts index 3c5b8df9..8ce19bc5 100644 --- a/packages/ethereum/src/receipt-utils.ts +++ b/packages/ethereum/src/receipt-utils.ts @@ -1,4 +1,5 @@ import { isPlainObject, parseBytes } from '@oyaprotocol/utils'; +import { parseQuantity } from './request-utils.js'; interface EthereumReceiptLog { readonly address: string; @@ -34,13 +35,6 @@ interface EthereumTransactionReceipt { readonly blobGasPrice?: bigint; } -function parseQuantity(value: unknown, name: string): bigint { - if (typeof value !== 'string' || !/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/.test(value)) { - throw new Error(`${name} must be an Ethereum quantity hex string without leading zeros.`); - } - return BigInt(value); -} - function assertMatchingHash(actual: string, expected: string, name: string): void { if (actual.toLowerCase() !== expected.toLowerCase()) { throw new Error(`${name} did not match the expected hash.`); diff --git a/packages/ethereum/src/receipts.ts b/packages/ethereum/src/receipts.ts index dc6bb4d3..a4c08c8e 100644 --- a/packages/ethereum/src/receipts.ts +++ b/packages/ethereum/src/receipts.ts @@ -1,6 +1,6 @@ import { assertBytes32HexString, - assertPositiveInteger, + assertTimerMs, combineAbortSignals, createTimeoutSignal, throwIfSignalAborted, @@ -54,14 +54,6 @@ class EthereumTransactionReceiptTimeoutError extends Error { } } -function assertTimerMs(value: unknown, name: string): number { - const duration = assertPositiveInteger(value, name); - if (duration > 2_147_483_647) { - throw new Error(`${name} must not exceed 2147483647 ms.`); - } - return duration; -} - async function ethGetTransactionReceipt({ config, fetch, @@ -139,7 +131,7 @@ async function ethWaitForTransactionReceipt({ } } -export { assertTimerMs, EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt }; +export { EthereumTransactionReceiptTimeoutError, ethGetTransactionReceipt, ethWaitForTransactionReceipt }; export type { EthGetTransactionReceiptOptions, EthGetTransactionReceiptResult, diff --git a/packages/ethereum/src/request-utils.ts b/packages/ethereum/src/request-utils.ts index f4327b39..d6fee67b 100644 --- a/packages/ethereum/src/request-utils.ts +++ b/packages/ethereum/src/request-utils.ts @@ -150,6 +150,13 @@ function normalizeJsonRpcId(id: unknown): string | number { throw new Error('id must be a non-empty string or safe integer.'); } +function parseQuantity(value: unknown, name: string): bigint { + if (typeof value !== 'string' || !/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/.test(value)) { + throw new Error(`${name} must be an Ethereum quantity hex string without leading zeros.`); + } + return BigInt(value); +} + function buildJsonRpcBody({ id, method, @@ -316,6 +323,7 @@ async function requestEthereumJsonRpc( export { EthereumJsonRpcError, normalizeJsonRpcId, + parseQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; diff --git a/packages/ethereum/src/transaction-preparer.ts b/packages/ethereum/src/transaction-preparer.ts new file mode 100644 index 00000000..1f9c4606 --- /dev/null +++ b/packages/ethereum/src/transaction-preparer.ts @@ -0,0 +1,181 @@ +import { keccak_256 } from '@noble/hashes/sha3.js'; +import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'; +import { + assertTimerMs, + createHttpConfig, + isPlainObject, + parseBytes, + runWithRetry, + throwIfSignalAborted, +} from '@oyaprotocol/utils'; +import type { HttpConfig, HttpPostFetchLike } from '@oyaprotocol/utils'; + +import { normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc } from './request-utils.js'; +import type { SignedTransaction, TransactionPreparer, TransactionSigner, UnsignedTransaction } from './transactions.js'; + +interface CreateTransactionPreparerOptions { + config: HttpConfig; + fetch: HttpPostFetchLike; + chainId: bigint; + signer: TransactionSigner; + /** Whole percent added to the estimate, rounded up. Default: 20. */ + gasLimitMarginPercent?: number; + /** Integer multiplier for the latest base fee. Default: 2. */ + baseFeeMultiplier?: number; + /** Exceeding either optional ceiling rejects before signing. */ + limits?: { gasLimit?: bigint; feePerGas?: bigint }; + /** Overall preparation deadline, including signing. Default: 30,000 ms. */ + timeoutMs?: number; + /** JSON-RPC ID for preparation reads. Default: 1. */ + id?: string | number; +} + +const UINT256_MAX = (1n << 256n) - 1n; + +function assertUint256(value: unknown, name: string): bigint { + if (typeof value !== 'bigint' || value < 0n || value > UINT256_MAX) { + throw new Error(`${name} must be a non-negative bigint fitting in 256 bits.`); + } + return value; +} + +function parseTransactionQuantity(value: unknown, name: string): bigint { + if (typeof value === 'string' && value.length > 66) { + throw new Error(`${name} must fit in 256 bits.`); + } + return parseQuantity(value, name); +} + +/** Prepare direct account calls; the host coordinates nonces through submission. */ +function createTransactionPreparer({ + config, fetch, chainId, signer, gasLimitMarginPercent = 20, + baseFeeMultiplier = 2, limits, timeoutMs = 30_000, id, +}: CreateTransactionPreparerOptions): TransactionPreparer { + const rpcConfig = createHttpConfig(config); + assertTimerMs(rpcConfig.timeoutMs, 'config.timeoutMs'); + const deadlineMs = assertTimerMs(timeoutMs, 'timeoutMs'); + const expectedChainId = assertUint256(chainId, 'chainId'); + if (expectedChainId === 0n) { + throw new Error('chainId must be positive.'); + } + const requestId = normalizeJsonRpcId(id); + if (typeof fetch !== 'function') { + throw new TypeError('fetch must be provided as a function.'); + } + if (signer == null || typeof signer.signTransaction !== 'function') { + throw new TypeError('signer.signTransaction must be provided as a function.'); + } + const signerAddress = parseBytes(signer.address, 'signer.address', 20); + const signTransaction = signer.signTransaction.bind(signer); + if (!Number.isSafeInteger(gasLimitMarginPercent) || gasLimitMarginPercent < 0) { + throw new Error('gasLimitMarginPercent must be a non-negative safe integer.'); + } + if (!Number.isSafeInteger(baseFeeMultiplier) || baseFeeMultiplier < 1) { + throw new Error('baseFeeMultiplier must be a positive safe integer.'); + } + if (limits !== undefined && !isPlainObject(limits)) { + throw new TypeError('limits must be a plain object.'); + } + const gasLimitCap = limits?.gasLimit === undefined + ? undefined : assertUint256(limits.gasLimit, 'limits.gasLimit'); + const feePerGasCap = limits?.feePerGas === undefined + ? undefined : assertUint256(limits.feePerGas, 'limits.feePerGas'); + if (gasLimitCap === 0n) { + throw new Error('limits.gasLimit must be positive.'); + } + + return async ({ to, data, value, signal }) => { + const call = { + to: parseBytes(to, 'to', 20), + data: parseBytes(data, 'data'), + value: assertUint256(value, 'value'), + }; + const abortMessage = 'Transaction preparation was aborted by the caller.'; + return await runWithRetry({ + maxRetries: 0, retryDelayMs: 0, timeoutMs: deadlineMs, signal, + abortErrorMessage: abortMessage, + shouldRetry: () => false, + normalizeError: (error) => error instanceof Error + ? error : new Error('Transaction preparation failed.', { cause: error }), + run: async ({ signal: operationSignal }) => { + const rpc = async (method: string, params: readonly unknown[] = []): Promise => { + const response = await requestEthereumJsonRpc({ + config: rpcConfig, fetch, method, params, id: requestId, + ...(operationSignal === undefined ? {} : { signal: operationSignal }), + }); + return response.result; + }; + const actualChainId = parseTransactionQuantity(await rpc('eth_chainId'), 'eth_chainId result'); + if (actualChainId !== expectedChainId) { + throw new Error(`RPC chain ID ${actualChainId} did not match configured chainId ${expectedChainId}.`); + } + const nonce = parseTransactionQuantity( + await rpc('eth_getTransactionCount', [signerAddress, 'pending']), + 'eth_getTransactionCount result', + ); + if (nonce > BigInt(Number.MAX_SAFE_INTEGER)) { + throw new Error('Transaction nonce must fit in a safe integer.'); + } + const block = await rpc('eth_getBlockByNumber', ['latest', false]); + if (!isPlainObject(block) || block.baseFeePerGas === undefined || block.baseFeePerGas === null) { + throw new Error('Latest block must include baseFeePerGas for EIP-1559 transaction preparation.'); + } + const baseFee = parseTransactionQuantity(block.baseFeePerGas, 'block.baseFeePerGas'); + const blockGasLimit = parseTransactionQuantity(block.gasLimit, 'block.gasLimit'); + if (blockGasLimit === 0n) { + throw new Error('block.gasLimit must be positive.'); + } + const maxPriorityFeePerGas = parseTransactionQuantity( + await rpc('eth_maxPriorityFeePerGas'), 'eth_maxPriorityFeePerGas result', + ); + const maxFeePerGas = assertUint256( + baseFee * BigInt(baseFeeMultiplier) + maxPriorityFeePerGas, 'maxFeePerGas', + ); + if (feePerGasCap !== undefined && maxFeePerGas > feePerGasCap) { + throw new Error('Calculated maxFeePerGas exceeds limits.feePerGas.'); + } + const estimate = parseTransactionQuantity(await rpc('eth_estimateGas', [{ + from: signerAddress, to: call.to, data: call.data, + value: `0x${call.value.toString(16)}`, + type: '0x2', chainId: `0x${expectedChainId.toString(16)}`, + nonce: `0x${nonce.toString(16)}`, + maxFeePerGas: `0x${maxFeePerGas.toString(16)}`, + maxPriorityFeePerGas: `0x${maxPriorityFeePerGas.toString(16)}`, + }, 'pending']), 'eth_estimateGas result'); + if (estimate === 0n) { + throw new Error('eth_estimateGas result must be positive.'); + } + const gasLimit = (estimate * (100n + BigInt(gasLimitMarginPercent)) + 99n) / 100n; + if (gasLimit > blockGasLimit) { + throw new Error('Buffered gas limit exceeds the latest block gas limit.'); + } + if (gasLimitCap !== undefined && gasLimit > gasLimitCap) { + throw new Error('Buffered gas limit exceeds limits.gasLimit.'); + } + const transaction: Readonly = Object.freeze({ + ...call, type: 2, chainId: expectedChainId, nonce: Number(nonce), + gasLimit, maxFeePerGas, maxPriorityFeePerGas, + }); + throwIfSignalAborted(operationSignal, abortMessage, operationSignal?.reason); + const signed = await signTransaction(transaction, operationSignal); + throwIfSignalAborted(operationSignal, abortMessage, operationSignal?.reason); + if (!isPlainObject(signed)) { + throw new TypeError('signer.signTransaction must return a plain object.'); + } + const rawTransaction = parseBytes(signed.rawTransaction, 'rawTransaction'); + const transactionHash = parseBytes(signed.transactionHash, 'transactionHash', 32); + if (!rawTransaction.startsWith('0x02') || rawTransaction.length <= 4) { + throw new Error('rawTransaction must contain a signed EIP-1559 type-2 transaction.'); + } + const computedHash = `0x${bytesToHex(keccak_256(hexToBytes(rawTransaction.slice(2))))}`; + if (computedHash !== transactionHash.toLowerCase()) { + throw new Error('transactionHash did not match the signed rawTransaction bytes.'); + } + return Object.freeze({ rawTransaction, transactionHash }); + }, + }); + }; +} + +export { createTransactionPreparer }; +export type { CreateTransactionPreparerOptions }; diff --git a/packages/ethereum/src/transactions.ts b/packages/ethereum/src/transactions.ts index b74932b7..b77e5130 100644 --- a/packages/ethereum/src/transactions.ts +++ b/packages/ethereum/src/transactions.ts @@ -35,6 +35,27 @@ interface SignedTransaction { readonly transactionHash: string; } +/** Fully specified EIP-1559 call with an empty access list. */ +interface UnsignedTransaction extends Omit { + readonly type: 2; + readonly chainId: bigint; + /** Nonces outside the safe integer range are rejected before signing. */ + readonly nonce: number; + readonly gasLimit: bigint; + readonly maxFeePerGas: bigint; + readonly maxPriorityFeePerGas: bigint; +} + +interface TransactionSigner { + /** Account signing the outer Ethereum transaction. */ + readonly address: string; + /** Preserve all supplied fields and sign without broadcasting. */ + signTransaction( + transaction: Readonly, + signal?: AbortSignal, + ): SignedTransaction | PromiseLike; +} + /** Prepare and sign the requested call without broadcasting it. */ type TransactionPreparer = ( request: TransactionRequest @@ -277,6 +298,8 @@ export { export type { TransactionRequest, SignedTransaction, + UnsignedTransaction, + TransactionSigner, TransactionPreparer, TransactionStage, EthSendRawTransactionOptions, diff --git a/packages/ethereum/test/transaction-preparer-types.test.ts b/packages/ethereum/test/transaction-preparer-types.test.ts new file mode 100644 index 00000000..961efd80 --- /dev/null +++ b/packages/ethereum/test/transaction-preparer-types.test.ts @@ -0,0 +1,43 @@ +import { createTransactionPreparer, logCid } from '@oyaprotocol/ethereum'; +import type { + CreateTransactionPreparerOptions, SignedTransaction, TransactionPreparer, + TransactionRequest, TransactionSigner, UnsignedTransaction, LogCidOptions, +} from '@oyaprotocol/ethereum'; + +declare const options: CreateTransactionPreparerOptions; +declare const signed: SignedTransaction; +declare const request: TransactionRequest; +declare const loggerOptions: LogCidOptions; + +const signer: TransactionSigner = { + address: '0x1111111111111111111111111111111111111111', + signTransaction(transaction, signal) { + const fields: readonly [2, bigint, number, bigint, bigint, bigint] = [ + transaction.type, transaction.chainId, transaction.nonce, transaction.gasLimit, + transaction.maxFeePerGas, transaction.maxPriorityFeePerGas, + ]; + const cancellation: AbortSignal | undefined = signal; + // @ts-expect-error Signing must preserve the supplied fields. + transaction.to = '0x'; + // @ts-expect-error Cancellation is passed separately from transaction fields. + transaction.signal; + void [fields, cancellation]; + return signed; + }, +}; +const asynchronousSigner: TransactionSigner = { ...signer, signTransaction: async () => signed }; +const preparer: TransactionPreparer = createTransactionPreparer({ + ...options, signer, chainId: 1n, gasLimitMarginPercent: 20, baseFeeMultiplier: 2, + limits: { gasLimit: 100_000n, feePerGas: 30_000_000_000n }, timeoutMs: 30_000, id: 'prepare', +}); +const result: SignedTransaction = await preparer(request); +const logging = logCid('cid', { ...loggerOptions, transactionPreparer: preparer }); +declare const transaction: UnsignedTransaction; +const call: Omit = transaction; +// @ts-expect-error Chain IDs use bigint to preserve precision. +createTransactionPreparer({ ...options, chainId: 1 }); +// @ts-expect-error A signing adapter must provide its address and signing method. +createTransactionPreparer({ ...options, signer: { address: signer.address } }); +// @ts-expect-error Fee limits are denominated in integer wei. +createTransactionPreparer({ ...options, limits: { feePerGas: 10 } }); +void [asynchronousSigner, result, logging, call]; diff --git a/packages/ethereum/test/transaction-preparer.test.js b/packages/ethereum/test/transaction-preparer.test.js new file mode 100644 index 00000000..6df3230c --- /dev/null +++ b/packages/ethereum/test/transaction-preparer.test.js @@ -0,0 +1,335 @@ +import assert from 'node:assert/strict'; +import { setImmediate as nextTurn } from 'node:timers/promises'; +import test from 'node:test'; + +import { createHttpConfig, createTransactionPreparer, EthereumJsonRpcError, logCid } from '@oyaprotocol/ethereum'; +import { sample, loggerContract, node, createReceipt, response } from './fixtures/logger-transaction.js'; + +// Opaque test bytes, not a real signature. Hash independently checked with cast keccak 0x02abcd. +const rawTransaction = '0x02abcd'; +const transactionHash = '0xe3607eedbe2ea88ad1994e3ef901f3c7ed167a59ebb5ffe5e40321e468f49eb1'; +const signed = { rawTransaction, transactionHash }; +const request = { to: loggerContract, data: '0x1234', value: 7n }; + +function fixture(overrides = {}) { + const calls = []; + const signatures = []; + const results = { + eth_chainId: '0x1', + eth_getTransactionCount: '0x3', + eth_getBlockByNumber: { baseFeePerGas: '0x64', gasLimit: '0x1c9c380' }, + eth_maxPriorityFeePerGas: '0x2', + eth_estimateGas: '0x5209', // 21,001; the margin must round up. + }; + const options = { + config: createHttpConfig({ + url: 'https://rpc.example', headers: {}, timeoutMs: 1_000, maxRetries: 0, retryDelayMs: 0, + }), + fetch: async (_url, init) => { + const body = JSON.parse(init.body); + calls.push(body); + assert.ok(body.method in results, `Unexpected RPC method ${body.method}`); + return response(results[body.method], body.id); + }, + chainId: 1n, + signer: { + address: node, + signTransaction(transaction, signal) { + assert.equal(this.address, node); + signatures.push({ transaction, signal }); + return signed; + }, + }, + ...overrides, + }; + return { options, results, calls, signatures }; +} + +test('the factory creates a frozen EIP-1559 transaction with current RPC values and no broadcast', async () => { + const { options, calls, signatures } = fixture(); + const prepare = createTransactionPreparer(options); + assert.equal(calls.length, 0); + const result = await prepare(request); + assert.deepEqual(result, signed); + assert.ok(Object.isFrozen(result)); + assert.equal(signatures.length, 1); + assert.ok(Object.isFrozen(signatures[0].transaction)); + assert.equal('signal' in signatures[0].transaction, false); + assert.deepEqual(signatures[0].transaction, { + ...request, type: 2, chainId: 1n, nonce: 3, + gasLimit: 25_202n, maxFeePerGas: 202n, maxPriorityFeePerGas: 2n, + }); + assert.deepEqual(calls.map(({ method, params, id }) => ({ method, params, id })), [ + { method: 'eth_chainId', params: [], id: 1 }, + { method: 'eth_getTransactionCount', params: [node, 'pending'], id: 1 }, + { method: 'eth_getBlockByNumber', params: ['latest', false], id: 1 }, + { method: 'eth_maxPriorityFeePerGas', params: [], id: 1 }, + { method: 'eth_estimateGas', params: [{ + from: node, to: request.to, data: request.data, value: '0x7', + type: '0x2', chainId: '0x1', nonce: '0x3', + maxFeePerGas: '0xca', maxPriorityFeePerGas: '0x2', + }, 'pending'], id: 1 }, + ]); +}); + +test('policies support exact ceilings, zero fees, empty calldata, large chain IDs, and fresh nonces', async () => { + const { options, results, calls, signatures } = fixture({ + chainId: 9_007_199_254_740_993n, id: 'prepare-42', gasLimitMarginPercent: 0, baseFeeMultiplier: 3, + limits: { gasLimit: 21_001n, feePerGas: 302n }, + }); + results.eth_chainId = '0x20000000000001'; + const prepare = createTransactionPreparer(options); + await prepare({ ...request, data: '0x', value: 0n }); + assert.equal(signatures[0].transaction.maxFeePerGas, 302n); + assert.equal(signatures[0].transaction.gasLimit, 21_001n); + results.eth_getTransactionCount = '0x4'; + results.eth_getBlockByNumber.baseFeePerGas = '0x0'; + results.eth_maxPriorityFeePerGas = '0x0'; + await prepare(request); + assert.equal(signatures[1].transaction.nonce, 4); + assert.equal(signatures[1].transaction.maxFeePerGas, 0n); + assert.ok(calls.every(({ id }) => id === 'prepare-42')); + results.eth_chainId = '0x2'; + await assert.rejects(prepare(request), /did not match configured chainId/); + assert.equal(signatures.length, 2); +}); + +test('invalid factory configuration is rejected before RPC or signing', () => { + const invalid = [ + { chainId: 1 }, { chainId: 0n }, { chainId: -1n }, { chainId: 1n << 256n }, + { signer: null }, { signer: { address: node } }, + { signer: { address: '0x1234', signTransaction() {} } }, { fetch: null }, + { id: '' }, { id: 1.5 }, { id: Number.MAX_SAFE_INTEGER + 1 }, + { gasLimitMarginPercent: -1 }, { gasLimitMarginPercent: 0.5 }, { gasLimitMarginPercent: Infinity }, + { baseFeeMultiplier: 0 }, { baseFeeMultiplier: 1.5 }, + { timeoutMs: 0 }, { timeoutMs: 2_147_483_648 }, + { limits: null }, { limits: [] }, { limits: { gasLimit: 0n } }, + { limits: { gasLimit: 1 } }, { limits: { feePerGas: -1n } }, + { limits: { feePerGas: 1n << 256n } }, + ]; + for (const overrides of invalid) { + const { options, calls, signatures } = fixture(overrides); + assert.throws(() => createTransactionPreparer(options)); + assert.equal(calls.length, 0); + assert.equal(signatures.length, 0); + } +}); + +test('invalid call intent is rejected before RPC or signing', async () => { + const { options, calls, signatures } = fixture(); + const prepare = createTransactionPreparer(options); + for (const changes of [ + { to: '0x' }, { to: ` ${node}` }, { data: '0x1' }, { data: '0xgg' }, + { value: 0 }, { value: -1n }, { value: 1n << 256n }, + ]) { + await assert.rejects(prepare({ ...request, ...changes })); + } + assert.equal(calls.length, 0); + assert.equal(signatures.length, 0); +}); + +test('malformed RPC results, unsupported fees, and unsafe quantities never reach the signer', async () => { + const cases = [ + ['eth_chainId', '0x2', /did not match configured chainId/], + ['eth_chainId', '0x01', /without leading zeros/], + ['eth_getTransactionCount', '0x20000000000000', /safe integer/], + ['eth_getTransactionCount', '-0x1', /quantity/], + ['eth_getBlockByNumber', null, /baseFeePerGas/], + ['eth_getBlockByNumber', { gasLimit: '0x5208' }, /baseFeePerGas/], + ['eth_getBlockByNumber', { baseFeePerGas: '0x1', gasLimit: '0x0' }, /gasLimit/], + ['eth_getBlockByNumber', { baseFeePerGas: '0x01', gasLimit: '0x5208' }, /quantity/], + ['eth_maxPriorityFeePerGas', '0x00', /quantity/], + ['eth_maxPriorityFeePerGas', '0x' + 'f'.repeat(65), /256 bits/], + ['eth_maxPriorityFeePerGas', '0x' + 'f'.repeat(64), /maxFeePerGas/], + ['eth_estimateGas', '0x', /quantity/], + ['eth_estimateGas', 21_000, /quantity/], + ['eth_estimateGas', '0x0', /positive/], + ]; + for (const [method, result, expected] of cases) { + const { options, results, signatures } = fixture(); + results[method] = result; + await assert.rejects(createTransactionPreparer(options)(request), expected); + assert.equal(signatures.length, 0); + } +}); + +test('gas and fee ceilings reject before signing instead of reducing the selected values', async () => { + for (const [limits, expected] of [ + [{ gasLimit: 25_201n }, /limits.gasLimit/], + [{ feePerGas: 201n }, /limits.feePerGas/], + ]) { + const { options, signatures } = fixture({ limits }); + await assert.rejects(createTransactionPreparer(options)(request), expected); + assert.equal(signatures.length, 0); + } + const { options, results, signatures } = fixture(); + results.eth_getBlockByNumber.gasLimit = '0x5209'; + await assert.rejects(createTransactionPreparer(options)(request), /block gas limit/); + assert.equal(signatures.length, 0); +}); + +test('RPC transport retries are reused but execution reverts and signer failures are not retried', async () => { + const { options, signatures } = fixture(); + options.config = { ...options.config, maxRetries: 1 }; + const fetch = options.fetch; + let attempts = 0; + options.fetch = async (...args) => { + if (++attempts === 1) return { ok: false, status: 503, statusText: 'Unavailable', text: async () => '' }; + return fetch(...args); + }; + await createTransactionPreparer(options)(request); + assert.equal(attempts, 6); + assert.equal(signatures.length, 1); + + const failed = fixture(); + failed.options.config = { ...failed.options.config, maxRetries: 2 }; + const normalFetch = failed.options.fetch; + let estimates = 0; + failed.options.fetch = async (url, init) => { + const body = JSON.parse(init.body); + if (body.method !== 'eth_estimateGas') return normalFetch(url, init); + estimates++; + return { ok: true, text: async () => JSON.stringify({ + jsonrpc: '2.0', id: body.id, error: { code: 3, message: 'execution reverted' }, + }) }; + }; + await assert.rejects(createTransactionPreparer(failed.options)(request), EthereumJsonRpcError); + assert.equal(estimates, 1); + assert.equal(failed.signatures.length, 0); + + let signingAttempts = 0; + const cause = new Error('Signer unavailable'); + options.signer.signTransaction = async () => { signingAttempts++; throw cause; }; + await assert.rejects(createTransactionPreparer(options)(request), (error) => error === cause); + assert.equal(signingAttempts, 1); +}); + +test('configuration and call fields are snapshotted before asynchronous work', async () => { + const { options, signatures } = fixture({ limits: { gasLimit: 30_000n, feePerGas: 300n } }); + const started = Promise.withResolvers(); + const release = Promise.withResolvers(); + const fetch = options.fetch; + options.config = { ...options.config, headers: { Authorization: 'original' } }; + options.fetch = async (url, init) => { + assert.equal(url, 'https://rpc.example'); + assert.equal(init.headers.Authorization, 'original'); + started.resolve(); + await release.promise; + return fetch(url, init); + }; + const prepare = createTransactionPreparer(options); + options.config.url = 'https://changed.example'; + options.config.headers.Authorization = 'changed'; + options.limits.gasLimit = 1n; + options.limits.feePerGas = 1n; + options.signer.signTransaction = () => { throw new Error('Replaced signer'); }; + options.fetch = () => { throw new Error('Replaced transport'); }; + const mutableRequest = { ...request }; + const promise = prepare(mutableRequest); + await started.promise; + mutableRequest.to = node; + mutableRequest.data = '0x'; + mutableRequest.value = 99n; + release.resolve(); + await promise; + assert.equal(signatures[0].transaction.to, request.to); + assert.equal(signatures[0].transaction.data, request.data); + assert.equal(signatures[0].transaction.value, request.value); +}); + +test('pre-aborted requests perform no RPC or signing', async () => { + const { options, calls, signatures } = fixture(); + await assert.rejects(createTransactionPreparer(options)({ + ...request, signal: AbortSignal.abort('Cancelled'), + }), /aborted/); + assert.equal(calls.length, 0); + assert.equal(signatures.length, 0); +}); + +test('cancellation during an uncooperative RPC prevents later signing', async () => { + const { options, signatures } = fixture(); + const controller = new AbortController(); + const started = Promise.withResolvers(); + const release = Promise.withResolvers(); + let calls = 0; + options.fetch = async () => { calls++; started.resolve(); await release.promise; return response('0x1'); }; + const promise = createTransactionPreparer(options)({ ...request, signal: controller.signal }); + await started.promise; + controller.abort('Cancelled'); + await assert.rejects(promise, /aborted/); + release.resolve(); + await nextTurn(); + assert.equal(calls, 1); + assert.equal(signatures.length, 0); +}); + +for (const cancel of ['caller', 'deadline']) { + test(`${cancel} cancellation bounds an uncooperative signer and ignores its late result`, async () => { + const { options } = fixture({ timeoutMs: cancel === 'deadline' ? 30 : 1_000 }); + const controller = new AbortController(); + const started = Promise.withResolvers(); + const release = Promise.withResolvers(); + let signingSignal; + let attempts = 0; + options.signer.signTransaction = async (_transaction, signal) => { + attempts++; + signingSignal = signal; + started.resolve(); + return await release.promise; + }; + const promise = createTransactionPreparer(options)({ ...request, signal: controller.signal }); + await started.promise; + if (cancel === 'caller') controller.abort('Cancelled'); + await assert.rejects(promise, /aborted|timed out/); + assert.equal(signingSignal.aborted, true); + release.resolve(signed); + await nextTurn(); + assert.equal(attempts, 1); + }); +} + +test('signed results must have type-2 bytes and a matching hash', async () => { + for (const output of [ + null, {}, { ...signed, rawTransaction: '0x' }, { ...signed, rawTransaction: '0x02' }, + { ...signed, rawTransaction: '0x02abc' }, { ...signed, rawTransaction: '0x01abcd' }, + { ...signed, transactionHash: '0x1234' }, { ...signed, transactionHash: '0x' + 'ff'.repeat(32) }, + ]) { + const { options } = fixture(); + options.signer.signTransaction = () => output; + await assert.rejects(createTransactionPreparer(options)(request)); + } + const { options } = fixture(); + const output = { rawTransaction: '0x02ABCD', transactionHash: '0x' + transactionHash.slice(2).toUpperCase() }; + options.signer.signTransaction = async () => output; + const result = await createTransactionPreparer(options)(request); + output.rawTransaction = '0x02'; + assert.equal(result.rawTransaction, '0x02ABCD'); +}); + +test('the default preparer composes with Logger submission and event verification', async () => { + const { options, signatures, calls } = fixture(); + const prepare = createTransactionPreparer(options); + const loggingCalls = []; + const result = await logCid(sample.cid, { + config: options.config, loggerContract, nodeAddress: node, transactionPreparer: prepare, + timeoutMs: 1_000, pollIntervalMs: 1, + fetch: async (_url, init) => { + assert.equal(signatures.length, 1); + const body = JSON.parse(init.body); + loggingCalls.push(body.method); + if (body.method === 'eth_sendRawTransaction') { + assert.deepEqual(body.params, [rawTransaction]); + return response(transactionHash); + } + const receipt = createReceipt(); + return response({ ...receipt, transactionHash, logs: receipt.logs.map(log => ({ ...log, transactionHash })) }); + }, + }); + assert.equal(signatures[0].transaction.data, sample.calldata); + assert.equal(signatures[0].transaction.value, 0n); + assert.equal(signatures[0].transaction.to, loggerContract); + assert.equal(result.transactionHash, transactionHash); + assert.equal(result.event.node, node); + assert.equal(calls.length, 5); + assert.deepEqual(loggingCalls, ['eth_sendRawTransaction', 'eth_getTransactionReceipt']); +}); diff --git a/packages/utils/README.md b/packages/utils/README.md index 1352bd69..cf187698 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -16,6 +16,7 @@ Small shared utilities for hardened Oya kernel packages. - `assertHexString(value, label)` - `assertPositiveInteger(value, label)` - `assertNonNegativeInteger(value, label)` +- `assertTimerMs(value, name)`: validates a positive integer duration up to 2,147,483,647 ms, avoiding timer overflow. - `assertHeadersObject(headers, label, options)` - `isPlainObject(value)` - `parseBytes(value, name, size?)`: validates `0x`-prefixed, byte-aligned hex, optionally requiring an exact byte count. Returns the original string without trimming; accepts `0x` when no size is required. diff --git a/packages/utils/dist/index.d.ts b/packages/utils/dist/index.d.ts index 10b91d32..3728b8af 100644 --- a/packages/utils/dist/index.d.ts +++ b/packages/utils/dist/index.d.ts @@ -3,4 +3,4 @@ export { combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry export type { AbortSignalHandle, RunWithRetryAttemptContext, RunWithRetryOptions, } from './async-utils.js'; export { HttpStatusError, RETRYABLE_HTTP_NETWORK_ERROR_CODES, createHttpConfig, hasRetryableNetworkErrorCode, readErrorStringChain, } from './http-utils.js'; export type { CreateHttpConfigOptions, HttpConfig, HttpFetchLike, HttpPostFetchLike, HttpPostFetchOptions, HttpStatusErrorOptions, HttpTextResponse, } from './http-utils.js'; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, } from './validation-utils.js'; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, } from './validation-utils.js'; diff --git a/packages/utils/dist/index.js b/packages/utils/dist/index.js index a9a55173..cbb7cc4e 100644 --- a/packages/utils/dist/index.js +++ b/packages/utils/dist/index.js @@ -1,5 +1,5 @@ export { assertCanonicalCid } from './cid-utils.js'; export { combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, } from './async-utils.js'; export { HttpStatusError, RETRYABLE_HTTP_NETWORK_ERROR_CODES, createHttpConfig, hasRetryableNetworkErrorCode, readErrorStringChain, } from './http-utils.js'; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, } from './validation-utils.js'; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, } from './validation-utils.js'; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/index.js.map b/packages/utils/dist/index.js.map index a79ec810..6c822188 100644 --- a/packages/utils/dist/index.js.map +++ b/packages/utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACH,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACH,eAAe,EACf,kCAAkC,EAClC,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,UAAU,GACb,MAAM,uBAAuB,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACH,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACH,eAAe,EACf,kCAAkC,EAClC,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,UAAU,GACb,MAAM,uBAAuB,CAAC"} \ No newline at end of file diff --git a/packages/utils/dist/validation-utils.d.ts b/packages/utils/dist/validation-utils.d.ts index 55d31847..e64434f9 100644 --- a/packages/utils/dist/validation-utils.d.ts +++ b/packages/utils/dist/validation-utils.d.ts @@ -1,6 +1,7 @@ declare function assertNonEmptyString(value: unknown, label: string): string; declare function assertPositiveInteger(value: unknown, label: string): number; declare function assertNonNegativeInteger(value: unknown, label: string): number; +declare function assertTimerMs(value: unknown, name: string): number; declare function isPlainObject(value: unknown): value is Record; declare function assertHeadersObject(headers: unknown, label: string, options?: { disallowedNames?: string[]; @@ -10,4 +11,4 @@ declare function assertHexString(value: unknown, label: string): string; declare function assertHexData(value: unknown, label: string): string; declare function assertBytes32HexString(value: unknown, label: string): string; declare function parseBytes(value: unknown, name: string, size?: number): string; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, }; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, }; diff --git a/packages/utils/dist/validation-utils.js b/packages/utils/dist/validation-utils.js index f6a73879..b00169e5 100644 --- a/packages/utils/dist/validation-utils.js +++ b/packages/utils/dist/validation-utils.js @@ -16,6 +16,13 @@ function assertNonNegativeInteger(value, label) { } return value; } +function assertTimerMs(value, name) { + const duration = assertPositiveInteger(value, name); + if (duration > 2_147_483_647) { + throw new Error(`${name} must not exceed 2147483647 ms.`); + } + return duration; +} function isPlainObject(value) { if (value === null || typeof value !== 'object' || Array.isArray(value)) { return false; @@ -76,5 +83,5 @@ function parseBytes(value, name, size) { } return value; } -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, }; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, }; //# sourceMappingURL=validation-utils.js.map \ No newline at end of file diff --git a/packages/utils/dist/validation-utils.js.map b/packages/utils/dist/validation-utils.js.map index d8f0df58..803597a0 100644 --- a/packages/utils/dist/validation-utils.js.map +++ b/packages/utils/dist/validation-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../src/validation-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../src/validation-utils.ts"],"names":[],"mappings":"AAAA,SAAS,oBAAoB,CAAC,KAAc,EAAE,KAAa;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8BAA8B,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAE,KAAa;IACxD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8BAA8B,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAc,EAAE,KAAa;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,kCAAkC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,IAAY;IAC/C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACpD,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,iCAAiC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACtE,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC/C,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,CAAC;AAChE,CAAC;AAED,SAAS,mBAAmB,CACxB,OAAgB,EAChB,KAAa,EACb,UAA0C,EAAE;IAE5C,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,0BAA0B,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,eAAe,GAAG,IAAI,GAAG,CAC3B,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CACpE,CAAC;IACF,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjD,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qBAAqB,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,GAAG,oBAAoB,CAAC,CAAC;QACzD,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAiB,EAAE,OAAe;IACxD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,GAAG,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,KAAa;IAClD,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACrD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oCAAoC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,KAAa;IAChD,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAChD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,2CAA2C,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAc,EAAE,KAAa;IACzD,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAChD,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,gCAAgC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,UAAU,CAAC,KAAc,EAAE,IAAY,EAAE,IAAa;IAC3D,IACI,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC;QACtC,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,EACvD,CAAC;QACC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,YAAY,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI,OAAO,YAAY,CAAC,CAAC;IACzG,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,UAAU,GACb,CAAC"} \ No newline at end of file diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 3ccddd76..328b229b 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -38,6 +38,7 @@ export { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, + assertTimerMs, isPlainObject, parseBytes, } from './validation-utils.js'; diff --git a/packages/utils/src/validation-utils.ts b/packages/utils/src/validation-utils.ts index 7d00bc31..504f08e7 100644 --- a/packages/utils/src/validation-utils.ts +++ b/packages/utils/src/validation-utils.ts @@ -19,6 +19,14 @@ function assertNonNegativeInteger(value: unknown, label: string): number { return value; } +function assertTimerMs(value: unknown, name: string): number { + const duration = assertPositiveInteger(value, name); + if (duration > 2_147_483_647) { + throw new Error(`${name} must not exceed 2147483647 ms.`); + } + return duration; +} + function isPlainObject(value: unknown): value is Record { if (value === null || typeof value !== 'object' || Array.isArray(value)) { return false; @@ -103,6 +111,7 @@ export { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, + assertTimerMs, isPlainObject, parseBytes, }; diff --git a/plans/default-transaction-preparer.md b/plans/default-transaction-preparer.md new file mode 100644 index 00000000..f5fdeeb7 --- /dev/null +++ b/plans/default-transaction-preparer.md @@ -0,0 +1,73 @@ +# Add a default transaction preparer with an injected signer + +This ExecPlan is maintained according to `PLANS.md`. + +## Purpose / Big Picture + +Nodes will be able to configure a reusable Ethereum transaction preparer once, provide their own signing implementation, and pass the returned callback to `logCid` or the existing publish-and-log handler. The package will obtain chain-dependent transaction fields without adding ethers, viem, a wallet adapter, private-key handling, or any new dependency. Mock RPC and signer tests will demonstrate preparation followed by existing Logger submission and receipt verification without using a real network or key. + +## Progress + +- [x] 2026-09-05 20:38Z: Read repository instructions and audited transaction, RPC, validation, cancellation, and Logger code. Checked Ethereum execution API and EIP-1559 specifications. +- [x] 2026-09-05 20:40Z: Implemented public types and the factory; reused quantity parsing, shared timer validation, RPC retries, and bounded async invocation. Initial build passed. +- [x] 2026-09-05 20:41Z: Added 14 passing runtime tests including Logger integration and uncooperative signer cancellation. Ethereum type tests passed. +- [x] 2026-09-05 20:44Z: Updated Ethereum/utils documentation, rebuilt tracked output, reviewed the implementation/declarations, and passed all 201 package runtime tests, Ethereum/messages type checks, package imports, and whitespace checks. Dependency metadata is unchanged. + +## Surprises & Discoveries + +- `requestEthereumJsonRpc` already supports retries for all five required read methods; no new transport or retry implementation is needed. +- Canonical RPC quantity parsing currently lives in `receipt-utils.ts`; bounded timer validation currently lives in `receipts.ts` despite also being used by Logger. Move those existing implementations to RPC utilities and shared validation utilities respectively so preparation can reuse them. +- A preparer cannot coordinate nonce reuse through submission because its callback finishes before broadcasting starts. An internal queue would not solve this lifecycle constraint. + +## Decision Log + +- 2026-09-05 / Codex: Support type-2 (EIP-1559) transactions to an explicit address, with empty access list, initially. This matches the discussed default and avoids inventing support for wallet-specific execution, contract creation, blobs, or legacy fees. +- 2026-09-05 / Codex: Require an expected positive bigint chain ID and a signer with an address and `signTransaction` method. Reuse existing `TransactionRequest`, `SignedTransaction`, and `TransactionPreparer`. Keep the new factory in `packages/ethereum/src/transaction-preparer.ts` and shared signing types in `transactions.ts`. +- 2026-09-05 / Codex: Read chain ID, pending nonce, latest block base fee/gas limit, suggested priority fee, then estimate gas against pending state with the completed call/fee fields. Check chain ID on every invocation. Default maximum fee is twice the current base fee plus the suggested priority fee. Default gas margin is 20%, rounded up. Configurable integer base-fee multiplier and margin, optional gas/fee ceilings, and block gas limit checks reject before signing rather than silently reducing values. +- 2026-09-05 / Codex: A configurable 30-second overall preparation deadline and the per-call abort signal cover RPC work and signing. Reuse `runWithRetry` with zero outer retries; individual RPC reads retain their existing retry policy. Sign only once and discard late results after cancellation. The signer is trusted to preserve the requested transaction and account; validate returned byte shapes, type-2 prefix, and hash correspondence with existing noble Keccak, without adding transaction decoding or key recovery. +- 2026-09-05 / Codex: Do not reserve or increment nonces locally. Document serialization of the complete transaction lifecycle per account, including reconciliation of uncertain submissions, and the lack of coordination across processes. RPC IDs default to 1 and are configurable at factory creation; they are not signed fields. + +## Outcomes & Retrospective + +The factory and signer interface are implemented with no new dependencies or concrete wallet adapter. All 201 runtime tests across utils, IPFS, Ethereum, and messages pass, including 14 new factory tests. Both Ethereum/messages type suites, package-root imports, the build, and `git diff --check` pass. The Logger integration test demonstrates preparation followed by one submission and the expected receipt/event verification. No live RPC, production key, deployment, or wallet adapter was used. The remaining operational responsibility is intentionally the host's signer implementation and coordination of the complete transaction lifecycle per account; no implementation work remains for this task. + +## Context and Orientation + +`packages/ethereum/src/transactions.ts` defines call intent (`to`, `data`, `value`, optional signal), a prepared signed result, and the existing callback accepted by Logger. `logger.ts` invokes that callback, submits bytes, waits for a receipt, and verifies an event. `request-utils.ts` performs JSON-RPC reads with bounded retries and response-envelope checks. `packages/utils/src/async-utils.ts` provides cancellation, deadlines, and retry composition. `packages/messages` composes IPFS publication with Logger; its API requires no change. Tracked `dist` files are rebuilt with TypeScript. Root and package `AGENTS.md` apply. + +An Ethereum nonce is an account's transaction sequence number. A gas limit bounds execution units, while fees are prices per unit in wei (integer native currency units). EIP-1559 transactions contain a maximum priority fee and maximum total fee per gas. The factory computes a policy suggestion and never broadcasts it. + +## Plan of Work + +First add `UnsignedTransaction`, `TransactionSigner`, and `CreateTransactionPreparerOptions` through the Ethereum package root. Move existing generic validation implementations without changing their behavior. Implement strict factory/request/RPC validation, snapshots of configuration and request fields, integer arithmetic, immutable signing input/output, and a single bounded signer invocation. Then test the new factory with injected RPC responses, synchronous/asynchronous fake signers, cancellation, mutated objects, and existing Logger orchestration. Finally explain configuration defaults, limits, supported wallet/transaction scope, and nonce ownership in the READMEs. + +## Concrete Steps + +All commands run from the repository root unless indicated: + + npm --prefix packages run build + node --test packages/ethereum/test/transaction-preparer.test.js + node --test --test-reporter=dot packages/utils/test/*.test.js packages/ipfs/test/*.test.js packages/ethereum/test/*.test.js packages/messages/test/*.test.js + packages/node_modules/.bin/tsc -p packages/ethereum/tsconfig.type-test.json + packages/node_modules/.bin/tsc -p packages/messages/tsconfig.type-test.json + git diff --check + +Smoke-import changed package roots with Node from `packages/`. Expect no missing exports, no TypeScript errors, and all mock tests passing. Inspect dependency metadata diff to verify no dependencies were added. + +## Validation and Acceptance + +Tests must prove exact default fields and RPC parameters (including pending nonce/state, request ID, fee fields and rounding), refreshed values across calls, configured overrides/caps, early rejection of invalid configuration, malformed or oversized quantities, unsupported fee data, chain mismatch and gas estimation errors. Cancellation before RPC, during RPC, and during an uncooperative signer must settle promptly, prevent later signing/submission, and preserve original objects. Retryable reads may retry, but signer failures never retry. Returned hashes must match signed bytes. A Logger integration test must show a completed signing request followed by one submission and the correct event verification. Type tests must establish public imports, callback compatibility, bigint fields, immutability, and required signer methods. + +## Idempotence and Recovery + +Build and mock tests are repeatable and do not contact external services. Factory construction performs no RPC calls or signing. Each invocation reads current state and can request another signature, so the host should reuse retained signed bytes for submission retries rather than invoke the factory again. The factory has no nonce reservation, broadcast, persistence, wallet approval, or deployment side effects. Aborting a wait cannot undo a signer operation already started; late completion is ignored. Hosts must coordinate all users of the signing account and reconcile ambiguous submissions. + +## Artifacts and Notes + +Protocol references checked: https://eips.ethereum.org/EIPS/eip-1559 and the Ethereum execution API `src/eth/execute.yaml` / `src/eth/fee_market.yaml`. The relevant facts and chosen defaults are recorded above; external sources are not required to resume implementation. Runtime tests use opaque type-2 bytes and a matching hash to exercise orchestration, not real cryptographic signing. + +Independent fixture check: `cast keccak 0x02abcd` returned `0xe3607eedbe2ea88ad1994e3ef901f3c7ed167a59ebb5ffe5e40321e468f49eb1`. The full runtime command printed 201 passing test dots and exited zero; builds, both type-check commands, smoke imports, and whitespace checks also exited zero. New files are `transaction-preparer.ts`, its generated dist artifacts, the corresponding runtime/type tests, and this plan. Existing quantity parsing moved to `request-utils.ts`; existing timer validation moved to `@oyaprotocol/utils` and all callers use the shared definition. + +## Interfaces and Dependencies + +`createTransactionPreparer(options)` returns the existing `TransactionPreparer`. Options include `config`, `fetch`, `chainId: bigint`, `signer`, optional `gasLimitMarginPercent` (20), `baseFeeMultiplier` (2), `limits: { gasLimit?: bigint; feePerGas?: bigint }`, `timeoutMs` (30000), and JSON-RPC `id` (1). `UnsignedTransaction` adds type 2, chain ID, a safe-integer nonce, gas limit and both fee fields to the existing call intent without its signal. `TransactionSigner` exposes an address and a signing method accepting the unsigned transaction and optional abort signal, returning `SignedTransaction` synchronously or asynchronously. Existing `@noble/hashes` and `@oyaprotocol/utils` are sufficient; package metadata remains unchanged. From 3427e8e8b981a13f1c19985039b5f638083f8f29 Mon Sep 17 00:00:00 2001 From: John Shutt Date: Sat, 5 Sep 2026 13:55:47 -0700 Subject: [PATCH 2/5] move assert timer function to async utils Signed-off-by: John Shutt --- packages/utils/README.md | 2 +- packages/utils/dist/async-utils.d.ts | 3 ++- packages/utils/dist/async-utils.js | 9 ++++++++- packages/utils/dist/async-utils.js.map | 2 +- packages/utils/dist/index.d.ts | 4 ++-- packages/utils/dist/index.js | 4 ++-- packages/utils/dist/index.js.map | 2 +- packages/utils/dist/validation-utils.d.ts | 3 +-- packages/utils/dist/validation-utils.js | 9 +-------- packages/utils/dist/validation-utils.js.map | 2 +- packages/utils/src/async-utils.ts | 9 +++++++++ packages/utils/src/index.ts | 2 +- packages/utils/src/validation-utils.ts | 9 --------- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/utils/README.md b/packages/utils/README.md index cf187698..4ab10df3 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -16,7 +16,6 @@ Small shared utilities for hardened Oya kernel packages. - `assertHexString(value, label)` - `assertPositiveInteger(value, label)` - `assertNonNegativeInteger(value, label)` -- `assertTimerMs(value, name)`: validates a positive integer duration up to 2,147,483,647 ms, avoiding timer overflow. - `assertHeadersObject(headers, label, options)` - `isPlainObject(value)` - `parseBytes(value, name, size?)`: validates `0x`-prefixed, byte-aligned hex, optionally requiring an exact byte count. Returns the original string without trimming; accepts `0x` when no size is required. @@ -38,6 +37,7 @@ Small shared utilities for hardened Oya kernel packages. ## Async Utilities +- `assertTimerMs(value, name)`: validates a positive integer duration up to 2,147,483,647 ms, avoiding timer overflow. - `AbortSignalHandle` - `RunWithRetryAttemptContext` - `RunWithRetryOptions` diff --git a/packages/utils/dist/async-utils.d.ts b/packages/utils/dist/async-utils.d.ts index 8c073f62..9ad8332d 100644 --- a/packages/utils/dist/async-utils.d.ts +++ b/packages/utils/dist/async-utils.d.ts @@ -16,6 +16,7 @@ interface RunWithRetryOptions { normalizeError(error: unknown): Error; run(context: RunWithRetryAttemptContext): Promise; } +declare function assertTimerMs(value: unknown, name: string): number; declare function createTimeoutSignal(timeoutMs: number): AbortSignalHandle; declare function combineAbortSignals(signals: Array): AbortSignalHandle; declare function invokeWithAbort(createPromise: () => Promise, signal: AbortSignal | undefined): Promise; @@ -26,5 +27,5 @@ declare function waitForRetryDelay({ retryDelayMs, signal, abortErrorMessage, }: abortErrorMessage: string; }): Promise; declare function runWithRetry({ maxRetries, retryDelayMs, timeoutMs, signal, abortErrorMessage, shouldRetry, normalizeError, run, }: RunWithRetryOptions): Promise; -export { combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, }; +export { assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, }; export type { AbortSignalHandle, RunWithRetryAttemptContext, RunWithRetryOptions, }; diff --git a/packages/utils/dist/async-utils.js b/packages/utils/dist/async-utils.js index c2f14429..a2ecb8fd 100644 --- a/packages/utils/dist/async-utils.js +++ b/packages/utils/dist/async-utils.js @@ -1,4 +1,11 @@ import { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, } from './validation-utils.js'; +function assertTimerMs(value, name) { + const duration = assertPositiveInteger(value, name); + if (duration > 2_147_483_647) { + throw new Error(`${name} must not exceed 2147483647 ms.`); + } + return duration; +} function createTimeoutSignal(timeoutMs) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(new Error('Request timed out.')), timeoutMs); @@ -175,5 +182,5 @@ async function runWithRetry({ maxRetries, retryDelayMs, timeoutMs, signal, abort } throw normalizeError(lastError); } -export { combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, }; +export { assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, }; //# sourceMappingURL=async-utils.js.map \ No newline at end of file diff --git a/packages/utils/dist/async-utils.js.map b/packages/utils/dist/async-utils.js.map index 6319baae..f85c128e 100644 --- a/packages/utils/dist/async-utils.js.map +++ b/packages/utils/dist/async-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"async-utils.js","sourceRoot":"","sources":["../src/async-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"async-utils.js","sourceRoot":"","sources":["../src/async-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/dist/index.d.ts b/packages/utils/dist/index.d.ts index 3728b8af..4365256c 100644 --- a/packages/utils/dist/index.d.ts +++ b/packages/utils/dist/index.d.ts @@ -1,6 +1,6 @@ export { assertCanonicalCid } from './cid-utils.js'; -export { combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, } from './async-utils.js'; +export { assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, } from './async-utils.js'; export type { AbortSignalHandle, RunWithRetryAttemptContext, RunWithRetryOptions, } from './async-utils.js'; export { HttpStatusError, RETRYABLE_HTTP_NETWORK_ERROR_CODES, createHttpConfig, hasRetryableNetworkErrorCode, readErrorStringChain, } from './http-utils.js'; export type { CreateHttpConfigOptions, HttpConfig, HttpFetchLike, HttpPostFetchLike, HttpPostFetchOptions, HttpStatusErrorOptions, HttpTextResponse, } from './http-utils.js'; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, } from './validation-utils.js'; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, } from './validation-utils.js'; diff --git a/packages/utils/dist/index.js b/packages/utils/dist/index.js index cbb7cc4e..ebacd4a0 100644 --- a/packages/utils/dist/index.js +++ b/packages/utils/dist/index.js @@ -1,5 +1,5 @@ export { assertCanonicalCid } from './cid-utils.js'; -export { combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, } from './async-utils.js'; +export { assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, } from './async-utils.js'; export { HttpStatusError, RETRYABLE_HTTP_NETWORK_ERROR_CODES, createHttpConfig, hasRetryableNetworkErrorCode, readErrorStringChain, } from './http-utils.js'; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, } from './validation-utils.js'; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, } from './validation-utils.js'; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/index.js.map b/packages/utils/dist/index.js.map index 6c822188..3e943ff4 100644 --- a/packages/utils/dist/index.js.map +++ b/packages/utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACH,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACH,eAAe,EACf,kCAAkC,EAClC,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,UAAU,GACb,MAAM,uBAAuB,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACH,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACH,eAAe,EACf,kCAAkC,EAClC,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,UAAU,GACb,MAAM,uBAAuB,CAAC"} \ No newline at end of file diff --git a/packages/utils/dist/validation-utils.d.ts b/packages/utils/dist/validation-utils.d.ts index e64434f9..55d31847 100644 --- a/packages/utils/dist/validation-utils.d.ts +++ b/packages/utils/dist/validation-utils.d.ts @@ -1,7 +1,6 @@ declare function assertNonEmptyString(value: unknown, label: string): string; declare function assertPositiveInteger(value: unknown, label: string): number; declare function assertNonNegativeInteger(value: unknown, label: string): number; -declare function assertTimerMs(value: unknown, name: string): number; declare function isPlainObject(value: unknown): value is Record; declare function assertHeadersObject(headers: unknown, label: string, options?: { disallowedNames?: string[]; @@ -11,4 +10,4 @@ declare function assertHexString(value: unknown, label: string): string; declare function assertHexData(value: unknown, label: string): string; declare function assertBytes32HexString(value: unknown, label: string): string; declare function parseBytes(value: unknown, name: string, size?: number): string; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, }; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, }; diff --git a/packages/utils/dist/validation-utils.js b/packages/utils/dist/validation-utils.js index b00169e5..f6a73879 100644 --- a/packages/utils/dist/validation-utils.js +++ b/packages/utils/dist/validation-utils.js @@ -16,13 +16,6 @@ function assertNonNegativeInteger(value, label) { } return value; } -function assertTimerMs(value, name) { - const duration = assertPositiveInteger(value, name); - if (duration > 2_147_483_647) { - throw new Error(`${name} must not exceed 2147483647 ms.`); - } - return duration; -} function isPlainObject(value) { if (value === null || typeof value !== 'object' || Array.isArray(value)) { return false; @@ -83,5 +76,5 @@ function parseBytes(value, name, size) { } return value; } -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertTimerMs, isPlainObject, parseBytes, }; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, }; //# sourceMappingURL=validation-utils.js.map \ No newline at end of file diff --git a/packages/utils/dist/validation-utils.js.map b/packages/utils/dist/validation-utils.js.map index 803597a0..d8f0df58 100644 --- a/packages/utils/dist/validation-utils.js.map +++ b/packages/utils/dist/validation-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../src/validation-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../src/validation-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/src/async-utils.ts b/packages/utils/src/async-utils.ts index f1f0f39c..ca4d8baf 100644 --- a/packages/utils/src/async-utils.ts +++ b/packages/utils/src/async-utils.ts @@ -25,6 +25,14 @@ interface RunWithRetryOptions { run(context: RunWithRetryAttemptContext): Promise; } +function assertTimerMs(value: unknown, name: string): number { + const duration = assertPositiveInteger(value, name); + if (duration > 2_147_483_647) { + throw new Error(`${name} must not exceed 2147483647 ms.`); + } + return duration; +} + function createTimeoutSignal(timeoutMs: number): AbortSignalHandle { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(new Error('Request timed out.')), timeoutMs); @@ -242,6 +250,7 @@ async function runWithRetry({ } export { + assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 328b229b..0cf2ae31 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,5 +1,6 @@ export { assertCanonicalCid } from './cid-utils.js'; export { + assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, @@ -38,7 +39,6 @@ export { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, - assertTimerMs, isPlainObject, parseBytes, } from './validation-utils.js'; diff --git a/packages/utils/src/validation-utils.ts b/packages/utils/src/validation-utils.ts index 504f08e7..7d00bc31 100644 --- a/packages/utils/src/validation-utils.ts +++ b/packages/utils/src/validation-utils.ts @@ -19,14 +19,6 @@ function assertNonNegativeInteger(value: unknown, label: string): number { return value; } -function assertTimerMs(value: unknown, name: string): number { - const duration = assertPositiveInteger(value, name); - if (duration > 2_147_483_647) { - throw new Error(`${name} must not exceed 2147483647 ms.`); - } - return duration; -} - function isPlainObject(value: unknown): value is Record { if (value === null || typeof value !== 'object' || Array.isArray(value)) { return false; @@ -111,7 +103,6 @@ export { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, - assertTimerMs, isPlainObject, parseBytes, }; From 86fd48b4d41e682a0d83ff027ac4815b095b1078 Mon Sep 17 00:00:00 2001 From: John Shutt Date: Sat, 5 Sep 2026 14:08:21 -0700 Subject: [PATCH 3/5] use pending block fees when preparing transactions Signed-off-by: John Shutt --- packages/ethereum/README.md | 4 +- .../ethereum/dist/transaction-preparer.d.ts | 2 +- .../ethereum/dist/transaction-preparer.js | 6 +-- .../ethereum/dist/transaction-preparer.js.map | 2 +- packages/ethereum/src/transaction-preparer.ts | 8 ++-- .../test/transaction-preparer.test.js | 37 ++++++++++++++++++- plans/default-transaction-preparer.md | 8 ++-- 7 files changed, 52 insertions(+), 15 deletions(-) diff --git a/packages/ethereum/README.md b/packages/ethereum/README.md index 10c81a56..bb4e8a98 100644 --- a/packages/ethereum/README.md +++ b/packages/ethereum/README.md @@ -75,9 +75,9 @@ const logging = await logCid(cid, { }); ``` -Construction validates and snapshots configuration without making RPC calls. Each invocation validates and snapshots the call, checks `eth_chainId` against the configured positive bigint chain ID, reads `eth_getTransactionCount(address, "pending")`, obtains the latest block's base fee and gas limit, and reads `eth_maxPriorityFeePerGas`. It then calls `eth_estimateGas` against pending state with the signing address, recipient, calldata, value, chain ID, nonce, and selected fees. These methods follow the [Ethereum execution API](https://github.com/ethereum/execution-apis/tree/main/src/eth); the fee fields follow [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). +Construction validates and snapshots configuration without making RPC calls. Each invocation validates and snapshots the call, checks `eth_chainId` against the configured positive bigint chain ID, reads `eth_getTransactionCount(address, "pending")`, obtains the pending block's base fee and gas limit, and reads `eth_maxPriorityFeePerGas`. It then calls `eth_estimateGas` against pending state with the signing address, recipient, calldata, value, chain ID, nonce, and selected fees. Fee selection and gas estimation both use pending state, although that state can advance between separate RPC calls. These methods follow the [Ethereum execution API](https://github.com/ethereum/execution-apis/tree/main/src/eth); the fee fields follow [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). -The gas limit is `ceil(estimate * (100 + gasLimitMarginPercent) / 100)`. The maximum fee per gas is `baseFee * baseFeeMultiplier + suggestedPriorityFee`; the priority fee is the RPC suggestion. The multiplier and margin are policy choices, not protocol requirements. Arithmetic uses bigint, and fee values are in wei per gas. Nonces above `Number.MAX_SAFE_INTEGER` reject before conversion for the signer. Both optional `limits` fields are ceilings: the factory rejects a selected value above a ceiling instead of reducing the gas buffer or fee suggestion. Omitting them adds no operator ceiling; the buffered gas limit must still fit the latest block's gas limit. A configured gas cap must be positive; a fee cap of zero is permitted. Networks without EIP-1559 base-fee data, unsupported RPC methods, malformed quantities, estimation errors, and out-of-range values reject before signing. +The gas limit is `ceil(estimate * (100 + gasLimitMarginPercent) / 100)`. The maximum fee per gas is `baseFee * baseFeeMultiplier + suggestedPriorityFee`; the priority fee is the RPC suggestion. The multiplier and margin are policy choices, not protocol requirements. Arithmetic uses bigint, and fee values are in wei per gas. Nonces above `Number.MAX_SAFE_INTEGER` reject before conversion for the signer. Both optional `limits` fields are ceilings: the factory rejects a selected value above a ceiling instead of reducing the gas buffer or fee suggestion. Omitting them adds no operator ceiling; the buffered gas limit must still fit the pending block's gas limit. A configured gas cap must be positive; a fee cap of zero is permitted. Networks without EIP-1559 base-fee data, unsupported RPC methods, malformed quantities, estimation errors, and out-of-range values reject before signing. The signer receives a frozen transaction and a separate signal combining caller cancellation with the overall deadline. Each RPC read uses the existing transport timeout/retry policy. The whole preparation has no retries, and the signer is called at most once per invocation. Signer errors propagate; timeout/cancellation stops waiting even when the signer ignores its signal, and late results are discarded. The host should honor the signal where its signing API permits. Aborting cannot undo an external signing request already started. diff --git a/packages/ethereum/dist/transaction-preparer.d.ts b/packages/ethereum/dist/transaction-preparer.d.ts index cdc2fe1e..f1d752a8 100644 --- a/packages/ethereum/dist/transaction-preparer.d.ts +++ b/packages/ethereum/dist/transaction-preparer.d.ts @@ -7,7 +7,7 @@ interface CreateTransactionPreparerOptions { signer: TransactionSigner; /** Whole percent added to the estimate, rounded up. Default: 20. */ gasLimitMarginPercent?: number; - /** Integer multiplier for the latest base fee. Default: 2. */ + /** Integer multiplier for the pending block's base fee. Default: 2. */ baseFeeMultiplier?: number; /** Exceeding either optional ceiling rejects before signing. */ limits?: { diff --git a/packages/ethereum/dist/transaction-preparer.js b/packages/ethereum/dist/transaction-preparer.js index 211e9947..53ea38a9 100644 --- a/packages/ethereum/dist/transaction-preparer.js +++ b/packages/ethereum/dist/transaction-preparer.js @@ -78,9 +78,9 @@ function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMar if (nonce > BigInt(Number.MAX_SAFE_INTEGER)) { throw new Error('Transaction nonce must fit in a safe integer.'); } - const block = await rpc('eth_getBlockByNumber', ['latest', false]); + const block = await rpc('eth_getBlockByNumber', ['pending', false]); if (!isPlainObject(block) || block.baseFeePerGas === undefined || block.baseFeePerGas === null) { - throw new Error('Latest block must include baseFeePerGas for EIP-1559 transaction preparation.'); + throw new Error('Pending block must include baseFeePerGas for EIP-1559 transaction preparation.'); } const baseFee = parseTransactionQuantity(block.baseFeePerGas, 'block.baseFeePerGas'); const blockGasLimit = parseTransactionQuantity(block.gasLimit, 'block.gasLimit'); @@ -105,7 +105,7 @@ function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMar } const gasLimit = (estimate * (100n + BigInt(gasLimitMarginPercent)) + 99n) / 100n; if (gasLimit > blockGasLimit) { - throw new Error('Buffered gas limit exceeds the latest block gas limit.'); + throw new Error('Buffered gas limit exceeds the pending block gas limit.'); } if (gasLimitCap !== undefined && gasLimit > gasLimitCap) { throw new Error('Buffered gas limit exceeds limits.gasLimit.'); diff --git a/packages/ethereum/dist/transaction-preparer.js.map b/packages/ethereum/dist/transaction-preparer.js.map index 999498dc..560ba196 100644 --- a/packages/ethereum/dist/transaction-preparer.js.map +++ b/packages/ethereum/dist/transaction-preparer.js.map @@ -1 +1 @@ -{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/src/transaction-preparer.ts b/packages/ethereum/src/transaction-preparer.ts index 1f9c4606..4c465c80 100644 --- a/packages/ethereum/src/transaction-preparer.ts +++ b/packages/ethereum/src/transaction-preparer.ts @@ -20,7 +20,7 @@ interface CreateTransactionPreparerOptions { signer: TransactionSigner; /** Whole percent added to the estimate, rounded up. Default: 20. */ gasLimitMarginPercent?: number; - /** Integer multiplier for the latest base fee. Default: 2. */ + /** Integer multiplier for the pending block's base fee. Default: 2. */ baseFeeMultiplier?: number; /** Exceeding either optional ceiling rejects before signing. */ limits?: { gasLimit?: bigint; feePerGas?: bigint }; @@ -116,9 +116,9 @@ function createTransactionPreparer({ if (nonce > BigInt(Number.MAX_SAFE_INTEGER)) { throw new Error('Transaction nonce must fit in a safe integer.'); } - const block = await rpc('eth_getBlockByNumber', ['latest', false]); + const block = await rpc('eth_getBlockByNumber', ['pending', false]); if (!isPlainObject(block) || block.baseFeePerGas === undefined || block.baseFeePerGas === null) { - throw new Error('Latest block must include baseFeePerGas for EIP-1559 transaction preparation.'); + throw new Error('Pending block must include baseFeePerGas for EIP-1559 transaction preparation.'); } const baseFee = parseTransactionQuantity(block.baseFeePerGas, 'block.baseFeePerGas'); const blockGasLimit = parseTransactionQuantity(block.gasLimit, 'block.gasLimit'); @@ -147,7 +147,7 @@ function createTransactionPreparer({ } const gasLimit = (estimate * (100n + BigInt(gasLimitMarginPercent)) + 99n) / 100n; if (gasLimit > blockGasLimit) { - throw new Error('Buffered gas limit exceeds the latest block gas limit.'); + throw new Error('Buffered gas limit exceeds the pending block gas limit.'); } if (gasLimitCap !== undefined && gasLimit > gasLimitCap) { throw new Error('Buffered gas limit exceeds limits.gasLimit.'); diff --git a/packages/ethereum/test/transaction-preparer.test.js b/packages/ethereum/test/transaction-preparer.test.js index 6df3230c..f6e2eb4d 100644 --- a/packages/ethereum/test/transaction-preparer.test.js +++ b/packages/ethereum/test/transaction-preparer.test.js @@ -62,7 +62,7 @@ test('the factory creates a frozen EIP-1559 transaction with current RPC values assert.deepEqual(calls.map(({ method, params, id }) => ({ method, params, id })), [ { method: 'eth_chainId', params: [], id: 1 }, { method: 'eth_getTransactionCount', params: [node, 'pending'], id: 1 }, - { method: 'eth_getBlockByNumber', params: ['latest', false], id: 1 }, + { method: 'eth_getBlockByNumber', params: ['pending', false], id: 1 }, { method: 'eth_maxPriorityFeePerGas', params: [], id: 1 }, { method: 'eth_estimateGas', params: [{ from: node, to: request.to, data: request.data, value: '0x7', @@ -72,6 +72,41 @@ test('the factory creates a frozen EIP-1559 transaction with current RPC values ]); }); +test('fees and gas limits use the pending block when the base fee multiplier is one', async () => { + const { options, signatures } = fixture({ baseFeeMultiplier: 1 }); + const blocks = { + latest: { baseFeePerGas: '0x64', gasLimit: '0x6271' }, + pending: { baseFeePerGas: '0x6e', gasLimit: '0x6272' }, + }; + const blockTags = []; + const fetch = options.fetch; + options.fetch = async (url, init) => { + const { method, params, id } = JSON.parse(init.body); + if (method === 'eth_getBlockByNumber') { + blockTags.push(params[0]); + return response(blocks[params[0]], id); + } + if (method === 'eth_estimateGas') { + assert.equal(params[1], 'pending'); + if (BigInt(params[0].maxFeePerGas) < BigInt(blocks.pending.baseFeePerGas)) { + return { ok: true, text: async () => JSON.stringify({ + jsonrpc: '2.0', id, error: { code: -32000, message: 'max fee per gas less than block base fee' }, + }) }; + } + } + return fetch(url, init); + }; + const prepare = createTransactionPreparer(options); + await prepare(request); + assert.deepEqual(blockTags, ['pending']); + assert.equal(signatures[0].transaction.maxFeePerGas, 112n); + assert.equal(signatures[0].transaction.gasLimit, 25_202n); + + blocks.pending.gasLimit = '0x6271'; + await assert.rejects(prepare(request), /pending block gas limit/); + assert.equal(signatures.length, 1); +}); + test('policies support exact ceilings, zero fees, empty calldata, large chain IDs, and fresh nonces', async () => { const { options, results, calls, signatures } = fixture({ chainId: 9_007_199_254_740_993n, id: 'prepare-42', gasLimitMarginPercent: 0, baseFeeMultiplier: 3, diff --git a/plans/default-transaction-preparer.md b/plans/default-transaction-preparer.md index f5fdeeb7..0a06bd81 100644 --- a/plans/default-transaction-preparer.md +++ b/plans/default-transaction-preparer.md @@ -12,24 +12,26 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p - [x] 2026-09-05 20:40Z: Implemented public types and the factory; reused quantity parsing, shared timer validation, RPC retries, and bounded async invocation. Initial build passed. - [x] 2026-09-05 20:41Z: Added 14 passing runtime tests including Logger integration and uncooperative signer cancellation. Ethereum type tests passed. - [x] 2026-09-05 20:44Z: Updated Ethereum/utils documentation, rebuilt tracked output, reviewed the implementation/declarations, and passed all 201 package runtime tests, Ethereum/messages type checks, package imports, and whitespace checks. Dependency metadata is unchanged. +- [x] 2026-09-05 21:06Z: Aligned the block fee/gas-limit lookup with pending gas estimation. Added a regression for differing latest/pending fees with multiplier 1, updated documentation/errors, rebuilt output, and passed all 137 Ethereum/messages runtime tests, both type suites, package import, and whitespace checks. ## Surprises & Discoveries - `requestEthereumJsonRpc` already supports retries for all five required read methods; no new transport or retry implementation is needed. -- Canonical RPC quantity parsing currently lives in `receipt-utils.ts`; bounded timer validation currently lives in `receipts.ts` despite also being used by Logger. Move those existing implementations to RPC utilities and shared validation utilities respectively so preparation can reuse them. +- Canonical RPC quantity parsing originally lived in `receipt-utils.ts`; it now lives in `request-utils.ts`. Bounded timer validation originally lived in `receipts.ts`; it is now exported by `@oyaprotocol/utils` from `async-utils.ts`, following the user's requested relocation. - A preparer cannot coordinate nonce reuse through submission because its callback finishes before broadcasting starts. An internal queue would not solve this lifecycle constraint. +- Reading latest-block fees while estimating pending state can underprice the estimate with multiplier 1. The regression reproduced `max fee per gas less than block base fee` before the fix; reading the pending block fixes that mismatch. Separate RPC calls can still observe advancing pending state. ## Decision Log - 2026-09-05 / Codex: Support type-2 (EIP-1559) transactions to an explicit address, with empty access list, initially. This matches the discussed default and avoids inventing support for wallet-specific execution, contract creation, blobs, or legacy fees. - 2026-09-05 / Codex: Require an expected positive bigint chain ID and a signer with an address and `signTransaction` method. Reuse existing `TransactionRequest`, `SignedTransaction`, and `TransactionPreparer`. Keep the new factory in `packages/ethereum/src/transaction-preparer.ts` and shared signing types in `transactions.ts`. -- 2026-09-05 / Codex: Read chain ID, pending nonce, latest block base fee/gas limit, suggested priority fee, then estimate gas against pending state with the completed call/fee fields. Check chain ID on every invocation. Default maximum fee is twice the current base fee plus the suggested priority fee. Default gas margin is 20%, rounded up. Configurable integer base-fee multiplier and margin, optional gas/fee ceilings, and block gas limit checks reject before signing rather than silently reducing values. +- 2026-09-05 / Codex, updated after user-approved review fix: Read chain ID, pending nonce, pending block base fee/gas limit, suggested priority fee, then estimate gas against pending state with the completed call/fee fields. Using pending for both the block lookup and estimate avoids the original latest/pending mismatch. Check chain ID on every invocation. Default maximum fee is twice the current base fee plus the suggested priority fee. Default gas margin is 20%, rounded up. Configurable integer base-fee multiplier and margin, optional gas/fee ceilings, and block gas limit checks reject before signing rather than silently reducing values. - 2026-09-05 / Codex: A configurable 30-second overall preparation deadline and the per-call abort signal cover RPC work and signing. Reuse `runWithRetry` with zero outer retries; individual RPC reads retain their existing retry policy. Sign only once and discard late results after cancellation. The signer is trusted to preserve the requested transaction and account; validate returned byte shapes, type-2 prefix, and hash correspondence with existing noble Keccak, without adding transaction decoding or key recovery. - 2026-09-05 / Codex: Do not reserve or increment nonces locally. Document serialization of the complete transaction lifecycle per account, including reconciliation of uncertain submissions, and the lack of coordination across processes. RPC IDs default to 1 and are configurable at factory creation; they are not signed fields. ## Outcomes & Retrospective -The factory and signer interface are implemented with no new dependencies or concrete wallet adapter. All 201 runtime tests across utils, IPFS, Ethereum, and messages pass, including 14 new factory tests. Both Ethereum/messages type suites, package-root imports, the build, and `git diff --check` pass. The Logger integration test demonstrates preparation followed by one submission and the expected receipt/event verification. No live RPC, production key, deployment, or wallet adapter was used. The remaining operational responsibility is intentionally the host's signer implementation and coordination of the complete transaction lifecycle per account; no implementation work remains for this task. +The factory and signer interface are implemented with no new dependencies or concrete wallet adapter. Initial validation passed all 201 runtime tests across utils, IPFS, Ethereum, and messages, including 14 new factory tests. The pending-block follow-up passed all 137 Ethereum/messages runtime tests, including the now 15 factory tests, both type suites, package import, the build, and `git diff --check`. The regression demonstrates successful preparation with differing block fees and multiplier 1, and rejection against the pending block's gas limit before signing. The Logger integration test demonstrates preparation followed by one submission and the expected receipt/event verification. No live RPC, production key, deployment, or wallet adapter was used. The remaining operational responsibility is intentionally the host's signer implementation and coordination of the complete transaction lifecycle per account; no implementation work remains for this task. ## Context and Orientation From 7814424f6af28102821d1a2625967fe2ea7cdc9a Mon Sep 17 00:00:00 2001 From: John Shutt Date: Sun, 6 Sep 2026 18:45:27 -0700 Subject: [PATCH 4/5] chainId config value does not need to be a bigint for realistic target chain ids Signed-off-by: John Shutt --- packages/ethereum/README.md | 8 +-- .../ethereum/dist/transaction-preparer.d.ts | 3 +- .../ethereum/dist/transaction-preparer.js | 8 +-- .../ethereum/dist/transaction-preparer.js.map | 2 +- packages/ethereum/dist/transactions.d.ts | 3 +- packages/ethereum/dist/transactions.js.map | 2 +- packages/ethereum/src/transaction-preparer.ts | 11 ++-- packages/ethereum/src/transactions.ts | 3 +- .../test/transaction-preparer-types.test.ts | 10 ++-- .../test/transaction-preparer.test.js | 52 ++++++++++++++++--- plans/default-transaction-preparer.md | 11 ++-- 11 files changed, 83 insertions(+), 30 deletions(-) diff --git a/packages/ethereum/README.md b/packages/ethereum/README.md index bb4e8a98..9c9a8d41 100644 --- a/packages/ethereum/README.md +++ b/packages/ethereum/README.md @@ -40,7 +40,7 @@ Hosts own transaction signing, environment configuration, and RPC endpoint disco - `TransactionRequest`: readonly `to`, `data`, `value: bigint` (wei), and optional `signal`. It describes call intent; the host supplies the remaining transaction fields. - `SignedTransaction`: readonly signed `rawTransaction` and its `transactionHash`. -- `UnsignedTransaction`: readonly `to`, `data`, `value`, `type: 2`, `chainId: bigint`, `nonce: number`, `gasLimit: bigint`, `maxFeePerGas: bigint`, and `maxPriorityFeePerGas: bigint`. The access list is empty. There is no embedded cancellation signal. +- `UnsignedTransaction`: readonly `to`, `data`, `value`, `type: 2`, `chainId: number` (positive safe integer), `nonce: number`, `gasLimit: bigint`, `maxFeePerGas: bigint`, and `maxPriorityFeePerGas: bigint`. The access list is empty. There is no embedded cancellation signal. - `TransactionSigner`: a readonly `address` and `signTransaction(transaction, signal?)` method returning `SignedTransaction`, synchronously or asynchronously. The host implements signing and must preserve all supplied fields, use the advertised account, and return without broadcasting. - `TransactionPreparer`: a callback from `TransactionRequest` to `SignedTransaction`, synchronously or asynchronously, without broadcasting. - `TransactionStage`: `'prepare' | 'submit' | 'receipt' | 'verify'`. Verification means the operation's checks after receiving a receipt, such as execution status and expected events. @@ -59,7 +59,7 @@ declare const signer: TransactionSigner; // Implemented by the host's wallet/sig const transactionPreparer = createTransactionPreparer({ config: rpcConfig, fetch: rpcFetch, - chainId: 1n, // The operator's expected network. + chainId: 1, // The operator's expected network; a positive safe integer. signer, gasLimitMarginPercent: 20, // Default: 20% above the estimate, rounded up. baseFeeMultiplier: 2, // Default: 2 * base fee + suggested priority fee. @@ -75,7 +75,9 @@ const logging = await logCid(cid, { }); ``` -Construction validates and snapshots configuration without making RPC calls. Each invocation validates and snapshots the call, checks `eth_chainId` against the configured positive bigint chain ID, reads `eth_getTransactionCount(address, "pending")`, obtains the pending block's base fee and gas limit, and reads `eth_maxPriorityFeePerGas`. It then calls `eth_estimateGas` against pending state with the signing address, recipient, calldata, value, chain ID, nonce, and selected fees. Fee selection and gas estimation both use pending state, although that state can advance between separate RPC calls. These methods follow the [Ethereum execution API](https://github.com/ethereum/execution-apis/tree/main/src/eth); the fee fields follow [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). +Construction validates and snapshots configuration without making RPC calls. `chainId` must be a `number` satisfying `Number.isSafeInteger(chainId) && chainId > 0`; bigint, string, fractional, nonpositive, and unsafe values are rejected. Update previous configurations such as `chainId: 1n` to `chainId: 1`. The signer receives the validated number and can use `BigInt(transaction.chainId)` if its wallet API requires bigint. + +Each invocation validates and snapshots the call, parses `eth_chainId` losslessly as bigint, and requires an exact match with `BigInt(chainId)`. Unsupported or mismatched RPC chain IDs reject before further RPC calls or signing; they are never rounded to a number. The preparer then reads `eth_getTransactionCount(address, "pending")`, obtains the pending block's base fee and gas limit, and reads `eth_maxPriorityFeePerGas`. It calls `eth_estimateGas` against pending state with the signing address, recipient, calldata, value, chain ID, nonce, and selected fees. Fee selection and gas estimation both use pending state, although that state can advance between separate RPC calls. These methods follow the [Ethereum execution API](https://github.com/ethereum/execution-apis/tree/main/src/eth); the fee fields follow [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). The gas limit is `ceil(estimate * (100 + gasLimitMarginPercent) / 100)`. The maximum fee per gas is `baseFee * baseFeeMultiplier + suggestedPriorityFee`; the priority fee is the RPC suggestion. The multiplier and margin are policy choices, not protocol requirements. Arithmetic uses bigint, and fee values are in wei per gas. Nonces above `Number.MAX_SAFE_INTEGER` reject before conversion for the signer. Both optional `limits` fields are ceilings: the factory rejects a selected value above a ceiling instead of reducing the gas buffer or fee suggestion. Omitting them adds no operator ceiling; the buffered gas limit must still fit the pending block's gas limit. A configured gas cap must be positive; a fee cap of zero is permitted. Networks without EIP-1559 base-fee data, unsupported RPC methods, malformed quantities, estimation errors, and out-of-range values reject before signing. diff --git a/packages/ethereum/dist/transaction-preparer.d.ts b/packages/ethereum/dist/transaction-preparer.d.ts index f1d752a8..c5aa9fd3 100644 --- a/packages/ethereum/dist/transaction-preparer.d.ts +++ b/packages/ethereum/dist/transaction-preparer.d.ts @@ -3,7 +3,8 @@ import type { TransactionPreparer, TransactionSigner } from './transactions.js'; interface CreateTransactionPreparerOptions { config: HttpConfig; fetch: HttpPostFetchLike; - chainId: bigint; + /** Expected network ID; must be a positive safe integer. */ + chainId: number; signer: TransactionSigner; /** Whole percent added to the estimate, rounded up. Default: 20. */ gasLimitMarginPercent?: number; diff --git a/packages/ethereum/dist/transaction-preparer.js b/packages/ethereum/dist/transaction-preparer.js index 53ea38a9..6e402b19 100644 --- a/packages/ethereum/dist/transaction-preparer.js +++ b/packages/ethereum/dist/transaction-preparer.js @@ -20,10 +20,10 @@ function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMar const rpcConfig = createHttpConfig(config); assertTimerMs(rpcConfig.timeoutMs, 'config.timeoutMs'); const deadlineMs = assertTimerMs(timeoutMs, 'timeoutMs'); - const expectedChainId = assertUint256(chainId, 'chainId'); - if (expectedChainId === 0n) { - throw new Error('chainId must be positive.'); + if (!Number.isSafeInteger(chainId) || chainId < 1) { + throw new Error('chainId must be a positive safe integer.'); } + const expectedChainId = BigInt(chainId); const requestId = normalizeJsonRpcId(id); if (typeof fetch !== 'function') { throw new TypeError('fetch must be provided as a function.'); @@ -111,7 +111,7 @@ function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMar throw new Error('Buffered gas limit exceeds limits.gasLimit.'); } const transaction = Object.freeze({ - ...call, type: 2, chainId: expectedChainId, nonce: Number(nonce), + ...call, type: 2, chainId, nonce: Number(nonce), gasLimit, maxFeePerGas, maxPriorityFeePerGas, }); throwIfSignalAborted(operationSignal, abortMessage, operationSignal?.reason); diff --git a/packages/ethereum/dist/transaction-preparer.js.map b/packages/ethereum/dist/transaction-preparer.js.map index 560ba196..968958ed 100644 --- a/packages/ethereum/dist/transaction-preparer.js.map +++ b/packages/ethereum/dist/transaction-preparer.js.map @@ -1 +1 @@ -{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/transactions.d.ts b/packages/ethereum/dist/transactions.d.ts index 54096a67..7dcfddf2 100644 --- a/packages/ethereum/dist/transactions.d.ts +++ b/packages/ethereum/dist/transactions.d.ts @@ -15,7 +15,8 @@ interface SignedTransaction { /** Fully specified EIP-1559 call with an empty access list. */ interface UnsignedTransaction extends Omit { readonly type: 2; - readonly chainId: bigint; + /** Positive safe integer identifying the expected network. */ + readonly chainId: number; /** Nonces outside the safe integer range are rejected before signing. */ readonly nonce: number; readonly gasLimit: bigint; diff --git a/packages/ethereum/dist/transactions.js.map b/packages/ethereum/dist/transactions.js.map index b15c60f3..b952847a 100644 --- a/packages/ethereum/dist/transactions.js.map +++ b/packages/ethereum/dist/transactions.js.map @@ -1 +1 @@ -{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"transactions.js","sourceRoot":"","sources":["../src/transactions.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/src/transaction-preparer.ts b/packages/ethereum/src/transaction-preparer.ts index 4c465c80..25f9795e 100644 --- a/packages/ethereum/src/transaction-preparer.ts +++ b/packages/ethereum/src/transaction-preparer.ts @@ -16,7 +16,8 @@ import type { SignedTransaction, TransactionPreparer, TransactionSigner, Unsigne interface CreateTransactionPreparerOptions { config: HttpConfig; fetch: HttpPostFetchLike; - chainId: bigint; + /** Expected network ID; must be a positive safe integer. */ + chainId: number; signer: TransactionSigner; /** Whole percent added to the estimate, rounded up. Default: 20. */ gasLimitMarginPercent?: number; @@ -54,10 +55,10 @@ function createTransactionPreparer({ const rpcConfig = createHttpConfig(config); assertTimerMs(rpcConfig.timeoutMs, 'config.timeoutMs'); const deadlineMs = assertTimerMs(timeoutMs, 'timeoutMs'); - const expectedChainId = assertUint256(chainId, 'chainId'); - if (expectedChainId === 0n) { - throw new Error('chainId must be positive.'); + if (!Number.isSafeInteger(chainId) || chainId < 1) { + throw new Error('chainId must be a positive safe integer.'); } + const expectedChainId = BigInt(chainId); const requestId = normalizeJsonRpcId(id); if (typeof fetch !== 'function') { throw new TypeError('fetch must be provided as a function.'); @@ -153,7 +154,7 @@ function createTransactionPreparer({ throw new Error('Buffered gas limit exceeds limits.gasLimit.'); } const transaction: Readonly = Object.freeze({ - ...call, type: 2, chainId: expectedChainId, nonce: Number(nonce), + ...call, type: 2, chainId, nonce: Number(nonce), gasLimit, maxFeePerGas, maxPriorityFeePerGas, }); throwIfSignalAborted(operationSignal, abortMessage, operationSignal?.reason); diff --git a/packages/ethereum/src/transactions.ts b/packages/ethereum/src/transactions.ts index b77e5130..f1e249e8 100644 --- a/packages/ethereum/src/transactions.ts +++ b/packages/ethereum/src/transactions.ts @@ -38,7 +38,8 @@ interface SignedTransaction { /** Fully specified EIP-1559 call with an empty access list. */ interface UnsignedTransaction extends Omit { readonly type: 2; - readonly chainId: bigint; + /** Positive safe integer identifying the expected network. */ + readonly chainId: number; /** Nonces outside the safe integer range are rejected before signing. */ readonly nonce: number; readonly gasLimit: bigint; diff --git a/packages/ethereum/test/transaction-preparer-types.test.ts b/packages/ethereum/test/transaction-preparer-types.test.ts index 961efd80..22ae5650 100644 --- a/packages/ethereum/test/transaction-preparer-types.test.ts +++ b/packages/ethereum/test/transaction-preparer-types.test.ts @@ -12,7 +12,7 @@ declare const loggerOptions: LogCidOptions; const signer: TransactionSigner = { address: '0x1111111111111111111111111111111111111111', signTransaction(transaction, signal) { - const fields: readonly [2, bigint, number, bigint, bigint, bigint] = [ + const fields: readonly [2, number, number, bigint, bigint, bigint] = [ transaction.type, transaction.chainId, transaction.nonce, transaction.gasLimit, transaction.maxFeePerGas, transaction.maxPriorityFeePerGas, ]; @@ -27,15 +27,17 @@ const signer: TransactionSigner = { }; const asynchronousSigner: TransactionSigner = { ...signer, signTransaction: async () => signed }; const preparer: TransactionPreparer = createTransactionPreparer({ - ...options, signer, chainId: 1n, gasLimitMarginPercent: 20, baseFeeMultiplier: 2, + ...options, signer, chainId: 1, gasLimitMarginPercent: 20, baseFeeMultiplier: 2, limits: { gasLimit: 100_000n, feePerGas: 30_000_000_000n }, timeoutMs: 30_000, id: 'prepare', }); const result: SignedTransaction = await preparer(request); const logging = logCid('cid', { ...loggerOptions, transactionPreparer: preparer }); declare const transaction: UnsignedTransaction; const call: Omit = transaction; -// @ts-expect-error Chain IDs use bigint to preserve precision. -createTransactionPreparer({ ...options, chainId: 1 }); +// @ts-expect-error Public chain IDs use numbers, validated at runtime as positive safe integers. +createTransactionPreparer({ ...options, chainId: 1n }); +// @ts-expect-error Chain ID strings must be converted and validated before use. +createTransactionPreparer({ ...options, chainId: '1' }); // @ts-expect-error A signing adapter must provide its address and signing method. createTransactionPreparer({ ...options, signer: { address: signer.address } }); // @ts-expect-error Fee limits are denominated in integer wei. diff --git a/packages/ethereum/test/transaction-preparer.test.js b/packages/ethereum/test/transaction-preparer.test.js index f6e2eb4d..5c91d372 100644 --- a/packages/ethereum/test/transaction-preparer.test.js +++ b/packages/ethereum/test/transaction-preparer.test.js @@ -31,7 +31,7 @@ function fixture(overrides = {}) { assert.ok(body.method in results, `Unexpected RPC method ${body.method}`); return response(results[body.method], body.id); }, - chainId: 1n, + chainId: 1, signer: { address: node, signTransaction(transaction, signal) { @@ -56,7 +56,7 @@ test('the factory creates a frozen EIP-1559 transaction with current RPC values assert.ok(Object.isFrozen(signatures[0].transaction)); assert.equal('signal' in signatures[0].transaction, false); assert.deepEqual(signatures[0].transaction, { - ...request, type: 2, chainId: 1n, nonce: 3, + ...request, type: 2, chainId: 1, nonce: 3, gasLimit: 25_202n, maxFeePerGas: 202n, maxPriorityFeePerGas: 2n, }); assert.deepEqual(calls.map(({ method, params, id }) => ({ method, params, id })), [ @@ -107,12 +107,11 @@ test('fees and gas limits use the pending block when the base fee multiplier is assert.equal(signatures.length, 1); }); -test('policies support exact ceilings, zero fees, empty calldata, large chain IDs, and fresh nonces', async () => { +test('policies support exact ceilings, zero fees, empty calldata, and fresh nonces', async () => { const { options, results, calls, signatures } = fixture({ - chainId: 9_007_199_254_740_993n, id: 'prepare-42', gasLimitMarginPercent: 0, baseFeeMultiplier: 3, + id: 'prepare-42', gasLimitMarginPercent: 0, baseFeeMultiplier: 3, limits: { gasLimit: 21_001n, feePerGas: 302n }, }); - results.eth_chainId = '0x20000000000001'; const prepare = createTransactionPreparer(options); await prepare({ ...request, data: '0x', value: 0n }); assert.equal(signatures[0].transaction.maxFeePerGas, 302n); @@ -129,9 +128,47 @@ test('policies support exact ceilings, zero fees, empty calldata, large chain ID assert.equal(signatures.length, 2); }); +test('the largest safe chain ID is passed exactly to estimation and signing', async () => { + const { options, results, calls, signatures } = fixture({ chainId: Number.MAX_SAFE_INTEGER }); + results.eth_chainId = '0x1fffffffffffff'; + await createTransactionPreparer(options)(request); + assert.equal(signatures[0].transaction.chainId, Number.MAX_SAFE_INTEGER); + assert.equal(calls.find(({ method }) => method === 'eth_estimateGas').params[0].chainId, + '0x1fffffffffffff'); +}); + +test('unsupported configured chain IDs reject before RPC or signing', () => { + for (const chainId of [ + 0, -1, 1.5, Number.MAX_SAFE_INTEGER + 1, NaN, Infinity, -Infinity, + 1n, '1', '0x1', null, undefined, + ]) { + const { options, calls, signatures } = fixture({ chainId }); + assert.throws(() => createTransactionPreparer(options), /chainId must be a positive safe integer/); + assert.equal(calls.length, 0); + assert.equal(signatures.length, 0); + } +}); + +test('unsupported RPC chain IDs reject losslessly before further RPC calls or signing', async () => { + for (const [rpcChainId, exactChainId] of [ + ['0x0', '0'], + ['0x20000000000000', '9007199254740992'], + ['0x20000000000001', '9007199254740993'], + ['0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', + '115792089237316195423570985008687907853269984665640564039457584007913129639935'], + ]) { + const { options, results, calls, signatures } = fixture({ chainId: Number.MAX_SAFE_INTEGER }); + results.eth_chainId = rpcChainId; + await assert.rejects(createTransactionPreparer(options)(request), { + message: `RPC chain ID ${exactChainId} did not match configured chainId ${Number.MAX_SAFE_INTEGER}.`, + }); + assert.deepEqual(calls.map(({ method }) => method), ['eth_chainId']); + assert.equal(signatures.length, 0); + } +}); + test('invalid factory configuration is rejected before RPC or signing', () => { const invalid = [ - { chainId: 1 }, { chainId: 0n }, { chainId: -1n }, { chainId: 1n << 256n }, { signer: null }, { signer: { address: node } }, { signer: { address: '0x1234', signTransaction() {} } }, { fetch: null }, { id: '' }, { id: 1.5 }, { id: Number.MAX_SAFE_INTEGER + 1 }, @@ -167,6 +204,7 @@ test('malformed RPC results, unsupported fees, and unsafe quantities never reach const cases = [ ['eth_chainId', '0x2', /did not match configured chainId/], ['eth_chainId', '0x01', /without leading zeros/], + ['eth_chainId', '0x' + 'f'.repeat(65), /256 bits/], ['eth_getTransactionCount', '0x20000000000000', /safe integer/], ['eth_getTransactionCount', '-0x1', /quantity/], ['eth_getBlockByNumber', null, /baseFeePerGas/], @@ -253,6 +291,7 @@ test('configuration and call fields are snapshotted before asynchronous work', a return fetch(url, init); }; const prepare = createTransactionPreparer(options); + options.chainId = 2; options.config.url = 'https://changed.example'; options.config.headers.Authorization = 'changed'; options.limits.gasLimit = 1n; @@ -267,6 +306,7 @@ test('configuration and call fields are snapshotted before asynchronous work', a mutableRequest.value = 99n; release.resolve(); await promise; + assert.equal(signatures[0].transaction.chainId, 1); assert.equal(signatures[0].transaction.to, request.to); assert.equal(signatures[0].transaction.data, request.data); assert.equal(signatures[0].transaction.value, request.value); diff --git a/plans/default-transaction-preparer.md b/plans/default-transaction-preparer.md index 0a06bd81..417c214d 100644 --- a/plans/default-transaction-preparer.md +++ b/plans/default-transaction-preparer.md @@ -13,6 +13,8 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p - [x] 2026-09-05 20:41Z: Added 14 passing runtime tests including Logger integration and uncooperative signer cancellation. Ethereum type tests passed. - [x] 2026-09-05 20:44Z: Updated Ethereum/utils documentation, rebuilt tracked output, reviewed the implementation/declarations, and passed all 201 package runtime tests, Ethereum/messages type checks, package imports, and whitespace checks. Dependency metadata is unchanged. - [x] 2026-09-05 21:06Z: Aligned the block fee/gas-limit lookup with pending gas estimation. Added a regression for differing latest/pending fees with multiplier 1, updated documentation/errors, rebuilt output, and passed all 137 Ethereum/messages runtime tests, both type suites, package import, and whitespace checks. +- [x] 2026-09-07 01:43Z: Audited public chain ID usage and changed factory/signing types to positive safe integer numbers while preserving bigint RPC parsing/comparison. Updated runtime/type coverage and documentation. +- [x] 2026-09-07 01:44Z: Rebuilt tracked output and reviewed the final diff. All 140 Ethereum/messages runtime tests, both type suites, package import, and whitespace checks passed for the chain ID change. ## Surprises & Discoveries @@ -20,11 +22,12 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p - Canonical RPC quantity parsing originally lived in `receipt-utils.ts`; it now lives in `request-utils.ts`. Bounded timer validation originally lived in `receipts.ts`; it is now exported by `@oyaprotocol/utils` from `async-utils.ts`, following the user's requested relocation. - A preparer cannot coordinate nonce reuse through submission because its callback finishes before broadcasting starts. An internal queue would not solve this lifecycle constraint. - Reading latest-block fees while estimating pending state can underprice the estimate with multiplier 1. The regression reproduced `max fee per gas less than block base fee` before the fix; reading the pending block fixes that mismatch. Separate RPC calls can still observe advancing pending state. +- Public chain IDs only occur in the Ethereum factory and unsigned transaction interface. Keeping the existing bigint RPC comparison against the validated configured ID rejects unsupported RPC IDs without converting or rounding them; the signer receives the configured number. ## Decision Log - 2026-09-05 / Codex: Support type-2 (EIP-1559) transactions to an explicit address, with empty access list, initially. This matches the discussed default and avoids inventing support for wallet-specific execution, contract creation, blobs, or legacy fees. -- 2026-09-05 / Codex: Require an expected positive bigint chain ID and a signer with an address and `signTransaction` method. Reuse existing `TransactionRequest`, `SignedTransaction`, and `TransactionPreparer`. Keep the new factory in `packages/ethereum/src/transaction-preparer.ts` and shared signing types in `transactions.ts`. +- 2026-09-05 / Codex, updated 2026-09-07 after user approval: Require an expected positive safe integer `number` chain ID and a signer with an address and `signTransaction` method. This replaces the original bigint chain ID interface to simplify host configuration and wallet integrations for supported target chains. Reject invalid configuration before RPC work, preserve bigint RPC parsing and exact comparison against `BigInt(chainId)`, and pass the validated number to the signer. Amounts, gas limits, and fees remain bigint. Reuse existing `TransactionRequest`, `SignedTransaction`, and `TransactionPreparer`. Keep the new factory in `packages/ethereum/src/transaction-preparer.ts` and shared signing types in `transactions.ts`. - 2026-09-05 / Codex, updated after user-approved review fix: Read chain ID, pending nonce, pending block base fee/gas limit, suggested priority fee, then estimate gas against pending state with the completed call/fee fields. Using pending for both the block lookup and estimate avoids the original latest/pending mismatch. Check chain ID on every invocation. Default maximum fee is twice the current base fee plus the suggested priority fee. Default gas margin is 20%, rounded up. Configurable integer base-fee multiplier and margin, optional gas/fee ceilings, and block gas limit checks reject before signing rather than silently reducing values. - 2026-09-05 / Codex: A configurable 30-second overall preparation deadline and the per-call abort signal cover RPC work and signing. Reuse `runWithRetry` with zero outer retries; individual RPC reads retain their existing retry policy. Sign only once and discard late results after cancellation. The signer is trusted to preserve the requested transaction and account; validate returned byte shapes, type-2 prefix, and hash correspondence with existing noble Keccak, without adding transaction decoding or key recovery. - 2026-09-05 / Codex: Do not reserve or increment nonces locally. Document serialization of the complete transaction lifecycle per account, including reconciliation of uncertain submissions, and the lack of coordination across processes. RPC IDs default to 1 and are configurable at factory creation; they are not signed fields. @@ -33,6 +36,8 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p The factory and signer interface are implemented with no new dependencies or concrete wallet adapter. Initial validation passed all 201 runtime tests across utils, IPFS, Ethereum, and messages, including 14 new factory tests. The pending-block follow-up passed all 137 Ethereum/messages runtime tests, including the now 15 factory tests, both type suites, package import, the build, and `git diff --check`. The regression demonstrates successful preparation with differing block fees and multiplier 1, and rejection against the pending block's gas limit before signing. The Logger integration test demonstrates preparation followed by one submission and the expected receipt/event verification. No live RPC, production key, deployment, or wallet adapter was used. The remaining operational responsibility is intentionally the host's signer implementation and coordination of the complete transaction lifecycle per account; no implementation work remains for this task. +The chain ID follow-up changes public configuration and signing fields to `number`, with positive safe integer validation and lossless bigint RPC comparison. Tests cover the largest safe ID, rejected configuration values, and exact errors for unsupported RPC IDs through the uint256 maximum. Tracked output is rebuilt, all 140 Ethereum/messages runtime tests (including 18 factory tests) passed, and both type suites, package import, and whitespace checks passed. No work remains for this follow-up. + ## Context and Orientation `packages/ethereum/src/transactions.ts` defines call intent (`to`, `data`, `value`, optional signal), a prepared signed result, and the existing callback accepted by Logger. `logger.ts` invokes that callback, submits bytes, waits for a receipt, and verifies an event. `request-utils.ts` performs JSON-RPC reads with bounded retries and response-envelope checks. `packages/utils/src/async-utils.ts` provides cancellation, deadlines, and retry composition. `packages/messages` composes IPFS publication with Logger; its API requires no change. Tracked `dist` files are rebuilt with TypeScript. Root and package `AGENTS.md` apply. @@ -58,7 +63,7 @@ Smoke-import changed package roots with Node from `packages/`. Expect no missing ## Validation and Acceptance -Tests must prove exact default fields and RPC parameters (including pending nonce/state, request ID, fee fields and rounding), refreshed values across calls, configured overrides/caps, early rejection of invalid configuration, malformed or oversized quantities, unsupported fee data, chain mismatch and gas estimation errors. Cancellation before RPC, during RPC, and during an uncooperative signer must settle promptly, prevent later signing/submission, and preserve original objects. Retryable reads may retry, but signer failures never retry. Returned hashes must match signed bytes. A Logger integration test must show a completed signing request followed by one submission and the correct event verification. Type tests must establish public imports, callback compatibility, bigint fields, immutability, and required signer methods. +Tests must prove exact default fields and RPC parameters (including pending nonce/state, request ID, fee fields and rounding), refreshed values across calls, configured overrides/caps, early rejection of invalid configuration, malformed or oversized quantities, unsupported fee data, chain mismatch and gas estimation errors. Chain ID tests must accept `Number.MAX_SAFE_INTEGER` exactly in estimation and signing, reject non-number/nonpositive/fractional/unsafe configuration before RPC work, and reject unsupported RPC IDs while preserving their exact values in errors and preventing further reads or signing. Cancellation before RPC, during RPC, and during an uncooperative signer must settle promptly, prevent later signing/submission, and preserve original objects. Retryable reads may retry, but signer failures never retry. Returned hashes must match signed bytes. A Logger integration test must show a completed signing request followed by one submission and the correct event verification. Type tests must establish public imports, callback compatibility, number chain IDs and nonces, bigint amount/gas/fee fields, immutability, and required signer methods. ## Idempotence and Recovery @@ -72,4 +77,4 @@ Independent fixture check: `cast keccak 0x02abcd` returned `0xe3607eedbe2ea88ad1 ## Interfaces and Dependencies -`createTransactionPreparer(options)` returns the existing `TransactionPreparer`. Options include `config`, `fetch`, `chainId: bigint`, `signer`, optional `gasLimitMarginPercent` (20), `baseFeeMultiplier` (2), `limits: { gasLimit?: bigint; feePerGas?: bigint }`, `timeoutMs` (30000), and JSON-RPC `id` (1). `UnsignedTransaction` adds type 2, chain ID, a safe-integer nonce, gas limit and both fee fields to the existing call intent without its signal. `TransactionSigner` exposes an address and a signing method accepting the unsigned transaction and optional abort signal, returning `SignedTransaction` synchronously or asynchronously. Existing `@noble/hashes` and `@oyaprotocol/utils` are sufficient; package metadata remains unchanged. +`createTransactionPreparer(options)` returns the existing `TransactionPreparer`. Options include `config`, `fetch`, `chainId: number` (positive safe integer), `signer`, optional `gasLimitMarginPercent` (20), `baseFeeMultiplier` (2), `limits: { gasLimit?: bigint; feePerGas?: bigint }`, `timeoutMs` (30000), and JSON-RPC `id` (1). `UnsignedTransaction` adds type 2, the validated number chain ID, a safe-integer nonce, gas limit and both fee fields to the existing call intent without its signal. RPC quantities remain bigint internally; host signer adapters can convert the validated numeric chain ID to bigint if needed by their wallet API. `TransactionSigner` exposes an address and a signing method accepting the unsigned transaction and optional abort signal, returning `SignedTransaction` synchronously or asynchronously. Existing `@noble/hashes` and `@oyaprotocol/utils` are sufficient; package metadata remains unchanged. From 7c9374d43d6543aa039dbe7a7e8c350298575633 Mon Sep 17 00:00:00 2001 From: John Shutt Date: Sun, 6 Sep 2026 19:02:26 -0700 Subject: [PATCH 5/5] extract some utility functions from transaction-preparer Signed-off-by: John Shutt --- packages/ethereum/dist/request-utils.d.ts | 3 ++- packages/ethereum/dist/request-utils.js | 8 +++++++- packages/ethereum/dist/request-utils.js.map | 2 +- .../ethereum/dist/transaction-preparer.js | 17 ++--------------- .../ethereum/dist/transaction-preparer.js.map | 2 +- packages/ethereum/src/request-utils.ts | 8 ++++++++ packages/ethereum/src/transaction-preparer.ts | 19 ++----------------- packages/utils/README.md | 1 + packages/utils/dist/index.d.ts | 2 +- packages/utils/dist/index.js | 2 +- packages/utils/dist/index.js.map | 2 +- packages/utils/dist/validation-utils.d.ts | 3 ++- packages/utils/dist/validation-utils.js | 9 ++++++++- packages/utils/dist/validation-utils.js.map | 2 +- packages/utils/src/index.ts | 1 + packages/utils/src/validation-utils.ts | 10 ++++++++++ plans/default-transaction-preparer.md | 5 +++++ 17 files changed, 54 insertions(+), 42 deletions(-) diff --git a/packages/ethereum/dist/request-utils.d.ts b/packages/ethereum/dist/request-utils.d.ts index e2885f39..5850dfa6 100644 --- a/packages/ethereum/dist/request-utils.d.ts +++ b/packages/ethereum/dist/request-utils.d.ts @@ -33,6 +33,7 @@ declare class EthereumJsonRpcError extends Error { } declare function normalizeJsonRpcId(id: unknown): string | number; declare function parseQuantity(value: unknown, name: string): bigint; +declare function parseTransactionQuantity(value: unknown, name: string): bigint; declare function requestEthereumJsonRpcWithCustomRetryPolicy({ config, fetch, method, params, id, signal, }: RequestEthereumJsonRpcOptions, shouldRetryJsonRpcMethod: (method: string) => boolean): Promise>; declare function requestEthereumJsonRpc(options: RequestEthereumJsonRpcOptions): Promise>; -export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; +export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, parseTransactionQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; diff --git a/packages/ethereum/dist/request-utils.js b/packages/ethereum/dist/request-utils.js index 096d1065..5b4bd2dc 100644 --- a/packages/ethereum/dist/request-utils.js +++ b/packages/ethereum/dist/request-utils.js @@ -108,6 +108,12 @@ function parseQuantity(value, name) { } return BigInt(value); } +function parseTransactionQuantity(value, name) { + if (typeof value === 'string' && value.length > 66) { + throw new Error(`${name} must fit in 256 bits.`); + } + return parseQuantity(value, name); +} function buildJsonRpcBody({ id, method, params, }) { try { return JSON.stringify({ @@ -229,5 +235,5 @@ async function requestEthereumJsonRpcWithCustomRetryPolicy({ config, fetch, meth async function requestEthereumJsonRpc(options) { return await requestEthereumJsonRpcWithCustomRetryPolicy(options, shouldRetryMethod); } -export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; +export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, parseTransactionQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; //# sourceMappingURL=request-utils.js.map \ No newline at end of file diff --git a/packages/ethereum/dist/request-utils.js.map b/packages/ethereum/dist/request-utils.js.map index 85706f92..85ff6942 100644 --- a/packages/ethereum/dist/request-utils.js.map +++ b/packages/ethereum/dist/request-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"request-utils.js","sourceRoot":"","sources":["../src/request-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"request-utils.js","sourceRoot":"","sources":["../src/request-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/dist/transaction-preparer.js b/packages/ethereum/dist/transaction-preparer.js index 6e402b19..99d0332a 100644 --- a/packages/ethereum/dist/transaction-preparer.js +++ b/packages/ethereum/dist/transaction-preparer.js @@ -1,20 +1,7 @@ import { keccak_256 } from '@noble/hashes/sha3.js'; import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'; -import { assertTimerMs, createHttpConfig, isPlainObject, parseBytes, runWithRetry, throwIfSignalAborted, } from '@oyaprotocol/utils'; -import { normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc } from './request-utils.js'; -const UINT256_MAX = (1n << 256n) - 1n; -function assertUint256(value, name) { - if (typeof value !== 'bigint' || value < 0n || value > UINT256_MAX) { - throw new Error(`${name} must be a non-negative bigint fitting in 256 bits.`); - } - return value; -} -function parseTransactionQuantity(value, name) { - if (typeof value === 'string' && value.length > 66) { - throw new Error(`${name} must fit in 256 bits.`); - } - return parseQuantity(value, name); -} +import { assertTimerMs, assertUint256, createHttpConfig, isPlainObject, parseBytes, runWithRetry, throwIfSignalAborted, } from '@oyaprotocol/utils'; +import { normalizeJsonRpcId, parseTransactionQuantity, requestEthereumJsonRpc } from './request-utils.js'; /** Prepare direct account calls; the host coordinates nonces through submission. */ function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMarginPercent = 20, baseFeeMultiplier = 2, limits, timeoutMs = 30_000, id, }) { const rpcConfig = createHttpConfig(config); diff --git a/packages/ethereum/dist/transaction-preparer.js.map b/packages/ethereum/dist/transaction-preparer.js.map index 968958ed..932a0355 100644 --- a/packages/ethereum/dist/transaction-preparer.js.map +++ b/packages/ethereum/dist/transaction-preparer.js.map @@ -1 +1 @@ -{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"transaction-preparer.js","sourceRoot":"","sources":["../src/transaction-preparer.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/ethereum/src/request-utils.ts b/packages/ethereum/src/request-utils.ts index d6fee67b..9ccb337b 100644 --- a/packages/ethereum/src/request-utils.ts +++ b/packages/ethereum/src/request-utils.ts @@ -157,6 +157,13 @@ function parseQuantity(value: unknown, name: string): bigint { return BigInt(value); } +function parseTransactionQuantity(value: unknown, name: string): bigint { + if (typeof value === 'string' && value.length > 66) { + throw new Error(`${name} must fit in 256 bits.`); + } + return parseQuantity(value, name); +} + function buildJsonRpcBody({ id, method, @@ -324,6 +331,7 @@ export { EthereumJsonRpcError, normalizeJsonRpcId, parseQuantity, + parseTransactionQuantity, requestEthereumJsonRpc, requestEthereumJsonRpcWithCustomRetryPolicy, }; diff --git a/packages/ethereum/src/transaction-preparer.ts b/packages/ethereum/src/transaction-preparer.ts index 25f9795e..da59544a 100644 --- a/packages/ethereum/src/transaction-preparer.ts +++ b/packages/ethereum/src/transaction-preparer.ts @@ -2,6 +2,7 @@ import { keccak_256 } from '@noble/hashes/sha3.js'; import { bytesToHex, hexToBytes } from '@noble/hashes/utils.js'; import { assertTimerMs, + assertUint256, createHttpConfig, isPlainObject, parseBytes, @@ -10,7 +11,7 @@ import { } from '@oyaprotocol/utils'; import type { HttpConfig, HttpPostFetchLike } from '@oyaprotocol/utils'; -import { normalizeJsonRpcId, parseQuantity, requestEthereumJsonRpc } from './request-utils.js'; +import { normalizeJsonRpcId, parseTransactionQuantity, requestEthereumJsonRpc } from './request-utils.js'; import type { SignedTransaction, TransactionPreparer, TransactionSigner, UnsignedTransaction } from './transactions.js'; interface CreateTransactionPreparerOptions { @@ -31,22 +32,6 @@ interface CreateTransactionPreparerOptions { id?: string | number; } -const UINT256_MAX = (1n << 256n) - 1n; - -function assertUint256(value: unknown, name: string): bigint { - if (typeof value !== 'bigint' || value < 0n || value > UINT256_MAX) { - throw new Error(`${name} must be a non-negative bigint fitting in 256 bits.`); - } - return value; -} - -function parseTransactionQuantity(value: unknown, name: string): bigint { - if (typeof value === 'string' && value.length > 66) { - throw new Error(`${name} must fit in 256 bits.`); - } - return parseQuantity(value, name); -} - /** Prepare direct account calls; the host coordinates nonces through submission. */ function createTransactionPreparer({ config, fetch, chainId, signer, gasLimitMarginPercent = 20, diff --git a/packages/utils/README.md b/packages/utils/README.md index 4ab10df3..2ed37b2f 100644 --- a/packages/utils/README.md +++ b/packages/utils/README.md @@ -16,6 +16,7 @@ Small shared utilities for hardened Oya kernel packages. - `assertHexString(value, label)` - `assertPositiveInteger(value, label)` - `assertNonNegativeInteger(value, label)` +- `assertUint256(value, name)`: requires a bigint from `0n` through `(1n << 256n) - 1n`, returning the original value. - `assertHeadersObject(headers, label, options)` - `isPlainObject(value)` - `parseBytes(value, name, size?)`: validates `0x`-prefixed, byte-aligned hex, optionally requiring an exact byte count. Returns the original string without trimming; accepts `0x` when no size is required. diff --git a/packages/utils/dist/index.d.ts b/packages/utils/dist/index.d.ts index 4365256c..7157e855 100644 --- a/packages/utils/dist/index.d.ts +++ b/packages/utils/dist/index.d.ts @@ -3,4 +3,4 @@ export { assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbor export type { AbortSignalHandle, RunWithRetryAttemptContext, RunWithRetryOptions, } from './async-utils.js'; export { HttpStatusError, RETRYABLE_HTTP_NETWORK_ERROR_CODES, createHttpConfig, hasRetryableNetworkErrorCode, readErrorStringChain, } from './http-utils.js'; export type { CreateHttpConfigOptions, HttpConfig, HttpFetchLike, HttpPostFetchLike, HttpPostFetchOptions, HttpStatusErrorOptions, HttpTextResponse, } from './http-utils.js'; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, } from './validation-utils.js'; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertUint256, isPlainObject, parseBytes, } from './validation-utils.js'; diff --git a/packages/utils/dist/index.js b/packages/utils/dist/index.js index ebacd4a0..a085c458 100644 --- a/packages/utils/dist/index.js +++ b/packages/utils/dist/index.js @@ -1,5 +1,5 @@ export { assertCanonicalCid } from './cid-utils.js'; export { assertTimerMs, combineAbortSignals, createTimeoutSignal, invokeWithAbort, runWithRetry, throwIfSignalAborted, waitForRetryDelay, } from './async-utils.js'; export { HttpStatusError, RETRYABLE_HTTP_NETWORK_ERROR_CODES, createHttpConfig, hasRetryableNetworkErrorCode, readErrorStringChain, } from './http-utils.js'; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, } from './validation-utils.js'; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertUint256, isPlainObject, parseBytes, } from './validation-utils.js'; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/utils/dist/index.js.map b/packages/utils/dist/index.js.map index 3e943ff4..29e19647 100644 --- a/packages/utils/dist/index.js.map +++ b/packages/utils/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACH,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACH,eAAe,EACf,kCAAkC,EAClC,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,UAAU,GACb,MAAM,uBAAuB,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACH,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACpB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACH,eAAe,EACf,kCAAkC,EAClC,gBAAgB,EAChB,4BAA4B,EAC5B,oBAAoB,GACvB,MAAM,iBAAiB,CAAC;AAWzB,OAAO,EACH,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,qBAAqB,EACrB,aAAa,EACb,aAAa,EACb,UAAU,GACb,MAAM,uBAAuB,CAAC"} \ No newline at end of file diff --git a/packages/utils/dist/validation-utils.d.ts b/packages/utils/dist/validation-utils.d.ts index 55d31847..f6e44d62 100644 --- a/packages/utils/dist/validation-utils.d.ts +++ b/packages/utils/dist/validation-utils.d.ts @@ -1,6 +1,7 @@ declare function assertNonEmptyString(value: unknown, label: string): string; declare function assertPositiveInteger(value: unknown, label: string): number; declare function assertNonNegativeInteger(value: unknown, label: string): number; +declare function assertUint256(value: unknown, name: string): bigint; declare function isPlainObject(value: unknown): value is Record; declare function assertHeadersObject(headers: unknown, label: string, options?: { disallowedNames?: string[]; @@ -10,4 +11,4 @@ declare function assertHexString(value: unknown, label: string): string; declare function assertHexData(value: unknown, label: string): string; declare function assertBytes32HexString(value: unknown, label: string): string; declare function parseBytes(value: unknown, name: string, size?: number): string; -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, }; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertUint256, isPlainObject, parseBytes, }; diff --git a/packages/utils/dist/validation-utils.js b/packages/utils/dist/validation-utils.js index f6a73879..53bd5ef4 100644 --- a/packages/utils/dist/validation-utils.js +++ b/packages/utils/dist/validation-utils.js @@ -1,3 +1,4 @@ +const UINT256_MAX = (1n << 256n) - 1n; function assertNonEmptyString(value, label) { if (typeof value !== 'string' || !value.trim()) { throw new Error(`${label} must be a non-empty string.`); @@ -16,6 +17,12 @@ function assertNonNegativeInteger(value, label) { } return value; } +function assertUint256(value, name) { + if (typeof value !== 'bigint' || value < 0n || value > UINT256_MAX) { + throw new Error(`${name} must be a non-negative bigint fitting in 256 bits.`); + } + return value; +} function isPlainObject(value) { if (value === null || typeof value !== 'object' || Array.isArray(value)) { return false; @@ -76,5 +83,5 @@ function parseBytes(value, name, size) { } return value; } -export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, isPlainObject, parseBytes, }; +export { assertAsciiBytes, assertBytes32HexString, assertHeadersObject, assertHexData, assertHexString, assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, assertUint256, isPlainObject, parseBytes, }; //# sourceMappingURL=validation-utils.js.map \ No newline at end of file diff --git a/packages/utils/dist/validation-utils.js.map b/packages/utils/dist/validation-utils.js.map index d8f0df58..8ed664f0 100644 --- a/packages/utils/dist/validation-utils.js.map +++ b/packages/utils/dist/validation-utils.js.map @@ -1 +1 @@ -{"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../src/validation-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"validation-utils.js","sourceRoot":"","sources":["../src/validation-utils.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 0cf2ae31..ce170655 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -39,6 +39,7 @@ export { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, + assertUint256, isPlainObject, parseBytes, } from './validation-utils.js'; diff --git a/packages/utils/src/validation-utils.ts b/packages/utils/src/validation-utils.ts index 7d00bc31..e4970cb0 100644 --- a/packages/utils/src/validation-utils.ts +++ b/packages/utils/src/validation-utils.ts @@ -1,3 +1,5 @@ +const UINT256_MAX = (1n << 256n) - 1n; + function assertNonEmptyString(value: unknown, label: string): string { if (typeof value !== 'string' || !value.trim()) { throw new Error(`${label} must be a non-empty string.`); @@ -19,6 +21,13 @@ function assertNonNegativeInteger(value: unknown, label: string): number { return value; } +function assertUint256(value: unknown, name: string): bigint { + if (typeof value !== 'bigint' || value < 0n || value > UINT256_MAX) { + throw new Error(`${name} must be a non-negative bigint fitting in 256 bits.`); + } + return value; +} + function isPlainObject(value: unknown): value is Record { if (value === null || typeof value !== 'object' || Array.isArray(value)) { return false; @@ -103,6 +112,7 @@ export { assertNonEmptyString, assertNonNegativeInteger, assertPositiveInteger, + assertUint256, isPlainObject, parseBytes, }; diff --git a/plans/default-transaction-preparer.md b/plans/default-transaction-preparer.md index 417c214d..5a18b2cb 100644 --- a/plans/default-transaction-preparer.md +++ b/plans/default-transaction-preparer.md @@ -15,6 +15,7 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p - [x] 2026-09-05 21:06Z: Aligned the block fee/gas-limit lookup with pending gas estimation. Added a regression for differing latest/pending fees with multiplier 1, updated documentation/errors, rebuilt output, and passed all 137 Ethereum/messages runtime tests, both type suites, package import, and whitespace checks. - [x] 2026-09-07 01:43Z: Audited public chain ID usage and changed factory/signing types to positive safe integer numbers while preserving bigint RPC parsing/comparison. Updated runtime/type coverage and documentation. - [x] 2026-09-07 01:44Z: Rebuilt tracked output and reviewed the final diff. All 140 Ethereum/messages runtime tests, both type suites, package import, and whitespace checks passed for the chain ID change. +- [x] 2026-09-07 02:02Z: Moved `assertUint256` to shared validation utilities and `parseTransactionQuantity` to Ethereum request utilities without changing behavior. Rebuilt output; all 98 utils/Ethereum runtime tests, Ethereum type checks, both package imports, uint256 export boundary checks, and whitespace checks passed. ## Surprises & Discoveries @@ -23,6 +24,7 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p - A preparer cannot coordinate nonce reuse through submission because its callback finishes before broadcasting starts. An internal queue would not solve this lifecycle constraint. - Reading latest-block fees while estimating pending state can underprice the estimate with multiplier 1. The regression reproduced `max fee per gas less than block base fee` before the fix; reading the pending block fixes that mismatch. Separate RPC calls can still observe advancing pending state. - Public chain IDs only occur in the Ethereum factory and unsigned transaction interface. Keeping the existing bigint RPC comparison against the validated configured ID rejects unsupported RPC IDs without converting or rounding them; the signer receives the configured number. +- The two preparer-local validation helpers have no orchestration dependency. Their existing tests continue to cover them after relocation; the new public `assertUint256` export also passed direct boundary checks. ## Decision Log @@ -31,6 +33,7 @@ Nodes will be able to configure a reusable Ethereum transaction preparer once, p - 2026-09-05 / Codex, updated after user-approved review fix: Read chain ID, pending nonce, pending block base fee/gas limit, suggested priority fee, then estimate gas against pending state with the completed call/fee fields. Using pending for both the block lookup and estimate avoids the original latest/pending mismatch. Check chain ID on every invocation. Default maximum fee is twice the current base fee plus the suggested priority fee. Default gas margin is 20%, rounded up. Configurable integer base-fee multiplier and margin, optional gas/fee ceilings, and block gas limit checks reject before signing rather than silently reducing values. - 2026-09-05 / Codex: A configurable 30-second overall preparation deadline and the per-call abort signal cover RPC work and signing. Reuse `runWithRetry` with zero outer retries; individual RPC reads retain their existing retry policy. Sign only once and discard late results after cancellation. The signer is trusted to preserve the requested transaction and account; validate returned byte shapes, type-2 prefix, and hash correspondence with existing noble Keccak, without adding transaction decoding or key recovery. - 2026-09-05 / Codex: Do not reserve or increment nonces locally. Document serialization of the complete transaction lifecycle per account, including reconciliation of uncertain submissions, and the lack of coordination across processes. RPC IDs default to 1 and are configurable at factory creation; they are not signed fields. +- 2026-09-07 / Codex, requested by the user: Export generic `assertUint256` from `packages/utils/src/validation-utils.ts` through `@oyaprotocol/utils`. Keep `parseTransactionQuantity` beside `parseQuantity` in `packages/ethereum/src/request-utils.ts` as an internal Ethereum helper. Preserve their original validation and errors, including the length check before bigint parsing. ## Outcomes & Retrospective @@ -38,6 +41,8 @@ The factory and signer interface are implemented with no new dependencies or con The chain ID follow-up changes public configuration and signing fields to `number`, with positive safe integer validation and lossless bigint RPC comparison. Tests cover the largest safe ID, rejected configuration values, and exact errors for unsupported RPC IDs through the uint256 maximum. Tracked output is rebuilt, all 140 Ethereum/messages runtime tests (including 18 factory tests) passed, and both type suites, package import, and whitespace checks passed. No work remains for this follow-up. +The utility relocation is complete with unchanged runtime behavior and no new dependencies. The build, `node --test --test-reporter=dot packages/utils/test/*.test.js packages/ethereum/test/*.test.js` (98 tests), Ethereum type suite, utils/Ethereum package imports, uint256 export boundary checks, and `git diff --check` all passed. + ## Context and Orientation `packages/ethereum/src/transactions.ts` defines call intent (`to`, `data`, `value`, optional signal), a prepared signed result, and the existing callback accepted by Logger. `logger.ts` invokes that callback, submits bytes, waits for a receipt, and verifies an event. `request-utils.ts` performs JSON-RPC reads with bounded retries and response-envelope checks. `packages/utils/src/async-utils.ts` provides cancellation, deadlines, and retry composition. `packages/messages` composes IPFS publication with Logger; its API requires no change. Tracked `dist` files are rebuilt with TypeScript. Root and package `AGENTS.md` apply.