diff --git a/package.json b/package.json index 1ca76dc..79db723 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pezkuwi-telegram-miniapp", - "version": "1.0.213", + "version": "1.0.214", "type": "module", "description": "Pezkuwichain Telegram Mini App - Forum, Announcements, Rewards", "author": "Pezkuwichain Team", diff --git a/src/components/wallet/HEZStakingModal.tsx b/src/components/wallet/HEZStakingModal.tsx index d9e02b8..b5a2e5f 100644 --- a/src/components/wallet/HEZStakingModal.tsx +++ b/src/components/wallet/HEZStakingModal.tsx @@ -1,6 +1,7 @@ /** * HEZ Staking Modal for Telegram Mini App - * Allows users to stake HEZ on Relay Chain for Trust Score + * Allows users to stake HEZ on Asset Hub for Trust Score + * (Staking moved from Relay Chain to Asset Hub) */ import { useState, useEffect, useCallback } from 'react'; @@ -34,7 +35,7 @@ interface HEZStakingModalProps { const UNITS = 1_000_000_000_000; // 10^12 export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { - const { api, keypair, address, balance } = useWallet(); + const { assetHubApi, keypair, address } = useWallet(); const { hapticImpact, hapticNotification, showAlert } = useTelegram(); const { t } = useTranslation(); @@ -47,21 +48,33 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { const [bondAmount, setBondAmount] = useState(''); const [unbondAmount, setUnbondAmount] = useState(''); const [selectedValidators, setSelectedValidators] = useState([]); + const [ahBalance, setAhBalance] = useState(null); - // Fetch staking info + // Fetch staking info from Asset Hub const fetchStakingInfo = useCallback(async () => { - if (!api || !address) return; + if (!assetHubApi || !address) return; setIsLoading(true); try { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const stakingPallet = api.query.staking as any; + const stakingPallet = assetHubApi.query.staking as any; if (!stakingPallet) { setError(t('staking.palletNotFound')); setIsLoading(false); return; } + // Fetch AH native HEZ balance + try { + const accountInfo = await assetHubApi.query.system.account(address); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const free = (accountInfo as any).data.free.toString(); + const balanceNum = Number(free) / UNITS; + setAhBalance(balanceNum.toFixed(4)); + } catch { + setAhBalance(null); + } + // Check if user has bonded const ledger = await stakingPallet.ledger(address); @@ -93,7 +106,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { setStakingInfo(null); } - // Fetch validators + // Fetch validators from AH staking pallet const validatorEntries = await stakingPallet.validators.entries(); const validatorList: ValidatorInfo[] = validatorEntries .slice(0, 20) // Limit to 20 validators @@ -120,13 +133,13 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { } finally { setIsLoading(false); } - }, [api, address]); + }, [assetHubApi, address]); useEffect(() => { - if (isOpen && api && address) { + if (isOpen && assetHubApi && address) { fetchStakingInfo(); } - }, [isOpen, api, address, fetchStakingInfo]); + }, [isOpen, assetHubApi, address, fetchStakingInfo]); const formatHEZ = (amount: bigint): string => { const hez = Number(amount) / UNITS; @@ -134,7 +147,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { }; const handleBond = async () => { - if (!api || !keypair || !bondAmount) return; + if (!assetHubApi || !keypair || !bondAmount) return; setIsProcessing(true); setError(null); @@ -143,7 +156,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { const amountBN = BigInt(Math.floor(parseFloat(bondAmount) * UNITS)); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const stakingPallet = api.tx.staking as any; + const stakingPallet = assetHubApi.tx.staking as any; let tx; if (stakingInfo) { @@ -169,7 +182,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { if (dispatchError) { let errorMsg = t('staking.bondFailed'); if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); + const decoded = assetHubApi.registry.findMetaError(dispatchError.asModule); errorMsg = `${decoded.section}.${decoded.name}`; } reject(new Error(errorMsg)); @@ -196,14 +209,14 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { }; const handleNominate = async () => { - if (!api || !keypair || selectedValidators.length === 0) return; + if (!assetHubApi || !keypair || selectedValidators.length === 0) return; setIsProcessing(true); setError(null); try { // eslint-disable-next-line @typescript-eslint/no-explicit-any - const tx = (api.tx.staking as any).nominate(selectedValidators); + const tx = (assetHubApi.tx.staking as any).nominate(selectedValidators); await new Promise((resolve, reject) => { tx.signAndSend( @@ -220,7 +233,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { if (dispatchError) { let errorMsg = t('staking.nominateFailed'); if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); + const decoded = assetHubApi.registry.findMetaError(dispatchError.asModule); errorMsg = `${decoded.section}.${decoded.name}`; } reject(new Error(errorMsg)); @@ -246,7 +259,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { }; const handleUnbond = async () => { - if (!api || !keypair || !unbondAmount) return; + if (!assetHubApi || !keypair || !unbondAmount) return; setIsProcessing(true); setError(null); @@ -255,7 +268,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { const amountBN = BigInt(Math.floor(parseFloat(unbondAmount) * UNITS)); // eslint-disable-next-line @typescript-eslint/no-explicit-any - const tx = (api.tx.staking as any).unbond(amountBN.toString()); + const tx = (assetHubApi.tx.staking as any).unbond(amountBN.toString()); await new Promise((resolve, reject) => { tx.signAndSend( @@ -272,7 +285,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { if (dispatchError) { let errorMsg = t('staking.unbondFailed'); if (dispatchError.isModule) { - const decoded = api.registry.findMetaError(dispatchError.asModule); + const decoded = assetHubApi.registry.findMetaError(dispatchError.asModule); errorMsg = `${decoded.section}.${decoded.name}`; } reject(new Error(errorMsg)); @@ -448,7 +461,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) {
{t('staking.yourBalance')} - {balance || '0'} HEZ + {ahBalance || '0'} HEZ
{stakingInfo && (
@@ -473,7 +486,7 @@ export function HEZStakingModal({ isOpen, onClose }: HEZStakingModalProps) { className="w-full bg-secondary border border-border rounded-xl p-4 pr-20 text-lg" />
) : ( <> + {/* Citizen Count Card */} +
+
+
+

+ {t('rewards.citizenCountTitle')} +

+

+ {citizenCount !== null ? citizenCount.toLocaleString() : '...'} +

+
+
+ +
+
+

+ {t('rewards.citizenCountDesc')} +

+ +
+ {/* Score Card */}
diff --git a/src/version.json b/src/version.json index 88a2f6f..cc6e896 100644 --- a/src/version.json +++ b/src/version.json @@ -1,5 +1,5 @@ { - "version": "1.0.213", - "buildTime": "2026-02-19T23:27:53.391Z", - "buildNumber": 1771543673392 + "version": "1.0.214", + "buildTime": "2026-02-20T23:55:07.518Z", + "buildNumber": 1771631707519 }