UNPKG

@bigmi/client

Version:

Reactive primitives for Bitcoin apps.

113 lines (112 loc) 5.5 kB
import { ConnectorChainIdDetectionError } from "../errors/connectors.js"; import { createConnector } from "../factories/createConnector.js"; import { BaseError, MethodNotSupportedRpcError, ProviderNotFoundError, UserRejectedRequestError, base64ToHex, getAddressChainId, hexToBase64 } from "@bigmi/core"; //#region src/connectors/ctrl.ts function ctrl(parameters = {}) { const { chainId, shimDisconnect = true } = parameters; let accountsChanged; return createConnector((config) => ({ id: "io.xdefi", name: "Ctrl Wallet", type: ctrl.type, icon: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTc1IiBoZWlnaHQ9IjE3NSIgdmlld0JveD0iMCAwIDE3NSAxNzUiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNzUiIGhlaWdodD0iMTc1IiByeD0iODcuNSIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTY3LjMzMyAxMTYuMzI1VjE0Mi4zMzdDNjcuMzMzIDE0Ni41NzYgNzAuNzY3MSAxNTAuMDAxIDc0Ljk5NTMgMTUwLjAwMUgxMDEuMDA0QzEwNS4yNDIgMTUwLjAwMSAxMDguNjY2IDE0Ni41NjYgMTA4LjY2NiAxNDIuMzM3VjEyOS4zMzFDMTA4LjY2NiAxMjMuNjE3IDExMC45NzYgMTE4LjQ1IDExNC43MiAxMTQuNzE2QzExOC40NjMgMTEwLjk3MiAxMjMuNjMgMTA4LjY2MiAxMjkuMzMzIDEwOC42NjJIMTQyLjMzN0MxNDYuNTc2IDEwOC42NjIgMTUwIDEwNS4yMjggMTUwIDEwMC45OTlWNzQuOTk3M0MxNTAgNzAuNzU4MiAxNDYuNTY2IDY3LjMzNCAxNDIuMzM3IDY3LjMzNEgxMTYuMzM5QzExMi4xIDY3LjMzNCAxMDguNjc3IDcwLjc2ODUgMTA4LjY3NyA3NC45OTczVjg4LjYzMjRDMTA4LjY3NyA5OS42OTkzIDk5LjcwNDYgMTA4LjY2MiA4OC42NDk0IDEwOC42NjJINzUuMDE2QzcwLjc3NzQgMTA4LjY2MiA2Ny4zNTM2IDExMi4wOTcgNjcuMzUzNiAxMTYuMzI1SDY3LjMzM1oiIGZpbGw9IiMwMDE0MDUiLz4KPHBhdGggZD0iTTI2IDc0Ljk5NTdWMTAxLjAwNEMyNiAxMDUuMjQzIDI5LjQzNDEgMTA4LjY2NyAzMy42NjIzIDEwOC42NjdINTkuNjcxQzYzLjkwOTUgMTA4LjY2NyA2Ny4zMzMzIDEwNS4yMzMgNjcuMzMzMyAxMDEuMDA0Vjg4QzY3LjMzMzMgODIuMjg2OCA2OS42NDM0IDc3LjEyMDEgNzMuMzg2OSA3My4zODY5Qzc3LjEzMDQgNjkuNjQzNCA4Mi4yOTcxIDY3LjMzMzMgODggNjcuMzMzM0gxMDEuMDA0QzEwNS4yNDMgNjcuMzMzMyAxMDguNjY3IDYzLjg5OTIgMTA4LjY2NyA1OS42NzFWMzMuNjYyM0MxMDguNjY3IDI5LjQyMzggMTA1LjIzMyAyNiAxMDEuMDA0IDI2SDc1LjAwNkM3MC43Njc1IDI2IDY3LjM0MzYgMjkuNDM0MSA2Ny4zNDM2IDMzLjY2MjNWNDcuMjk1N0M2Ny4zNDM2IDU4LjM2MTMgNTguMzcxNiA2Ny4zMjMgNDcuMzE2NCA2Ny4zMjNIMzMuNjYyM0MyOS40MjM4IDY3LjMyMyAyNiA3MC43NTcyIDI2IDc0Ljk4NTRWNzQuOTk1N1oiIGZpbGw9IiMwMDE0MDUiLz4KPC9zdmc+Cg==", async setup() {}, async getInternalProvider() { if (typeof window === "undefined") return; if ("xfi" in window) return window.xfi?.bitcoin; }, async getProvider() { const internalProvider = await this.getInternalProvider(); if (!internalProvider) return; return { request: this.request.bind(internalProvider) }; }, async request({ method, params }) { switch (method) { case "signPsbt": { const { psbt, ...options } = params; const psbt64 = hexToBase64(psbt); const response = await this.signPsbt({ psbt: psbt64, broadcast: Boolean(options.finalize) }); if (response.status === "success") return base64ToHex(response.result.psbt); throw new BaseError(response.error); } default: throw new MethodNotSupportedRpcError(method); } }, async connect() { const provider = await this.getInternalProvider(); if (!provider) throw new ProviderNotFoundError(); try { const accounts = await this.getAccounts(); const chainId = getAddressChainId(accounts[0].address); if (!accountsChanged) { accountsChanged = this.onAccountsChanged.bind(this); provider.addListener("accountsChanged", accountsChanged); } if (shimDisconnect) await Promise.all([config.storage?.setItem(`${this.id}.connected`, true), config.storage?.removeItem(`${this.id}.disconnected`)]); return { accounts, chainId }; } catch (error) { console.error({ error }); throw new UserRejectedRequestError(error.message); } }, async disconnect() { const provider = await this.getInternalProvider(); if (accountsChanged) { provider?.removeListener("accountsChanged", accountsChanged); accountsChanged = void 0; } if (shimDisconnect) await Promise.all([config.storage?.setItem(`${this.id}.disconnected`, true), config.storage?.removeItem(`${this.id}.connected`)]); }, async getAccounts() { const provider = await this.getInternalProvider(); if (!provider) throw new ProviderNotFoundError(); const { status, result } = await provider.request({ method: "request_accounts_and_keys", params: { purposes: ["payment"] } }); if (status === "success") return result.map((account) => ({ address: account.address, addressType: account.addressType.toLowerCase(), publicKey: account.publicKey, purpose: account.purpose })); throw new BaseError("Error getting accounts"); }, async getChainId() { if (chainId) return chainId; const accounts = await this.getAccounts(); if (accounts.length === 0) throw new ConnectorChainIdDetectionError({ connector: this.name }); return getAddressChainId(accounts[0].address); }, async isAuthorized() { try { return shimDisconnect && Boolean(await config.storage?.getItem(`${this.id}.connected`)); } catch { return false; } }, async onAccountsChanged(accounts) { if (accounts.length === 0) this.onDisconnect(); else { const newAccounts = await this.getAccounts(); config.emitter.emit("change", { accounts: newAccounts }); } }, onChainChanged(chainId) { config.emitter.emit("change", { chainId }); }, async onDisconnect(_error) { config.emitter.emit("disconnect"); } })); } ctrl.type = "UTXO"; //#endregion export { ctrl }; //# sourceMappingURL=ctrl.js.map