Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure default properties are used by contract class #5688

14 changes: 10 additions & 4 deletions CHANGELOG.md
Expand Up @@ -916,16 +916,16 @@ should use 4.0.1-alpha.0 for testing.

### Fixed

#### web3-core

- Make the `request` method of `EIP1193Provider` class, compatible with EIP 1193 (#5591)

#### web3-eth-contract

- Emit past contract events based on `fromBlock` when passed to `contract.events.someEventName` (#5201)
- Use different types for `ContractOptions` -> `jsonInterface` setter and getter (#5474)
- An issue within the `Contract` constructor where `provider` wasn't being set when provided within the `optionsOrContextOrReturnFormat` argument (#5669)

#### web3-types

- Make the `request` method of `EIP1193Provider` class, compatible with EIP 1193 (#5591)

#### web3-utils

- Use Uuid for the response id, to fix the issue "Responses get mixed up due to conflicting payload IDs" (#5373).
Expand All @@ -945,3 +945,9 @@ should use 4.0.1-alpha.0 for testing.
- These types were moved from `web3-eth-accounts` to `web3-types` package: Cipher, CipherOptions, ScryptParams, PBKDF2SHA256Params, KeyStore (#5581 )

## [Unreleased]

### Fixed

#### web3-core

- The method `getConfig()` of `Web3Config` can returns `defaultCommon` if it was set as a property of a static class that inherit from `Web3Config` (#5688)
2 changes: 2 additions & 0 deletions packages/web3-core/CHANGELOG.md
Expand Up @@ -59,3 +59,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Make the `request` method of `EIP1193Provider` class, compatible with EIP 1193 (#5591)

## [Unreleased]

- The method `getConfig()` of `Web3Config` can returns the value of `defaultCommon`, if it was set as a property of a static class that inherit from `Web3Config` (#5688)
26 changes: 21 additions & 5 deletions packages/web3-core/src/web3_config.ts
Expand Up @@ -80,7 +80,6 @@ export abstract class Web3Config
defaultNetworkId: undefined,
defaultChain: 'mainnet',
defaultHardfork: 'london',
// TODO - Check if there is a default Common
defaultCommon: undefined,
defaultTransactionType: '0x0',
defaultMaxPriorityFeePerGas: toHex(2500000000),
Expand All @@ -98,7 +97,10 @@ export abstract class Web3Config
}

public getConfig() {
return this._config;
return {
...this._config,
defaultCommon: this.defaultCommon,
};
}

public setConfig(options: Partial<Web3ConfigOptions>) {
Expand Down Expand Up @@ -133,14 +135,20 @@ export abstract class Web3Config
}

/**
* Returns the `defaultAccount` from inside the config.
* And if not found return the `defaultAccount` if set into the static property of the inherit class
* This default address is used as the default `from` property, if no `from` property is specified in for the following methods:
* - web3.eth.sendTransaction()
* - web3.eth.call()
* - myContract.methods.myMethod().call()
* - myContract.methods.myMethod().send()
*/
public get defaultAccount() {
return this._config.defaultAccount;
return (
this._config.defaultAccount ??
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
((this.constructor as any).defaultAccount as string | undefined)
);
}
/**
* Will set the default account.
Expand Down Expand Up @@ -444,8 +452,16 @@ export abstract class Web3Config
* Default is `undefined`.
*
*/
public get defaultCommon() {
return this._config.defaultCommon;
public get defaultCommon(): Common | undefined {
const defaultCommon = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
...((this.constructor as any).defaultCommon as Common),
...this._config.defaultCommon,
};
if (Object.keys(defaultCommon).length) {
return defaultCommon;
}
return undefined;
}

/**
Expand Down
20 changes: 2 additions & 18 deletions packages/web3-eth-contract/src/contract.ts
Expand Up @@ -428,14 +428,6 @@ export class Contract<Abi extends ContractAbi>
});
}

public get defaultAccount() {
return (this.constructor as typeof Contract).defaultAccount ?? super.defaultAccount;
}

public set defaultAccount(value: Address | undefined) {
super.defaultAccount = value;
}

public get defaultBlock() {
return (this.constructor as typeof Contract).defaultBlock ?? super.defaultBlock;
}
Expand All @@ -452,14 +444,6 @@ export class Contract<Abi extends ContractAbi>
super.defaultHardfork = value;
}

public get defaultCommon(): Common | undefined {
return (this.constructor as typeof Contract).defaultCommon ?? super.defaultCommon;
}

public set defaultCommon(value: Common | undefined) {
super.defaultCommon = value;
}

public get transactionSendTimeout() {
return (
(this.constructor as typeof Contract).transactionSendTimeout ??
Expand Down Expand Up @@ -1131,7 +1115,7 @@ export class Contract<Abi extends ContractAbi>
modifiedContractOptions = {
...modifiedContractOptions,
data: undefined,
from: modifiedContractOptions.from ?? this.defaultAccount ?? undefined,
from: modifiedContractOptions.from ?? this.defaultAccount,
};

const tx = getSendTxParams({
Expand Down Expand Up @@ -1163,7 +1147,7 @@ export class Contract<Abi extends ContractAbi>
let modifiedContractOptions = contractOptions ?? this.options;
modifiedContractOptions = {
...modifiedContractOptions,
from: modifiedContractOptions.from ?? this.defaultAccount ?? undefined,
from: modifiedContractOptions.from ?? this.defaultAccount,
};

const tx = getSendTxParams({
Expand Down
Expand Up @@ -76,7 +76,6 @@ describe('contract defaults (extra)', () => {
Contract.defaultHardfork = hardfork;

// const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');

contract = await contract.deploy(deployOptions).send(sendOptions);

expect(contract.defaultHardfork).toBe(hardfork);
Expand Down Expand Up @@ -179,24 +178,32 @@ describe('contract defaults (extra)', () => {
contract = await contract.deploy(deployOptions).send(sendOptions);
});

// todo this test fails, seems like a bug. any thoughts?
// it('should use "defaultCommon" on "Contract" level', async () => {
// Contract.defaultCommon = common;
it('should use "defaultCommon" on "Contract" level', async () => {
Contract.defaultCommon = common;
expect(Contract.defaultCommon).toMatchObject(common);

// Any contract instance will use the defaultCommon if set on the class level
expect(contract.defaultCommon).toMatchObject(common);

// const sendTransactionSpy = jest.spyOn(Web3Eth, 'sendTransaction');
// TODO: ensure that `defaultCommon` is read and used from within both calls and transactions
// Note: the test should not be with `_config` because this will not hold the value set at static properties of the class.

// expect(contract.defaultCommon).toMatchObject(common);
// The following is just a reference. There could be a refactoring or some another way to check.
// const getConfigSpy = jest.spyOn(contract, 'getConfig');

// await contract.methods.setGreeting('New Greeting').send(sendOptions);
// await contract.methods.greet().call();

// expect(sendTransactionSpy).toHaveBeenLastCalledWith(
// expect.objectContaining({
// _config: expect.objectContaining({ defaultCommon: common }),
// }),
// expect.any(Object),
// expect.any(Object),
// );
// });
// await contract.methods.setGreeting('New Greeting').send(sendOptions);

// // the method `getConfig` will be called twice. One time when calling `greet()`,
// // and another time when sending a transaction for `setGreeting('New Greeting')`)
// expect(getConfigSpy.mock.results[0].value).toMatchObject({
// defaultCommon: common,
// });
// expect(getConfigSpy.mock.results[1].value).toMatchObject({
// defaultCommon: common,
// });
});

it('should use "defaultCommon" on "instance" level', async () => {
contract.defaultCommon = common;
Expand Down
2 changes: 1 addition & 1 deletion packages/web3-eth-contract/test/unit/contract.test.ts
Expand Up @@ -318,7 +318,7 @@ describe('Contract', () => {
hardfork: 'constantinople' as Hardfork,
};
contract.defaultCommon = defaultCommon;
expect(contract.defaultCommon).toBe(defaultCommon);
expect(contract.defaultCommon).toStrictEqual(defaultCommon);

const transactionBlockTimeout = 130;
expect(contract.transactionBlockTimeout).toBe(50);
Expand Down
4 changes: 2 additions & 2 deletions packages/web3-eth/test/integration/defaults.test.ts
Expand Up @@ -883,15 +883,15 @@ describe('defaults', () => {
web3Eth.setConfig({
defaultCommon: common,
});
expect(web3Eth.defaultCommon).toBe(common);
expect(web3Eth.defaultCommon).toEqual(common);

// set by create new instance
eth2 = new Web3Eth({
config: {
defaultCommon: common,
},
});
expect(eth2.defaultCommon).toBe(common);
expect(eth2.defaultCommon).toEqual(common);
});
it('defaultTransactionType', () => {
// default
Expand Down