部署React前端
为Algorand dApps创建React前端,并集成钱包。当创建与智能合约交互的React前端、设置钱包连接(Pera、Defly、Exodus)、集成带钱包签名者的类型化应用客户端,或构建调用合约方法的dApp UI时使用。强烈的触发词包括“为我创建一个前端合约”、“在我的React应用中添加钱包连接”、“我如何从前端调用我的合约?”、“设置use-wallet与我的类型化客户端”、“将Pera钱包连接到我的dApp”、“algorand.setSigner”。
部署Algorand的React前端
构建连接到Algorand钱包并与智能合约交互的React应用程序,使用类型化客户端。
先决条件
在使用此技能之前,请确保:
- 智能合约已部署,并且已知应用ID
- 存在ARC-56/ARC-32应用规范(例如,
MyContract.arc56.json) - React项目已设置(Vite、Next.js或Create React App)
核心工作流程:"签名者交接"模式
关键见解是将钱包的交易签名者传递给AlgorandClient,然后AlgorandClient将其提供给类型化应用客户端:
钱包(use-wallet)→交易签名者
↓
AlgorandClient.setSigner()
↓
类型化应用客户端(defaultSender)
↓
合约方法调用(自动签名)
如何进行
第1步:生成类型化客户端
从您的合约应用规范生成TypeScript客户端:
algokit generate client path/to/MyContract.arc56.json --output src/contracts/MyContractClient.ts
这会创建一个带有完整IntelliSense的类型化客户端,用于您的合约方法。
第2步:安装依赖项
核心包:
npm install @algorandfoundation/algokit-utils @txnlab/use-wallet-react algosdk
钱包对等依赖项(仅安装您使用的钱包):
| 钱包 | 包 |
|---|---|
| Pera | @perawallet/connect |
| Defly | @blockshake/defly-connect |
| Kibisis | @agoralabs-sh/avm-web-provider |
| Lute | lute-connect |
例如Pera + Defly:
npm install @perawallet/connect @blockshake/defly-connect
第3步:设置WalletProvider
在根级别用WalletProvider包装您的应用:
import { NetworkId, WalletId, WalletManager, WalletProvider } from '@txnlab/use-wallet-react'
const walletManager = new WalletManager({
wallets: [WalletId.PERA, WalletId.DEFLY, WalletId.EXODUS],
defaultNetwork: NetworkId.TESTNET,
})
export default function App() {
return (
<WalletProvider manager={walletManager}>
<YourApp />
</WalletProvider>
)
}
第4步:创建钱包连接UI
使用useWallet()钩子显示可用钱包:
import { useWallet } from '@txnlab/use-wallet-react'
function ConnectWallet() {
const { wallets, activeAddress } = useWallet()
if (activeAddress) {
return <p>已连接:{activeAddress}</p>
}
return (
<div>
{wallets.map((wallet) => (
<button key={wallet.id} onClick={() => wallet.connect()}>
连接{wallet.metadata.name}
</button>
))}
</div>
)
}
第5步:将类型化客户端与钱包签名者集成
这是关键的集成步骤。将钱包的签名者注册到AlgorandClient:
import { useWallet } from '@txnlab/use-wallet-react'
import { AlgorandClient } from '@algorandfoundation/algokit-utils'
import { MyContractClient } from './contracts/MyContractClient'
function ContractInteraction() {
const { transactionSigner, activeAddress } = useWallet()
const callContract = async () => {
if (!activeAddress || !transactionSigner) {
alert('请先连接您的钱包')
return
}
// 1. 为网络创建AlgorandClient
const algorand = AlgorandClient.testNet()
// 2. 将钱包签名者注册到AlgorandClient
algorand.setSigner(activeAddress, transactionSigner)
// 3. 使用钱包作为默认发送者创建类型化客户端
const appClient = algorand.client.getTypedAppClientById(MyContractClient, {
appId: 12345n, // 您部署的应用ID
defaultSender: activeAddress,
})
// 4. 调用合约方法 - 签名者自动使用
const result = await appClient.send.myMethod({ args: { value: 42n } })
console.log('结果:', result.return)
}
return <button onClick={callContract}>调用合约</button>
}
第6步:部署新合约(可选)
如果从前端部署(较少见),请使用工厂模式:
import { MyContractFactory } from './contracts/MyContractClient'
const factory = new MyContractFactory({
algorand,
defaultSender: activeAddress,
})
const { appClient } = await factory.deploy({
onSchemaBreak: 'append',
onUpdate: 'append',
})
重要规则/指南
- 在创建客户端之前始终调用setSigner() - 必须首先将签名者注册到AlgorandClient
- 检查null activeAddress和transactionSigner - 当没有连接钱包时它们为null
- 使用TypeScript - 类型化客户端提供完整的类型安全性和IntelliSense
- 匹配网络 - 确保AlgorandClient网络与WalletManager网络匹配
- 仅限React - 此技能涵盖React;其他框架有不同的模式
获取应用客户端
获取类型化应用客户端的三种方式:
| 方法 | 用例 |
|---|---|
getTypedAppClientById() |
已知应用ID(前端最常见) |
getTypedAppClientByCreatorAndName() |
通过创建者地址和应用名称解析 |
factory.deploy() |
部署新实例并获取客户端 |
// 通过应用ID(推荐前端使用)
const appClient = algorand.client.getTypedAppClientById(MyContractClient, {
appId: 12345n,
defaultSender: activeAddress,
})
// 通过创建者和名称
const appClient = await algorand.client.getTypedAppClientByCreatorAndName(
MyContractClient,
{
creatorAddress: 'CREATORADDRESS...',
appName: 'MyContract',
}
)
常见错误/故障排除
| 错误 | 原因 | 解决方案 |
|---|---|---|
activeAddress为null |
钱包未连接 | 在合约调用之前检查钱包连接 |
transactionSigner未定义 |
没有活动钱包 | 提示用户先连接钱包 |
地址找不到签名者 |
未注册签名者 | 调用algorand.setSigner(activeAddress, transactionSigner) |
应用不存在 |
应用ID错误 | 验证应用ID与部署的合约匹配 |
方法未找到 |
方法名称或签名错误 | 检查类型化客户端API;确保参数与ABI匹配 |
网络不匹配 |
不同网络 | 确保AlgorandClient和WalletManager使用相同网络 |
用户拒绝交易 |
用户在钱包中取消 | 在UI中优雅地处理拒绝 |
global未定义 |
algosdk在浏览器中引用global |
添加到vite.config.ts:define: { global: 'globalThis' } |
| 生成客户端中的TypeScript错误 | 严格TS模式不兼容 | 在tsconfig.json中设置verbatimModuleSyntax: false |
钱包断开连接
处理钱包断开连接:
function DisconnectButton() {
const { wallets } = useWallet()
const disconnect = async () => {
const activeWallet = wallets.find((w) => w.isActive)
if (activeWallet) {
await activeWallet.disconnect()
}
}
return <button onClick={disconnect}>断开连接</button>
}
参考资料/进一步阅读
- REFERENCE.md - 详细的API参考
- EXAMPLES.md - 完整的代码示例
- use-wallet文档
- AlgoKit Utils TypeScript
- 类型化应用客户端