UNPKG

@btc-vision/walletconnect

Version:

The OP_NET Wallet Connect library helps your dApp connect to any compatible wallet.

224 lines (223 loc) 7.34 kB
import { networks } from '@btc-vision/bitcoin'; import { UnisatChainType, } from '@btc-vision/transaction'; import { _e } from '../utils/accessibility/errorDecoder'; class WalletController { static wallets = new Map(); static currentWallet = null; static getWallets = () => { return [...WalletController.wallets.values()]; }; static isWalletInstalled(wallet) { return this.wallets.get(wallet)?.controller?.isInstalled() || false; } static getWalletType() { return WalletController.currentWallet?.name || null; } static getWalletInstance() { const wallet = this.currentWallet; if (!wallet) { return null; } const walletInstance = wallet.controller.getWalletInstance(); return walletInstance ? new Proxy(walletInstance, {}) : null; } static async getProvider() { const wallet = this.currentWallet; if (!wallet) { return null; } const provider = await wallet.controller.getProvider(); return provider ? new Proxy(provider, {}) : null; } static async getSigner() { const wallet = this.currentWallet; if (!wallet) { return null; } return await wallet.controller.getSigner(); } static convertChainTypeToNetwork(chainType) { const walletNetwork = (network, name) => { return { ...network, chainType: chainType, network: name }; }; switch (chainType) { case UnisatChainType.BITCOIN_REGTEST: return walletNetwork(networks.regtest, 'regtest'); case UnisatChainType.OPNET_TESTNET: return walletNetwork(networks.opnetTestnet, 'testnet'); case UnisatChainType.BITCOIN_MAINNET: return walletNetwork(networks.bitcoin, 'mainnet'); case UnisatChainType.BITCOIN_TESTNET: case UnisatChainType.BITCOIN_TESTNET4: case UnisatChainType.BITCOIN_SIGNET: case UnisatChainType.FRACTAL_BITCOIN_TESTNET: case UnisatChainType.FRACTAL_BITCOIN_MAINNET: default: return null; } } static async getNetwork() { const wallet = this.currentWallet; if (!wallet) { return null; } const chainType = await wallet.controller.getNetwork(); return this.convertChainTypeToNetwork(chainType); } static async getPublicKey() { const wallet = this.currentWallet; if (!wallet) { return null; } return wallet.controller.getPublicKey(); } static async canAutoConnect(walletName) { const wallet = this.wallets.get(walletName); return (wallet && (await wallet.controller.canAutoConnect())) || false; } static async connect(walletName) { const wallet = this.wallets.get(walletName); if (!wallet) { return { code: 404, data: { message: _e('Wallet not found'), }, }; } try { const accounts = await wallet.controller.connect(); await this.disconnectIfWalletChanged(wallet); this.currentWallet = wallet; return { code: 200, data: accounts, }; } catch (error) { return { code: 499, data: { message: _e(error?.message || error), }, }; } } static async disconnectIfWalletChanged(newWallet) { const wallet = this.currentWallet; if (wallet && wallet.name != newWallet.name) { await this.disconnect(); this.unbindHooks(); } } static async disconnect() { const wallet = this.currentWallet; if (!wallet) { return; } await wallet.controller.disconnect(); this.currentWallet = null; } static setAccountsChangedHook(fn) { const wallet = this.currentWallet; if (!wallet) { return; } wallet.controller.removeAccountsChangedHook(); wallet.controller.setAccountsChangedHook(fn); } static setDisconnectHook(fn) { const wallet = this.currentWallet; if (!wallet) { return; } wallet.controller.removeDisconnectHook(); wallet.controller.setDisconnectHook(fn); } static setChainChangedHook(fn) { const wallet = this.currentWallet; if (!wallet) { console.log('No current wallet to set network switch hook for'); return; } wallet.controller.removeChainChangedHook(); wallet.controller.setChainChangedHook((chainType) => { const network = this.convertChainTypeToNetwork(chainType); if (network) { fn(network); } }); } static removeAccountsChangedHook() { const wallet = this.currentWallet; if (!wallet) { console.log('No current wallet to remove accounts changed hook from'); return; } try { wallet.controller.removeAccountsChangedHook(); } catch (error) { console.error('Error removing accounts changed hook:', error); } } static removeDisconnectHook() { const wallet = this.currentWallet; if (!wallet) { console.log('No current wallet to remove disconnect hook from'); return; } try { wallet.controller.removeDisconnectHook(); } catch (error) { console.error('Error removing disconnect hook:', error); } } static removeChainChangedHook() { const wallet = this.currentWallet; if (!wallet) { console.log('No current wallet to remove network change hook from'); return; } try { wallet.controller.removeChainChangedHook(); } catch (error) { console.error('Error removing network change hook:', error); } } static registerWallet = (wallet) => { this.wallets.set(wallet.name, wallet); }; static unbindHooks() { this.removeDisconnectHook(); this.removeChainChangedHook(); this.removeAccountsChangedHook(); } static async getMLDSAPublicKey() { const wallet = this.currentWallet; if (!wallet) return null; return wallet.controller.getMLDSAPublicKey(); } static async getHashedMLDSAKey() { const wallet = this.currentWallet; if (!wallet) return null; return wallet.controller.getHashedMLDSAKey(); } static async signMLDSAMessage(message) { const wallet = this.currentWallet; if (!wallet) return null; return wallet.controller.signMLDSAMessage(message); } static async verifyMLDSASignature(message, signature) { const wallet = this.currentWallet; if (!wallet) return false; return wallet.controller.verifyMLDSASignature(message, signature); } } export { WalletController };