UNPKG

@reown/appkit-controllers

Version:

The full stack toolkit to build onchain app UX.

149 lines • 7.51 kB
import { ConstantsUtil } from '@reown/appkit-common'; import { ChainController } from '../controllers/ChainController.js'; import { CoreHelperUtil } from './CoreHelperUtil.js'; /* * Exclude wallets that do not support relay connections but have custom deeplink mechanisms * Excludes: * - Phantom * - Coinbase */ export const CUSTOM_DEEPLINK_WALLETS = { PHANTOM: { id: 'a797aa35c0fadbfc1a53e7f675162ed5226968b44a19ee3d24385c64d1d3c393', url: 'https://phantom.app', androidPackage: 'app.phantom' }, SOLFLARE: { id: '1ca0bdd4747578705b1939af023d120677c64fe6ca76add81fda36e350605e79', url: 'https://solflare.com' }, COINBASE: { id: 'd0ca99ff52b99abc48743dad0f7fc891e041be73574f7fac4afe5d4bb83845c8', url: 'https://go.cb-w.com', evmDeeplink: 'cbwallet://miniapp' }, /* * Got details from their npm package: * https://www.npmjs.com/package/@binance/w3w-utils?activeTab=code * https://developers.binance.com/docs/binance-w3w/evm-compatible-provider#getdeeplink */ BINANCE: { id: '2fafea35bb471d22889ccb49c08d99dd0a18a37982602c33f696a5723934ba25', appId: 'yFK5FCqYprrXDiVFbhyRx7', deeplink: 'bnc://app.binance.com/mp/app', url: 'https://app.binance.com/en/download' } }; export const MobileWalletUtil = { /** * Checks if a wallet is a custom deeplink wallet that uses Universal Links * instead of WalletConnect deeplinks for the given chain namespace. * * Only returns true for supported wallet-chain combinations: * - Phantom: Solana, EVM, and Bitcoin (doesn't support WalletConnect) * - Solflare: Solana only * - Coinbase: Solana and EVM * - Binance: Bitcoin only * * @param {string} id - The id of the wallet. * @param {ChainControllerState['activeChain']} namespace - The chain namespace. * @returns {boolean} Whether the wallet is a custom deeplink wallet for the given namespace. */ isCustomDeeplinkWallet(id, namespace) { // Phantom doesn't support WalletConnect, uses Universal Links for all supported chains if (id === CUSTOM_DEEPLINK_WALLETS.PHANTOM.id) { return (namespace === ConstantsUtil.CHAIN.SOLANA || namespace === ConstantsUtil.CHAIN.EVM || namespace === ConstantsUtil.CHAIN.BITCOIN); } if (id === CUSTOM_DEEPLINK_WALLETS.SOLFLARE.id) { return namespace === ConstantsUtil.CHAIN.SOLANA; } if (id === CUSTOM_DEEPLINK_WALLETS.COINBASE.id) { return namespace === ConstantsUtil.CHAIN.SOLANA || namespace === ConstantsUtil.CHAIN.EVM; } if (id === CUSTOM_DEEPLINK_WALLETS.BINANCE.id) { return namespace === ConstantsUtil.CHAIN.BITCOIN; } return false; }, /** * Handles mobile wallet redirection for wallets that have Universal Links and doesn't support WalletConnect Deep Links. * * @param {string} id - The id of the wallet. * @param {ChainNamespace} namespace - The namespace of the chain. * @param {object} options - Optional configuration. * @param {boolean} options.isCoinbaseDisabled - Whether Coinbase wallet is disabled. When true, always trigger deeplink. */ handleMobileDeeplinkRedirect(id, namespace, options) { /** * Universal Links requires explicit user interaction to open the wallet app. * Previously we've been calling this with the life-cycle methods in the Solana clients by listening the SELECT_WALLET event of EventController. * But this breaks the UL functionality for some wallets like Phantom. */ const href = window.location.href; const encodedHref = encodeURIComponent(href); const isCoinbaseDisabled = options?.isCoinbaseDisabled ?? false; if (id === CUSTOM_DEEPLINK_WALLETS.PHANTOM.id && !('phantom' in window)) { const protocol = href.startsWith('https') ? 'https' : 'http'; const host = href.split('/')[2]; const encodedRef = encodeURIComponent(`${protocol}://${host}`); const browseUrl = `${CUSTOM_DEEPLINK_WALLETS.PHANTOM.url}/ul/browse/${encodedHref}?ref=${encodedRef}`; if (CoreHelperUtil.isAndroid()) { /* * Use Android intent URL for Phantom on Android devices. * Universal Links don't work reliably on many Android browsers (Opera, UC Browser, Samsung Internet, in-app browsers). * Intent URLs bypass browser app link verification and work on all Android browsers. * See: https://developer.chrome.com/docs/android/intents */ const intentUrl = `intent://browse/${encodedHref}?ref=${encodedRef}#Intent;scheme=phantom;package=${CUSTOM_DEEPLINK_WALLETS.PHANTOM.androidPackage};end`; window.location.href = intentUrl; } else { // Use Universal Link on iOS - well supported by Safari window.location.href = browseUrl; } } // Solflare only supports Solana if (id === CUSTOM_DEEPLINK_WALLETS.SOLFLARE.id && namespace === ConstantsUtil.CHAIN.SOLANA && !('solflare' in window)) { window.location.href = `${CUSTOM_DEEPLINK_WALLETS.SOLFLARE.url}/ul/v1/browse/${encodedHref}?ref=${encodedHref}`; } if (namespace === ConstantsUtil.CHAIN.SOLANA) { if (id === CUSTOM_DEEPLINK_WALLETS.COINBASE.id && (isCoinbaseDisabled || !('coinbaseSolana' in window))) { window.location.href = `${CUSTOM_DEEPLINK_WALLETS.COINBASE.url}/dapp?cb_url=${encodedHref}`; } } /* * Coinbase/Base wallet deeplink for EVM chains. * Uses cbwallet://miniapp?url={REDIRECT_URL} to open in-app browser. */ if (namespace === ConstantsUtil.CHAIN.EVM) { if (id === CUSTOM_DEEPLINK_WALLETS.COINBASE.id && (isCoinbaseDisabled || !('coinbaseWalletExtension' in window))) { window.location.href = `${CUSTOM_DEEPLINK_WALLETS.COINBASE.evmDeeplink}?url=${encodedHref}`; } } /* * Binance Web3 Wallet doesn't support WalletConnect for Bitcoin. * For now we use their deeplink to open the in-app browser instead. */ if (namespace === ConstantsUtil.CHAIN.BITCOIN) { if (id === CUSTOM_DEEPLINK_WALLETS.BINANCE.id && !('binancew3w' in window)) { const activeCaipNetwork = ChainController.state.activeCaipNetwork; const startPagePath = window.btoa('/pages/browser/index'); const startPageQuery = window.btoa(`url=${encodedHref}&defaultChainId=${activeCaipNetwork?.id ?? 1}`); const deeplink = new URL(CUSTOM_DEEPLINK_WALLETS.BINANCE.deeplink); deeplink.searchParams.set('appId', CUSTOM_DEEPLINK_WALLETS.BINANCE.appId); deeplink.searchParams.set('startPagePath', startPagePath); deeplink.searchParams.set('startPageQuery', startPageQuery); const universalLink = new URL(CUSTOM_DEEPLINK_WALLETS.BINANCE.url); universalLink.searchParams.set('_dp', window.btoa(deeplink.toString())); window.location.href = universalLink.toString(); } } } }; //# sourceMappingURL=MobileWallet.js.map