mirror of
https://github.com/pezkuwichain/pezkuwi-telegram-miniapp.git
synced 2026-06-20 23:11:06 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ac4147304d | |||
| 6f1d293926 | |||
| 52b6344614 | |||
| de0f96a6a5 | |||
| e02ef74c58 | |||
| fc6be59519 | |||
| f5ad1cee29 | |||
| 39ff9e959f |
Generated
+1125
-452
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "pezkuwi-telegram-miniapp",
|
"name": "pezkuwi-telegram-miniapp",
|
||||||
"version": "1.0.230",
|
"version": "1.0.233",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards",
|
"description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards",
|
||||||
"author": "Pezkuwichain Team",
|
"author": "Pezkuwichain Team",
|
||||||
|
|||||||
@@ -21,11 +21,14 @@ import {
|
|||||||
TrendingDown,
|
TrendingDown,
|
||||||
Fuel,
|
Fuel,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
|
import type { ApiPromise } from '@pezkuwi/api';
|
||||||
import { useWallet } from '@/contexts/WalletContext';
|
import { useWallet } from '@/contexts/WalletContext';
|
||||||
import { useTelegram } from '@/hooks/useTelegram';
|
import { useTelegram } from '@/hooks/useTelegram';
|
||||||
import { useTranslation } from '@/i18n';
|
import { useTranslation } from '@/i18n';
|
||||||
import {
|
import {
|
||||||
subscribeToConnection,
|
subscribeToConnection,
|
||||||
|
subscribeToAssetHubConnection,
|
||||||
|
subscribeToPeopleConnection,
|
||||||
getLastError,
|
getLastError,
|
||||||
getAssetHubAPI,
|
getAssetHubAPI,
|
||||||
getPeopleAPI,
|
getPeopleAPI,
|
||||||
@@ -76,6 +79,7 @@ interface TokenConfig {
|
|||||||
logo: string;
|
logo: string;
|
||||||
isDefault: boolean;
|
isDefault: boolean;
|
||||||
priority: number; // Lower = higher in list
|
priority: number; // Lower = higher in list
|
||||||
|
standard?: 'PEZ-20'; // fungible Asset Hub asset → PEZ-20 token standard
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_TOKENS: TokenConfig[] = [
|
const DEFAULT_TOKENS: TokenConfig[] = [
|
||||||
@@ -98,6 +102,7 @@ const DEFAULT_TOKENS: TokenConfig[] = [
|
|||||||
logo: '/tokens/PEZ.png',
|
logo: '/tokens/PEZ.png',
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
|
standard: 'PEZ-20',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
assetId: ASSET_IDS.WUSDT,
|
assetId: ASSET_IDS.WUSDT,
|
||||||
@@ -108,6 +113,7 @@ const DEFAULT_TOKENS: TokenConfig[] = [
|
|||||||
logo: '/tokens/USDT.png',
|
logo: '/tokens/USDT.png',
|
||||||
isDefault: true,
|
isDefault: true,
|
||||||
priority: 2,
|
priority: 2,
|
||||||
|
standard: 'PEZ-20',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
assetId: ASSET_IDS.DOT,
|
assetId: ASSET_IDS.DOT,
|
||||||
@@ -209,51 +215,68 @@ export function TokensCard({ onSendToken }: Props) {
|
|||||||
return () => unsubscribe();
|
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(() => {
|
useEffect(() => {
|
||||||
if (!address) return;
|
if (!address) return;
|
||||||
|
let cancelled = false;
|
||||||
|
let ahBalUnsub: (() => void) | null = null;
|
||||||
|
let peopleBalUnsub: (() => void) | null = null;
|
||||||
|
|
||||||
const fetchMultiChainBalances = async () => {
|
type AccountInfo = { data: { free: { toString(): string } } };
|
||||||
// Asset Hub HEZ balance
|
const liveBalance = async (
|
||||||
const assetHubApi = getAssetHubAPI();
|
api: ApiPromise | null,
|
||||||
if (assetHubApi) {
|
setBalance: (v: string) => void,
|
||||||
try {
|
label: string
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
) => {
|
||||||
const accountInfo = (await (assetHubApi.query.system as any).account(address)) as {
|
if (!api) return null;
|
||||||
data: { free: { toString(): string } };
|
try {
|
||||||
};
|
// callback form = live subscription, fires on every change
|
||||||
const free = accountInfo.data.free.toString();
|
const unsub = await api.query.system.account(address, (info: AccountInfo) => {
|
||||||
const balanceNum = Number(free) / 1e12;
|
const balanceNum = Number(info.data.free.toString()) / 1e12;
|
||||||
setAssetHubHezBalance(balanceNum.toFixed(4));
|
setBalance(balanceNum.toFixed(4));
|
||||||
} catch (err) {
|
});
|
||||||
console.error('Error fetching Asset Hub HEZ balance:', err);
|
return unsub as unknown as () => void;
|
||||||
setAssetHubHezBalance('0.0000');
|
} catch (err) {
|
||||||
}
|
console.error(`Error subscribing to ${label} HEZ balance:`, err);
|
||||||
}
|
return null;
|
||||||
|
|
||||||
// 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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchMultiChainBalances();
|
const unsubAhConn = subscribeToAssetHubConnection(async (connected) => {
|
||||||
// Refresh every 30 seconds
|
if (ahBalUnsub) {
|
||||||
const interval = setInterval(fetchMultiChainBalances, 30000);
|
ahBalUnsub();
|
||||||
return () => clearInterval(interval);
|
ahBalUnsub = null;
|
||||||
}, [address, rpcConnected]);
|
}
|
||||||
|
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)
|
// Initialize with default tokens immediately (no API required)
|
||||||
const [tokens, setTokens] = useState<TokenBalance[]>(() =>
|
const [tokens, setTokens] = useState<TokenBalance[]>(() =>
|
||||||
@@ -838,6 +861,18 @@ export function TokensCard({ onSendToken }: Props) {
|
|||||||
<div>
|
<div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-semibold">{token.displaySymbol}</span>
|
<span className="font-semibold">{token.displaySymbol}</span>
|
||||||
|
{token.standard === 'PEZ-20' && (
|
||||||
|
<a
|
||||||
|
href="https://docs.pezkuwichain.io/token-standards"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
title="PEZ-20 token standard on Pezkuwi Asset Hub"
|
||||||
|
className="text-[10px] bg-blue-500/20 text-blue-300 px-1.5 py-0.5 rounded no-underline"
|
||||||
|
>
|
||||||
|
PEZ-20
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
{token.assetId <= -100 && (
|
{token.assetId <= -100 && (
|
||||||
<span className="text-[10px] bg-purple-500/20 text-purple-400 px-1.5 py-0.5 rounded">
|
<span className="text-[10px] bg-purple-500/20 text-purple-400 px-1.5 py-0.5 rounded">
|
||||||
LP
|
LP
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.0.230",
|
"version": "1.0.233",
|
||||||
"buildTime": "2026-02-27T23:33:39.279Z",
|
"buildTime": "2026-06-13T04:42:17.513Z",
|
||||||
"buildNumber": 1772235219280
|
"buildNumber": 1781325737513
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user