Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Example Plugin Implementation #5393

Merged
merged 47 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2da30e0
Init abstract Web3PluginBase class. Init registerPlugin method
spacesailor24 Aug 30, 2022
530b4ce
Update web3.ts to have a named export instead of using default
spacesailor24 Aug 30, 2022
546fa28
Init web3-plugin-example package
spacesailor24 Aug 30, 2022
cb636c2
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
spacesailor24 Aug 30, 2022
3233a76
Update CHANGELOG and README
spacesailor24 Aug 30, 2022
d0d388b
Merge branch 'wyatt/4.x/5091-chainlink-plugin' of github.com:ChainSaf…
spacesailor24 Aug 30, 2022
db296ff
Update packages/web3-plugin-example/test/unit/plugin.test.ts
spacesailor24 Aug 30, 2022
a2f43db
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
spacesailor24 Aug 30, 2022
45881ee
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
spacesailor24 Aug 30, 2022
6514f13
Remove unneeded npm scripts
spacesailor24 Aug 30, 2022
9b4896e
Remove webpack config
spacesailor24 Aug 30, 2022
dbc133f
Init ExistingPluginNamespaceError
spacesailor24 Aug 30, 2022
dc36d4b
registerPluging - throw error is namespace not undefined
spacesailor24 Aug 30, 2022
755d6d6
Update Web3 to use default and named exports
spacesailor24 Sep 1, 2022
1036836
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
jdevcs Sep 1, 2022
08cbe72
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
spacesailor24 Sep 27, 2022
7642f41
Add peerDependencies
spacesailor24 Sep 27, 2022
816f2f5
Default API generic to Web3APISpec for Web3PluginBase
spacesailor24 Sep 28, 2022
eaceff9
Remove use of ChainlinkPluginAPI. Define return type for getPrice
spacesailor24 Sep 28, 2022
5e6d3a2
Remove no longer needed generic values
spacesailor24 Sep 28, 2022
0666cff
Override link method for plugin
spacesailor24 Sep 29, 2022
c7c2a06
Remove no longer used import
spacesailor24 Sep 29, 2022
75bf686
Remove ChainlinkPlugin code
spacesailor24 Oct 3, 2022
3978175
Init custom_rpc_methods plugin example
spacesailor24 Oct 3, 2022
205b928
Init contract_method_wrappers plugin example
spacesailor24 Oct 3, 2022
b3c9140
Update web3 import to remove import ts error
spacesailor24 Oct 4, 2022
369e024
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
spacesailor24 Oct 5, 2022
7acb576
Fix typing compatibility when linking a contract to a context (#5416)
Muhammad-Altabba Oct 5, 2022
3ad7e1d
Fix lint error
spacesailor24 Oct 5, 2022
de3403d
Move web3-plugin-example to tools/. Remove @ts-expect-errors. Move We…
spacesailor24 Oct 11, 2022
5be6ef5
Update CHANGELOGs
spacesailor24 Oct 11, 2022
b455e21
Fix tsc and linter errors
spacesailor24 Oct 11, 2022
051a35f
Update packages/web3-types/CHANGELOG.md
spacesailor24 Oct 11, 2022
bba74e6
Add CHANGELOG changes to root CHANGELOG
spacesailor24 Oct 11, 2022
6093e5b
Merge branch 'wyatt/4.x/5091-chainlink-plugin' of github.com:ChainSaf…
spacesailor24 Oct 11, 2022
9481519
Update packages/web3-types/CHANGELOG.md
spacesailor24 Oct 12, 2022
c1b2cc5
Update CHANGELOG.md
spacesailor24 Oct 12, 2022
744bfc2
Update CHANGELOG.md
spacesailor24 Oct 12, 2022
c939cbc
Add web3-plugin-example CHANGELOG
spacesailor24 Oct 12, 2022
e55e65f
Merge branch 'wyatt/4.x/5091-chainlink-plugin' of github.com:ChainSaf…
spacesailor24 Oct 12, 2022
8d90ddd
Remove unnecessary web3 imports
spacesailor24 Oct 12, 2022
f242b48
Revert change to Web3 export
spacesailor24 Oct 20, 2022
56bf6b7
Init web3_export_helper.ts
spacesailor24 Oct 20, 2022
b79c68b
Merge branch '4.x' into wyatt/4.x/5091-chainlink-plugin
spacesailor24 Oct 20, 2022
d1ba3ec
Update packages/web3/CHANGELOG.md
spacesailor24 Oct 24, 2022
1e271b9
Update CHANGELOG.md
spacesailor24 Oct 24, 2022
4375a5d
Update comments for mocking in contract_method_wrappers.test.ts
spacesailor24 Oct 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ should use 4.0.1-alpha.0 for testing.
#### web3-core

- If the response error was `execution reverted`, raise `ContractExecutionError` and pass the response error to it in order to be set as `innerError` (this innerError will be decoded at web3-eth-contract if its ABI was provided according to EIP-838). (#5434)
- `registerPlugin` method to `Web3Context` (#5393)
- `Web3PluginBase` exported abstract class (#5393)
- `Web3EthPluginBase` exported abstract class (#5393)

#### web3-error

Expand All @@ -749,6 +752,7 @@ should use 4.0.1-alpha.0 for testing.
- Added `SignatureError` to `web3-errors/src/errors/signature_errors.ts` (moved from `web3-eth/src/errors.ts`) (#5462)
- Added the errors' classes to `web3-errors/src/errors/transaction_errors.ts` from `web3-eth/src/errors.ts` (#5462)
- Added `TransactionBlockTimeoutError` class and its error code `ERR_TX_BLOCK_TIMEOUT` (#5294)
- `ExistingPluginNamespaceError` class and it's error code `ERR_EXISTING_PLUGIN_NAMESPACE` (#5393)

#### web3-eth

Expand All @@ -771,6 +775,10 @@ should use 4.0.1-alpha.0 for testing.

### Changed

#### web3

- `Web3` is now a default and named export (#5393)

#### web3-error

- Moved `SignerError` from `web3-errors/src/errors/signature_errors.ts` to `web3-errors/src/errors/transaction_errors.ts`, and renamed it to `TransactionSigningError` (#5462)
Expand All @@ -789,6 +797,10 @@ should use 4.0.1-alpha.0 for testing.

- Return `BigInt` instead of `string` when decoding function parameters for large numbers, such as `uint256`. (#5435)

#### web3-types

- `Web3APISpec`, `Web3APIMethod`, and `Web3APIParams` not support `unknown` APIs (#5393)

### Removed

#### web3-eth
Expand Down
8 changes: 8 additions & 0 deletions packages/web3-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- If the response error was `execution reverted`, raise `ContractExecutionError` and pass the response error to it in order to be set as `innerError` (this innerError will be decoded at web3-eth-contract if its ABI was provided according to EIP-838). (#5434)
- `registerPlugin` method to `Web3Context` (#5393)
- `Web3PluginBase` exported abstract class (#5393)
- `Web3EthPluginBase` exported abstract class (#5393)

### Changed

- Default value for `API` generic for `Web3ContextObject` from `any` to `unknown` (#5393)
- Default value for `API` generic for `Web3ContextInitOptions` from `any` to `unknown` (#5393)
95 changes: 74 additions & 21 deletions packages/web3-core/src/web3_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@ 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 <http://www.gnu.org/licenses/>.
*/

// eslint-disable-next-line max-classes-per-file
import {
Web3APISpec,
Web3BaseWallet,
Web3BaseWalletAccount,
Web3AccountProvider,
SupportedProviders,
HexString,
EthExecutionAPI,
} from 'web3-types';
import { isNullish } from 'web3-utils';
import { ExistingPluginNamespaceError } from 'web3-errors';

import { isSupportedProvider } from './utils';
// eslint-disable-next-line import/no-cycle
import { Web3Config, Web3ConfigEvent, Web3ConfigOptions } from './web3_config';
Expand All @@ -34,8 +37,7 @@ import { Web3BatchRequest } from './web3_batch_request';

// To avoid circular dependencies, we need to export type from here.
export type Web3ContextObject<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
API extends Web3APISpec = any,
API extends Web3APISpec = unknown,
RegisteredSubs extends {
[key: string]: Web3SubscriptionConstructor<API>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -52,8 +54,7 @@ export type Web3ContextObject<
};

export type Web3ContextInitOptions<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
API extends Web3APISpec = any,
API extends Web3APISpec = unknown,
RegisteredSubs extends {
[key: string]: Web3SubscriptionConstructor<API>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -68,23 +69,22 @@ export type Web3ContextInitOptions<
wallet?: Web3BaseWallet<Web3BaseWalletAccount>;
};

export type Web3ContextConstructor<
// eslint-disable-next-line no-use-before-define, @typescript-eslint/no-explicit-any
T extends Web3Context<any>,
T2 extends unknown[],
> = new (...args: [...extras: T2, context: Web3ContextObject]) => T;
// eslint-disable-next-line no-use-before-define
export type Web3ContextConstructor<T extends Web3Context, T2 extends unknown[]> = new (
...args: [...extras: T2, context: Web3ContextObject]
) => T;

// To avoid circular dependencies, we need to export type from here.
export type Web3ContextFactory<
// eslint-disable-next-line no-use-before-define, @typescript-eslint/no-explicit-any
T extends Web3Context<any>,
// eslint-disable-next-line no-use-before-define
T extends Web3Context,
T2 extends unknown[],
> = Web3ContextConstructor<T, T2> & {
fromContextObject(this: Web3ContextConstructor<T, T2>, contextObject: Web3ContextObject): T;
};

export class Web3Context<
API extends Web3APISpec,
API extends Web3APISpec = unknown,
RegisteredSubs extends {
[key: string]: Web3SubscriptionConstructor<API>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -172,7 +172,7 @@ export class Web3Context<
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public static fromContextObject<T extends Web3Context<any>, T3 extends unknown[]>(
public static fromContextObject<T extends Web3Context, T3 extends unknown[]>(
this: Web3ContextConstructor<T, T3>,
...args: [Web3ContextObject, ...T3]
) {
Expand All @@ -198,8 +198,7 @@ export class Web3Context<
* and link it to current context. This can be used to initiate a global context object
* and then use it to create new objects of any type extended by `Web3Context`.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public use<T extends Web3Context<any>, T2 extends unknown[]>(
public use<T extends Web3Context, T2 extends unknown[]>(
ContextRef: Web3ContextConstructor<T, T2>,
...args: [...T2]
) {
Expand All @@ -218,7 +217,7 @@ export class Web3Context<
/**
* Link current context to another context.
*/
public link<T extends Web3Context<API, RegisteredSubs>>(parentContext: T) {
public link<T extends Web3Context>(parentContext: T) {
this.setConfig(parentContext.getConfig());
this._requestManager = parentContext.requestManager;
this.provider = parentContext.provider;
Expand All @@ -232,6 +231,19 @@ export class Web3Context<
});
}

// eslint-disable-next-line no-use-before-define
public registerPlugin(plugin: Web3PluginBase) {
// @ts-expect-error No index signature with a parameter of type 'string' was found on type 'Web3Context<API, RegisteredSubs>'
if (this[plugin.pluginNamespace] !== undefined)
throw new ExistingPluginNamespaceError(plugin.pluginNamespace);

const _pluginObject = {
[plugin.pluginNamespace]: plugin,
};
_pluginObject[plugin.pluginNamespace].link(this);
Object.assign(this, _pluginObject);
}

public get provider(): SupportedProviders<API> | string | undefined {
return this.requestManager.provider;
}
Expand Down Expand Up @@ -268,11 +280,52 @@ export class Web3Context<

// To avoid cycle dependency declare this type in this file
// TODO: When we have `web3-types` package we can share TransactionType
export type TransactionBuilder<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
API extends Web3APISpec = any,
> = <ReturnType = Record<string, unknown>>(options: {
export type TransactionBuilder<API extends Web3APISpec = unknown> = <
ReturnType = Record<string, unknown>,
>(options: {
transaction: Record<string, unknown>;
web3Context: Web3Context<API>;
privateKey?: HexString | Buffer;
}) => Promise<ReturnType>;

/**
* Extend this class when creating a plugin that either doesn't require {@link EthExecutionAPI},
* or interacts with a RPC node that doesn't fully implement {@link EthExecutionAPI}.
*
* To add type support for RPC methods to the {@link Web3RequestManager},
* define a {@link Web3APISpec} and pass it as a generic to Web3PluginBase like so:
*
* ```ts
* type CustomRpcApi = {
* custom_rpc_method: () => string;
* custom_rpc_method_with_parameters: (parameter1: string, parameter2: number) => string;
* };
*
* class CustomPlugin extends Web3PluginBase<CustomRpcApi> {...}
* ```
*/
export abstract class Web3PluginBase<
API extends Web3APISpec = Web3APISpec,
> extends Web3Context<API> {
public abstract pluginNamespace: string;
}

/**
* Extend this class when creating a plugin that makes use of {@link EthExecutionAPI},
* or depends on other Web3 packages (such as `web3-eth-contract`) that depend on {@link EthExecutionAPI}.
*
* To add type support for RPC methods to the {@link Web3RequestManager} (in addition to {@link EthExecutionAPI}),
* define a {@link Web3APISpec} and pass it as a generic to Web3PluginBase like so:
*
* ```ts
* type CustomRpcApi = {
* custom_rpc_method: () => string;
* custom_rpc_method_with_parameters: (parameter1: string, parameter2: number) => string;
* };
*
* class CustomPlugin extends Web3PluginBase<CustomRpcApi> {...}
* ```
*/
export abstract class Web3EthPluginBase<API extends Web3APISpec = unknown> extends Web3PluginBase<
API & EthExecutionAPI
> {}
22 changes: 21 additions & 1 deletion packages/web3-core/test/unit/web3_context.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/

// eslint-disable-next-line max-classes-per-file
import { ExistingPluginNamespaceError } from 'web3-errors';
import HttpProvider from 'web3-providers-http';
import { Web3Context } from '../../src/web3_context';
import { Web3Context, Web3PluginBase } from '../../src/web3_context';
import { Web3RequestManager } from '../../src/web3_request_manager';

// eslint-disable-next-line @typescript-eslint/ban-types
Expand Down Expand Up @@ -201,4 +202,23 @@ describe('Web3Context', () => {
expect(child.provider).toBe(parent.provider);
});
});

describe('registerPlugin', () => {
it('should throw ExistingPluginNamespaceError', () => {
const context = new Context1('http://test/abc');
const pluginNamespace = 'plugin';

class Plugin extends Web3PluginBase {
public pluginNamespace = pluginNamespace;
}
class Plugin2 extends Web3PluginBase {
public pluginNamespace = pluginNamespace;
}

context.registerPlugin(new Plugin());
expect(() => context.registerPlugin(new Plugin2())).toThrow(
new ExistingPluginNamespaceError(pluginNamespace),
);
});
});
});
1 change: 1 addition & 0 deletions packages/web3-errors/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `SignatureError` to `web3-errors/src/errors/signature_errors.ts` (moved from `web3-eth/src/errors.ts`) (#5462)
- Added the errors' classes to `web3-errors/src/errors/transaction_errors.ts` from `web3-eth/src/errors.ts` (#5462)
- Added `TransactionBlockTimeoutError` class and its error code `ERR_TX_BLOCK_TIMEOUT` (#5294)
- `ExistingPluginNamespaceError` class and it's error code `ERR_EXISTING_PLUGIN_NAMESPACE` (#5393)

### Changed

Expand Down
1 change: 1 addition & 0 deletions packages/web3-errors/src/error_codes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const ERR_METHOD_NOT_IMPLEMENTED = 202;
export const ERR_OPERATION_TIMEOUT = 203;
export const ERR_OPERATION_ABORT = 204;
export const ERR_ABI_ENCODING = 205;
export const ERR_EXISTING_PLUGIN_NAMESPACE = 206;

// Contract error codes
export const ERR_CONTRACT = 300;
Expand Down
9 changes: 9 additions & 0 deletions packages/web3-errors/src/errors/generic_errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
ERR_OPERATION_ABORT,
ERR_OPERATION_TIMEOUT,
ERR_PARAM,
ERR_EXISTING_PLUGIN_NAMESPACE,
} from '../error_codes';
import { Web3Error } from '../web3_error_base';

Expand Down Expand Up @@ -67,3 +68,11 @@ export class OperationAbortError extends Web3Error {
export class AbiError extends Web3Error {
public code = ERR_ABI_ENCODING;
}

export class ExistingPluginNamespaceError extends Web3Error {
public code = ERR_EXISTING_PLUGIN_NAMESPACE;

public constructor(pluginNamespace: string) {
super(`A plugin with the namespace: ${pluginNamespace} has already been registered.`);
}
}
2 changes: 1 addition & 1 deletion packages/web3-eth-ens/test/unit/constructor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('ens', () => {

beforeAll(() => {
const context = new Web3Context('http://test.com');
object = context.getContextObject() as Web3ContextObject;
object = context.getContextObject();
});
it('should construct registry with expected methods', () => {
const registry = new Registry(object);
Expand Down
6 changes: 3 additions & 3 deletions packages/web3-eth/test/integration/defaults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ describe('defaults', () => {
value: '0x174876e800',
gas: '0x5208',
},
web3Context: eth2 as Web3Context<any>,
web3Context: eth2 as Web3Context,
});
expect(res.networkId).toBe(4);

Expand All @@ -706,7 +706,7 @@ describe('defaults', () => {
gas: '0x5208',
networkId: 5,
},
web3Context: eth2 as Web3Context<any>,
web3Context: eth2 as Web3Context,
});

expect(resWithPassNetworkId.networkId).toBe(BigInt(5));
Expand Down Expand Up @@ -736,7 +736,7 @@ describe('defaults', () => {
value: '0x174876e800',
gas: '0x5208',
},
web3Context: eth2 as Web3Context<any>,
web3Context: eth2 as Web3Context,
});
expect(res.chain).toBe('rinkeby');
});
Expand Down
4 changes: 4 additions & 0 deletions packages/web3-types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `Web3EthExecutionAPI` export (#5441)
- `Web3NetAPI` export (#5441)
- `EthPersonalAPI` export (#5441)

### Changed

- `Web3APISpec`, `Web3APIMethod`, and `Web3APIParams` not support `unknown` APIs (#5393)
14 changes: 7 additions & 7 deletions packages/web3-types/src/web3_api_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.

import { JsonRpcId, JsonRpcIdentifier } from './json_rpc_types';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Web3APISpec = Record<string, (...params: any) => any>;
export type Web3APIMethod<T extends Web3APISpec> = string & keyof T;
export type Web3APIParams<API extends Web3APISpec, Method extends Web3APIMethod<API>> = Parameters<
API[Method]
>;
export type Web3APISpec = Record<string, (...params: any) => any> | unknown;
export type Web3APIMethod<T extends Web3APISpec> = string & keyof Exclude<T, unknown>;
export type Web3APIParams<
API extends Web3APISpec,
Method extends Web3APIMethod<API>,
> = API extends Exclude<Web3APISpec, unknown> ? Parameters<API[Method]> : unknown;

export interface Web3APIRequest<API extends Web3APISpec, Method extends Web3APIMethod<API>> {
method: Method;
Expand All @@ -38,4 +38,4 @@ export interface Web3APIPayload<API extends Web3APISpec, Method extends Web3APIM
export type Web3APIReturnType<
API extends Web3APISpec,
Method extends Web3APIMethod<API>,
> = ReturnType<API[Method]>;
> = API extends Record<string, (...params: any) => any> ? ReturnType<API[Method]> : any;
6 changes: 6 additions & 0 deletions packages/web3/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ But this internal behavior is not exposed any further. Though you can achieve sa
```ts
web3.currentProvider.disconnect();
```

## [Unreleased]

### Changed

- `Web3` is now a default and named export (#5393)
3 changes: 2 additions & 1 deletion packages/web3/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,4 +323,5 @@ along with web3.js. If not, see <http://www.gnu.org/licenses/>.
*/
import Web3 from './web3';

export = Web3;
export * from './web3';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those changes revert back the modifications made at: https://github.com/web3/web3.js/pull/5221/files#diff-bef53270c59945a684e63b962974a96318e07549c207ea92bbc9c369e35bc476R326
And it will cause backward incompatibility with version 1.x, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't break anything as mentioned here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I am referring to how web3 will be imported inside javascript and typescript files.

So the question is: After this MR, can the user still use the old way?

import Web3 from 'web3';  // without the curly brackets around Web3

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, on line 327, Web3 is still the default export of the package:

export default Web3;

An example of this working is in the contract_method_wrappers tests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a simple javascript project with the following code:

const Web3 = require('web3'); 

const web3 = new Web3();

And only when using this branch, the following error occurs:

TypeError: Web3 is not a constructor

So, could you please revert back any changes made to how Web3 is exported? Or else, if it is necessary to have those changes for the plugin, then please let me know where exactly this is needed so we can investigate more on this matter...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you face any problems reverting this MR's changes to the Web3 export statement?
It was export = Web3; not module.exports = Web3;
It was:

import Web3 from './web3';

export = Web3;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, TypeScript module augmentation seems to be designed to work with named ES modules. So only exporting Web3 as a CommonJS module results in the following error

test/unit/contract_method_wrappers.test.ts:27:16 - error TS2664: Invalid module name in augmentation, module 'web3' cannot be found.

    27 declare module 'web3' {

I've tried many different ways to work around this, but it boils down to us not being able to mix CommonJS and ES modules, the latter being needed to provide module augmentation

However, we can use

import Web3 from './web3';

export * from './web3';
export default Web3;

and the user would still be able to do

const Web3 = require('web3').default;

but of course this still results in a breaking change and module augmentation doesn't work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spacesailor24 Limitation is for module augmentation there must be named export as mentioned in ts docs Module Augmentation part:
"image"

so If we do named export of Web3 in current CJS settings module augmentation works fine.

As discussed earlier for supporting legacy applications, and not introducing breaking change, I am in favour of keeping current Web3 4x export settings ( Also mentioned by Muhammad-Altabba ) and there is a workaround for module augmentation for now:

so in user plugin project where web3 augmentation is required: if Web3 is imported and reexported as named, users can augment.

web3.ts in user project

import Web3 from 'web3';
export { Web3 };

and pluginConsumer.ts using named reexported web3 from user's web3.ts

import { Web3 } from './web3';
import { Web3Context } from 'web3-core';
import { EthExecutionAPI } from 'web3-types';

import { ContractMethodWrappersPlugin } from './contract_method_wrappers';
import { ERC20TokenAbi } from './ERC20Token';

declare module './web3' {
    interface Web3 extends Web3Context<EthExecutionAPI> {
        contractMethodWrappersPlugin: ContractMethodWrappersPlugin;
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Muhammad-Altabba @jdevcs This commit adds the work around mentioned above by Junaid

Copy link
Contributor

@Muhammad-Altabba Muhammad-Altabba Oct 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jdevcs for the great workaround.
And thanks @spacesailor24 for the great implementation.
I think the MR is ready to be merged after updating the CHANGELOG.md.

export default Web3;
3 changes: 2 additions & 1 deletion packages/web3/src/web3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { initAccountsForContext } from './accounts';
import { Web3EthInterface } from './types';
import { Web3PkgInfo } from './version';

export default class Web3 extends Web3Context<EthExecutionAPI> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break minified web3.js build #5345

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit updates Web3 to be exported via default and named. I've created a test example that uses the web3.min.js and calls various functions to ensure the minified build works

export class Web3 extends Web3Context<EthExecutionAPI> {
public static version = Web3PkgInfo.version;
public static utils = utils;
public static modules = {
Expand Down Expand Up @@ -128,3 +128,4 @@ export default class Web3 extends Web3Context<EthExecutionAPI> {
});
}
}
export default Web3;
Loading