跟踪解除质押完成情况
当解除质押期完成时,协议会通过系统交易,通过 StableSystem 预编译合约(0x0000000000000000000000000000000000009999)发出一个 UnbondingCompleted 事件。这允许 dApp 实时通知用户并更新余额,而无需运行自定义索引器或轮询 REST 端点。
前提条件
概述
- 设置合约实例:为 StableSystem 预编译合约创建合约实例。
- 在你的应用程序中处理事件:根据你的应用程序逻辑订阅实时事件或查询历史数据。
- 处理连接问题:为持久的 WebSocket 订阅实现重新连接逻辑。
步骤 1:设置合约实例
使用 UnbondingCompleted 事件 ABI 为 StableSystem 预编译合约创建一个合约实例。
// config.ts
import { ethers } from "ethers";
export const STABLE_SYSTEM_ADDRESS =
"0x0000000000000000000000000000000000009999";
export const STABLE_SYSTEM_ABI = [
"event UnbondingCompleted(address indexed delegator, address indexed validator, uint256 amount)",
];
export const provider = new ethers.JsonRpcProvider("https://rpc.testnet.stable.xyz");
export const stableSystem = new ethers.Contract(
STABLE_SYSTEM_ADDRESS,
STABLE_SYSTEM_ABI,
provider
);步骤 2:在你的应用程序中处理事件
根据你的应用程序逻辑,订阅实时事件、查询历史数据或两者兼而有之。
实时订阅
订阅 UnbondingCompleted 事件以获取任何解除质押完成时的实时通知。这对于触发余额更新、发送通知或刷新仪表板统计数据非常有用。
// subscribeBasic.ts
import { stableSystem } from "./config";
stableSystem.on("UnbondingCompleted", (delegator, validator, amount, event) => {
console.log("Unbonding completed:");
console.log(" Delegator:", delegator);
console.log(" Validator:", validator);
console.log(" Amount:", ethers.formatEther(amount), "tokens");
console.log(" Block:", event.log.blockNumber);
console.log(" Tx Hash:", event.log.transactionHash);
});按用户筛选
要仅接收特定委托人地址的事件,请使用索引事件参数创建过滤器。
// subscribeByUser.ts
import { ethers } from "ethers";
import { stableSystem } from "./config";
const userAddress = "0xabcd...";
const filter = stableSystem.filters.UnbondingCompleted(userAddress);
stableSystem.on(filter, (delegator, validator, amount, event) => {
refreshUserBalance(userAddress);
showNotification(
`您的 ${ethers.formatEther(amount)} 代币的解除质押已完成!`
);
});按验证者筛选
// subscribeByValidator.ts
import { stableSystem } from "./config";
const validatorAddress = "0x1234...";
const validatorFilter = stableSystem.filters.UnbondingCompleted(
null,
validatorAddress
);
stableSystem.on(validatorFilter, (delegator, validator, amount) => {
updateValidatorStats(validator, amount);
});历史查询
如果你的 dApp 需要显示过去解除质押完成的历史记录,请使用带有区块范围的事件过滤器查询历史事件。
// queryHistory.ts
import { ethers } from "ethers";
import { provider, stableSystem } from "./config";
async function getUnbondingHistory(
userAddress: string,
fromBlock: number,
toBlock: number
) {
const filter = stableSystem.filters.UnbondingCompleted(userAddress);
const events = await stableSystem.queryFilter(filter, fromBlock, toBlock);
return events.map((event) => ({
delegator: event.args.delegator,
validator: event.args.validator,
amount: ethers.formatEther(event.args.amount),
blockNumber: event.blockNumber,
txHash: event.transactionHash,
}));
}
const currentBlock = await provider.getBlockNumber();
const history = await getUnbondingHistory(
"0xabcd...",
currentBlock - 1000,
currentBlock
);步骤 3:处理连接问题
事件订阅依赖于持久的 WebSocket 连接。为生产 dApp 实现重新连接逻辑。
// subscribeWithReconnection.ts
import { ethers } = "ethers";
import { STABLE_SYSTEM_ADDRESS, STABLE_SYSTEM_ABI } from "./config";
let reconnectAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
function handleUnbonding(delegator: string, validator: string, amount: bigint) {
console.log("解除质押完成:", { delegator, validator, amount });
}
function setupEventListener() {
const wsProvider = new ethers.WebSocketProvider("wss://rpc.testnet.stable.xyz");
wsProvider.on("error", (error) => {
console.error("提供者错误:", error);
if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
reconnectAttempts++;
setTimeout(() => setupEventListener(), 5000);
}
});
const stableSystem = new ethers.Contract(
STABLE_SYSTEM_ADDRESS,
STABLE_SYSTEM_ABI,
wsProvider
);
stableSystem.on("UnbondingCompleted", handleUnbonding);
}
setupEventListener();
