From bf7e9d22e34adae8b11dfbd9fc5b84a45920ca7e Mon Sep 17 00:00:00 2001 From: Faizan ul haq Date: Tue, 24 Dec 2024 00:02:37 +0400 Subject: [PATCH 1/4] feat: add vultisig support --- packages/swapkit/core/src/client.ts | 2 + .../helpers/src/helpers/web3wallets.ts | 5 +- .../helpers/src/modules/swapKitError.ts | 4 + packages/swapkit/helpers/src/types/sdk.ts | 1 + packages/swapkit/helpers/src/types/wallet.ts | 1 + packages/swapkit/wallets/src/index.ts | 3 +- packages/wallets/vultisig/build.ts | 4 + packages/wallets/vultisig/package.json | 32 ++ packages/wallets/vultisig/src/helpers.ts | 392 ++++++++++++++++++ packages/wallets/vultisig/src/index.ts | 58 +++ .../wallets/vultisig/src/vultisigWallet.ts | 59 +++ packages/wallets/vultisig/tsconfig.json | 4 + playgrounds/vite/src/WalletPicker.tsx | 23 +- 13 files changed, 582 insertions(+), 6 deletions(-) create mode 100644 packages/wallets/vultisig/build.ts create mode 100644 packages/wallets/vultisig/package.json create mode 100644 packages/wallets/vultisig/src/helpers.ts create mode 100644 packages/wallets/vultisig/src/index.ts create mode 100644 packages/wallets/vultisig/src/vultisigWallet.ts create mode 100644 packages/wallets/vultisig/tsconfig.json diff --git a/packages/swapkit/core/src/client.ts b/packages/swapkit/core/src/client.ts index ec62a5dfe..bff189f10 100644 --- a/packages/swapkit/core/src/client.ts +++ b/packages/swapkit/core/src/client.ts @@ -171,6 +171,8 @@ export function SwapKit(chain: T) { + console.log(chain); + console.log(connectedWallets); return connectedWallets[chain]; } diff --git a/packages/swapkit/helpers/src/helpers/web3wallets.ts b/packages/swapkit/helpers/src/helpers/web3wallets.ts index 660aaba42..0749ea413 100644 --- a/packages/swapkit/helpers/src/helpers/web3wallets.ts +++ b/packages/swapkit/helpers/src/helpers/web3wallets.ts @@ -207,7 +207,8 @@ export function getEIP6963Wallets() { const providers: EIP6963Provider[] = []; function onAnnouncement(event: EIP6963AnnounceProviderEvent) { - if (providers.map((p) => p.info.uuid).includes(event.detail.info.uuid)) return; + // FIXME: vultisig gives new UUID each time, so we should either find and replace or ignore new entries + if (providers.map((p) => p.info.name).includes(event.detail.info.name)) return; providers.push(event.detail); } @@ -217,7 +218,7 @@ export function getEIP6963Wallets() { function removeEIP6963EventListener() { window.removeEventListener("eip6963:announceProvider", onAnnouncement); } - + console.log(providers, "providers"); return { providers, removeEIP6963EventListener }; } diff --git a/packages/swapkit/helpers/src/modules/swapKitError.ts b/packages/swapkit/helpers/src/modules/swapKitError.ts index 458639e20..25bc5e14e 100644 --- a/packages/swapkit/helpers/src/modules/swapKitError.ts +++ b/packages/swapkit/helpers/src/modules/swapKitError.ts @@ -94,6 +94,10 @@ const errorCodes = { wallet_keepkey_contract_address_not_provided: 20902, wallet_keepkey_send_transaction_no_address: 20903, wallet_bitkeep_not_found: 21001, + wallet_vultisig_not_found: 21100, + wallet_vultisig_asset_not_defined: 21101, + wallet_vultisig_contract_address_not_provided: 21102, + wallet_vultisig_send_transaction_no_address: 21103, /** * Chainflip */ diff --git a/packages/swapkit/helpers/src/types/sdk.ts b/packages/swapkit/helpers/src/types/sdk.ts index af4d63f62..f83a9885a 100644 --- a/packages/swapkit/helpers/src/types/sdk.ts +++ b/packages/swapkit/helpers/src/types/sdk.ts @@ -56,6 +56,7 @@ export type WalletTxParams = { from?: string; memo?: string; // optional memo to pass recipient: string; + gasLimit?: string | bigint | undefined; }; export enum MemoType { diff --git a/packages/swapkit/helpers/src/types/wallet.ts b/packages/swapkit/helpers/src/types/wallet.ts index 42592771f..f6c44a7c0 100644 --- a/packages/swapkit/helpers/src/types/wallet.ts +++ b/packages/swapkit/helpers/src/types/wallet.ts @@ -50,6 +50,7 @@ export enum WalletOption { TALISMAN = "TALISMAN", TRUSTWALLET_WEB = "TRUSTWALLET_WEB", WALLETCONNECT = "WALLETCONNECT", + VULTISIG = "VULTISIG", } export enum LedgerErrorCode { diff --git a/packages/swapkit/wallets/src/index.ts b/packages/swapkit/wallets/src/index.ts index 1f26adc5b..d1ecce368 100644 --- a/packages/swapkit/wallets/src/index.ts +++ b/packages/swapkit/wallets/src/index.ts @@ -13,8 +13,8 @@ import { polkadotWallet } from "@swapkit/wallet-polkadotjs"; import { radixWallet } from "@swapkit/wallet-radix"; import { talismanWallet } from "@swapkit/wallet-talisman"; import { trezorWallet } from "@swapkit/wallet-trezor"; +import { vultisigWallet } from "@swapkit/wallet-vultisig"; import { walletconnectWallet } from "@swapkit/wallet-wc"; - export const wallets = { ...bitgetWallet, ...coinbaseWallet, @@ -32,4 +32,5 @@ export const wallets = { ...trezorWallet, ...walletconnectWallet, ...ctrlWallet, + ...vultisigWallet, }; diff --git a/packages/wallets/vultisig/build.ts b/packages/wallets/vultisig/build.ts new file mode 100644 index 000000000..e7817001f --- /dev/null +++ b/packages/wallets/vultisig/build.ts @@ -0,0 +1,4 @@ +import { buildPackage } from "../../../tools/builder"; +import { dependencies } from "./package.json"; + +buildPackage({ dependencies }); diff --git a/packages/wallets/vultisig/package.json b/packages/wallets/vultisig/package.json new file mode 100644 index 000000000..e1d852072 --- /dev/null +++ b/packages/wallets/vultisig/package.json @@ -0,0 +1,32 @@ +{ + "description": "SwapKit Wallet - vultisig", + "dependencies": { + "@swapkit/helpers": "workspace:*", + "@swapkit/toolbox-cosmos": "workspace:*", + "@swapkit/toolbox-evm": "workspace:*", + "@swapkit/toolbox-utxo": "workspace:*" + }, + "files": [ + "src/", + "dist/" + ], + "homepage": "https://github.com/thorswap/SwapKit", + "license": "Apache-2.0", + "main": "./dist/index.js", + "name": "@swapkit/wallet-vultisig", + "repository": { + "type": "git", + "url": "git+https://github.com/thorswap/SwapKit.git" + }, + "scripts": { + "build": "bun run ./build.ts", + "clean": "rm -rf dist node_modules *.tsbuildinfo", + "lint": "biome check --diagnostic-level=error --write ./src", + "test": "echo 'bun test'", + "test:coverage": "bun test --coverage", + "type-check": "tsc --noEmit" + }, + "type": "module", + "types": "./src/index.ts", + "version": "1.0.3" +} diff --git a/packages/wallets/vultisig/src/helpers.ts b/packages/wallets/vultisig/src/helpers.ts new file mode 100644 index 000000000..f522a7653 --- /dev/null +++ b/packages/wallets/vultisig/src/helpers.ts @@ -0,0 +1,392 @@ +import type { Keplr } from "@keplr-wallet/types"; +import { + type AssetValue, + Chain, + type ChainApi, + ChainId, + ChainToChainId, + ChainToHexChainId, + type EVMChain, + SwapKitError, + WalletOption, + type WalletTxParams, + addEVMWalletNetwork, + getRPCUrl, + prepareNetworkSwitch, +} from "@swapkit/helpers"; +import type { TransferParams } from "@swapkit/toolbox-cosmos"; +import type { Eip1193Provider } from "@swapkit/toolbox-evm"; +import type { Psbt, UTXOTransferParams } from "@swapkit/toolbox-utxo"; + +type TransactionMethod = "transfer" | "deposit"; + +type TransactionParams = { + asset: string | { chain: string; symbol: string; ticker: string }; + amount: number | string | { amount: number; decimals?: number }; + decimal?: number; + recipient: string; + memo?: string; +}; + +const ChainToVultisigWallet: Partial> = { + [Chain.Bitcoin]: "bitcoin", + [Chain.BitcoinCash]: "bitcoincash", + [Chain.Dogecoin]: "dogecoin", + [Chain.Litecoin]: "litecoin", + [Chain.THORChain]: "thorchain", + [Chain.Dash]: "dash", + [Chain.Cosmos]: "cosmos", + [Chain.Kujira]: "cosmos", +}; + +export function getVultisigProvider( + chain: T, +): T extends Chain.Cosmos | Chain.Kujira + ? Keplr + : T extends EVMChain + ? Eip1193Provider + : undefined { + if (!window.vultisig) throw new SwapKitError("wallet_vultisig_not_found"); + + switch (chain) { + case Chain.Ethereum: + // @ts-expect-error + return window.vultisig.ethereum; + + case Chain.Kujira: + // @ts-expect-error + return window.vultisig.cosmos; + + case Chain.Cosmos: + // @ts-expect-error + return window.vultisig.cosmos; + + case Chain.Bitcoin: + // @ts-expect-error + return window.vultisig.bitcoin; + case Chain.BitcoinCash: + // @ts-expect-error + return window.vultisig.bitcoincash; + case Chain.Dogecoin: + // @ts-expect-error + return window.vultisig.dogecoin; + case Chain.Litecoin: + // @ts-expect-error + return window.vultisig.litecoin; + case Chain.THORChain: + // @ts-expect-error + return window.vultisig.thorchain; + case Chain.Maya: + // @ts-expect-error + return window.vultisig.mayachain; + case Chain.Solana: + // @ts-expect-error + return window.vultisig.solana; + + default: + // @ts-expect-error + return undefined; + } +} + +async function transaction({ + method, + params, + chain, +}: { + method: TransactionMethod; + params: TransactionParams[]; + chain: Chain; +}): Promise { + const client = getVultisigProvider(chain); + + return new Promise((resolve, reject) => { + if (client && "request" in client) { + // @ts-ignore + client.request({ method, params }, (err: string, tx: string) => { + err ? reject(err) : resolve(tx); + }); + } + }); +} + +export async function getVultisigAddress(chain: Chain) { + console.log(chain, "chain"); + const eipProvider = getVultisigProvider(chain) as Eip1193Provider; + console.log(eipProvider, "eipProvider"); + if (!eipProvider) { + throw new SwapKitError({ + errorKey: "wallet_provider_not_found", + info: { wallet: WalletOption.VULTISIG, chain }, + }); + } + + if ([Chain.Cosmos, Chain.Kujira].includes(chain)) { + const provider = getVultisigProvider(Chain.Cosmos); + if (!provider || "request" in provider) { + throw new SwapKitError({ + errorKey: "wallet_provider_not_found", + info: { wallet: WalletOption.VULTISIG, chain }, + }); + } + + // Enabling before using the Keplr is recommended. + // This method will ask the user whether to allow access if they haven't visited this website. + // Also, it will request that the user unlock the wallet if the wallet is locked. + const chainId = ChainToChainId[chain]; + await provider.enable(chainId); + + const offlineSigner = provider.getOfflineSigner(chainId); + + const [item] = await offlineSigner.getAccounts(); + return item?.address; + } + + if (chain === Chain.Ethereum) { + const [response] = await eipProvider.request({ method: "eth_requestAccounts" }); + + return response; + } + + return new Promise((resolve, reject) => + eipProvider.request( + { method: "request_accounts" }, + // @ts-expect-error + (error: any, [response]: string[]) => (error ? reject(error) : resolve(response)), + ), + ); +} + +export async function walletTransfer( + { assetValue, recipient, memo, gasLimit }: WalletTxParams & { assetValue: AssetValue }, + method: TransactionMethod = "transfer", +) { + if (!assetValue) { + throw new SwapKitError("wallet_vultisig_asset_not_defined"); + } + + /** + * EVM requires amount to be hex string + * UTXO/Cosmos requires amount to be number + */ + + const from = await getVultisigAddress(assetValue.chain); + const params = [ + { + amount: { + amount: assetValue.getBaseValue("number"), + decimals: assetValue.decimal, + }, + asset: { + chain: assetValue.chain, + symbol: assetValue.symbol.toUpperCase(), + ticker: assetValue.symbol.toUpperCase(), + }, + memo, + from, + recipient, + gasLimit, + }, + ]; + + return transaction({ method, params, chain: assetValue.chain }); +} + +export function cosmosTransfer(rpcUrl?: string) { + return async ({ from, recipient, assetValue, memo }: TransferParams) => { + const { getMsgSendDenom, createSigningStargateClient } = await import( + "@swapkit/toolbox-cosmos" + ); + if (!(window.vultisig && "keplr" in window.vultisig)) { + throw new SwapKitError("wallet_vultisig_not_found"); + } + + const { keplr: wallet } = window.vultisig; + + const offlineSigner = wallet.getOfflineSignerOnlyAmino(ChainId.Cosmos); + const cosmJS = await createSigningStargateClient( + rpcUrl || getRPCUrl(Chain.Cosmos), + offlineSigner, + ); + + const coins = [ + { + denom: getMsgSendDenom(assetValue.symbol).toLowerCase(), + amount: assetValue.getBaseValue("string"), + }, + ]; + + try { + const { transactionHash } = await cosmJS.sendTokens(from, recipient, coins, 2, memo); + return transactionHash; + } catch (error) { + throw new SwapKitError("core_transaction_failed", { error }); + } + }; +} + +// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: +export async function getWalletForChain({ + chain, + ethplorerApiKey, + covalentApiKey, + blockchairApiKey, + rpcUrl, + api, +}: { + chain: Chain; + ethplorerApiKey?: string; + covalentApiKey?: string; + blockchairApiKey?: string; + rpcUrl?: string; + api?: ChainApi; +}) { + const vultisig = window.vultisig; + if (!vultisig) throw new SwapKitError("wallet_vultisig_not_found"); + const vultiProvider = ChainToVultisigWallet[chain] as string; + + switch (chain) { + case Chain.Ethereum: { + if (!(vultisig && "ethereum" in vultisig)) { + throw new SwapKitError("wallet_vultisig_not_found"); + } + + const wallet = vultisig.ethereum; + + const { getProvider } = await import("@swapkit/toolbox-evm"); + + const evmWallet = await getWeb3WalletMethods({ + chain, + ethplorerApiKey, + covalentApiKey, + ethereumWindowProvider: wallet, + }); + + const [address]: [string, ...string[]] = await wallet.request({ + method: "eth_requestAccounts", + }); + + const getBalance = async (addressOverwrite?: string, potentialScamFilter = true) => + evmWallet.getBalance(addressOverwrite || address, potentialScamFilter, getProvider(chain)); + + return { ...evmWallet, getBalance, address }; + } + + case Chain.Maya: + case Chain.THORChain: { + const { getToolboxByChain, THORCHAIN_GAS_VALUE, MAYA_GAS_VALUE } = await import( + "@swapkit/toolbox-cosmos" + ); + + const gasLimit = chain === Chain.Maya ? MAYA_GAS_VALUE : THORCHAIN_GAS_VALUE; + const toolbox = getToolboxByChain(chain); + + return { + ...toolbox(), + deposit: (tx: WalletTxParams) => walletTransfer({ ...tx, recipient: "" }, "deposit"), + transfer: (tx: WalletTxParams) => walletTransfer({ ...tx, gasLimit }, "transfer"), + }; + } + + case Chain.Bitcoin: + case Chain.BitcoinCash: + case Chain.Dash: + case Chain.Dogecoin: + case Chain.Litecoin: { + console.log(chain, vultisig, vultiProvider in vultisig); + if (!(vultisig && vultiProvider in vultisig)) { + throw new SwapKitError("wallet_vultisig_not_found"); + } + const wallet = vultisig[vultiProvider]; + + const { Psbt, BTCToolbox } = await import("@swapkit/toolbox-utxo"); + + const [address] = await wallet.request({ method: "request_accounts" }); + console.log(address); + const apiClient = typeof api === "object" && "getConfirmedBalance" in api ? api : undefined; + + const toolbox = BTCToolbox({ rpcUrl, apiKey: blockchairApiKey, apiClient }); + const signTransaction = async (psbt: Psbt) => { + const signedPsbt = await wallet.request({ method: "sign_psbt", params: [psbt] }); + console.log(`${chain} Transaction Hash:`, signedPsbt); + return Psbt.fromHex(signedPsbt); + }; + + const transfer = (transferParams: UTXOTransferParams) => { + return toolbox.transfer({ ...transferParams, signTransaction }); + }; + + return { ...toolbox, transfer, address }; + } + case Chain.Kujira: + case Chain.Cosmos: { + if (!(vultisig && vultiProvider in vultisig)) { + throw new SwapKitError("wallet_vultisig_not_found"); + } + const wallet = vultisig[vultiProvider]; + + const accounts = await wallet.request({ method: "request_accounts" }); + console.log(accounts); + if (!accounts?.[0]) throw new Error("No cosmos account found"); + + const { GaiaToolbox } = await import("@swapkit/toolbox-cosmos"); + const [{ address }] = accounts; + + return { + address, + ...GaiaToolbox({ server: typeof api === "string" ? api : undefined }), + transfer: cosmosTransfer(rpcUrl), + }; + } + + default: + throw new SwapKitError("wallet_chain_not_supported"); + } +} + +export const getWeb3WalletMethods = async ({ + ethereumWindowProvider, + chain, + covalentApiKey, + ethplorerApiKey, +}: { + ethereumWindowProvider: Eip1193Provider | undefined; + chain: EVMChain; + covalentApiKey?: string; + ethplorerApiKey?: string; +}) => { + const { getToolboxByChain, BrowserProvider } = await import("@swapkit/toolbox-evm"); + if (!ethereumWindowProvider) throw new SwapKitError("wallet_provider_not_found"); + + if ( + (chain !== Chain.Ethereum && !covalentApiKey) || + (chain === Chain.Ethereum && !ethplorerApiKey) + ) { + throw new SwapKitError({ + errorKey: "wallet_missing_api_key", + info: { + missingKey: chain === Chain.Ethereum ? "ethplorerApiKey" : "covalentApiKey", + chain, + }, + }); + } + + const provider = new BrowserProvider(ethereumWindowProvider, "any"); + + const toolbox = getToolboxByChain(chain)({ + provider, + signer: await provider.getSigner(), + ethplorerApiKey: ethplorerApiKey as string, + covalentApiKey: covalentApiKey as string, + }); + + try { + if (chain !== Chain.Ethereum && "getNetworkParams" in toolbox) { + await addEVMWalletNetwork(provider, toolbox.getNetworkParams()); + } + } catch (_error) { + throw new Error(`Failed to add/switch ${chain} network: ${chain}`); + } + + return prepareNetworkSwitch({ toolbox, provider, chainId: ChainToHexChainId[chain] }); +}; diff --git a/packages/wallets/vultisig/src/index.ts b/packages/wallets/vultisig/src/index.ts new file mode 100644 index 000000000..9e9f698ea --- /dev/null +++ b/packages/wallets/vultisig/src/index.ts @@ -0,0 +1,58 @@ +import type { StdSignDoc, StdSignature } from "@cosmjs/amino"; +import type { AminoSignResponse, OfflineAminoSigner } from "@cosmjs/amino"; +import type { EthereumWindowProvider } from "@swapkit/helpers"; + +export { vultisigWallet, VULTISIG_SUPPORTED_CHAINS } from "./vultisigWallet"; + +type UnisatToSignInputs = { + index: number; + sighashTypes?: number[]; + disableTweakSigner?: boolean; +} & ( + | { + address: string; + } + | { + publicKey: string; + } +); + +declare global { + interface Window { + vultisig?: { + unisat: { + requestAccounts: () => Promise<[string, ...string[]]>; + signMessage: (message: string, type?: "ecdsa" | "bip322-simple") => Promise; + signPsbt: ( + psbtHex: string, + { + autoFinalized, + toSignInputs, + }: { autoFinalized?: boolean; toSignInputs?: UnisatToSignInputs[] }, + ) => Promise; + }; + keplr: { + enable: (chainId: string | string[]) => Promise; + signAmino: ( + chainId: string, + signer: string, + signDoc: StdSignDoc, + signOptions: any, + ) => Promise; + signArbitrary: ( + chainId: string, + signer: string, + data: string | Uint8Array, + ) => Promise; + verifyArbitrary: ( + chainId: string, + signer: string, + data: string | Uint8Array, + signature: StdSignature, + ) => Promise; + getOfflineSignerOnlyAmino: (chainId: string) => OfflineAminoSigner; + }; + ethereum: EthereumWindowProvider; + }; + } +} diff --git a/packages/wallets/vultisig/src/vultisigWallet.ts b/packages/wallets/vultisig/src/vultisigWallet.ts new file mode 100644 index 000000000..81b2dba10 --- /dev/null +++ b/packages/wallets/vultisig/src/vultisigWallet.ts @@ -0,0 +1,59 @@ +import { + Chain, + type ConnectWalletParams, + WalletOption, + setRequestClientConfig, +} from "@swapkit/helpers"; + +import { getVultisigAddress, getWalletForChain } from "./helpers"; + +export const VULTISIG_SUPPORTED_CHAINS = [ + Chain.Ethereum, + Chain.THORChain, + Chain.Maya, + Chain.Cosmos, + Chain.Kujira, + Chain.BitcoinCash, + Chain.Dash, + Chain.Dogecoin, + Chain.Litecoin, + Chain.Bitcoin, +] as const; + +function connectVultisig({ + addChain, + config: { thorswapApiKey, covalentApiKey, ethplorerApiKey, blockchairApiKey }, +}: ConnectWalletParams) { + return async function connectVultisig(chains: (typeof VULTISIG_SUPPORTED_CHAINS)[number][]) { + setRequestClientConfig({ apiKey: thorswapApiKey }); + + const promises = chains.map(async (chain) => { + let address = ""; + try { + address = await getVultisigAddress(chain); + } catch (error) { + console.log(error, "error"); + } + const walletMethods = await getWalletForChain({ + chain, + covalentApiKey, + ethplorerApiKey, + blockchairApiKey, + }); + console.log(address, "address"); + addChain({ + ...walletMethods, + chain, + balance: [], + walletType: WalletOption.VULTISIG, + address, + }); + }); + + await Promise.all(promises); + + return true; + }; +} + +export const vultisigWallet = { connectVultisig } as const; diff --git a/packages/wallets/vultisig/tsconfig.json b/packages/wallets/vultisig/tsconfig.json new file mode 100644 index 000000000..d0fdb4cd9 --- /dev/null +++ b/packages/wallets/vultisig/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../../tools/typescript/base.json", + "include": ["src", "./build.ts"] +} diff --git a/playgrounds/vite/src/WalletPicker.tsx b/playgrounds/vite/src/WalletPicker.tsx index 0c0b2f9ac..56bd470ec 100644 --- a/playgrounds/vite/src/WalletPicker.tsx +++ b/playgrounds/vite/src/WalletPicker.tsx @@ -17,6 +17,7 @@ import { PHANTOM_SUPPORTED_CHAINS } from "@swapkit/wallet-phantom"; import type { Eip1193Provider } from "ethers"; import type { SwapKitClient } from "./swapKitClient"; + type Props = { setPhrase: (phrase: string) => void; setWallet: (wallet: FullWallet[Chain] | FullWallet[Chain][]) => void; @@ -145,6 +146,18 @@ export const availableChainsByWallet = { [WalletOption.EXODUS]: [Chain.Ethereum, Chain.BinanceSmartChain, Chain.Polygon, Chain.Bitcoin], [WalletOption.LEDGER_LIVE]: [], [WalletOption.RADIX_WALLET]: [Chain.Radix], + [WalletOption.VULTISIG]: [ + Chain.Ethereum, + Chain.THORChain, + Chain.Maya, + Chain.Cosmos, + Chain.Kujira, + Chain.BitcoinCash, + Chain.Dash, + Chain.Dogecoin, + Chain.Litecoin, + Chain.Bitcoin, + ] }; export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { @@ -212,6 +225,9 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { case WalletOption.WALLETCONNECT: return skClient.connectWalletconnect?.(chains); + case WalletOption.VULTISIG: + return skClient.connectVultisig?.(chains); + default: throw new Error(`Unsupported wallet option: ${option}`); } @@ -260,6 +276,7 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { const walletDataArray = await Promise.all( chains.map((chain) => skClient.getWalletWithBalance(chain, true)), ); + console.log(walletDataArray, 'walletDataArray'); setWallet(walletDataArray.filter(Boolean)); setLoading(false); @@ -270,9 +287,9 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => { const isWalletDisabled = useCallback( (wallet: WalletOption) => chains.length > 0 - ? !chains.every((chain) => + ? !chains.every((chain) =>{ // @ts-ignore - availableChainsByWallet[wallet].includes(chain), + return availableChainsByWallet[wallet].includes(chain)} ) : false, [chains], @@ -303,7 +320,7 @@ export const WalletPicker = ({ skClient, setWallet, setPhrase }: Props) => {