UNPKG

@bigmi/client

Version:

Reactive primitives for Bitcoin apps.

130 lines 5.28 kB
import { base64ToHex, hexToBase64 } from '@bigmi/core'; import { MethodNotSupportedRpcError, UserRejectedRequestError, } from '@bigmi/core'; import { ProviderNotFoundError } from '../errors/connectors.js'; import { createConnector } from '../factories/createConnector.js'; dynamic.type = 'UTXO'; export function dynamic(parameters) { const { chainId, shimDisconnect = true, wallet } = parameters; let accountChanged; return createConnector((config) => ({ id: wallet.connector.providerId, name: wallet.connector.name, type: dynamic.type, icon: wallet.connector._metadata?.icon, emitter: config.emitter, async isAuthorized() { return wallet.isAuthenticated; }, async request({ method, params }) { switch (method) { case 'signPsbt': { try { const { psbt, ...options } = params; const allowedSighash = options.inputsToSign.map((input) => Number(input.sigHash)); const psbtBase64 = hexToBase64(psbt); const response = await wallet.signPsbt({ allowedSighash, unsignedPsbtBase64: psbtBase64, signature: options.inputsToSign, }); if (!response) { throw new Error('Error signing the transaction'); } const { signedPsbt } = response; const signedPsbtHex = base64ToHex(signedPsbt); return signedPsbtHex; } catch (error) { throw new UserRejectedRequestError(error.message); } } default: throw new MethodNotSupportedRpcError(); } }, async setup() { // }, async getProvider() { const internalProvider = await this.getInternalProvider(); if (!internalProvider) { throw new ProviderNotFoundError(); } const provider = { request: this.request.bind(internalProvider), }; return provider; }, async connect() { if (!wallet.connector) { throw new Error('DynamicWalletConnector not defined'); } try { const accounts = await this.getAccounts(); const chainId = await this.getChainId(); if (!accountChanged) { accountChanged = this.onAccountsChanged.bind(this); wallet.connector.addListener('accountChange', ({ accounts }) => accountChanged?.(accounts)); } // Remove disconnected shim if it exists if (shimDisconnect) { await Promise.all([ config.storage?.setItem(`${this.id}.connected`, true), config.storage?.removeItem(`${this.id}.disconnected`), ]); } return { accounts, chainId }; } catch (error) { throw new UserRejectedRequestError(error.message); } }, async disconnect() { const provider = wallet.connector; if (accountChanged) { provider.removeListener('accountChange', ({ accounts }) => accountChanged?.(accounts)); accountChanged = undefined; } if (shimDisconnect) { await Promise.all([ config.storage?.setItem(`${this.id}.disconnected`, true), config.storage?.removeItem(`${this.id}.connected`), ]); } }, async getAccounts() { const paymentAdress = wallet.additionalAddresses.find((wallet) => wallet.type === 'payment'); if (!paymentAdress) { throw new Error('Please connect a wallet with a segwit address'); } return [paymentAdress.address]; }, async getChainId() { return chainId; }, async getInternalProvider() { return wallet.connector; }, async onAccountsChanged(accounts) { if (accounts.length === 0) { this.onDisconnect(); } else { config.emitter.emit('change', { accounts: accounts, }); } }, onChainChanged(chain) { const chainId = Number(chain); config.emitter.emit('change', { chainId }); }, async onDisconnect(_error) { // No need to remove `${this.id}.disconnected` from storage because `onDisconnect` is typically // only called when the wallet is disconnected through the wallet's interface, meaning the wallet // actually disconnected and we don't need to simulate it. config.emitter.emit('disconnect'); }, })); } //# sourceMappingURL=dynamic.js.map