nimbus-bridge
Version:
171 lines • 8.32 kB
JavaScript
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