diff --git a/CHANGELOG.md b/CHANGELOG.md index 783691404b9..8eba8930d2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2564,3 +2564,20 @@ If there are any bugs, improvements, optimizations or any new feature proposal f - `getName` reverse resolution ## [Unreleased] + +### Fixed + +#### web3-eth + +- Fixed geth issue when running a new instance, transactions will index when there are no blocks created (#7098) + +### Added + +#### web3 + +- `web3.eth.Contract` will get transaction middleware and use it, if `web3.eth` has transaction middleware. (#7138) + +#### web3-eth-contract + +- `populateTransaction` was added to contract methods (#7124) +- Contract has `setTransactionMiddleware` and `getTransactionMiddleware` for automatically passing to `sentTransaction` for `deploy` and `send` functions (#7138) diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index e0cda223234..a1c4b6f35e5 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -390,4 +390,6 @@ Documentation: ### Added -- Contract has `setTransactionMiddleware` and `getTransactionMiddleware` for automatically passing to `sentTransaction` for `deploy` and `send` functions (#7138) \ No newline at end of file +- `populateTransaction` was added to contract methods (#7124) + +- Contract has `setTransactionMiddleware` and `getTransactionMiddleware` for automatically passing to `sentTransaction` for `deploy` and `send` functions (#7138) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index 64f44440472..cba5043df95 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -1278,7 +1278,29 @@ export class Contract send: (options?: PayableTxOptions | NonPayableTxOptions): ContractMethodSend => this._contractMethodSend(methodAbi, abiParams, internalErrorsAbis, options), - + populateTransaction: ( + options?: PayableTxOptions | NonPayableTxOptions, + contractOptions?: ContractOptions, + ) => { + let modifiedContractOptions = contractOptions ?? this.options; + modifiedContractOptions = { + ...modifiedContractOptions, + input: undefined, + from: modifiedContractOptions?.from ?? this.defaultAccount ?? undefined, + }; + const tx = getSendTxParams({ + abi, + params, + options: { ...options, dataInputFill: this.config.contractDataInputFill }, + contractOptions: modifiedContractOptions, + }); + // @ts-expect-error remove unnecessary field + if (tx.dataInputFill) { + // @ts-expect-error remove unnecessary field + delete tx.dataInputFill; + } + return tx; + }, estimateGas: async ( options?: PayableCallOptions | NonPayableCallOptions, returnFormat: ReturnFormat = this diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index cc2e0c4aec7..8f4bf564ca4 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -28,13 +28,15 @@ import { DataFormat, DEFAULT_RETURN_FORMAT, FormatType, + TransactionCall, } from 'web3-types'; import { NewHeadsSubscription, SendTransactionEvents } from 'web3-eth'; +import type { ContractOptions } from 'web3-types'; import { LogsSubscription } from './log_subscription.js'; export type NonPayableTxOptions = NonPayableCallOptions; export type PayableTxOptions = PayableCallOptions; -export { ContractAbiWithSignature, EventLog, ContractOptions } from 'web3-types'; +export type { ContractAbiWithSignature, EventLog, ContractOptions } from 'web3-types'; export interface ContractEventOptions { /** @@ -177,6 +179,10 @@ export interface NonPayableMethodObject FormatType, SendTransactionEvents >; + populateTransaction( + tx?: PayableTxOptions | NonPayableTxOptions, + contractOptions?: ContractOptions, + ): TransactionCall; /** * Returns the amount of gas consumed by executing the method locally without creating a new transaction on the blockchain. @@ -375,6 +381,15 @@ export interface PayableMethodObject { SendTransactionEvents >; + /** + * + * @param tx + * @param contractOptions + */ + populateTransaction( + tx?: PayableTxOptions | NonPayableTxOptions, + contractOptions?: ContractOptions, + ): TransactionCall; /** * Returns the amount of gas consumed by executing the method locally without creating a new transaction on the blockchain. * The returned amount can be used as a gas estimate for executing the transaction publicly. The actual gas used can be diff --git a/packages/web3-eth-contract/test/unit/contract.test.ts b/packages/web3-eth-contract/test/unit/contract.test.ts index 8d5c0445fb2..449280c41a7 100644 --- a/packages/web3-eth-contract/test/unit/contract.test.ts +++ b/packages/web3-eth-contract/test/unit/contract.test.ts @@ -16,13 +16,20 @@ along with web3.js. If not, see . */ import * as eth from 'web3-eth'; -import { ValidChains, Hardfork, AccessListResult, Address, ETH_DATA_FORMAT , DEFAULT_RETURN_FORMAT } from 'web3-types'; +import { + ValidChains, + Hardfork, + AccessListResult, + Address, + ETH_DATA_FORMAT, + DEFAULT_RETURN_FORMAT, +} from 'web3-types'; import { Web3ContractError } from 'web3-errors'; -import { Web3Context , Web3ConfigEvent } from 'web3-core'; +import { Web3Context, Web3ConfigEvent } from 'web3-core'; import { Web3ValidatorError } from 'web3-validator'; import { AbiItem } from 'web3-utils'; import { stringify } from 'flatted'; -import {Abi} from '../fixtures/AbiItem' +import { Abi } from '../fixtures/AbiItem'; import { Contract } from '../../src'; import { sampleStorageContractABI } from '../fixtures/storage'; import { GreeterAbi, GreeterBytecode } from '../shared_fixtures/build/Greeter'; @@ -541,7 +548,7 @@ describe('Contract', () => { // calling with wrong parameters should throw try { // eslint-disable-next-line @typescript-eslint/no-unsafe-call - await(deployedContract.methods.setGreeting as any)(arg, 'test').send(sendOptions); + await (deployedContract.methods.setGreeting as any)(arg, 'test').send(sendOptions); expect(true).toBe(false); } catch (error) { // eslint-disable-next-line jest/no-conditional-expect @@ -555,7 +562,7 @@ describe('Contract', () => { // calling with wrong parameters should throw try { // eslint-disable-next-line @typescript-eslint/no-unsafe-call - await(deployedContract.methods.setGreeting as any)(arg, true, 'test').send( + await (deployedContract.methods.setGreeting as any)(arg, true, 'test').send( sendOptions, ); expect(true).toBe(false); @@ -1909,5 +1916,32 @@ describe('Contract', () => { const contract = new Contract(GreeterAbi, web3Context); expect(contract.config).toStrictEqual(web3Context.config); }); + + it('should populate method to tx object', () => { + const expectedProvider = 'http://127.0.0.1:8545'; + const web3Context = new Web3Context({ + provider: expectedProvider, + config: { handleRevert: true, defaultTransactionType: '0x2' }, + }); + const contract = new Contract( + GreeterAbi, + '0x00000000219ab540356cBB839Cbe05303d7705F1', + web3Context, + ); + + const tx = contract.methods + .greet() + .populateTransaction({ from: '0x00000000219ab540356cBB839Cbe05303d7705F2' }); + expect(tx).toEqual({ + to: '0x00000000219AB540356cBb839cbe05303D7705F1', + gas: undefined, + gasPrice: undefined, + from: '0x00000000219ab540356cBB839Cbe05303d7705F2', + input: undefined, + maxPriorityFeePerGas: undefined, + maxFeePerGas: undefined, + data: '0xcfae3217', + }); + }); }); }); diff --git a/packages/web3-types/src/eth_types.ts b/packages/web3-types/src/eth_types.ts index 5c628994c8d..9c83e92d0d5 100644 --- a/packages/web3-types/src/eth_types.ts +++ b/packages/web3-types/src/eth_types.ts @@ -47,6 +47,7 @@ export enum BlockTags { PENDING = 'pending', SAFE = 'safe', FINALIZED = 'finalized', + COMMITTED = 'committed', } export type BlockTag = `${BlockTags}`; @@ -138,8 +139,8 @@ export interface Withdrawals { } export interface BlockOutput { - readonly gasLimit: bigint | number; - readonly gasUsed: bigint | number; + readonly gasLimit: bigint | number; + readonly gasUsed: bigint | number; readonly size: bigint | number; readonly timestamp: bigint | number; readonly number?: bigint | number; @@ -152,54 +153,54 @@ export interface BlockOutput { // Added properties readonly blobGasUsed?: bigint | number; - readonly excessBlobGas?: bigint | number; - readonly extraData?: Bytes; - readonly hash?: HexString32Bytes; - readonly logsBloom?: Bytes; - readonly nonce?: bigint | number; - readonly parentBeaconBlockRoot?: HexString32Bytes; - readonly receiptsRoot?: HexString32Bytes; - readonly sha3Uncles: HexString32Bytes[]; - readonly stateRoot?: HexString32Bytes; - readonly transactionsRoot?: HexString32Bytes; - readonly withdrawalsRoot?: HexString32Bytes; - readonly mixHash?: HexString32Bytes; - readonly uncles?: Uncles; - readonly withdrawals?: Withdrawals[]; + readonly excessBlobGas?: bigint | number; + readonly extraData?: Bytes; + readonly hash?: HexString32Bytes; + readonly logsBloom?: Bytes; + readonly nonce?: bigint | number; + readonly parentBeaconBlockRoot?: HexString32Bytes; + readonly receiptsRoot?: HexString32Bytes; + readonly sha3Uncles: HexString32Bytes[]; + readonly stateRoot?: HexString32Bytes; + readonly transactionsRoot?: HexString32Bytes; + readonly withdrawalsRoot?: HexString32Bytes; + readonly mixHash?: HexString32Bytes; + readonly uncles?: Uncles; + readonly withdrawals?: Withdrawals[]; } export interface BlockHeaderOutput { - readonly baseFeePerGas?: Numbers; - readonly blobGasUsed?: Numbers; - readonly difficulty?: Numbers; - readonly excessBlobGas?: Numbers; - readonly extraData?: Bytes; - readonly gasLimit: Numbers; - readonly gasUsed: Numbers; - readonly hash?: HexString32Bytes; - readonly logsBloom?: Bytes; - readonly miner?: HexString; - readonly nonce?: Numbers; - readonly number?: Numbers; - readonly parentBeaconBlockRoot?: HexString32Bytes; - readonly parentHash?: HexString32Bytes; - readonly receiptsRoot?: HexString32Bytes; - readonly sha3Uncles: HexString32Bytes[]; - readonly stateRoot?: HexString32Bytes; - readonly timestamp: Numbers; - readonly transactionsRoot?: HexString32Bytes; - readonly withdrawalsRoot?: HexString32Bytes; - - // These fields are returned when the RPC client is Nethermind, - // but aren't available in other clients such as Geth - readonly author?: Address; - readonly totalDifficulty?: Numbers; - readonly size?: Numbers; - readonly excessDataGas?: Numbers; - readonly mixHash?: HexString32Bytes; - readonly transactions?: TransactionOutput[]; - readonly uncles?: Uncles; - readonly withdrawals?: Withdrawals[]; + readonly baseFeePerGas?: Numbers; + readonly blobGasUsed?: Numbers; + readonly difficulty?: Numbers; + readonly excessBlobGas?: Numbers; + readonly extraData?: Bytes; + readonly gasLimit: Numbers; + readonly gasUsed: Numbers; + readonly hash?: HexString32Bytes; + readonly logsBloom?: Bytes; + readonly miner?: HexString; + readonly nonce?: Numbers; + readonly number?: Numbers; + readonly parentBeaconBlockRoot?: HexString32Bytes; + readonly parentHash?: HexString32Bytes; + readonly receiptsRoot?: HexString32Bytes; + readonly sha3Uncles: HexString32Bytes[]; + readonly stateRoot?: HexString32Bytes; + readonly timestamp: Numbers; + readonly transactionsRoot?: HexString32Bytes; + readonly withdrawalsRoot?: HexString32Bytes; + + // These fields are returned when the RPC client is Nethermind, + // but aren't available in other clients such as Geth + readonly author?: Address; + readonly totalDifficulty?: Numbers; + readonly size?: Numbers; + readonly excessDataGas?: Numbers; + readonly mixHash?: HexString32Bytes; + readonly transactions?: TransactionOutput[]; + readonly uncles?: Uncles; + readonly withdrawals?: Withdrawals[]; } export interface ReceiptInput { @@ -553,13 +554,13 @@ export interface Eip712TypedData { /** * To contain the gas Fee Data to be used with EIP-1559 transactions. * EIP-1559 was applied to Ethereum after London hardfork. - * + * * Typically you will only need `maxFeePerGas` and `maxPriorityFeePerGas` for a transaction following EIP-1559. * However, if you want to get informed about the fees of last block, you can use `baseFeePerGas` too. - * - * + * + * * @see https://eips.ethereum.org/EIPS/eip-1559 - * + * */ export interface FeeData { /** @@ -569,20 +570,20 @@ export interface FeeData { /** * The baseFeePerGas returned from the last available block. - * + * * If EIP-1559 is not supported, this will be `undefined` - * - * However, the user will only pay (the future baseFeePerGas + the maxPriorityFeePerGas). + * + * However, the user will only pay (the future baseFeePerGas + the maxPriorityFeePerGas). * And this value is just for getting informed about the fees of last block. */ readonly baseFeePerGas?: Numbers; /** * The maximum fee that the user would be willing to pay per-gas. - * + * * However, the user will only pay (the future baseFeePerGas + the maxPriorityFeePerGas). * And the `maxFeePerGas` could be used to prevent paying more than it, if `baseFeePerGas` went too high. - * + * * If EIP-1559 is not supported, this will be `undefined` */ readonly maxFeePerGas?: Numbers; @@ -593,4 +594,4 @@ export interface FeeData { * If EIP-1559 is not supported, this will be `undefined` */ readonly maxPriorityFeePerGas?: Numbers; -} \ No newline at end of file +} diff --git a/packages/web3/CHANGELOG.md b/packages/web3/CHANGELOG.md index fb638a0d56b..d95a14cc116 100644 --- a/packages/web3/CHANGELOG.md +++ b/packages/web3/CHANGELOG.md @@ -387,4 +387,4 @@ Documentation: #### web3 -- `web3.eth.Contract` will get transaction middleware and use it, if `web3.eth` has transaction middleware. (#7138) \ No newline at end of file +- `web3.eth.Contract` will get transaction middleware and use it, if `web3.eth` has transaction middleware. (#7138)