mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-13 21:31:01 +00:00
fix: query PEZ balance from Asset Hub and prevent localhost WebSocket errors
- Add Asset Hub API connection for PEZ token queries (Asset ID 1 is on Asset Hub) - Update AccountBalance to fetch PEZ balance from Asset Hub instead of main chain - WebSocket: Only try localhost endpoints when running locally, use production endpoint directly when on domain
This commit is contained in:
@@ -18,7 +18,7 @@ interface TokenBalance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const AccountBalance: React.FC = () => {
|
export const AccountBalance: React.FC = () => {
|
||||||
const { api, isApiReady, selectedAccount } = usePezkuwi();
|
const { api, assetHubApi, isApiReady, isAssetHubReady, selectedAccount } = usePezkuwi();
|
||||||
const [balance, setBalance] = useState<{
|
const [balance, setBalance] = useState<{
|
||||||
free: string;
|
free: string;
|
||||||
reserved: string;
|
reserved: string;
|
||||||
@@ -318,21 +318,26 @@ export const AccountBalance: React.FC = () => {
|
|||||||
total: totalTokens,
|
total: totalTokens,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch PEZ balance (Asset ID: 1)
|
// Fetch PEZ balance (Asset ID: 1) from Asset Hub
|
||||||
try {
|
try {
|
||||||
const pezAssetBalance = await api.query.assets.account(1, selectedAccount.address);
|
if (assetHubApi && isAssetHubReady) {
|
||||||
|
const pezAssetBalance = await assetHubApi.query.assets.account(1, selectedAccount.address);
|
||||||
|
|
||||||
if (pezAssetBalance.isSome) {
|
if (pezAssetBalance.isSome) {
|
||||||
const assetData = pezAssetBalance.unwrap();
|
const assetData = pezAssetBalance.unwrap();
|
||||||
const pezAmount = assetData.balance.toString();
|
const pezAmount = assetData.balance.toString();
|
||||||
const pezTokens = (parseInt(pezAmount) / divisor).toFixed(4);
|
const pezTokens = (parseInt(pezAmount) / divisor).toFixed(4);
|
||||||
setPezBalance(pezTokens);
|
setPezBalance(pezTokens);
|
||||||
|
} else {
|
||||||
|
setPezBalance('0.0000');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setPezBalance('0');
|
if (import.meta.env.DEV) console.log('Asset Hub not ready, PEZ balance pending...');
|
||||||
|
setPezBalance('0.0000');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (import.meta.env.DEV) console.error('Failed to fetch PEZ balance:', error);
|
if (import.meta.env.DEV) console.error('Failed to fetch PEZ balance from Asset Hub:', error);
|
||||||
setPezBalance('0');
|
setPezBalance('0.0000');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch USDT balance (wUSDT - Asset ID: 1000)
|
// Fetch USDT balance (wUSDT - Asset ID: 1000)
|
||||||
@@ -460,26 +465,28 @@ export const AccountBalance: React.FC = () => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Subscribe to PEZ balance (Asset ID: 1)
|
// Subscribe to PEZ balance (Asset ID: 1) from Asset Hub
|
||||||
try {
|
if (assetHubApi && isAssetHubReady) {
|
||||||
unsubscribePez = await api.query.assets.account(
|
try {
|
||||||
1,
|
unsubscribePez = await assetHubApi.query.assets.account(
|
||||||
selectedAccount.address,
|
1,
|
||||||
(assetBalance) => {
|
selectedAccount.address,
|
||||||
if (assetBalance.isSome) {
|
(assetBalance) => {
|
||||||
const assetData = assetBalance.unwrap();
|
if (assetBalance.isSome) {
|
||||||
const pezAmount = assetData.balance.toString();
|
const assetData = assetBalance.unwrap();
|
||||||
const decimals = 12;
|
const pezAmount = assetData.balance.toString();
|
||||||
const divisor = Math.pow(10, decimals);
|
const decimals = 12;
|
||||||
const pezTokens = (parseInt(pezAmount) / divisor).toFixed(4);
|
const divisor = Math.pow(10, decimals);
|
||||||
setPezBalance(pezTokens);
|
const pezTokens = (parseInt(pezAmount) / divisor).toFixed(4);
|
||||||
} else {
|
setPezBalance(pezTokens);
|
||||||
setPezBalance('0');
|
} else {
|
||||||
|
setPezBalance('0.0000');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
);
|
} catch (error) {
|
||||||
} catch (error) {
|
if (import.meta.env.DEV) console.error('Failed to subscribe to PEZ balance from Asset Hub:', error);
|
||||||
if (import.meta.env.DEV) console.error('Failed to subscribe to PEZ balance:', error);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe to USDT balance (wUSDT - Asset ID: 2)
|
// Subscribe to USDT balance (wUSDT - Asset ID: 2)
|
||||||
@@ -513,7 +520,7 @@ export const AccountBalance: React.FC = () => {
|
|||||||
if (unsubscribeUsdt) unsubscribeUsdt();
|
if (unsubscribeUsdt) unsubscribeUsdt();
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [api, isApiReady, selectedAccount]);
|
}, [api, assetHubApi, isApiReady, isAssetHubReady, selectedAccount]);
|
||||||
|
|
||||||
if (!selectedAccount) {
|
if (!selectedAccount) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -5,9 +5,14 @@ import type { InjectedAccountWithMeta } from '@pezkuwi/extension-inject/types';
|
|||||||
import { DEFAULT_ENDPOINT } from '../../../shared/blockchain/pezkuwi';
|
import { DEFAULT_ENDPOINT } from '../../../shared/blockchain/pezkuwi';
|
||||||
import { isMobileApp, getNativeWalletAddress, getNativeAccountName } from '@/lib/mobile-bridge';
|
import { isMobileApp, getNativeWalletAddress, getNativeAccountName } from '@/lib/mobile-bridge';
|
||||||
|
|
||||||
|
// Asset Hub endpoint for PEZ token queries
|
||||||
|
const ASSET_HUB_ENDPOINT = 'wss://asset-hub-rpc.pezkuwichain.io';
|
||||||
|
|
||||||
interface PezkuwiContextType {
|
interface PezkuwiContextType {
|
||||||
api: ApiPromise | null;
|
api: ApiPromise | null;
|
||||||
|
assetHubApi: ApiPromise | null;
|
||||||
isApiReady: boolean;
|
isApiReady: boolean;
|
||||||
|
isAssetHubReady: boolean;
|
||||||
isConnected: boolean;
|
isConnected: boolean;
|
||||||
accounts: InjectedAccountWithMeta[];
|
accounts: InjectedAccountWithMeta[];
|
||||||
selectedAccount: InjectedAccountWithMeta | null;
|
selectedAccount: InjectedAccountWithMeta | null;
|
||||||
@@ -30,7 +35,9 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
|||||||
endpoint = DEFAULT_ENDPOINT // Beta testnet RPC from shared config
|
endpoint = DEFAULT_ENDPOINT // Beta testnet RPC from shared config
|
||||||
}) => {
|
}) => {
|
||||||
const [api, setApi] = useState<ApiPromise | null>(null);
|
const [api, setApi] = useState<ApiPromise | null>(null);
|
||||||
|
const [assetHubApi, setAssetHubApi] = useState<ApiPromise | null>(null);
|
||||||
const [isApiReady, setIsApiReady] = useState(false);
|
const [isApiReady, setIsApiReady] = useState(false);
|
||||||
|
const [isAssetHubReady, setIsAssetHubReady] = useState(false);
|
||||||
const [accounts, setAccounts] = useState<InjectedAccountWithMeta[]>([]);
|
const [accounts, setAccounts] = useState<InjectedAccountWithMeta[]>([]);
|
||||||
const [selectedAccount, setSelectedAccount] = useState<InjectedAccountWithMeta | null>(null);
|
const [selectedAccount, setSelectedAccount] = useState<InjectedAccountWithMeta | null>(null);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
@@ -127,12 +134,50 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
|||||||
setIsApiReady(false);
|
setIsApiReady(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Initialize Asset Hub API for PEZ token
|
||||||
|
const initAssetHubApi = async () => {
|
||||||
|
try {
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
console.log('🔗 Connecting to Asset Hub:', ASSET_HUB_ENDPOINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = new WsProvider(ASSET_HUB_ENDPOINT);
|
||||||
|
const assetHubApiInstance = await ApiPromise.create({
|
||||||
|
provider,
|
||||||
|
signedExtensions: {
|
||||||
|
AuthorizeCall: {
|
||||||
|
extrinsic: {},
|
||||||
|
payload: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await assetHubApiInstance.isReady;
|
||||||
|
|
||||||
|
setAssetHubApi(assetHubApiInstance);
|
||||||
|
setIsAssetHubReady(true);
|
||||||
|
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
console.log('✅ Connected to Asset Hub for PEZ token');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (import.meta.env.DEV) {
|
||||||
|
console.error('❌ Failed to connect to Asset Hub:', err);
|
||||||
|
}
|
||||||
|
// Don't set error - PEZ features just won't work
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
initApi();
|
initApi();
|
||||||
|
initAssetHubApi();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (api) {
|
if (api) {
|
||||||
api.disconnect();
|
api.disconnect();
|
||||||
}
|
}
|
||||||
|
if (assetHubApi) {
|
||||||
|
assetHubApi.disconnect();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [endpoint]);
|
}, [endpoint]);
|
||||||
@@ -311,7 +356,9 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
|||||||
|
|
||||||
const value: PezkuwiContextType = {
|
const value: PezkuwiContextType = {
|
||||||
api,
|
api,
|
||||||
|
assetHubApi,
|
||||||
isApiReady,
|
isApiReady,
|
||||||
|
isAssetHubReady,
|
||||||
isConnected: isApiReady, // Alias for backward compatibility
|
isConnected: isApiReady, // Alias for backward compatibility
|
||||||
accounts,
|
accounts,
|
||||||
selectedAccount,
|
selectedAccount,
|
||||||
|
|||||||
@@ -17,12 +17,20 @@ interface WebSocketContextType {
|
|||||||
|
|
||||||
const WebSocketContext = createContext<WebSocketContextType | null>(null);
|
const WebSocketContext = createContext<WebSocketContextType | null>(null);
|
||||||
|
|
||||||
const ENDPOINTS = [
|
// Only use localhost endpoints if running locally
|
||||||
'ws://localhost:8082', // Local Vite dev server
|
const isLocalhost = typeof window !== 'undefined' &&
|
||||||
'ws://127.0.0.1:9944', // Local development node (primary)
|
(window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');
|
||||||
'ws://localhost:9944', // Local development node (alternative)
|
|
||||||
'wss://ws.pezkuwichain.io', // Production WebSocket (fallback)
|
const ENDPOINTS = isLocalhost
|
||||||
];
|
? [
|
||||||
|
'ws://localhost:8082', // Local Vite dev server
|
||||||
|
'ws://127.0.0.1:9944', // Local development node (primary)
|
||||||
|
'ws://localhost:9944', // Local development node (alternative)
|
||||||
|
'wss://ws.pezkuwichain.io', // Production WebSocket (fallback)
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
'wss://ws.pezkuwichain.io', // Production WebSocket only
|
||||||
|
];
|
||||||
|
|
||||||
export const useWebSocket = () => {
|
export const useWebSocket = () => {
|
||||||
const context = useContext(WebSocketContext);
|
const context = useContext(WebSocketContext);
|
||||||
|
|||||||
Reference in New Issue
Block a user