@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
JavaScript
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 };