UNPKG

nimbus-bridge

Version:
171 lines 8.32 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useEffect, useMemo, useRef, useState } from "react"; import { SwapWidget } from "@reservoir0x/relay-kit-ui"; import { useDynamicContext, useDynamicEvents, useDynamicModals, useSwitchWallet, useUserWallets, } from "@dynamic-labs/sdk-react-core"; import { isEthereumWallet } from "@dynamic-labs/ethereum"; import { isSolanaWallet } from "@dynamic-labs/solana"; import { isBitcoinWallet } from "@dynamic-labs/bitcoin"; import { isEclipseWallet } from "@dynamic-labs/eclipse"; import { isSuiWallet } from "@dynamic-labs/sui"; import { adaptViemWallet, } from "@reservoir0x/relay-sdk"; import { adaptBitcoinWallet } from "@reservoir0x/relay-bitcoin-wallet-adapter"; import { adaptSolanaWallet } from "@reservoir0x/relay-svm-wallet-adapter"; import { adaptSuiWallet } from "@reservoir0x/relay-sui-wallet-adapter"; import { useWalletFilter } from "./context/walletFilter"; import { convertToLinkedWallet } from "./utils/dynamic"; export const Bridge = ({ config }) => { useDynamicEvents("walletAdded", (newWallet) => { if (linkWalletPromise) { linkWalletPromise?.resolve(convertToLinkedWallet(newWallet)); setLinkWalletPromise(undefined); } }); const { setWalletFilter } = useWalletFilter(); const { setShowAuthFlow, primaryWallet } = useDynamicContext(); const _switchWallet = useSwitchWallet(); const { setShowLinkNewWalletModal } = useDynamicModals(); const userWallets = useUserWallets(); const wallets = useRef(); const switchWallet = useRef(); const [wallet, setWallet] = useState(); const [linkWalletPromise, setLinkWalletPromise] = useState(); const linkedWallets = useMemo(() => { const _wallets = userWallets.reduce((linkedWallets, wallet) => { linkedWallets.push(convertToLinkedWallet(wallet)); return linkedWallets; }, []); wallets.current = userWallets; return _wallets; }, [userWallets]); useEffect(() => { switchWallet.current = _switchWallet; }, [_switchWallet]); useEffect(() => { const adaptWallet = async () => { try { if (primaryWallet !== null) { let adaptedWallet; if (isEthereumWallet(primaryWallet)) { const walletClient = await primaryWallet.getWalletClient(); adaptedWallet = adaptViemWallet(walletClient); } else if (isBitcoinWallet(primaryWallet)) { const wallet = convertToLinkedWallet(primaryWallet); adaptedWallet = adaptBitcoinWallet(wallet.address, async (_address, _psbt, dynamicParams) => { try { // Request the wallet to sign the PSBT const response = await primaryWallet.signPsbt(dynamicParams); if (!response) { throw "Missing psbt response"; } return response.signedPsbt; } catch (e) { throw e; } }); } else if (isSolanaWallet(primaryWallet) || isEclipseWallet(primaryWallet)) { const connection = await primaryWallet.getConnection(); const signer = await primaryWallet.getSigner(); const _chainId = isEclipseWallet(primaryWallet) ? 9286185 : 792703809; adaptedWallet = adaptSolanaWallet(primaryWallet.address, _chainId, connection, signer.signAndSendTransaction); } else if (isSuiWallet(primaryWallet)) { const suiWallet = primaryWallet; const walletClient = await suiWallet.getWalletClient(); if (!walletClient) { throw "Unable to setup Sui wallet"; } adaptedWallet = adaptSuiWallet(suiWallet.address, 103665049, // @TODO: handle sui testnet walletClient, async (tx) => { const signedTransaction = await suiWallet.signTransaction(tx); const executionResult = await walletClient.executeTransactionBlock({ options: {}, signature: signedTransaction.signature, transactionBlock: signedTransaction.bytes, }); return executionResult; }); } setWallet(adaptedWallet); } else { setWallet(undefined); } } catch (e) { setWallet(undefined); } }; adaptWallet(); }, [primaryWallet, primaryWallet?.address]); return (_jsx(SwapWidget, { lockChainId: config.lockChainId, singleChainMode: false, supportedWalletVMs: config.supportedWalletVMs, wallet: wallet, multiWalletSupportEnabled: true, linkedWallets: linkedWallets, toToken: config.defaultToToken, fromToken: config.defaultFromToken, defaultAmount: config.defaultAmount, onAnalyticEvent: config.onAnalyticEvent, onLinkNewWallet: ({ chain, direction }) => { if (linkWalletPromise) { linkWalletPromise.reject(); setLinkWalletPromise(undefined); } if (chain?.vmType === "evm") { setWalletFilter("EVM"); } else if (chain?.id === 792703809) { setWalletFilter("SOL"); } else if (chain?.id === 8253038) { setWalletFilter("BTC"); } else if (chain?.id === 9286185) { setWalletFilter("ECLIPSE"); } else if (chain?.vmType === "suivm") { setWalletFilter("SUI"); } else { setWalletFilter(undefined); } const promise = new Promise((resolve, reject) => { setLinkWalletPromise({ resolve, reject, params: { chain, direction, }, }); }); setShowLinkNewWalletModal(true); return promise; }, onSetPrimaryWallet: async (address) => { //In some cases there's a race condition between connecting the wallet and having it available to switch to so we need to poll for it const maxAttempts = 20; let attemptCount = 0; const timer = setInterval(async () => { attemptCount++; const newPrimaryWallet = wallets.current?.find((wallet) => wallet.address === address || wallet.additionalAddresses.find((_address) => _address.address === address)); if (attemptCount >= maxAttempts) { clearInterval(timer); return; } if (!newPrimaryWallet || !switchWallet.current) { return; } try { await switchWallet.current(newPrimaryWallet?.id); clearInterval(timer); } catch (e) { } }, 200); }, onConnectWallet: () => { setShowAuthFlow(true); }, onFromTokenChange: (token) => console.log("From token changed to: ", token), onToTokenChange: (token) => console.log("To token changed to: ", token), onSwapError: (e, data) => { console.log("onSwapError Triggered", e, data); }, onSwapSuccess: (data) => { console.log("onSwapSuccess Triggered", data); } }, "swap-widget-multi-chain")); }; export default Bridge; //# sourceMappingURL=Bridge.js.map