import { ref, reactive, computed } from 'vue'; import { getAccount, watchAccount, watchChainId, type Config } from '@wagmi/core'; import { type WatchAccountReturnType, type GetAccountReturnType, type GetBalanceReturnType } from '@wagmi/core'; import { config, KRAIKEN_LOCAL_CHAIN } from '@/wagmi'; import { getAllowance, HarbContract, getNonce } from '@/contracts/harb'; import logger from '@/utils/logger'; import { setHarbContract } from '@/contracts/harb'; import { setStakeContract } from '@/contracts/stake'; import { chainsData, DEFAULT_CHAIN_ID } from '@/config'; import { createPublicClient, custom, formatUnits, type EIP1193Provider, type PublicClient, type Transport, type WalletClient } from 'viem'; import { getWalletPublicClient, setWalletPublicClient } from '@/services/walletRpc'; const balance = ref({ value: 0n, decimals: 0, symbol: '', formatted: '', }); const account = ref(getAccount(config as Config)); if (!account.value.chainId) { account.value.chainId = DEFAULT_CHAIN_ID; } const selectedChainId = computed(() => account.value.chainId ?? DEFAULT_CHAIN_ID); export const chainData = computed(() => { return chainsData.find(obj => obj.id === selectedChainId.value); }); const TOKEN_DECIMALS = 18; const TOKEN_SYMBOL = 'KRK'; async function syncWalletPublicClient(data: GetAccountReturnType | undefined = account.value): Promise { if (!data?.address || !data.connector) { setWalletPublicClient(null); return null; } try { const connector = data.connector; if (!connector || typeof connector.getProvider !== 'function') { setWalletPublicClient(null); return null; } const connectorAny = connector as { getProvider?: () => Promise; getWalletClient?: (args: { chainId: number }) => Promise; }; const provider = connectorAny.getProvider ? await connectorAny.getProvider() : null; const walletClient = connectorAny.getWalletClient ? await connectorAny.getWalletClient({ chainId: data.chainId ?? selectedChainId.value }) : null; if (!provider || typeof (provider as { request?: unknown }).request !== 'function') { setWalletPublicClient(null); return null; } const chain = (walletClient as WalletClient | null)?.chain ?? KRAIKEN_LOCAL_CHAIN; const transport = custom(provider as EIP1193Provider) as Transport; const publicClient = createPublicClient({ chain, transport, }) as PublicClient; setWalletPublicClient(publicClient); return publicClient; } catch (_error) { logger.contract('Failed to create wallet public client'); setWalletPublicClient(null); return null; } } let unwatch: WatchAccountReturnType | null = null; let unwatchChain: WatchAccountReturnType | null = null; export function useWallet() { async function loadBalance() { logger.contract('loadBalance'); const userAddress = account.value.address; if (!userAddress) { return 0n; } let publicClient = getWalletPublicClient(); if (!publicClient) { publicClient = await syncWalletPublicClient(); } if (!publicClient) { return 0n; } const value = (await publicClient.readContract({ abi: HarbContract.abi, address: HarbContract.contractAddress, functionName: 'balanceOf', args: [userAddress], })) as bigint; balance.value = { value, decimals: TOKEN_DECIMALS, symbol: TOKEN_SYMBOL, formatted: formatUnits(value, TOKEN_DECIMALS), } as GetBalanceReturnType; return value; } if (!unwatch) { unwatch = watchAccount(config as Config, { async onChange(data) { if (!data.address) { logger.info(`disconnected`); setWalletPublicClient(null); balance.value = { value: 0n, decimals: 0, symbol: '', formatted: '', }; } else if (account.value.address !== data.address || account.value.chainId !== data.chainId) { logger.info(`Account changed!:`, data.address); account.value = data; await syncWalletPublicClient(data); await loadBalance(); await getAllowance(); // await loadPositions(); await getNonce(); setHarbContract(); setStakeContract(); } }, }); } //funzt nicht mehr-> library Änderung? if (account.value.address) { void syncWalletPublicClient(account.value); } if (!unwatchChain) { unwatchChain = watchChainId(config as Config, { async onChange(_chainId) { await syncWalletPublicClient(account.value); await loadBalance(); await getAllowance(); await getNonce(); }, }); } return reactive({ balance, account, loadBalance }); }