跳至主要內容
本頁面使用機器翻譯自英語,可能包含錯誤或不清楚的語言。如需最準確的信息,請參閱英文原文。由於更新頻繁,部分內容可能與英文原文有出入。請加入我們在 Crowdin 上的努力,幫助我們改進本頁面的翻譯。 (Crowdin translation page, Contributing guide)

將 Web3Auth 集成到 dApp 中

導言

Web3Auth 是一種錢包基礎設施,可插入 dApp 或錢包。 它是 Web3 錢包和應用程序的可插拔認證基礎設施。 憑藉 Web3Auth 卓越的用戶體驗,無論是主流用戶還是加密貨幣原住民,都可以在幾分鐘內完成註冊。

作為一種錢包基礎設施,它為所有社交登錄、網絡和移動原生平臺、錢包和其他密鑰管理方法提供開箱即用的支持。 本指南結束時,您將把 Web3Auth 集成到基於 Kaia 網絡構建的去中心化網絡應用程序中。 要將 Web3Auth 集成到其他平臺(Android、iOS、React Native、Flutter 和 Unity),請參考本 指南

為了快速入門,本教程的完整代碼可在 GitHub 上獲取。 您可以克隆或下載該版本庫,以便跟隨學習。

先決條件

  • 一個正在運行的 react 項目(通過執行 npm create vite@latest project-name -- --template react-ts)
  • 安裝必要的錢包(Coinbase WalletMetamask)。
  • RPC 端點:您可以從支持的端點提供者中獲取。
  • 水龍頭測試 KAIA:為賬戶注入足夠的 KAIA。
  • Web3Auth 控制面板 獲取您的客戶 ID。

安裝

要在 dApp 中使用 Web3Auth,必須先安裝所需的庫和 SDK。 因此,您需要設置 ethers.js 和 Web3Auth Web SDK。 您可以將 Web3Auth 與 etherthers.jsweb3.jskaia sdk 庫一起使用,以便與 Kaia 區塊鏈通信。 本指南將使用 ethers.js。


npm install --save @web3auth/modal @web3auth/base @web3auth/ethereum-provider @web3auth/default-evm-adapter
npm install --save ethers

初始化 Web3Auth 和提供程序實例

成功安裝所需的庫後,接下來要初始化 Web3Auth 實例,在 "useState() "鉤子中設置 Web3Auth provider 實例,並在 "useEffect() "鉤子中設置 "init() "函數。

導入 Web3Auth 和其他依賴軟件包。

導入 React 掛鉤(useState 和 useEffect)和實用功能:

  • useStateuseEffect:用於狀態管理和副作用的 React 掛鉤。
  • RPC:來自 etherRPC.ts 的自定義實用功能,用於使用 ethers.js 進行以太坊兼容的區塊鏈交互。

從 Web3Auth 控制面板粘貼您的 ** 客戶 ID**。

設置 ** 鏈配置**:要使用 Web3Auth,您需要為選定的鏈 - Kaia 設置鏈配置。

通過使用構造函數初始化 Web3Auth,在構造函數中,您可以傳入您想要的 Web3Auth 的所有配置。

在 "useState() "鉤子中設置 Web3Auth provider 實例、userInfo 和 "useEffect() "鉤子中的 "init() "函數。

App.tsx
etherRPC.ts
package.json
vite.config.ts

import {
CHAIN_NAMESPACES,
IProvider,
IAdapter,
WEB3AUTH_NETWORK,
} from '@web3auth/base'
import { EthereumPrivateKeyProvider } from '@web3auth/ethereum-provider'
import { Web3Auth, Web3AuthOptions } from '@web3auth/modal'
import { getDefaultExternalAdapters } from '@web3auth/default-evm-adapter'
import './App.css'
import { useEffect, useState } from 'react'
import RPC from './etherRPC'
const clientId =
'BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ'
const chainConfig = {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: '0x3e9', // Kairos Testnet
rpcTarget: 'https://public-en-kairos.node.kaia.io',
displayName: 'Kairos Testnet',
blockExplorerUrl: 'https://kairos.kaiascan.io',
ticker: 'KLAY',
tickerName: 'KLAY',
}
const privateKeyProvider = new EthereumPrivateKeyProvider({
config: { chainConfig },
})
const web3AuthOptions: Web3AuthOptions = {
clientId,
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
privateKeyProvider,
}
const web3auth = new Web3Auth(web3AuthOptions)
const adapters = await getDefaultExternalAdapters({ options: web3AuthOptions })
adapters.forEach((adapter: IAdapter<unknown>) => {
web3auth.configureAdapter(adapter)
})
interface UserInfo {
email: string;
name: string;
profileImage: string;
[key: string]: unknown;
}
function App() {
const [provider, setProvider] = useState<IProvider | null>(null);
const [loggedIn, setLoggedIn] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(true);
const [address, setAddress] = useState<string>("");
const [balance, setBalance] = useState<string>("");
const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
useEffect(() => {
const init = async () => {
try {
await web3auth.initModal()
setProvider(web3auth.provider)
if (web3auth.connected) {
setLoggedIn(true)
await updateUserInfo()
}
} catch (error) {
console.error(error)
} finally {
setLoading(false)
}
}
init()
}, [])
const updateUserInfo = async () => {
if (web3auth.provider) {
const user = await web3auth.getUserInfo()
// @ts-ignore
setUserInfo(user)
const accounts = await RPC.getAccounts(web3auth.provider)
setAddress(accounts)
const balance = await RPC.getBalance(web3auth.provider)
setBalance(balance)
}
}
}

