From 59fc43846f0558c4d02b67876edbf88d3a162127 Mon Sep 17 00:00:00 2001 From: Muhammad Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Wed, 13 Dec 2023 16:29:16 +0100 Subject: [PATCH] fix: The Contract is not using the context wallet passed if context was passed at constructor (#6661) * fix Contract not using context wallet passed at constructor * add integration test * update CHANGELOG.md --- packages/web3-eth-contract/CHANGELOG.md | 1 + packages/web3-eth-contract/src/contract.ts | 9 ++ .../web3/test/integration/contract.test.ts | 95 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 packages/web3/test/integration/contract.test.ts diff --git a/packages/web3-eth-contract/CHANGELOG.md b/packages/web3-eth-contract/CHANGELOG.md index 159712d744a..ef88ed80d13 100644 --- a/packages/web3-eth-contract/CHANGELOG.md +++ b/packages/web3-eth-contract/CHANGELOG.md @@ -358,3 +358,4 @@ Documentation: ### Fixed - Fix and error that happen when trying to get past events by calling `contract.getPastEvents` or `contract.events.allEvents()`, if there is no matching events. (#6647) +- Fixed: The Contract is not using the context wallet passed if context was passed at constructor. (#6661) diff --git a/packages/web3-eth-contract/src/contract.ts b/packages/web3-eth-contract/src/contract.ts index eb60285a52d..ac965ac6ef0 100644 --- a/packages/web3-eth-contract/src/contract.ts +++ b/packages/web3-eth-contract/src/contract.ts @@ -483,6 +483,15 @@ export class Contract provider, registeredSubscriptions: contractSubscriptions, }); + + // Init protected properties + if ((contractContext as Web3Context)?.wallet) { + this._wallet = (contractContext as Web3Context).wallet; + } + if ((contractContext as Web3Context)?.accountProvider) { + this._accountProvider = (contractContext as Web3Context).accountProvider; + } + if ( !isNullish(options) && !isNullish(options.data) && diff --git a/packages/web3/test/integration/contract.test.ts b/packages/web3/test/integration/contract.test.ts new file mode 100644 index 00000000000..3b07f56c009 --- /dev/null +++ b/packages/web3/test/integration/contract.test.ts @@ -0,0 +1,95 @@ +/* +This file is part of web3.js. + +web3.js is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +web3.js is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with web3.js. If not, see . +*/ +import * as Web3Eth from 'web3-eth'; +import { Web3, Contract } from '../../src/index'; + +import { + ERC20TokenAbi, + // eslint-disable-next-line import/no-relative-packages +} from '../shared_fixtures/contracts/ERC20Token'; + +jest.mock('web3-eth'); + +describe('Contract', () => { + describe('Contract use the the context wallet', () => { + it('should work when created as web.eth.Contract', async () => { + const web3 = new Web3('https://rpc2.sepolia.org'); + const contract = new web3.eth.Contract( + ERC20TokenAbi, + '0x7af963cF6D228E564e2A0aA0DdBF06210B38615D', + ); + + // could be add wallet also as: + // const account = web3.eth.accounts.wallet.add('Private Key').get(0); + const account = web3.eth.accounts.create(); + + expect(contract.wallet).toBeDefined(); + + const sendTransactionSpy = jest + .spyOn(Web3Eth, 'sendTransaction') + .mockImplementation((_objInstance, tx) => { + expect(tx.from).toStrictEqual(account.address); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { on: jest.fn() } as any; + }); + + await contract.methods.transfer(account.address, 100).send({ from: account?.address }); + + expect(sendTransactionSpy).toHaveBeenLastCalledWith( + expect.any(Object), + expect.objectContaining({ + from: account.address, + }), + expect.any(Object), + expect.any(Object), + ); + }); + it('should work when passed to constructor as Contract(..., web3Context)', async () => { + const web3 = new Web3('https://rpc2.sepolia.org'); + const contract = new Contract( + ERC20TokenAbi, + '0x7af963cF6D228E564e2A0aA0DdBF06210B38615D', + web3, + ); + + // could be add wallet also as: + // const account = web3.eth.accounts.wallet.add('Private Key').get(0); + const account = web3.eth.accounts.create(); + + expect(contract.wallet).toBeDefined(); + + const sendTransactionSpy = jest + .spyOn(Web3Eth, 'sendTransaction') + .mockImplementation((_objInstance, tx) => { + expect(tx.from).toStrictEqual(account.address); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return { on: jest.fn() } as any; + }); + + await contract.methods.transfer(account.address, 100).send({ from: account?.address }); + + expect(sendTransactionSpy).toHaveBeenLastCalledWith( + expect.any(Object), + expect.objectContaining({ + from: account.address, + }), + expect.any(Object), + expect.any(Object), + ); + }); + }); +});