mirror of
https://github.com/pezkuwichain/pezkuwi-telegram-miniapp.git
synced 2026-06-19 19:11:04 +00:00
fix(wallet): live multi-chain HEZ balances (real-time, connection-aware)
The Asset Hub / People Chain HEZ balances were fetched on [address, rpcConnected] + a 30s poll, so they didn't react to the Asset Hub/People connection becoming ready — People HEZ could sit at '--' until a later trigger (e.g. a transaction). Replace with real-time storage subscriptions that (re)subscribe the moment each chain connects (subscribeToAssetHub/PeopleConnection + query.system.account(addr, cb)). Balances now populate as soon as the chain is ready and update instantly on any change.
This commit is contained in:
@@ -26,6 +26,8 @@ import { useTelegram } from '@/hooks/useTelegram';
|
||||
import { useTranslation } from '@/i18n';
|
||||
import {
|
||||
subscribeToConnection,
|
||||
subscribeToAssetHubConnection,
|
||||
subscribeToPeopleConnection,
|
||||
getLastError,
|
||||
getAssetHubAPI,
|
||||
getPeopleAPI,
|
||||
@@ -212,51 +214,55 @@ export function TokensCard({ onSendToken }: Props) {
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
// Fetch multi-chain HEZ balances (Asset Hub & People Chain)
|
||||
// Live multi-chain HEZ balances (Asset Hub & People Chain).
|
||||
// Uses real-time storage subscriptions and (re)subscribes the moment each
|
||||
// chain connects — so balances populate as soon as the chain is ready and
|
||||
// update instantly on any change (no 30s polling lag, no stuck "--").
|
||||
useEffect(() => {
|
||||
if (!address) return;
|
||||
let cancelled = false;
|
||||
let ahBalUnsub: (() => void) | null = null;
|
||||
let peopleBalUnsub: (() => void) | null = null;
|
||||
|
||||
const fetchMultiChainBalances = async () => {
|
||||
// Asset Hub HEZ balance
|
||||
const assetHubApi = getAssetHubAPI();
|
||||
if (assetHubApi) {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const accountInfo = (await (assetHubApi.query.system as any).account(address)) as {
|
||||
data: { free: { toString(): string } };
|
||||
};
|
||||
const free = accountInfo.data.free.toString();
|
||||
const balanceNum = Number(free) / 1e12;
|
||||
setAssetHubHezBalance(balanceNum.toFixed(4));
|
||||
} catch (err) {
|
||||
console.error('Error fetching Asset Hub HEZ balance:', err);
|
||||
setAssetHubHezBalance('0.0000');
|
||||
}
|
||||
}
|
||||
|
||||
// People Chain HEZ balance
|
||||
const peopleApi = getPeopleAPI();
|
||||
if (peopleApi) {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const accountInfo = (await (peopleApi.query.system as any).account(address)) as {
|
||||
data: { free: { toString(): string } };
|
||||
};
|
||||
const free = accountInfo.data.free.toString();
|
||||
const balanceNum = Number(free) / 1e12;
|
||||
setPeopleHezBalance(balanceNum.toFixed(4));
|
||||
} catch (err) {
|
||||
console.error('Error fetching People Chain HEZ balance:', err);
|
||||
setPeopleHezBalance('0.0000');
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const liveBalance = async (api: any, setBalance: (v: string) => void, label: string) => {
|
||||
if (!api) return null;
|
||||
try {
|
||||
// callback form = live subscription, fires on every change
|
||||
return (await api.query.system.account(address, (info: any) => {
|
||||
const balanceNum = Number(info.data.free.toString()) / 1e12;
|
||||
setBalance(balanceNum.toFixed(4));
|
||||
})) as () => void;
|
||||
} catch (err) {
|
||||
console.error(`Error subscribing to ${label} HEZ balance:`, err);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
fetchMultiChainBalances();
|
||||
// Refresh every 30 seconds
|
||||
const interval = setInterval(fetchMultiChainBalances, 30000);
|
||||
return () => clearInterval(interval);
|
||||
}, [address, rpcConnected]);
|
||||
const unsubAhConn = subscribeToAssetHubConnection(async (connected) => {
|
||||
if (ahBalUnsub) { ahBalUnsub(); ahBalUnsub = null; }
|
||||
if (connected) {
|
||||
const u = await liveBalance(getAssetHubAPI(), setAssetHubHezBalance, 'Asset Hub');
|
||||
if (cancelled) u?.(); else ahBalUnsub = u;
|
||||
}
|
||||
});
|
||||
|
||||
const unsubPeopleConn = subscribeToPeopleConnection(async (connected) => {
|
||||
if (peopleBalUnsub) { peopleBalUnsub(); peopleBalUnsub = null; }
|
||||
if (connected) {
|
||||
const u = await liveBalance(getPeopleAPI(), setPeopleHezBalance, 'People Chain');
|
||||
if (cancelled) u?.(); else peopleBalUnsub = u;
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
if (ahBalUnsub) ahBalUnsub();
|
||||
if (peopleBalUnsub) peopleBalUnsub();
|
||||
unsubAhConn();
|
||||
unsubPeopleConn();
|
||||
};
|
||||
}, [address]);
|
||||
|
||||
// Initialize with default tokens immediately (no API required)
|
||||
const [tokens, setTokens] = useState<TokenBalance[]>(() =>
|
||||
|
||||
Reference in New Issue
Block a user