連接錢包

App.tsx 文件的 App 函數中,調用 web3Auth 實例的 connect() 方法啟動錢包連接。


function App() {
const [provider, setProvider] = (useState < IProvider) | (null > null)
const [loggedIn, setLoggedIn] = useState < boolean > false
const login = async () => {
if (!web3auth) {
console.log('web3auth not initialized yet')
return
}
const web3authProvider = await web3auth.connect()
setProvider(web3authProvider)
if (web3auth.connected) {
setLoggedIn(true)
await updateUserInfo()
}
}
return (
<div className="App">
<button onClick={login}>Login</button>
</div>
)
}

設置實用工具功能

在本指南中,我們將使用實用工具函數:truncateAddress()。 truncateAddress() 函數接收一個有效地址,並返回一個更可讀的地址格式。 以下步驟展示瞭如何在項目中設置和使用 utils 函數。

第 1 步在 src 根文件夾中創建一個 utils.ts 文件。

將以下代碼粘貼到新創建的 utils.ts 文件中:


export const truncateAddress = (address) => {
if (!address) return 'No Account'
const match = address.match(
/^(0x[a-zA-Z0-9]{2})[a-zA-Z0-9]+([a-zA-Z0-9]{4})$/
)
if (!match) return address
return `${match[1]}…${match[2]}`
}

第 2 步在您的 App.tsx 文件中導入該函數。


從'./utils'導入 { truncateAddress }

獲取賬戶和餘額

調用 Web3Auth 實例上的 connect() 方法成功連接錢包後,就可以使用提供者和簽名者對象獲取用戶賬戶及其餘額。


function App() {
const [provider, setProvider] = useState<IProvider | null>(null);
const [address, setAddress] = useState<string>("");
const [balance, setBalance] = useState<string>("");
const getAccounts = async () => {
if (!provider) {
console.log('provider not initialized yet')
return
}
const address = await RPC.getAccounts(provider)
setAddress(address)
console.log('Address:', address)
}
const getBalance = async () => {
if (!provider) {
console.log('provider not initialized yet')
return
}
const balance = await RPC.getBalance(provider)
setBalance(balance)
console.log('Balance:', balance)
}
return (
<div className="App">
<div>
<button onClick={getAccounts}>Get Account</button>
<h2>
{' '}
Address: <span>
{' '}
{`${truncateAddress(address)}` || 'Not available'}
</span>
</h2>
</div>
<div>
<button onClick={getBalance}>Get Balance</button>
<h2>
Balance: <span> {balance || 'Not available'}</span>
</h2>
</div>
</div>
)
}

斷開錢包連接

使用 Web3Auth 實例上的 logout() 方法可以斷開與錢包的連接。 此外,一個好的做法是刷新狀態,清除之前存儲的連接數據。


function App() {
const logout = async () => {
if (!web3auth) {
console.log('web3auth not initialized yet')
return
}
await web3auth.logout()
setProvider(null)
setLoggedIn(false)
setAddress('')
setBalance('')
setUserInfo(null)
console.log('Logged out')
}
return (
<div className="App">
<button onClick={logout}>Logout</button>
</div>
)
}

獲取用戶信息

Web3Auth 的一個獨特功能是社交登錄。 用戶使用社交平臺登錄後,Web3Auth 實例會返回登錄用戶的一些信息。 在 Web3Auth 實例上調用 getUserInfo() 方法即可簡單地獲取登錄用戶信息。


