From 6d7d83da4a637cd2f8f9c39cf19ebcdc0c761de2 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 16:38:27 +0100 Subject: [PATCH 01/12] show Ipc and WebSocket providers in the documentation + add public getter for `SocketConnection` --- packages/web3-providers-ipc/src/index.ts | 7 ++++--- packages/web3-providers-ws/src/index.ts | 8 ++++++-- packages/web3-utils/src/socket_provider.ts | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/web3-providers-ipc/src/index.ts b/packages/web3-providers-ipc/src/index.ts index 67a3afb353f..4faa92627bb 100644 --- a/packages/web3-providers-ipc/src/index.ts +++ b/packages/web3-providers-ipc/src/index.ts @@ -27,9 +27,6 @@ import { } from 'web3-types'; import { existsSync } from 'fs'; -// todo had to ignore, introduce error in doc generation,see why/better solution -/** @ignore */ - export default class IpcProvider extends SocketProvider< Buffer | string, CloseEvent, @@ -38,6 +35,9 @@ export default class IpcProvider exte > { // Message handlers. Due to bounding of `this` and removing the listeners we have to keep it's reference. protected _socketConnection?: Socket; + public get SocketConnection() { + return this._socketConnection; + } public getStatus(): Web3ProviderStatus { if (this._socketConnection?.connecting) { @@ -103,6 +103,7 @@ export default class IpcProvider exte this._socketConnection?.removeAllListeners('end'); this._socketConnection?.removeAllListeners('close'); this._socketConnection?.removeAllListeners('data'); + // note: we intentionally keep the error event listener to be able to emit it in case an error happens when closing the connection } protected _onCloseEvent(event: CloseEvent): void { diff --git a/packages/web3-providers-ws/src/index.ts b/packages/web3-providers-ws/src/index.ts index 8740ba4ea2a..a5be70017ad 100644 --- a/packages/web3-providers-ws/src/index.ts +++ b/packages/web3-providers-ws/src/index.ts @@ -28,15 +28,18 @@ import { isNullish, SocketProvider } from 'web3-utils'; import { ConnectionNotOpenError } from 'web3-errors'; export { ClientRequestArgs } from 'http'; -// todo had to ignore, introduce error in doc generation,see why/better solution -/** @ignore */ + export { ClientOptions } from 'isomorphic-ws'; export default class WebSocketProvider< API extends Web3APISpec = EthExecutionAPI, > extends SocketProvider { protected readonly _providerOptions?: ClientOptions | ClientRequestArgs; + protected _socketConnection?: WebSocket; + public get SocketConnection() { + return this._socketConnection; + } // eslint-disable-next-line class-methods-use-this protected _validateProviderPath(providerUrl: string): boolean { @@ -59,6 +62,7 @@ export default class WebSocketProvider< } return 'disconnected'; } + protected _openSocketConnection() { this._socketConnection = new WebSocket( this._socketPath, diff --git a/packages/web3-utils/src/socket_provider.ts b/packages/web3-utils/src/socket_provider.ts index 7c5fcda3287..827228c549b 100644 --- a/packages/web3-utils/src/socket_provider.ts +++ b/packages/web3-utils/src/socket_provider.ts @@ -201,7 +201,7 @@ export abstract class SocketProvider< /** * Removes a listener for the specified event type. * @param type - The event type to remove the listener for - * @param callback - The callback to be exetuted + * @param callback - The callback to be executed */ public removeListener(type: EventType, callback: Web3ProviderEventCallback): void { this._eventEmitter.removeListener(type, callback); From 4b2b665a7823d3f56e45e988b34ae4ad7210485d Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 16:39:10 +0100 Subject: [PATCH 02/12] add guides for providers and their events --- .../web3_providers_guide/events_listening.md | 61 +++++++++++++++++++ .../docs/guides/web3_providers_guide/index.md | 33 ++++++++++ 2 files changed, 94 insertions(+) create mode 100644 docs/docs/guides/web3_providers_guide/events_listening.md create mode 100644 docs/docs/guides/web3_providers_guide/index.md diff --git a/docs/docs/guides/web3_providers_guide/events_listening.md b/docs/docs/guides/web3_providers_guide/events_listening.md new file mode 100644 index 00000000000..7b064e71c3c --- /dev/null +++ b/docs/docs/guides/web3_providers_guide/events_listening.md @@ -0,0 +1,61 @@ +--- +sidebar_position: 0 +sidebar_label: 'Providers Events Listening' +--- + +# Providers Events Listening + +Some providers are, by design, always connected. And so they can communicate changes with the user through events. Actually, among the 3 providers, `HttpProvider` is the only one that does not support event. And the rest 2: +[WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) and [IpcProvider](/api/web3-providers-ipc/class/IpcProvider) enable the user to listen to emitted events. + +Actually, the events can be categorized as follow ([according to EIP 1193](https://eips.ethereum.org/EIPS/eip-1193#rationale)): + +- Communicate arbitrary messages: `message` +- Changes to the Provider’s ability to make RPC requests; + - `connect` + - `disconnect` +- Common Client and/or Wallet state changes that any non-trivial application must handle: + - `chainChanged` + - `accountsChanged` + +Below a sample code for listening and remove listening to EIP 1193 events: + +```ts +import { Web3 } from `web3` + +const web3 = new Web3(/* PROVIDER*/); + +web3.provider.on('message',()=>{ + // ... +}) + +web3.provider.on('connect',()=>{ + // ... +}) + +web3.provider.on('disconnect',()=>{ + // ... +}) + +web3.provider.on('accountsChanged',()=>{ + // ... +}) + +web3.provider.on('chainChanged',()=>{ + // ... +}) + +// ... + +// for every event above `once` could be used to register to the event only once +web3.provider.once('SUPPORTED_EVENT_NAME',()=>{ + // ... +}) + +// And to unregister a listener `removeListener` could be called +web3.provider.removeListener('SUPPORTED_EVENT_NAME',()=>{ + // ... +}) +``` + +However, the underlying `SocketConnection` of both `WebSocketProvider` and `IpcProvider` could be accessed. This enables the user to access any special properties of the used Socket. As well as, registering to the custom server events directly. Actually the Socket used at `WebSocketProvider` is [isomorphic-ws](https://github.com/heineiuo/isomorphic-ws). And the Socket used at `IpcProvider` is [net.Server](https://nodejs.org/api/net.html#class-netserver) diff --git a/docs/docs/guides/web3_providers_guide/index.md b/docs/docs/guides/web3_providers_guide/index.md new file mode 100644 index 00000000000..e8e6c98e1c8 --- /dev/null +++ b/docs/docs/guides/web3_providers_guide/index.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 1 +sidebar_label: 'web3 Providers' +--- + +# web3.js Providers Guide + +Connecting to a chain happens through a provider. You can pass the provider to the `Web3` constructor as follow: + +```ts +import { Web3 } from `web3` + +const web3 = new Web3(/* PROVIDER*/); + +// calling any method that interact with the network would involve using the early passed provider. +await web3.eth.sendTransaction({ + from, + to, + value, +}); +``` + +The created Web3 instance will use the passed provider to interact with the blockchain network. This interaction happen when sending a request and receiving the response, and when possibly listen to provider events (if the provider support this). + +The provider could be any of the following: + +- An instance of [HttpProvider](/api/web3-providers-http/class/HttpProvider) +- An instance of [WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) +- An instance of [IpcProvider](/api/web3-providers-ipc/class/IpcProvider) +- A string containing string url for `http`/`https`, `ws`/`wss`, or `ipc` protocol. And when a string is passed, an instance of the compatible class above will be created accordingly. ex. WebSocketProvider instance will be created for string containing `ws` or `ws`. And you access this instance by calling `web3.provider` to read the provider and possibly register an event listener. +- Any provider object that adhere to [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193). And it has been tested with Ganache provider, Hardhat provider, and Incubed (IN3) as a provider. + +For both [WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) and [IpcProvider](/api/web3-providers-ipc/class/IpcProvider)the user can listen to emitted events. More on this is at [Providers Events Listening](events_listening). From 780b3fa21e5887212b788e0c2b6c3fe344fec040 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 17:28:39 +0100 Subject: [PATCH 03/12] modify providers test cases --- packages/web3-providers-ipc/test/unit/ipc_provider.test.ts | 2 ++ .../web3-providers-ws/test/unit/web_socket_provider.test.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts b/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts index 822effbda1d..bee625b2947 100644 --- a/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts +++ b/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ +import { Socket } from 'dgram'; import * as fs from 'fs'; import { ConnectionError, InvalidClientError } from 'web3-errors'; import IpcProvider from '../../src/index'; @@ -34,6 +35,7 @@ describe('IpcProvider', () => { it('should construct the instance of the provider', () => { const provider = new IpcProvider(socketPath); expect(provider).toBeInstanceOf(IpcProvider); + expect(provider.SocketConnection).toBeInstanceOf(Socket); }); it('should try to connect', () => { diff --git a/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts b/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts index eac7053e111..433f01c2ad7 100644 --- a/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts +++ b/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts @@ -57,6 +57,7 @@ describe('WebSocketProvider', () => { expect(wsProvider.connect).toBeDefined(); expect(wsProvider.disconnect).toBeDefined(); expect(wsProvider.reset).toBeDefined(); + expect(wsProvider.SocketConnection).toBeInstanceOf(WebSocket); }); it('should allow for providerOptions to be passed upon instantiation', () => { From 165164b031089b9b41c8c1f37d533a75ada41b7e Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 19:03:43 +0100 Subject: [PATCH 04/12] fix a class import at test --- packages/web3-providers-ipc/test/unit/ipc_provider.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts b/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts index bee625b2947..d765ac80238 100644 --- a/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts +++ b/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts @@ -15,7 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { Socket } from 'dgram'; +import { Socket } from 'net'; import * as fs from 'fs'; import { ConnectionError, InvalidClientError } from 'web3-errors'; import IpcProvider from '../../src/index'; From 6960f4089d4aad00f0253c873ad080644adb37d5 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:01:18 +0100 Subject: [PATCH 05/12] move the generic section of the providers guide from the migration guide --- .../providers_migration_guide.md | 75 +-------- .../docs/guides/web3_providers_guide/index.md | 148 +++++++++++++++++- 2 files changed, 148 insertions(+), 75 deletions(-) diff --git a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md index 7d58b9f6f85..5957d52dbbe 100644 --- a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md +++ b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md @@ -4,78 +4,11 @@ sidebar_position: 2 sidebar_label: web3.providers --- -There are multiple ways to set the provider. +For full description about the providers, their priorities and their types, you can check [web3.js Providers Guide](/docs/guides/web3_providers_guide/). -```ts title='Setting a provider' -web3.setProvider(myProvider); -web3.eth.setProvider(myProvider); -web3.Contract.setProvider(myProvider); -contractInstance.setProvider(myProvider); -``` - -The key rule for setting provider is as follows: - -1. Any provider set on the higher level will be applied to all lower levels. e.g. Any provider set using `web3.setProvider` will also be applied to `web3.eth` object. -2. For contracts `web3.Contract.setProvider` can be used to set provider for **all instances** of contracts created by `web3.eth.Contract`. - -:::tip -A provider can be either type `string` or [`SupportedProviders`](/api/web3-core#SupportedProviders). -::: - -## Examples - -### Local Geth Node - -```ts -const Web3 = require('web3'); -const web3 = new Web3('http://localhost:8545'); -// or -const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); - -// change provider -web3.setProvider('ws://localhost:8546'); -// or -web3.setProvider(new Web3.providers.WebsocketProvider('ws://localhost:8546')); - -// Using the IPC provider in node.js -const net = require('net'); -const web3 = new Web3('/Users/myuser/Library/Ethereum/geth.ipc', net); // mac os path -// or -const web3 = new Web3( - new Web3.providers.IpcProvider('/Users/myuser/Library/Ethereum/geth.ipc', net), -); // mac os path -// on windows the path is: "\\\\.\\pipe\\geth.ipc" -// on linux the path is: "/users/myuser/.ethereum/geth.ipc" -``` - -### Remote Node Provider - -```ts -// Using a remote node provider, like Alchemy (https://www.alchemyapi.io/supernode), is simple. -const Web3 = require('web3'); -const web3 = new Web3('https://eth-mainnet.alchemyapi.io/v2/your-api-key'); -``` - -### Injected providers - -The Injected provider should be in compliance with [EIP1193](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md). - -The web3.js 4.x Provider specifications are defined in [web3 base provider](https://github.com/ChainSafe/web3.js/blob/4.x/packages/web3-types/src/web3_base_provider.ts) for Injected Providers. - -```ts -const Web3 = require('web3'); -// Using an EIP1193 provider like MetaMask can be injected - -if (window.ethereum) { - // Check if ethereum object exists - await window.ethereum.request(); - window.web3 = new Web3(window.ethereum); // inject provider -} -``` - -### Provider Options +### Provider Options Changes -There are differences in the objects that could be passed in the Provider constructors. +There are differences in the objects that could be passed in the Provider constructors between version 1.x and 4.x. Bellow, you will find the difference for every Provider object type. #### HttpProvider @@ -147,7 +80,7 @@ let httpOptions = { }; ``` -#### WebsocketProvider +#### WebSocketProvider In 1.x, options passed in the constructor should be of type [`WebsocketProviderOptions`](https://github.com/web3/web3.js/blob/1.x/packages/web3-core-helpers/types/index.d.ts#L192). The `WebsocketProviderOptions` interface consists of: diff --git a/docs/docs/guides/web3_providers_guide/index.md b/docs/docs/guides/web3_providers_guide/index.md index e8e6c98e1c8..fa366aaab8c 100644 --- a/docs/docs/guides/web3_providers_guide/index.md +++ b/docs/docs/guides/web3_providers_guide/index.md @@ -1,11 +1,11 @@ --- sidebar_position: 1 -sidebar_label: 'web3 Providers' +sidebar_label: 'Providers' --- # web3.js Providers Guide -Connecting to a chain happens through a provider. You can pass the provider to the `Web3` constructor as follow: +Connecting to a chain happens through a provider. You can pass the provider to the constructor as in the following example: ```ts import { Web3 } from `web3` @@ -22,7 +22,9 @@ await web3.eth.sendTransaction({ The created Web3 instance will use the passed provider to interact with the blockchain network. This interaction happen when sending a request and receiving the response, and when possibly listen to provider events (if the provider support this). -The provider could be any of the following: +## Providers Types + +Actually, the provider could be any of the following: - An instance of [HttpProvider](/api/web3-providers-http/class/HttpProvider) - An instance of [WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) @@ -30,4 +32,142 @@ The provider could be any of the following: - A string containing string url for `http`/`https`, `ws`/`wss`, or `ipc` protocol. And when a string is passed, an instance of the compatible class above will be created accordingly. ex. WebSocketProvider instance will be created for string containing `ws` or `ws`. And you access this instance by calling `web3.provider` to read the provider and possibly register an event listener. - Any provider object that adhere to [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193). And it has been tested with Ganache provider, Hardhat provider, and Incubed (IN3) as a provider. -For both [WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) and [IpcProvider](/api/web3-providers-ipc/class/IpcProvider)the user can listen to emitted events. More on this is at [Providers Events Listening](events_listening). +For both [WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) and [IpcProvider](/api/web3-providers-ipc/class/IpcProvider) the user can listen to emitted events. More on this is at [Providers Events Listening](events_listening). + +:::tip +The passed provider can be either type `string` or one of the [`SupportedProviders`](/api/web3-core#SupportedProviders). And if it is passed as a string, then internally the compatible provider object will be created and used. +::: + +## Providers Priorities + +There are multiple ways to set the provider. + +```ts title='Setting a provider' +web3.setProvider(myProvider); +web3.eth.setProvider(myProvider); +web3.Contract.setProvider(myProvider); +contractInstance.setProvider(myProvider); +``` + +The key rule for setting provider is as follows: + +1. Any provider set on the higher level will be applied to all lower levels. e.g. Any provider set using `web3.setProvider` will also be applied to `web3.eth` object. +2. For contracts `web3.Contract.setProvider` can be used to set provider for **all instances** of contracts created by `web3.eth.Contract`. + +--- + +## Examples + +### Local Geth Node + +```ts +const Web3 = require('web3'); +const web3 = new Web3('http://localhost:8545'); +// or +const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545')); + +// change provider +web3.setProvider('ws://localhost:8546'); +// or +web3.setProvider(new Web3.providers.WebsocketProvider('ws://localhost:8546')); + +// Using the IPC provider in node.js +const net = require('net'); +const web3 = new Web3('/Users/myuser/Library/Ethereum/geth.ipc', net); // mac os path +// or +const web3 = new Web3( + new Web3.providers.IpcProvider('/Users/myuser/Library/Ethereum/geth.ipc', net), +); // mac os path +// on windows the path is: "\\\\.\\pipe\\geth.ipc" +// on linux the path is: "/users/myuser/.ethereum/geth.ipc" +``` + +### Remote Node Provider + +```ts +// Using a remote node provider, like Alchemy (https://www.alchemyapi.io/supernode), is simple. +const Web3 = require('web3'); +const web3 = new Web3('https://eth-mainnet.alchemyapi.io/v2/your-api-key'); +``` + +### Injected providers + +As stated above, the injected provider should be in compliance with [EIP-1193](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1193.md). And it is tested with Ganache provider, Hardhat provider, and Incubed (IN3) as a provider. + +The web3.js 4.x Provider specifications are defined in [web3 base provider](https://github.com/ChainSafe/web3.js/blob/4.x/packages/web3-types/src/web3_base_provider.ts) for Injected Providers. + +```ts +const Web3 = require('web3'); +// Using an EIP1193 provider like MetaMask can be injected + +if (window.ethereum) { + // Check if ethereum object exists + await window.ethereum.request(); + window.web3 = new Web3(window.ethereum); // inject provider +} +``` + +### Provider Options + +There are differences in the objects that could be passed in the Provider constructors. + +#### HttpProvider + +The options is of type `HttpProviderOptions`, which is an object with a single key named `providerOptions` and its value is an object of type `RequestInit`. +Regarding `RequestInit` see [microsoft's github](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.requestinit.html). + +For example: + +```ts +const httpOptions = { + providerOptions: { + body: undefined, + cache: 'force-cache', + credentials: 'same-origin', + headers: { + 'Content-Type': 'application/json', + }, + integrity: 'foo', + keepalive: true, + method: 'GET', + mode: 'same-origin', + redirect: 'error', + referrer: 'foo', + referrerPolicy: 'same-origin', + signal: undefined, + window: undefined, + } as RequestInit, +}; +``` + +#### WebSocketProvider + +The options object is of type `ClientRequestArgs` or of `ClientOptions`. See [here](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules__types_node_http_d_._http_.clientrequestargs.html) for `ClientRequestArgs` and [here](https://github.com/websockets/ws) for `ClientOptions`. + +The second option parameter can be given regarding reconnecting. And here is its type: + +```ts +export type ReconnectOptions = { + autoReconnect: boolean; + delay: number; + maxAttempts: number; +}; +``` + +For example: + +```ts +let clientOptions: ClientOptions = { + // Useful for credentialed urls, e.g: ws://username:password@localhost:8546 + headers: { + authorization: 'Basic username:password', + }, + maxPayload: 100000000, +}; + +const reconnectOptions: ReconnectOptions = { + autoReconnect: true, + delay: 5000, + maxAttempts: 5, +}; +``` From 9b7799db5ce05041bbaa6a63c6e526a30cd6236a Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:05:26 +0100 Subject: [PATCH 06/12] fix typo --- .../guides/web3_migration_guide/providers_migration_guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md index 5957d52dbbe..71a8c721941 100644 --- a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md +++ b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md @@ -8,7 +8,7 @@ For full description about the providers, their priorities and their types, you ### Provider Options Changes -There are differences in the objects that could be passed in the Provider constructors between version 1.x and 4.x. Bellow, you will find the difference for every Provider object type. +There are differences in the objects that could be passed in the Provider constructors between version 1.x and 4.x. Below, you will find the difference for every Provider object type. #### HttpProvider From 9b7433c3686f8142bde5affe37dfa212f7206c4d Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:17:15 +0100 Subject: [PATCH 07/12] rearrange docs guide indexes --- docs/docs/guides/web3_plugin_guide/index.md | 2 +- docs/docs/guides/web3_tree_shaking_support_guide/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/guides/web3_plugin_guide/index.md b/docs/docs/guides/web3_plugin_guide/index.md index c85745adbf3..32d0f8c15b4 100644 --- a/docs/docs/guides/web3_plugin_guide/index.md +++ b/docs/docs/guides/web3_plugin_guide/index.md @@ -1,5 +1,5 @@ --- -sidebar_position: 1 +sidebar_position: 2 sidebar_label: 'web3 Plugins' --- diff --git a/docs/docs/guides/web3_tree_shaking_support_guide/index.md b/docs/docs/guides/web3_tree_shaking_support_guide/index.md index 64835249d00..893af66f7fb 100644 --- a/docs/docs/guides/web3_tree_shaking_support_guide/index.md +++ b/docs/docs/guides/web3_tree_shaking_support_guide/index.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 sidebar_label: web3 Tree Shaking Guide --- From 1e39c7bd55e2da67ecb186814b06e7d1dd89b4ca Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Fri, 3 Mar 2023 23:41:02 +0100 Subject: [PATCH 08/12] edit some texts at guides --- .../web3_migration_guide/providers_migration_guide.md | 7 ++----- docs/docs/guides/web3_providers_guide/events_listening.md | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md index 71a8c721941..78504d1b386 100644 --- a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md +++ b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md @@ -105,12 +105,9 @@ export interface ReconnectOptions { } ``` -In 4.x, the options object is of type `ClientRequestArgs` or of `ClientOptions`. See -Regarding `RequestInit` see [here](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules__types_node_http_d_._http_.clientrequestargs.html) for `ClientRequestArgs` and [here](https://github.com/websockets/ws) for `ClientOptions`. +In 4.x, the options object is of type `ClientRequestArgs` or of `ClientOptions`. See [here](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules__types_node_http_d_._http_.clientrequestargs.html) for `ClientRequestArgs` and [here](https://github.com/websockets/ws) for `ClientOptions`. -In 4.x a second option parameter can be given regarding reconnecting. - -The interface: +In 4.x a second option parameter can be given regarding auto-reconnecting, delay and max tries attempts. And here is its type: ```ts export type ReconnectOptions = { diff --git a/docs/docs/guides/web3_providers_guide/events_listening.md b/docs/docs/guides/web3_providers_guide/events_listening.md index 7b064e71c3c..33dec8c9075 100644 --- a/docs/docs/guides/web3_providers_guide/events_listening.md +++ b/docs/docs/guides/web3_providers_guide/events_listening.md @@ -5,10 +5,10 @@ sidebar_label: 'Providers Events Listening' # Providers Events Listening -Some providers are, by design, always connected. And so they can communicate changes with the user through events. Actually, among the 3 providers, `HttpProvider` is the only one that does not support event. And the rest 2: +Some providers are, by design, always connected. Therefor, they can communicate changes with the user through events. Actually, among the 3 providers, `HttpProvider` is the only one that does not support event. And the other 2: [WebSocketProvider](/api/web3-providers-ws/class/WebSocketProvider) and [IpcProvider](/api/web3-providers-ipc/class/IpcProvider) enable the user to listen to emitted events. -Actually, the events can be categorized as follow ([according to EIP 1193](https://eips.ethereum.org/EIPS/eip-1193#rationale)): +Actually, the events can be categorized as follows ([according to EIP 1193](https://eips.ethereum.org/EIPS/eip-1193#rationale)): - Communicate arbitrary messages: `message` - Changes to the Provider’s ability to make RPC requests; From 6ce47917d2ca3695fe7df71feb4eb36efc069051 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 4 Mar 2023 00:55:38 +0100 Subject: [PATCH 09/12] edit docs especially for catching providers errors --- .../providers_migration_guide.md | 42 ++++++++++++++----- .../web3_providers_guide/events_listening.md | 7 ++++ .../docs/guides/web3_providers_guide/index.md | 37 +++++++++++++++- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md index 78504d1b386..635921260a4 100644 --- a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md +++ b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md @@ -15,7 +15,7 @@ There are differences in the objects that could be passed in the Provider constr In 1.x, options passed in the constructor should be of type [`HttpProviderOptions`](https://github.com/web3/web3.js/blob/1.x/packages/web3-core-helpers/types/index.d.ts#L173). The `HttpProviderOptions` interface consists of: ```ts -export interface HttpProviderOptions { +interface HttpProviderOptions { keepAlive?: boolean; timeout?: number; headers?: HttpHeader[]; @@ -23,13 +23,13 @@ export interface HttpProviderOptions { agent?: HttpAgent; } -export interface HttpAgent { +interface HttpAgent { http?: http.Agent; https?: https.Agent; baseUrl?: string; } -export interface HttpHeader { +interface HttpHeader { name: string; value: string; } @@ -85,7 +85,7 @@ let httpOptions = { In 1.x, options passed in the constructor should be of type [`WebsocketProviderOptions`](https://github.com/web3/web3.js/blob/1.x/packages/web3-core-helpers/types/index.d.ts#L192). The `WebsocketProviderOptions` interface consists of: ```ts -export interface WebsocketProviderOptions { +interface WebsocketProviderOptions { host?: string; timeout?: number; reconnectDelay?: number; @@ -97,7 +97,7 @@ export interface WebsocketProviderOptions { reconnect?: ReconnectOptions; } -export interface ReconnectOptions { +interface ReconnectOptions { auto?: boolean; delay?: number; maxAttempts?: number; @@ -110,14 +110,16 @@ In 4.x, the options object is of type `ClientRequestArgs` or of `ClientOptions`. In 4.x a second option parameter can be given regarding auto-reconnecting, delay and max tries attempts. And here is its type: ```ts -export type ReconnectOptions = { - autoReconnect: boolean; - delay: number; - maxAttempts: number; +type ReconnectOptions = { + autoReconnect: boolean; // default: `true` + delay: number; // default: `5000` + maxAttempts: number; // default: `5` }; ``` -For example: +##### Options examples + +Below is an example for the passed options for each version: ```ts // in 1.x @@ -162,3 +164,23 @@ const reconnectOptions: ReconnectOptions = { maxAttempts: 5, }; ``` + +##### Error message + +The error in, version 1.x, was an Error object that contains the message: +`'Maximum number of reconnect attempts reached!'` + +However, the error, in version 4.x, is just an error message (not wrapped in an Error object). And the error message will contain the value of the variable `maxAttempts` as follows: + +`` `Max connection attempts exceeded (${maxAttempts})` `` + +And here is how to catch the error, in version 4.x, if max attempts reached when there is auto reconnecting: + +```ts +provider.on('error', errorMessage => { + if (errorMessage.startsWith('Max connection attempts exceeded')) { + // the `errorMessage` will be `Max connection attempts exceeded (${maxAttempts})` + // the `maxAttempts` is equal to the provided value by the user, or the default value `5`. + } +}); +``` diff --git a/docs/docs/guides/web3_providers_guide/events_listening.md b/docs/docs/guides/web3_providers_guide/events_listening.md index 33dec8c9075..8c85bb00e2f 100644 --- a/docs/docs/guides/web3_providers_guide/events_listening.md +++ b/docs/docs/guides/web3_providers_guide/events_listening.md @@ -45,6 +45,13 @@ web3.provider.on('chainChanged',()=>{ // ... }) +// it is possible to catch errors that could happen in the underlying connection Socket with the `error` event +// and it is also used to catch the error when max connection attempts exceeded +// as in section: /docs/guides/web3_providers_guide/#error-message +web3.provider.on('error',()=>{ + // ... +} + // ... // for every event above `once` could be used to register to the event only once diff --git a/docs/docs/guides/web3_providers_guide/index.md b/docs/docs/guides/web3_providers_guide/index.md index fa366aaab8c..a130e22374c 100644 --- a/docs/docs/guides/web3_providers_guide/index.md +++ b/docs/docs/guides/web3_providers_guide/index.md @@ -147,14 +147,30 @@ The options object is of type `ClientRequestArgs` or of `ClientOptions`. See [he The second option parameter can be given regarding reconnecting. And here is its type: ```ts -export type ReconnectOptions = { +type ReconnectOptions = { autoReconnect: boolean; delay: number; maxAttempts: number; }; ``` -For example: +:::info +Here is how to catch the error if max attempts reached when the auto reconnecting: + +```ts +provider.on('error', errorMessage => { + if (errorMessage.startsWith('Max connection attempts exceeded')) { + // the `errorMessage` will be `Max connection attempts exceeded (${maxAttempts})` + // the `maxAttempts` is equal to the provided value by the user or the default `5`. + } +}); +``` + +::: + +##### Options example + +Below is an example for the passed options: ```ts let clientOptions: ClientOptions = { @@ -171,3 +187,20 @@ const reconnectOptions: ReconnectOptions = { maxAttempts: 5, }; ``` + +##### Error message + +The error message (not wrapped in an Error object) will contain the value of the variable `maxAttempts` as follows: + +`` `Max connection attempts exceeded (${maxAttempts})` `` + +And here is how to catch the error, in version 4.x, if max attempts reached when there is auto reconnecting: + +```ts +provider.on('error', errorMessage => { + if (errorMessage.startsWith('Max connection attempts exceeded')) { + // the `errorMessage` will be `Max connection attempts exceeded (${maxAttempts})` + // the `maxAttempts` is equal to the provided value by the user or the default `5`. + } +}); +``` From bea42e0dfc55659330db7b6b54290311cdd4d4dd Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 4 Mar 2023 01:02:55 +0100 Subject: [PATCH 10/12] revert a suggestion to be done in another PR --- packages/web3-providers-ipc/src/index.ts | 3 --- packages/web3-providers-ws/src/index.ts | 3 --- 2 files changed, 6 deletions(-) diff --git a/packages/web3-providers-ipc/src/index.ts b/packages/web3-providers-ipc/src/index.ts index 4faa92627bb..7b4d8cae1f7 100644 --- a/packages/web3-providers-ipc/src/index.ts +++ b/packages/web3-providers-ipc/src/index.ts @@ -35,9 +35,6 @@ export default class IpcProvider exte > { // Message handlers. Due to bounding of `this` and removing the listeners we have to keep it's reference. protected _socketConnection?: Socket; - public get SocketConnection() { - return this._socketConnection; - } public getStatus(): Web3ProviderStatus { if (this._socketConnection?.connecting) { diff --git a/packages/web3-providers-ws/src/index.ts b/packages/web3-providers-ws/src/index.ts index a5be70017ad..e5352aba929 100644 --- a/packages/web3-providers-ws/src/index.ts +++ b/packages/web3-providers-ws/src/index.ts @@ -37,9 +37,6 @@ export default class WebSocketProvider< protected readonly _providerOptions?: ClientOptions | ClientRequestArgs; protected _socketConnection?: WebSocket; - public get SocketConnection() { - return this._socketConnection; - } // eslint-disable-next-line class-methods-use-this protected _validateProviderPath(providerUrl: string): boolean { From b42540e298f43ed9e22e23035580e7144899839e Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 4 Mar 2023 01:23:14 +0100 Subject: [PATCH 11/12] modify tests for reverted changes --- packages/web3-providers-ipc/test/unit/ipc_provider.test.ts | 2 -- .../web3-providers-ws/test/unit/web_socket_provider.test.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts b/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts index d765ac80238..822effbda1d 100644 --- a/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts +++ b/packages/web3-providers-ipc/test/unit/ipc_provider.test.ts @@ -15,7 +15,6 @@ You should have received a copy of the GNU Lesser General Public License along with web3.js. If not, see . */ -import { Socket } from 'net'; import * as fs from 'fs'; import { ConnectionError, InvalidClientError } from 'web3-errors'; import IpcProvider from '../../src/index'; @@ -35,7 +34,6 @@ describe('IpcProvider', () => { it('should construct the instance of the provider', () => { const provider = new IpcProvider(socketPath); expect(provider).toBeInstanceOf(IpcProvider); - expect(provider.SocketConnection).toBeInstanceOf(Socket); }); it('should try to connect', () => { diff --git a/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts b/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts index 433f01c2ad7..eac7053e111 100644 --- a/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts +++ b/packages/web3-providers-ws/test/unit/web_socket_provider.test.ts @@ -57,7 +57,6 @@ describe('WebSocketProvider', () => { expect(wsProvider.connect).toBeDefined(); expect(wsProvider.disconnect).toBeDefined(); expect(wsProvider.reset).toBeDefined(); - expect(wsProvider.SocketConnection).toBeInstanceOf(WebSocket); }); it('should allow for providerOptions to be passed upon instantiation', () => { From e473e4f80c03f69a140f47e53c132a23b9757f84 Mon Sep 17 00:00:00 2001 From: Muhammad-Altabba <24407834+Muhammad-Altabba@users.noreply.github.com> Date: Sat, 4 Mar 2023 01:35:18 +0100 Subject: [PATCH 12/12] tiny edits at providers guides --- .../web3_migration_guide/providers_migration_guide.md | 2 +- docs/docs/guides/web3_providers_guide/index.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md index 635921260a4..7cc50878c15 100644 --- a/docs/docs/guides/web3_migration_guide/providers_migration_guide.md +++ b/docs/docs/guides/web3_migration_guide/providers_migration_guide.md @@ -165,7 +165,7 @@ const reconnectOptions: ReconnectOptions = { }; ``` -##### Error message +##### Error message for reconnect attempts The error in, version 1.x, was an Error object that contains the message: `'Maximum number of reconnect attempts reached!'` diff --git a/docs/docs/guides/web3_providers_guide/index.md b/docs/docs/guides/web3_providers_guide/index.md index a130e22374c..c8d5f8ffe5b 100644 --- a/docs/docs/guides/web3_providers_guide/index.md +++ b/docs/docs/guides/web3_providers_guide/index.md @@ -188,13 +188,13 @@ const reconnectOptions: ReconnectOptions = { }; ``` -##### Error message +##### Error message for reconnect attempts -The error message (not wrapped in an Error object) will contain the value of the variable `maxAttempts` as follows: +The error message (not wrapped in an Error object) for the max reconnect attempts, will contain the value of the variable `maxAttempts` as follows: `` `Max connection attempts exceeded (${maxAttempts})` `` -And here is how to catch the error, in version 4.x, if max attempts reached when there is auto reconnecting: +And here is how to catch the error, if max attempts reached when there is auto reconnecting: ```ts provider.on('error', errorMessage => {