UNPKG

@btc-vision/walletconnect

Version:

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

188 lines (187 loc) 6.88 kB
import { fromHex, networks, sha256, toHex } from '@btc-vision/bitcoin'; import { UnisatChainType, } from '@btc-vision/transaction'; import { JSONRpcProvider } from 'opnet'; const notInstalledError = 'OP_WALLET is not installed'; class OPWallet { walletBase; accountsChangedHookWrapper; chainChangedHookWrapper; disconnectHookWrapper; _isConnected = false; isInstalled() { if (typeof window === 'undefined') { return false; } this.walletBase = window.opnet; return !!this.walletBase; } isConnected() { return !!this.walletBase && this._isConnected; } async canAutoConnect() { const accounts = (await this.walletBase?.getAccounts()) || []; return accounts.length > 0; } getChainId() { throw new Error('Method not implemented.'); } async connect() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } return this.walletBase.requestAccounts().then((accounts) => { this._isConnected = accounts.length > 0; return accounts; }); } async disconnect() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } return this._isConnected ? await this.walletBase.disconnect().then(() => { this._isConnected = false; }) : undefined; } getWalletInstance() { return (this._isConnected && this.walletBase) || null; } async getProvider() { if (!this._isConnected || !this.walletBase) return null; const chain = await this.walletBase.getChain(); switch (chain.enum) { case UnisatChainType.BITCOIN_MAINNET: return new JSONRpcProvider({ url: 'https://mainnet.opnet.org', network: networks.bitcoin, }); case UnisatChainType.OPNET_TESTNET: return new JSONRpcProvider({ url: 'https://testnet.opnet.org', network: networks.opnetTestnet, }); case UnisatChainType.BITCOIN_REGTEST: return new JSONRpcProvider({ url: 'https://regtest.opnet.org', network: networks.regtest, }); default: return null; } } async getSigner() { return Promise.resolve(null); } getPublicKey() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } return this.walletBase.getPublicKey(); } async getNetwork() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } const chainInfo = await this.walletBase.getChain(); if (!chainInfo) { throw new Error('Failed to retrieve chain information'); } return chainInfo.enum; } setAccountsChangedHook(fn) { console.log('Setting account changed hook for OPWallet'); if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } this.accountsChangedHookWrapper = (accounts) => { console.log('OPWallet Account Changed Hook', accounts, accounts.length); if (accounts.length > 0) { fn(accounts); } else { console.log('OPWallet Account Changed Hook --> Disconnect', accounts.length, !!this.disconnectHookWrapper); this._isConnected = false; this.disconnectHookWrapper?.(); } }; this.walletBase.on('accountsChanged', this.accountsChangedHookWrapper); } removeAccountsChangedHook() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } if (this.accountsChangedHookWrapper) { console.log('Removing account changed hook for OPWallet'); this.walletBase.removeListener('accountsChanged', this.accountsChangedHookWrapper); this.accountsChangedHookWrapper = undefined; } } setDisconnectHook(fn) { console.log('Setting disconnect hook for OPWallet'); if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } this.disconnectHookWrapper = () => { console.log('OPWallet Disconnecting Hook'); fn(); }; this.walletBase.on('disconnect', this.disconnectHookWrapper); } removeDisconnectHook() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } if (this.disconnectHookWrapper) { console.log('Removing disconnect hook for OPWallet'); this.walletBase.removeListener('disconnect', this.disconnectHookWrapper); this.disconnectHookWrapper = undefined; } } setChainChangedHook(fn) { console.log('Setting chain changed hook for OPWallet'); if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } this.chainChangedHookWrapper = (chainInfo) => { console.log('OPWallet ChainChanged Hook', chainInfo); fn(chainInfo.enum); }; this.walletBase.on('chainChanged', this.chainChangedHookWrapper); } removeChainChangedHook() { if (!this.isInstalled() || !this.walletBase) { throw new Error(notInstalledError); } if (this.chainChangedHookWrapper) { console.log('Removing chain changed hook for OPWallet'); this.walletBase.removeListener('chainChanged', this.chainChangedHookWrapper); this.chainChangedHookWrapper = undefined; } } async getMLDSAPublicKey() { if (!this._isConnected || !this.walletBase?.web3) return null; return this.walletBase.web3.getMLDSAPublicKey(); } async getHashedMLDSAKey() { const mldsaPublicKey = await this.getMLDSAPublicKey(); if (!mldsaPublicKey) return null; const publicKeyBytes = fromHex(mldsaPublicKey); const hash = sha256(publicKeyBytes); return toHex(hash); } async signMLDSAMessage(message) { if (!this._isConnected || !this.walletBase?.web3) return null; return this.walletBase.web3.signMLDSAMessage(message); } async verifyMLDSASignature(message, signature) { if (!this._isConnected || !this.walletBase?.web3) return false; return this.walletBase.web3.verifyMLDSASignature(message, signature); } } export default OPWallet;