const [userInfo, setUserInfo] = useState<UserInfo | null>(null);
const getUserInfo = async () => {
if (!web3auth) {
console.log('web3auth not initialized yet')
return
}
const user = await web3auth.getUserInfo()
// @ts-ignore
setUserInfo(user)
console.log('User Info:', user)
}
return (
<div className="App">
<button onClick={getUserInfo}>Get User Info</button>
<div>
<h2>User Info:</h2>
<pre>
{userInfo ? JSON.stringify(userInfo, null, 2) : 'Not available'}
</pre>
</div>
</div>
)

簽署信息

初始化提供者和簽名者對象後,用戶就可以簽署任意字符串。


// add to the existing useState hook.
const [signedMessage, setSignedMessage] = useState<string>("");
const signMessage = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
const originalMessage = "YOUR_MESSAGE";
const signedMessage = await RPC.signMessage(provider, originalMessage);
setSignedMessage(signedMessage);
console.log("Signed Message:", signedMessage);
};
return (
<div className="App">
<button onClick={signMessage}>Sign Message</button>
{signedMessage && (
<div>
<h2 className="text-wrap text-center text-sm font-semibold">
Signed Message: <span className="font-normal">{signedMessage}</span>
</h2>
</div>
)}
</div>
)

發送本地事務

您可以執行本地事務,如將 KAIA 從一個用戶發送到另一個用戶。


// add to the existing useState hook.
const [txHash, setTxHash] = useState<string>("");
const sendKaiaTx = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
console.log("Sending Transaction...");
const destination = "0x75Bc50a5664657c869Edc0E058d192EeEfD570eb";
const amount = "0.1";
const receipt = await RPC.sendKaiaTx(provider, destination, amount);
setTxHash(receipt.hash);
console.log("Transaction Receipt:", receipt);
};
return (
<div className="App">
<button onClick={sendKaiaTx}>Send Kaia</button>
{txHash && (
<div>
<h2>
Transaction Hash:{' '}
<a
href={`${chainConfig.blockExplorerUrl}/tx/${txHash}`}
target="_blank"
rel="noopener noreferrer"
>
{txHash}
</a>
</h2>
</div>
)}
</div>
)

使用智能合約

您可以根據智能合約的應用程序二進制接口(ABI)和合約地址與已部署的智能合約進行交互。 以下步驟說明瞭如何在項目中設置和使用合同地址和 ABI。

第 1 步在 src 根文件夾中創建一個 constants.ts 文件。

將以下代碼粘貼到新創建的 constants.ts 文件中:


export const contractABI = [
{
"inputs": [
{
"internalType": "uint256",
"name": "_initNum",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "retrieve",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "num",
"type": "uint256"
}
],
"name": "store",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
] as const;
export const contractAddress = "0x3b01E4025B428fFad9481a500BAc36396719092C";

第 2 步:在 etherRPC.ts 文件中導入contractABIcontractAddress


從"./constants "導入 { contractAddress, contractABI };

1. 撰寫合同


// add to existing useState hook
const [contractTxHash, setContractTxHash] = useState<string>("");
const setContractValue = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
console.log("setting contract value...");
const value = "100";
const tx = await RPC.setContractValue(provider, value);
setContractTxHash(tx.hash);
console.log("Transaction Receipt:", tx);
}
return (
<div className="App">
<button onClick={setContractValue}>Write to Contract</button>
{contractTxHash && (
<div>
<h2>
Contract Tx Hash: <span>{contractTxHash}</span>
</h2>
</div>
)}
</div>
)

2. 閱讀合同


// add to existing useState hook
const [contractMessage, setContractMessage] = useState<string>("");
const getContractValue = async () => {
if (!provider) {
console.log("provider not initialized yet");
return;
}
console.log("getting value from contract...");
const message = await RPC.getContractValue(provider);
setContractMessage(message);
console.log("contract message:", message);
}
return (
<button onClick={getContractValue}>Read From Contract</button>
{contractMessage && (
<div>
<h2 className="text-wrap text-center text-sm font-semibold">Read Message: <span className="font-normal">{contractMessage}</span></h2>
</div>
)}
)

故障排除

您可以訪問故障排除頁面,從不同的捆綁程序中探索常見挑戰和問題的解決方案。

下一步

有關 Web3Auth 的更多深入指南,請參閱 Web3Auth 文檔Web3Auth Github 存儲庫

讓這個頁面變得更好