UNPKG

@hyperlane-xyz/widgets

Version:

Common react components for Hyperlane projects

100 lines 4.28 kB
import { useAccount, useConnect, useDisconnect, useNetwork, useSendTransaction, useSwitchChain, } from '@starknet-react/core'; import { useCallback, useMemo } from 'react'; import { useStarknetkitConnectModal } from 'starknetkit'; import { ProviderType, chainMetadataToStarknetChain, } from '@hyperlane-xyz/sdk'; import { ProtocolType, assert } from '@hyperlane-xyz/utils'; import { widgetLogger } from '../logger.js'; import { getChainsForProtocol } from './utils.js'; const logger = widgetLogger.child({ module: 'widgets/walletIntegrations/starknet', }); export function useStarknetAccount(_multiProvider) { const { address, isConnected } = useAccount(); return useMemo(() => ({ protocol: ProtocolType.Starknet, addresses: address ? [{ address }] : [], isReady: !!isConnected, }), [address, isConnected]); } export function useStarknetWalletDetails() { const { connector } = useAccount(); return useMemo(() => ({ name: connector?.id || 'Starknet Wallet', logoUrl: typeof connector?.icon === 'string' ? connector.icon : connector?.icon?.light, }), [connector]); } export function useStarknetConnectFn() { const { connectAsync, connectors } = useConnect(); // This is how they do it: https://github.com/argentlabs/starknetkit-example-dapp/blob/d1d5ba8b5e06eef76b9df9b01832b57d2f22c649/src/components/connect/ConnectStarknetReactNext.tsx#L21 const { starknetkitConnectModal } = useStarknetkitConnectModal({ connectors: connectors, }); return useCallback(async () => { const { connector } = await starknetkitConnectModal(); if (connector) { await connectAsync({ connector }); } else { logger.error('No Starknet wallet connectors available'); } }, [connectAsync, starknetkitConnectModal]); } export function useStarknetDisconnectFn() { const { disconnectAsync } = useDisconnect(); return disconnectAsync; } export function useStarknetActiveChain(_multiProvider) { const { chain } = useNetwork(); return useMemo(() => ({ chainDisplayName: chain?.name, chainName: chain?.id ? chain.id.toString() : undefined, }), [chain]); } export function useStarknetTransactionFns(multiProvider) { const { account } = useAccount(); const { sendAsync } = useSendTransaction({}); const { switchChainAsync } = useSwitchChain({}); const onSwitchNetwork = useCallback(async (chainName) => { const chainId = multiProvider.getChainMetadata(chainName).chainId; await switchChainAsync({ chainId: chainId.toString(), }); }, [multiProvider, switchChainAsync]); const onSendTx = useCallback(async ({ tx, chainName, activeChainName, }) => { if (tx.type !== ProviderType.Starknet) { throw new Error(`Invalid transaction type for Starknet: ${tx.type}`); } if (activeChainName && activeChainName !== chainName) { await onSwitchNetwork(chainName); } if (!account) { throw new Error('No StarkNet account connected'); } const chainId = multiProvider.getChainMetadata(chainName).chainId; const chainIdFromWallet = await account.getChainId(); try { assert(chainIdFromWallet === chainId, `Wallet not on chain ${chainName} (ChainMismatchError)`); const result = await sendAsync([tx.transaction]); const hash = result.transaction_hash; const confirm = async () => { const receipt = await account.waitForTransaction(hash); return { type: ProviderType.Starknet, receipt, }; }; return { hash, confirm }; } catch (error) { logger.error('Failed to send StarkNet transaction:', error); throw error; } }, [account, multiProvider, onSwitchNetwork, sendAsync]); return { sendTransaction: onSendTx, switchNetwork: onSwitchNetwork }; } export function getStarknetChains(multiProvider) { return getChainsForProtocol(multiProvider, ProtocolType.Starknet).map(chainMetadataToStarknetChain); } //# sourceMappingURL=starknet.js.map