Skip to content

Commit

Permalink
Merge branch '4.x' into fix-native
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex authored Feb 27, 2024
2 parents 0aa37ec + 86447cd commit 007104e
Show file tree
Hide file tree
Showing 16 changed files with 394 additions and 46 deletions.
28 changes: 28 additions & 0 deletions docs/docs/guides/resources/resources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
sidebar_position: 16
sidebar_label: '📚 Resources'
---
# Resources

## [Web3.js v4 course](https://www.youtube.com/watch?v=3ZO_t-Kyr1g&list=PLPn3rQCo3XrP4LbQcOyyHQR8McV7w3HZT)

This comprehensive 14-part video course from ChainSafe equips you with the skills to conquer the blockchain using web3.js v4. Unlock the potential of web3.js v4 and build cutting-edge dApps. This course caters to all skill levels.

[![Web3.js v4 course](https://img.youtube.com/vi/3ZO_t-Kyr1g/0.jpg)](https://www.youtube.com/watch?v=3ZO_t-Kyr1g&list=PLPn3rQCo3XrP4LbQcOyyHQR8McV7w3HZT)


## [Web3.js series](https://www.youtube.com/watch?v=BQ_bDH91S4k&list=PLPn3rQCo3XrNf__8irs4-MjMt4fJqW2I_)

This series of 3 videos takes you on a journey through web3.js. Whether you're a complete beginner or want to refine your skills, these videos have something for you:

1. Getting Started: Kick off your web3 adventure by learning the ropes of web3.js. Master the basics, from installation to making your first call to the blockchain.

2. Essential Tools: Unleash the power of web3.js utilities! From generating random bytes to hashing and checksumming addresses, you'll gain mastery of essential tools for Ethereum development.

3. Sending Transactions: Dive deep into wallets and accounts. Learn how to sign and send transactions to the network, empowering you to interact with the blockchain directly.

[![Web3.js series](https://img.youtube.com/vi/BQ_bDH91S4k/0.jpg)](https://www.youtube.com/watch?v=BQ_bDH91S4k&list=PLPn3rQCo3XrNf__8irs4-MjMt4fJqW2I_)

## Hackathons

You'll find the latest hackathons opportunities by following [web3js](https://twitter.com/web3_js) on X.
5 changes: 5 additions & 0 deletions docs/docs/guides/wagmi_usage/_category_.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
label: '🔄 Wagmi usage'
collapsible: true
collapsed: true
link: null
position: 11
131 changes: 131 additions & 0 deletions docs/docs/guides/wagmi_usage/wagmi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
sidebar_position: 1
sidebar_label: 'Wagmi Web3js Adapter'
title: 'Wagmi Web3js Adapter'
---


### Reference Implementation
If you're using [Wagmi](https://wagmi.sh/react/getting-started#use-wagmi) and want to add web3.js, use this code in your project. This snippet will help you to convert a `Viem` client to a `web3.js` instance for signing transactions and interacting with the blockchain:


```typescript
import {Web3} from 'web3'
import {useMemo} from 'react'
import type {Chain, Client, Transport} from 'viem'
import {type Config, useClient, useConnectorClient} from 'wagmi'

export function clientToWeb3js(client?: Client<Transport, Chain>) {
if (!client) {
return new Web3()
}

const {transport} = client

if (transport.type === 'fallback') {
return new Web3(transport.transports[0].value.url)
}
return new Web3(transport)
}

/** Action to convert a viem Client to a web3.js Instance. */
export function useWeb3js({chainId}: { chainId?: number } = {}) {
const client = useClient<Config>({chainId})
return useMemo(() => clientToWeb3js(client), [client])
}

/** Action to convert a viem ConnectorClient to a web3.js Instance. */
export function useWeb3jsSigner({chainId}: { chainId?: number } = {}) {
const {data: client} = useConnectorClient<Config>({chainId})
return useMemo(() => clientToWeb3js(client), [client])
}
```

### Usage examples
Get block data example:

```typescript
import {useWeb3js} from '../web3/useWeb3js'
import {mainnet} from 'wagmi/chains'
import {useEffect, useState} from "react";

type Block = {
hash: string
extraData: string
miner: string

}

function Block() {
const web3js = useWeb3js({chainId: mainnet.id})
const [block, setBlock] = useState<Block>()

useEffect(() => {
web3js.eth.getBlock(19235006).then((b) => {
setBlock(b as Block)
}).catch(console.error)
}, [setBlock]);


if (!block) return (<div>Loading...</div>)

return (
<>
<div id='hash'>{block.hash}</div>
<div id='extraData'>{block.extraData}</div>
<div id='miner'>{block.miner}</div>

</>
)
}

export default Block

```

Send transaction example:

```typescript
import {mainnet} from 'wagmi/chains'
import {useAccount, useConnect} from "wagmi";
import {useWeb3jsSigner} from "../web3/useWeb3js";
import {useEffect} from "react";

function SendTransaction() {
const account = useAccount()
const {connectors, connect,} = useConnect()
const web3js = useWeb3jsSigner({chainId: mainnet.id})

useEffect(() => {
if (account && account.address) {
web3js.eth.sendTransaction({
from: account.address,
to: '0x', // some address
value: '0x1' // set your value
}).then(console.log).catch(console.error)
}
}, [account])

return (
<>
{connectors.map((connector) => (
<button
key={connector.uid}
onClick={() => connect({connector})}
type="button"
>
{connector.name}
</button>
))}
</>
)
}

export default SendTransaction

```


:::tip
[This repository](https://github.com/avkos/wagmi-web3js-example-app) contains an example Wagmi app that demonstrates how to interact with the Ethereum blockchain using the web3.js library
:::
58 changes: 58 additions & 0 deletions docs/docs/guides/web3_providers_guide/eip6963.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
sidebar_position: 2
sidebar_label: 'EIP-6963: Multi Injected Provider Discovery'
---

# EIP-6963: Multi Injected Provider Discovery

## Introduction

EIP-6963 proposes the "Multi Injected Provider Discovery" standard, which aims to enhance the discoverability and interaction with multiple injected Ethereum providers in a browser environment. Injected providers refer to browser extensions or other injected scripts that provide access to an Ethereum provider within the context of a web application.

Web3.js library has utility function for discovery of injected providers using `requestEIP6963Providers()` function. When `requestEIP6963Providers()` is used it returns `eip6963Providers` Map object. This Map object is in global scope so every time `requestEIP6963Providers()` function is called it will update Map object and return it.

`eip6963Providers` Map object has provider's `UUID` as keys and `EIP6963ProviderDetail` as values. `EIP6963ProviderDetail` is:

```ts
export interface EIP6963ProviderDetail {
info: EIP6963ProviderInfo;
provider: EIP1193Provider;
}
```

where `info` has details of provider containing UUID, name, Icon and RDNS as defined in EIP-6963:

```ts
export interface EIP6963ProviderInfo {
uuid: string;
name: string;
icon: string;
rdns: string;
}
```

`provider` in `EIP6963ProviderDetail` is `EIP1193Provider` and it contains actual provider that can be injected in web3 instance.

Following code snippet demonstrates usage of `requestEIP6963Providers()` function for providers discovery.

```ts
//Assuming multiple providers are installed in browser.

import { Web3 } from 'web3';

const providers = Web3.requestEIP6963Providers();

for (const [key, value] of providers) {
console.log(value);

/* Based on your DApp's logic show use list of providers and get selected provider's UUID from user for injecting its EIP6963ProviderDetail.provider EIP1193 object into web3 object */

if (value.info.name === 'MetaMask') {
const web3 = new Web3(value.provider);

// now you can use web3 object with injected provider
console.log(await web3.eth.getTransaction('0x82512812c11f56aa2474a16d5cc8916b73cd6ed96bf9b8defb3499ec2d9070cb'));
}
}

```
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/events_listening.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 2
sidebar_position: 3
sidebar_label: 'Providers Events Listening'
---

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/http.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 3
sidebar_position: 4
sidebar_label: 'Tutorial: HTTP Provider'
---

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/injected_provider.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 6
sidebar_position: 7
sidebar_label: 'Tutorial: Injected provider'
---

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/ipc.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 5
sidebar_position: 6
sidebar_label: 'Tutorial: IPC Provider'
---

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/truffle.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 7
sidebar_position: 8
sidebar_label: 'Tutorial: Third Party Provider'
---

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/guides/web3_providers_guide/websocket.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
sidebar_position: 4
sidebar_position: 5
sidebar_label: 'Tutorial: WebSocket Provider'
---

Expand Down
4 changes: 2 additions & 2 deletions packages/web3-eth-abi/src/api/functions_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import { AbiFunctionFragment } from 'web3-types';
import { isAbiFunctionFragment, jsonInterfaceMethodToString } from '../utils.js';
import { encodeParameters } from './parameters_api.js';

// todo Add link to JSON interface documentation
/**
* Encodes the function name to its ABI representation, which are the first 4 bytes of the sha3 of the function name including types.
* The JSON interface spec documentation https://docs.soliditylang.org/en/latest/abi-spec.html#json
* @param functionName - The function name to encode or the `JSON interface` object of the function.
* If the passed parameter is a string, it has to be in the form of `functionName(param1Type,param2Type,...)`. eg: myFunction(uint256,uint32[],bytes10,bytes)
* @returns - The ABI signature of the function.
Expand Down Expand Up @@ -75,9 +75,9 @@ export const encodeFunctionSignature = (functionName: string | AbiFunctionFragme
return sha3Raw(name).slice(0, 10);
};

// todo Add link to JSON interface documentation
/**
* Encodes a function call using its `JSON interface` object and given parameters.
* The JSON interface spec documentation https://docs.soliditylang.org/en/latest/abi-spec.html#json
* @param jsonInterface - The `JSON interface` object of the function.
* @param params - The parameters to encode
* @returns - The ABI encoded function call, which, means the function signature and the parameters passed.
Expand Down
6 changes: 5 additions & 1 deletion packages/web3/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,8 @@ Documentation:

- Dependencies updated ( details are in root changelog )

## [Unreleased]
## [Unreleased]

### Added

- Added EIP-6963 utility function `requestEIP6963Providers` for multi provider discovery
2 changes: 2 additions & 0 deletions packages/web3/src/web3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import abi from './abi.js';
import { initAccountsForContext } from './accounts.js';
import { Web3EthInterface } from './types.js';
import { Web3PkgInfo } from './version.js';
import { requestEIP6963Providers } from './web3_eip6963.js';

export class Web3<
CustomRegisteredSubscription extends {
Expand All @@ -52,6 +53,7 @@ export class Web3<
> extends Web3Context<EthExecutionAPI, CustomRegisteredSubscription & RegisteredSubscription> {
public static version = Web3PkgInfo.version;
public static utils = utils;
public static requestEIP6963Providers = requestEIP6963Providers;
public static modules = {
Web3Eth,
Iban,
Expand Down
71 changes: 71 additions & 0 deletions packages/web3/src/web3_eip6963.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
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 <http://www.gnu.org/licenses/>.
*/

import { Web3APISpec, EIP1193Provider } from "web3-types";


export enum Eip6963EventName {
eip6963announceProvider = 'eip6963:announceProvider',
eip6963requestProvider = 'eip6963:requestProvider',
};

export interface EIP6963ProviderInfo {
uuid: string;
name: string;
icon: string;
rdns: string;
}

export interface EIP6963ProviderDetail<API = Web3APISpec> {
info: EIP6963ProviderInfo;
provider: EIP1193Provider<API>;
}

export interface EIP6963AnnounceProviderEvent<API = Web3APISpec> extends CustomEvent {
type: Eip6963EventName.eip6963announceProvider;
detail: EIP6963ProviderDetail<API>;
}

export interface EIP6963RequestProviderEvent extends Event {
type: Eip6963EventName.eip6963requestProvider;
}

export const eip6963Providers: Map<string, EIP6963ProviderDetail> = new Map();

export const requestEIP6963Providers = () => {

if (typeof window === 'undefined')
throw new Error(
"window object not available, EIP-6963 is intended to be used within a browser"
);

window.addEventListener(
Eip6963EventName.eip6963announceProvider as any,
(event: EIP6963AnnounceProviderEvent) => {

eip6963Providers.set(
event.detail.info.uuid,
event.detail);
}
);

window.dispatchEvent(new Event(Eip6963EventName.eip6963requestProvider));

return eip6963Providers;
}


Loading

2 comments on commit 007104e

@github-actions
Copy link

Choose a reason for hiding this comment

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

Benchmark

Benchmark suite Current: 007104e Previous: 6c075db Ratio
processingTx 9415 ops/sec (±4.19%) 9301 ops/sec (±4.81%) 0.99
processingContractDeploy 38548 ops/sec (±8.26%) 39129 ops/sec (±7.62%) 1.02
processingContractMethodSend 20560 ops/sec (±6.94%) 19443 ops/sec (±5.19%) 0.95
processingContractMethodCall 40964 ops/sec (±5.96%) 38971 ops/sec (±6.34%) 0.95
abiEncode 47708 ops/sec (±7.14%) 44252 ops/sec (±6.92%) 0.93
abiDecode 32731 ops/sec (±7.48%) 30419 ops/sec (±8.89%) 0.93
sign 1645 ops/sec (±4.67%) 1656 ops/sec (±4.08%) 1.01
verify 376 ops/sec (±0.55%) 373 ops/sec (±0.78%) 0.99

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

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

Benchmark

Benchmark suite Current: 007104e Previous: 6c075db Ratio
processingTx 9589 ops/sec (±3.94%) 9301 ops/sec (±4.81%) 0.97
processingContractDeploy 39438 ops/sec (±7.72%) 39129 ops/sec (±7.62%) 0.99
processingContractMethodSend 19687 ops/sec (±7.00%) 19443 ops/sec (±5.19%) 0.99
processingContractMethodCall 39755 ops/sec (±6.33%) 38971 ops/sec (±6.34%) 0.98
abiEncode 45819 ops/sec (±6.46%) 44252 ops/sec (±6.92%) 0.97
abiDecode 31489 ops/sec (±9.47%) 30419 ops/sec (±8.89%) 0.97
sign 1639 ops/sec (±3.99%) 1656 ops/sec (±4.08%) 1.01
verify 382 ops/sec (±0.45%) 373 ops/sec (±0.78%) 0.98

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.