如何用React和@tonconnect/ui-react在TON网络发送USDT
在TON Connect React应用中发送USDT替代TON的解决方案
要实现发送USDT,你不能直接像转TON那样填收款地址,而是需要调用TON链上的USDT合约来完成转账操作,核心是修改交易的目标地址、金额转换逻辑和合约调用payload。
关键修改点说明
- 目标地址替换为USDT合约地址:TON主网的USDT合约地址是
EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs,测试网地址为EQB-MPm21tCpt65eQaO954648Q2SuLIIae897c77VkE0z2wY,根据你的环境选择。 - 金额单位转换:USDT采用6位小数(1 USDT = 1,000,000 最小单位),需要替换原有的TON转nanoTON函数。
- 构造合约调用Payload:生成触发USDT合约
transfer方法的编码payload,包含收款地址、转账金额等核心参数。
修改后的完整代码
import React, { useCallback, useState } from 'react'; import ReactJson from 'react-json-view'; import './style.scss'; import { SendTransactionRequest, useTonConnectUI, useTonWallet } from "@tonconnect/ui-react"; import { Address, beginCell, toNano } from "@ton/core"; // 需安装@ton/core依赖 // USDT转最小单位(6位小数) const usdtToUnits = (amountInUSDT: number): string => { const units = amountInUSDT * 1_000_000; return units.toString(); }; // 生成USDT转账的payload const buildUsdtTransferPayload = (toAddress: string, amount: string) => { return beginCell() .storeUint(0x178d4519, 32) // transfer方法的opcode .storeUint(0, 64) // query id,可自定义 .storeAddress(Address.parse(toAddress)) // 实际收款钱包地址 .storeCoins(BigInt(amount)) // USDT最小单位金额 .storeAddress(null) // 退回地址,填null用默认逻辑 .storeUint(0, 1) // 自定义payload标记,0表示无附加内容 .endCell() .toBoc() .toString('base64'); }; type TxFormProps = { tonno: string; }; // 初始化USDT转账交易 const defaultTx: SendTransactionRequest = { validUntil: Math.floor(Date.now() / 1000) + 600, messages: [ { address: 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs', // USDT主网合约地址 amount: toNano('0.05').toString(), // 支付给合约的gas费用(TON),至少保留0.05TON payload: buildUsdtTransferPayload('你的收款钱包地址', usdtToUnits(0.000005)), // 替换为实际收款地址和USDT金额 } ] }; export function TxForm({ tonno }: TxFormProps) { const [tx, setTx] = useState(defaultTx); const wallet = useTonWallet(); const [tonConnectUi] = useTonConnectUI(); const onChange = useCallback((value: object) => setTx((value as { updated_src: typeof defaultTx }).updated_src), []); const sendTx = () => { tonConnectUi.sendTransaction(tx).then((res) => { console.log(res, "交易成功"); }).catch((error) => { console.error("交易失败", error); }); }; return ( <div className="send-tx-form"> <h6>收款钱包地址: --8MVY1W </h6> {wallet ? ( <button onClick={() => sendTx()}> 发送交易 - {tonno} USDT </button> ) : ( <button onClick={() => tonConnectUi.openModal()}>连接钱包以发送交易</button> )} </div> ); }
注意事项
- 先安装
@ton/core依赖:执行npm install @ton/core或yarn add @ton/core。 amount字段是支付给合约的gas费用(TON),不是USDT金额,USDT的转账金额在payload中指定,gas至少保留0.05TON避免交易失败。- 如果使用测试网,替换USDT合约地址为测试网地址,并确保钱包连接的是测试网环境。
内容的提问来源于stack exchange,提问作者Muluken M
相关产品推荐
相关产品推荐

