如何用@solana/web3.js订阅USDT等代币到账回调(Node.js)
监听Solana链上SPL代币(如USDT)到账的实现方案
你的现有代码仅能监听原生SOL的到账,因为SOL直接存储在钱包主账户中;而USDT这类SPL代币是存储在**关联代币账户(ATA)**中的,需要针对SPL代币的特性调整监听逻辑,以下是两种可行方案:
方案一:监听目标钱包的指定代币ATA账户
每个钱包对应某一SPL代币都有唯一的ATA,当代币转入时该账户余额会变化,可直接监听这个ATA的日志:
步骤1:安装依赖
确保安装SPL Token工具包:
npm install @solana/web3.js @solana/spl-token
步骤2:代码实现
const web3 = require("@solana/web3.js"); const { getAssociatedTokenAddress } = require("@solana/spl-token"); (async () => { // 配置参数 const walletPublicKey = new web3.PublicKey("你的钱包地址"); // USDT的Mint地址,替换为其他代币Mint地址即可监听对应代币 const tokenMint = new web3.PublicKey("Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"); const httpsNode = "https://api.mainnet-beta.solana.com"; const wssNode = "wss://api.mainnet-beta.solana.com"; // 获取目标钱包对应该代币的ATA地址 const ataAddress = await getAssociatedTokenAddress( tokenMint, walletPublicKey, false ); console.log("监听的ATA地址:", ataAddress.toString()); const solanaConnection = new web3.Connection(httpsNode, { wsEndpoint: wssNode, }); // 监听ATA账户日志,触发代币转入回调 solanaConnection.onLogs( ataAddress, (logs, context) => { if (logs.logs.some(log => log.includes("Transfer"))) { console.log(`收到代币!交易签名: ${context.signature}`); console.log("日志详情:", logs); // 此处添加你的业务逻辑 } }, "confirmed" ); })();
方案二:监听所有涉及目标钱包的SPL代币转移交易
如果需要监听任意代币的到账,可监听SPL Token程序的全局日志,过滤出接收方为目标钱包的转移事件:
const web3 = require("@solana/web3.js"); const { TokenProgram } = require("@solana/spl-token"); (async () => { const walletPublicKey = new web3.PublicKey("你的钱包地址"); const httpsNode = "https://api.mainnet-beta.solana.com"; const wssNode = "wss://api.mainnet-beta.solana.com"; const solanaConnection = new web3.Connection(httpsNode, { wsEndpoint: wssNode, }); // 监听SPL Token程序的所有日志 solanaConnection.onProgramLogs( TokenProgram.programId, async (logs, context) => { // 解析Transfer指令,判断接收方是否为目标钱包 const transferLog = logs.logs.find(log => log.startsWith("Program log: Transfer: ")); if (transferLog) { const recipient = new web3.PublicKey(transferLog.split(" ")[3]); if (recipient.equals(walletPublicKey)) { console.log(`收到任意代币!交易签名: ${context.signature}`); console.log("转移详情:", transferLog); // 可选:获取完整交易信息,解析代币数量、发送方等 const tx = await solanaConnection.getTransaction(context.signature); console.log("交易完整信息:", tx); } } }, "confirmed" ); })();
关键说明
- 替换
tokenMint为目标代币的Mint地址即可切换监听对象(如USDC的Mint地址为EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) - 方案一适合监听单一代币,性能更优;方案二适合监听所有代币,但需处理更多日志量
- 通过
context.signature可调用getTransaction获取完整交易数据,进一步解析代币数量、发送方等信息
内容的提问来源于stack exchange,提问作者Makasin
相关产品推荐
相关产品推荐

