Metamask財布に反応する方法
54459 ワード
フロントエンドとスマート契約を統合するには、最初のタスクは通常、どのようにフロントエンドのアプリケーションに財布を接続することです.このブログのポストは、反応のアプリケーションから財布を接続する方法を示します.
財布を接続するには以下のパッケージが必要です. WalletConnectProvider ウォレット Web 3モード イーサネット(これは、ブロックチェーン上のスマート契約に接続するために使用されます) 上記のパッケージは、次のコマンドを端末で実行することで、反応アプリケーションにインストールできます.
このファイルには次の内容があります
我々は、財布を接続するために使用されるボタンを作成する必要があります.つの関数を定義します
次に、作成した関数を生成する関数を作成しました
The
我々がすでに我々の財布に接続しているならば、我々はページまたは構成要素を訪問するとき、自動的に再接続したいです.これは、呼び出しによって行うことができます
//app > jx
読書ありがとう.
インストールするパッケージ
財布を接続するには以下のパッケージが必要です.
npm i --save walletlink @walletconnect/web3-provider ethers
web3modal
次のパッケージをインストールした後、あなたの反応を開きますApp.js
ファイルまたはアプリケーションの最上位コンポーネントです.最初にインストールしたパッケージをインポートします. import { useEffect, useState, useCallback } from "react";
import { ethers, providers } from "ethers";
import Web3Modal from "web3modal";
import WalletConnectProvider from '@walletconnect/web3-provider'
import WalletLink from 'walletlink';
const App = () => {
return (
<div>
<h1>Hello</h1>
</div>
)
}
これは単純な反応成分の骨格です.我々は、我々が使用したい財布の選択を許可するweb 3モードを宣言した.私たちは、渡されるプロバイダオプションを作成する必要がありますweb3Modal
. const INFURA_ID = "your-infura-api-key";
const providerOptions = {
walletconnect: {
package: WalletConnectProvider, // required
options: {
infuraId: INFURA_ID, // required
},
},
'custom-walletlink': {
display: {
logo: 'https://play-lh.googleusercontent.com/PjoJoG27miSglVBXoXrxBSLveV6e3EeBPpNY55aiUUBM9Q1RCETKCOqdOkX2ZydqVf0',
name: 'Coinbase',
description: 'Connect to Coinbase Wallet',
},
options: {
appName: 'Coinbase', // Your app name
networkUrl: `https://mainnet.infura.io/v3/${INFURA_ID}`,
chainId: 1,
},
package: WalletLink,
connector: async (_, options) => {
const { appName, networkUrl, chainId } = options
const walletLink = new WalletLink({
appName,
})
const provider = walletLink.makeWeb3Provider(networkUrl, chainId)
await provider.enable()
return provider
},
},
}
The WalletLink
パッケージは、ユーザーが拡張機能をインストールすることなく、任意のデスクトップブラウザでアプリケーションを使用することができますし、クライアントが生成されたキーを使用してエンドツーエンドの暗号化とアプリとモバイル財布の間に安全なトンネルを確立し、すべてのユーザーの活動を非公開にします.WalletConnect
パッケージは、ウォレットとDApps(web 3 Apps)の間で安全に通信するのに役立つオープンプロトコルです.プロトコルはペイロードを中継するためにブリッジ・サーバーを使用している2つのアプリケーションと/またはデバイスの間のリモート接続を確立します.接続するAPIキーを提供する必要があります.let web3Modal
if (typeof window !== 'undefined') {
web3Modal = new Web3Modal({
network: 'mainnet', // optional
cacheProvider: true,
providerOptions, // required
})
}
ProviderOptionsをWeb 3モーダルインスタンスに渡します.アプリ.JSXは今まさにこのように見えます.
import { useEffect, useState, useCallback } from "react";
import { ethers, providers } from "ethers";
import Web3Modal from "web3modal";
import WalletConnectProvider from '@walletconnect/web3-provider'
import WalletLink from 'walletlink';
const INFURA_ID = "your-infura-api-key";
const providerOptions = {
walletconnect: {
package: WalletConnectProvider, // required
options: {
infuraId: INFURA_ID, // required
},
},
'custom-walletlink': {
display: {
logo: 'https://play-lh.googleusercontent.com/PjoJoG27miSglVBXoXrxBSLveV6e3EeBPpNY55aiUUBM9Q1RCETKCOqdOkX2ZydqVf0',
name: 'Coinbase',
description: 'Connect to Coinbase Wallet',
},
options: {
appName: 'Coinbase', // Your app name
networkUrl: `https://mainnet.infura.io/v3/${INFURA_ID}`,
chainId: 1,
},
package: WalletLink,
connector: async (_, options) => {
const { appName, networkUrl, chainId } = options
const walletLink = new WalletLink({
appName,
})
const provider = walletLink.makeWeb3Provider(networkUrl, chainId)
await provider.enable()
return provider
},
},
}
let web3Modal
if (typeof window !== 'undefined') {
web3Modal = new Web3Modal({
network: 'mainnet', // optional
cacheProvider: true,
providerOptions, // required
})
}
const App = () => {
return (
<div>
<h1>Hello</h1>
</div>
)
}
プロバイダーオブジェクトは我々のアプリケーションで永続的である必要があり、アプリケーションのすべてのコンポーネントを通過するプロップを防ぐことができます.コンテキストファイルを作成しますwalletContext.js
.このファイルには次の内容があります
import * as React from "react";
const WalletContext = React.createContext();
const accountDetails = {
provider: null,
address: null,
signer: null,
web3Provider: null,
network: null
}
function WalletProvider({children}){
const [account, setAccountDetails ] =
React.useState(accountDetails);
const value = { account, setAccountDetails };
return <WalletContext.Provider value={value}>{children}
</WalletContext.Provider>
}
function useWallet(){
const context = React.useContext(WalletContext);
if (!context){
throw new Error("useWallet must be used within a WalletProvider")
}
return context;
}
export {WalletProvider, useWallet }
我々は反応文脈を作成し、それを命名したWalletContext
. それから、我々はWalletProvider
を返す関数WalletContext.Provider
ラップされたコンポーネントchildren
それはそれに渡されます.インサイドWalletProvider
関数は、接続されたアカウントの詳細を格納するために使用される反応状態を宣言しました.The account
状態を変化させる状態と機能setAccountDetails
がvalue
プロパティWalletContext.Provider
コンポーネント.See application state management 我々は、財布を接続するために使用されるボタンを作成する必要があります.つの関数を定義します
connect
とdisconnect
関数.彼らの名前が示唆するように、彼らは接続を切って、ブロックを財布から切り離すのに用いられます.その前に、関数から返される値を格納するために使用される反応状態を作成する必要があります.次に、作成した関数を生成する関数を作成しました
WalletContext
. The useWallet
フックが消費するWalletContext
を返し、context
使用する. <-- previous code above -->
const App = () => {
const { account, setAccountDetails } = useWallet();
const { provider,
address,
signer,
web3Provider,
network } = account;
const connect = useCallback(async function () {
const provider = await web3Modal.connect();
const web3Provider = new providers.Web3Provider(provider);
const signer = web3Provider.getSigner()
const address = await signer.getAddress()
const network = await web3Provider.getNetwork();
const accountDetails = {
provider,
web3Provider,
signer,
address,
network
}
setAccountDetails(accountDetails);
}, []);
const disconnect = useCallback(
async function () {
await web3Modal.clearCachedProvider()
if (provider?.disconnect && typeof provider.disconnect === 'function') {
await provider.disconnect()
}
//reset the state here
const accountDetails = {
provider: null,
web3Provider: null,
signer: null,
address: null,
network: null
}
setAccountDetails(accountDetails);
},
[provider]
)
return (
<div>
<h1>Hello</h1>
</div>
)
}
Connect関数は、既定のWeb 3モード接続に設定されているプロバイダー変数を作成します.このプロバイダーは、それからプロバイダのオブジェクトにプラグインされますether.js
.const web3Provider = new providers.Web3Provider(provider)
を使用することができますweb3Provider
object created by ether.js
得るsigner
, network
, address
からether.js
. この値は、setAccountDetails
関数.The
disconnect
関数はweb3Modal
キャッシュ、保存された状態およびprovider
. 我々は両方の機能を最適化し、それらを包むuseCallback
と依存を渡す.自動接続
我々がすでに我々の財布に接続しているならば、我々はページまたは構成要素を訪問するとき、自動的に再接続したいです.これは、呼び出しによって行うことができます
connect
インuseEffect
フック. // Auto connect to the cached provider
useEffect(() => {
if (web3Modal.cachedProvider) {
connect()
}
}, [connect]);
また、いくつかのシナリオを処理するためにプロバイダーオブジェクトのイベントを聞くこともできます.ユーザーが接続されたアカウントを切り替える場合、我々はまだ接続されることがありますように.機能handleAccountsChanged
アカウントを変更したイベントを聞くことによって行われ、WalletContext
. useEffect(() => {
if (provider?.on) {
const handleAccountsChanged = (accounts) => {
console.log('accountsChanged', accounts);
setAccountDetails({
...account,
address: accounts[0],
})
}
const handleChainChanged = (_hexChainId) => {
window.location.reload()
}
const handleDisconnect = (error) => {
console.log('disconnect', error)
disconnect()
}
provider.on('accountsChanged', handleAccountsChanged)
provider.on('chainChanged', handleChainChanged)
provider.on('disconnect', handleDisconnect)
// Subscription Cleanup
return () => {
if (provider.removeListener) {
provider.removeListener('accountsChanged', handleAccountsChanged)
provider.removeListener('chainChanged', handleChainChanged)
provider.removeListener('disconnect', handleDisconnect)
}
}
}
}, [provider, disconnect])
すべてをまとめる//app > jx
import { useEffect, useState, useCallback } from "react";
import { ethers, providers } from "ethers";
import Web3Modal from "web3modal";
import WalletConnectProvider from '@walletconnect/web3-provider'
import WalletLink from 'walletlink';
import { useWallet } from './walletContext';
import './App.css';
const trimAddress = ( address ) => {
const firstpart = address.slice(0, 4);
const midpart = "....";
const endpart = address.slice(address.length - 4, address.length );
return `${firstpart}${midpart}${endpart}`
}
const INFURA_ID = '460f40a260564ac4a4f4b3fffb032dad'
const providerOptions = {
walletconnect: {
package: WalletConnectProvider, // required
options: {
infuraId: INFURA_ID, // required
},
},
'custom-walletlink': {
display: {
logo: 'https://play-lh.googleusercontent.com/PjoJoG27miSglVBXoXrxBSLveV6e3EeBPpNY55aiUUBM9Q1RCETKCOqdOkX2ZydqVf0',
name: 'Coinbase',
description: 'Connect to Coinbase Wallet (not Coinbase App)',
},
options: {
appName: 'Coinbase', // Your app name
networkUrl: `https://mainnet.infura.io/v3/${INFURA_ID}`,
chainId: 1,
},
package: WalletLink,
connector: async (_, options) => {
const { appName, networkUrl, chainId } = options
const walletLink = new WalletLink({
appName,
})
const provider = walletLink.makeWeb3Provider(networkUrl, chainId)
await provider.enable()
return provider
},
},
}
let web3Modal
if (typeof window !== 'undefined') {
web3Modal = new Web3Modal({
network: 'mainnet', // optional
cacheProvider: true,
providerOptions, // required
})
}
function App() {
const { account, setAccountDetails } = useWallet();
const { provider,
address,
signer,
web3Provider,
network } = account;
const connect = useCallback(async function () {
const provider = await web3Modal.connect();
const web3Provider = new providers.Web3Provider(provider);
const signer = web3Provider.getSigner()
const address = await signer.getAddress()
const network = await web3Provider.getNetwork();
const accountDetails = {
provider,
web3Provider,
signer,
address,
network
}
setAccountDetails(accountDetails);
}, []);
const disconnect = useCallback(
async function () {
await web3Modal.clearCachedProvider()
if (provider?.disconnect && typeof provider.disconnect === 'function') {
await provider.disconnect()
}
//reset the state here
const accountDetails = {
provider: null,
web3Provider: null,
signer: null,
address: null,
network: null
}
setAccountDetails(accountDetails);
},
[provider]
)
// Auto connect to the cached provider
useEffect(() => {
if (web3Modal.cachedProvider) {
connect()
}
}, [connect]);
useEffect(() => {
if (provider?.on) {
const handleAccountsChanged = (accounts) => {
// eslint-disable-next-line no-console
console.log('accountsChanged', accounts);
setAccountDetails({
...account,
address: accounts[0],
})
}
const handleChainChanged = (_hexChainId) => {
window.location.reload()
}
const handleDisconnect = (error) => {
console.log('disconnect', error)
disconnect()
}
provider.on('accountsChanged', handleAccountsChanged)
provider.on('chainChanged', handleChainChanged)
provider.on('disconnect', handleDisconnect)
// Subscription Cleanup
return () => {
if (provider.removeListener) {
provider.removeListener('accountsChanged', handleAccountsChanged)
provider.removeListener('chainChanged', handleChainChanged)
provider.removeListener('disconnect', handleDisconnect)
}
}
}
}, [provider, disconnect])
return (
<div className="App">
{web3Provider ? (
<button className="btn btn-danger" type="button" onClick={disconnect}>
{trimAddress(address)}
</button>
) : (
<button className="btn btn-success" type="button" onClick={connect}>
Connect
</button>
)}
</div>
);
}
export default App;
利用するWalletProvider
我々はアプリのコンポーネントをラップします.これはWalletContext
それが必要とされるすべてのコンポーネントで利用できる.import { WalletProvider } from "./walletContext";
ReactDOM.render(
<React.StrictMode>
<WalletProvider>
<App />
</WalletProvider>
</React.StrictMode>,
document.getElementById('root')
コードが利用可能ですhere 読書ありがとう.
Reference
この問題について(Metamask財布に反応する方法), 我々は、より多くの情報をここで見つけました https://dev.to/jamiescript/how-to-connect-to-metamask-wallet-in-react-316oテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol