如何用Ether.js结合Infura Websocket监听指定地址的Pending交易?
解决方案:用Ethers.js监听指定地址的Pending交易
你当前方案的核心问题是:监听所有pending交易后,每笔都调用getTransaction查询详情,这不仅浪费性能,还会快速耗尽Infura的请求限额。正确的做法是利用Ethers.js的原生API,直接通过WebSocket获取完整的pending交易对象,或让节点端提前过滤目标交易,避免不必要的请求。
方案一:直接获取Pending交易对象(避免额外请求)
使用watchPendingTransactions方法,WebSocket会直接推送完整的交易对象,无需额外发起查询请求,仅在本地过滤目标地址即可:
const wsProvider = new InfuraWebSocketProvider('sepolia', API_KEY); export const initTransactionsListener = (address: string): WebSocketListener => { // 订阅pending交易,直接获取交易对象 const unsubscribe = wsProvider.watchPendingTransactions().on('data', (transaction) => { if (!transaction) return; const { from, to } = transaction; // 过滤目标地址的交易(from或to匹配) if (from === address || to === address) { console.log('匹配的Pending交易', transaction); } }); return { destroy: async () => { // 取消订阅并销毁Provider unsubscribe(); await wsProvider.destroy(); } }; };
方案二:节点端过滤(减少推送量)
如果希望进一步降低带宽消耗,可以通过过滤器让Infura节点直接在服务器端过滤交易,只推送涉及目标地址的pending交易:
const wsProvider = new InfuraWebSocketProvider('sepolia', API_KEY); export const initTransactionsListener = (address: string): WebSocketListener => { // 创建过滤器:仅监听from或to为目标地址的pending交易 const filter = { from: address, to: address }; const listener = (transaction) => { console.log('匹配的Pending交易', transaction); }; wsProvider.on(filter, listener); return { destroy: async () => { // 移除监听并销毁Provider wsProvider.off(filter, listener); await wsProvider.destroy(); } }; };
关键优化说明
- 消除额外请求:两种方案都无需调用
getTransaction,彻底解决请求超限问题 - 性能提升:方案一减少查询开销,方案二直接降低WebSocket推送的数据量
- 避免内存泄漏:销毁时必须取消订阅或移除监听,防止残留回调占用资源
内容的提问来源于stack exchange,提问作者David Dal Busco
相关产品推荐
相关产品推荐

