diff --git a/docs/docs/guides/web3_migration_guide/index.md b/docs/docs/guides/web3_migration_guide/index.md index 27be98c9302..061a0d40497 100644 --- a/docs/docs/guides/web3_migration_guide/index.md +++ b/docs/docs/guides/web3_migration_guide/index.md @@ -32,6 +32,10 @@ const web3 = new Web3(); Passing callbacks to functions is no longer supported, except for event listeners. +For example, the approach to subscribing-to and listening-for blockchain events has changed in version 4.x. Detailed instructions can be found in the [**`web3.eth.subscribe` Migration Guide**](/docs/guides/web3_migration_guide/subscribe_migration_guide#subscribing-to-events). + +However, the approach to subscribing to Provider events remains the same, utilizing callbacks as explained in the [Providers Events Listening guide](/docs/guides/web3_providers_guide/events_listening). It is important to note that Providers have undergone some breaking changes, including the renaming of the `on('close', ...)` to `on('disconnect', ...)`. + ### Not Implemented or Exported - [extend](https://web3js.readthedocs.io/en/v1.7.3/web3.html#extend) Extending web3 modules functionality is not implemented diff --git a/docs/docs/guides/web3_migration_guide/subscribe_migration_guide.md b/docs/docs/guides/web3_migration_guide/subscribe_migration_guide.md index 708fa639503..6ce6c2512a2 100644 --- a/docs/docs/guides/web3_migration_guide/subscribe_migration_guide.md +++ b/docs/docs/guides/web3_migration_guide/subscribe_migration_guide.md @@ -7,6 +7,45 @@ sidebar_label: web3.eth.subscribe ## Breaking Changes +### Subscribing to events + +You subscribe to blockchain events using the `web3.eth.subscribe` API. + +However, in web3.js version 1.x, for example, you could subscribe to the `newBlockHeaders` event, in one step, with the following code snippet: + +```typescript +var subscription = web3.eth.subscribe('newBlockHeaders', function (error, result) { + if (!error) console.log(result); +}); +``` + +But, in web3.js Version 4.x, the function signature has changed for `web3.eth.subscribe`. In addition, the way you get notified for `data` and `error` has also changed. It is now in 2 steps: First you subscribe and then you listen to events. Here's an example of how you would subscribe to the same `newBlockHeaders` event in web3.js version 4.x: + +```typescript +// in 4.x +const subscription = await web3.eth.subscribe('newHeads'); + +// note that in version 4.x the way you get notified for `data` and `error` has changed +subscription.on('data', async blockhead => { + console.log('New block header: ', blockhead); +}); +subscription.on('error', error => + console.log('Error when subscribing to New block header: ', error), +); +``` + +#### Differences + +In summary, the differences you need to be aware of when subscribing to blockchain events in web3.js version 4.x are: + +- The `subscribe` function signature has changed: + - It does not accept a callback function. + - It returns a subscription object that you can use to listen to `data` and `error` events. +- You should now use the `on`, or `once`, method on the newly returned subscription object to listen to `data` and `error` events, instead of passing a callback function directly. +- You can have multiple event listeners, if you have, for example multiple `on` calls. And you can get the number of listeners in you code by calling `listenerCount(event_name)` or get the listeners with `listeners(event_name)`. + +Keep in mind that these differences apply to all blockchain event subscriptions, not just to the `newBlockHeaders` event. + ### New Block Headers event In 1.x, `web3.eth.subscribe('newBlockHeaders')` was used to subscribe to new block headers. @@ -30,7 +69,18 @@ web3.eth.clearSubscriptions(function (error, success) { // in 4.x const subscription = await web3.eth.subscribe('newHeads'); -subscription.unsubscribe().then( - console.log(), // [...] Array of subsription ids + +// note that in version 4.x the way you get notified for `data` and `error` has changed +newBlocksSubscription.on('data', async blockhead => { + console.log('New block header: ', blockhead); +}); +newBlocksSubscription.on('error', error => + console.log('Error when subscribing to New block header: ', error), ); + +const ids = await web3.eth.clearSubscriptions(); +console.log(ids); // [...] An array of subscription ids that were cleared + +// note that you can unsubscribe from a specific subscription by calling unsubscribe() +// on that subscription object: `await subscription.unsubscribe();` and this would return void if succeeded. ``` diff --git a/packages/web3-core/src/web3_config.ts b/packages/web3-core/src/web3_config.ts index ce73361f34c..71c297fa0d2 100644 --- a/packages/web3-core/src/web3_config.ts +++ b/packages/web3-core/src/web3_config.ts @@ -282,7 +282,7 @@ export abstract class Web3Config } /** - * The blockHeaderTimeout is used over socket-based connections. This option defines the amount seconds it should wait for “newBlockHeaders” event before falling back to polling to fetch transaction receipt. + * The blockHeaderTimeout is used over socket-based connections. This option defines the amount seconds it should wait for `'newBlockHeaders'` event before falling back to polling to fetch transaction receipt. * Default is `10` seconds. */ public get blockHeaderTimeout() { diff --git a/packages/web3-eth-contract/src/types.ts b/packages/web3-eth-contract/src/types.ts index 43cc490efb7..877a5f0e793 100644 --- a/packages/web3-eth-contract/src/types.ts +++ b/packages/web3-eth-contract/src/types.ts @@ -70,7 +70,7 @@ export interface ContractEventOptions { */ fromBlock?: BlockNumberOrTag; /** - * This allows to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically. Each topic can also be a nested array of topics that behaves as “or” operation between the given nested topics. + * This allows to manually set the topics for the event filter. If given the filter property and event signature, (topic[0]) will not be set automatically. Each topic can also be a nested array of topics that behaves as `or` operation between the given nested topics. */ topics?: string[]; } diff --git a/packages/web3-eth/src/web3_eth.ts b/packages/web3-eth/src/web3_eth.ts index 4aafb61db39..c9f73fcbd4d 100644 --- a/packages/web3-eth/src/web3_eth.ts +++ b/packages/web3-eth/src/web3_eth.ts @@ -1244,13 +1244,13 @@ export class Web3Eth extends Web3Context console.log(data)); + * logSubscription.on('error', (error: any) => console.log(error)); * - * const subscription = web3.eth.subscribe('logs', { - * address: '0x1234567890123456789012345678901234567890', - * topics: ['0x033456732123ffff2342342dd12342434324234234fd234fd23fd4f23d4234'] - * }) - * .then(logs => console.log(logs)) - * .catch(error => console.log(error)); + * ``` + * + * @example **Subscribe to new block headers** + * ```ts + * // Subscribe to `newBlockHeaders` + * const newBlocksSubscription = await web3.eth.subscribe('newBlockHeaders'); + * + * newBlocksSubscription.on('data', async blockhead => { + * console.log('New block header: ', blockhead); + * + * // You do not need the next line, if you like to keep notified for every new block + * await newBlocksSubscription.unsubscribe(); + * console.log('Unsubscribed from new block headers.'); + * }); + * newBlocksSubscription.on('error', error => + * console.log('Error when subscribing to New block header: ', error), + * ); * ``` */ public async subscribe< @@ -1614,11 +1625,11 @@ export class Web3Eth extends Web3Context true + * > [...] An array of subscription ids that were cleared * ``` */ public clearSubscriptions(notClearSyncing = false): Promise | undefined { diff --git a/packages/web3-eth/src/web3_subscriptions.ts b/packages/web3-eth/src/web3_subscriptions.ts index 78d22d11b15..27e9ad73442 100644 --- a/packages/web3-eth/src/web3_subscriptions.ts +++ b/packages/web3-eth/src/web3_subscriptions.ts @@ -34,13 +34,13 @@ type CommonSubscriptionEvents = { connected: number; }; /** - * ## subscribe(“logs”) + * ## subscribe('logs') * Subscribes to incoming logs, filtered by the given options. If a valid numerical fromBlock options property is set, web3.js will retrieve logs beginning from this point, backfilling the response as necessary. * * You can subscribe to logs matching a given filter object, which can take the following parameters: - * - `fromBlock`: (optional, default: “latest”) Integer block number, or “latest” for the last mined block or “pending”, “earliest” for not yet mined transactions. + * - `fromBlock`: (optional, default: 'latest') Integer block number, or `'latest'` for the last mined block or `'pending'`, `'earliest'` for not yet mined transactions. * - `address`: (optional) Contract address or a list of addresses from which logs should originate. - * - `topics`: (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with “or” options. + * - `topics`: (optional) Array of 32 Bytes DATA topics. Topics are order-dependent. Each topic can also be an array of DATA with `or` options. * */ export class LogsSubscription extends Web3Subscription< @@ -68,13 +68,13 @@ export class LogsSubscription extends Web3Subscription< } /** - * ## subscribe(“pendingTransactions”) + * ## subscribe('pendingTransactions') * Subscribes to incoming pending transactions. * - * You can subscribe to pending transactions by calling web3.eth.subscribe(“pendingTransactions”). + * You can subscribe to pending transactions by calling web3.eth.subscribe('pendingTransactions'). * @example * ```ts - * web3.eth.subscribe('pendingTransactions').on("data", console.log(transaction); + * (await web3.eth.subscribe('pendingTransactions')).on('data', console.log); * ``` */ export class NewPendingTransactionsSubscription extends Web3Subscription< @@ -97,15 +97,15 @@ export class NewPendingTransactionsSubscription extends Web3Subscription< } /** - * ## subscribe(“newHeads”) ( same as subscribe("newBlockHeaders")) + * ## subscribe('newHeads') ( same as subscribe('newBlockHeaders')) * * Subscribes to incoming block headers. This can be used as timer to check for changes on the blockchain. * * The structure of a returned block header is {@link BlockHeaderOutput}: * @example * ```ts - * (await web3.eth.subscribe("newHeads")).on( // "newBlockHeaders" would work as well - * "data", + * (await web3.eth.subscribe('newHeads')).on( // 'newBlockHeaders' would work as well + * 'data', * console.log * ); * >{ @@ -145,15 +145,15 @@ export class NewHeadsSubscription extends Web3Subscription< } /** - * ## subscribe(“syncing”) + * ## subscribe('syncing') * * Subscribe to syncing events. This will return `true` when the node is syncing and when it’s finished syncing will return `false`, for the `changed` event. * @example * ```ts - * (await web3.eth.subscribe("syncing")).on("changed", console.log); + * (await web3.eth.subscribe('syncing')).on('changed', console.log); * > `true` // when syncing * - * (await web3.eth.subscribe("syncing")).on("data", console.log); + * (await web3.eth.subscribe('syncing')).on('data', console.log); * > { * startingBlock: 0, * currentBlock: 0, diff --git a/packages/web3-types/src/eth_contract_types.ts b/packages/web3-types/src/eth_contract_types.ts index 9a57f054395..29668ef12e3 100644 --- a/packages/web3-types/src/eth_contract_types.ts +++ b/packages/web3-types/src/eth_contract_types.ts @@ -50,12 +50,12 @@ export interface ContractInitOptions { export interface NonPayableCallOptions { nonce?: HexString; /** - * The address the call `transaction` should be made from. For calls the `from` property is optional however it is + * The address which is the call (the transaction) should be made from. For calls the `from` property is optional however it is * highly recommended to explicitly set it or it may default to address(0) depending on your node or provider. */ from?: Address; /** - * The maximum gas provided for this call “transaction” (gas limit) + * The maximum gas (gas limit) provided for this call (this transaction) */ gas?: string; maxPriorityFeePerGas?: HexString;