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