UNPKG

@bigmi/client

Version:

Reactive primitives for Bitcoin apps.

148 lines (147 loc) 6.12 kB
import { ChainNotSupportedError } from "../errors/connectors.js"; import { createConnector } from "../factories/createConnector.js"; import { createBidirectionalMap } from "../utils/createBidirectionalMap.js"; import { ChainId, MethodNotSupportedRpcError, ProviderNotFoundError, UserRejectedRequestError, getAddressInfo } from "@bigmi/core"; //#region src/connectors/binance.ts function binance(parameters = {}) { const { forward: BinanceBitcoinNetworkChainIdMap, reverse: ReverseChainIdMap } = createBidirectionalMap([ ["livenet", ChainId.BITCOIN_MAINNET], ["testnet", ChainId.BITCOIN_TESTNET], ["signet", ChainId.BITCOIN_SIGNET] ]); const { shimDisconnect = true } = parameters; let accountsChanged; let chainChanged; return createConnector((config) => ({ id: "binance", name: "Binance", type: binance.type, icon: "data:image/svg+xml;base64,PHN2ZyB4bWxuczp4PSJuc19leHRlbmQ7IiB4bWxuczppPSJuc19haTsiIHhtbG5zOmdyYXBoPSJuc19ncmFwaHM7IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUwIDUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MCA1MDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPgogPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KICAuc3Qwe2ZpbGw6I0YwQjkwQjt9CiA8L3N0eWxlPgogPG1ldGFkYXRhPgogIDxzZncgeG1sbnM9Im5zX3NmdzsiPgogICA8c2xpY2VzPgogICA8L3NsaWNlcz4KICAgPHNsaWNlU291cmNlQm91bmRzIGJvdHRvbUxlZnRPcmlnaW49InRydWUiIGhlaWdodD0iNTAiIHdpZHRoPSI1MCIgeD0iMjQ5Ny45IiB5PSItNzEyLjIiPgogICA8L3NsaWNlU291cmNlQm91bmRzPgogIDwvc2Z3PgogPC9tZXRhZGF0YT4KIDxnPgogIDxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xMS4zLDI1bC01LjYsNS42TDAsMjVsNS43LTUuN0wxMS4zLDI1eiBNMjUsMTEuM2w5LjcsOS43bDUuNy01LjdMMjUsMEw5LjcsMTUuM2w1LjcsNS43TDI1LDExLjN6IE00NC4zLDE5LjMgICBMMzguNywyNWw1LjcsNS43TDUwLDI1TDQ0LjMsMTkuM3ogTTI1LDM4LjdMMTUuMywyOWwtNS43LDUuN0wyNSw1MGwxNS4zLTE1LjNMMzQuNywyOUwyNSwzOC43eiBNMjUsMzAuNmw1LjctNS43TDI1LDE5LjNMMTkuMywyNSAgIEwyNSwzMC42TDI1LDMwLjZ6Ij4KICA8L3BhdGg+CiA8L2c+Cjwvc3ZnPg==", async setup() {}, async getInternalProvider() { if (typeof window === "undefined") return; if ("binancew3w" in window) return window.binancew3w.bitcoin; if ("unisat" in window) { const anyWindow = window; if (anyWindow.unisat.isBinance) return anyWindow.unisat; } }, 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 toSignInputs = options.inputsToSign.flatMap(({ sigHash, address, signingIndexes }) => signingIndexes.map((index) => ({ index, address, sighashTypes: sigHash !== void 0 ? [sigHash] : void 0 }))); return await this.signPsbt(psbt, { toSignInputs, autoFinalized: options.finalize }); } default: throw new MethodNotSupportedRpcError(); } }, async connect() { const provider = await this.getInternalProvider(); if (!provider) throw new ProviderNotFoundError(); try { await provider.requestAccounts(); const accounts = await this.getAccounts(); const chainId = await this.getChainId(); if (!accountsChanged) { accountsChanged = this.onAccountsChanged.bind(this); provider.addListener("accountsChanged", accountsChanged); } if (!chainChanged) { chainChanged = (network) => this.onChainChanged(BinanceBitcoinNetworkChainIdMap[network]); provider.addListener("networkChanged", chainChanged); } 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 = await this.getInternalProvider(); if (accountsChanged) { provider?.removeListener("accountsChanged", accountsChanged); accountsChanged = void 0; } if (chainChanged) { provider?.removeListener("networkChanged", chainChanged); chainChanged = 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 address = (await provider.getAccounts())[0]; const publicKey = await provider.getPublicKey(); const { type, purpose } = getAddressInfo(address); return [{ address, addressType: type, publicKey, purpose }]; }, async getChainId() { const provider = await this.getInternalProvider(); if (!provider) throw new ProviderNotFoundError(); return BinanceBitcoinNetworkChainIdMap[await provider.getNetwork()]; }, async isAuthorized() { try { if (shimDisconnect && await config.storage?.getItem(`${this.id}.disconnected`)) return false; return !!(await this.getAccounts()).length; } catch { return false; } }, async switchChain({ chainId }) { try { const provider = await this.getInternalProvider(); if (!provider) throw new ProviderNotFoundError(); const network = ReverseChainIdMap[chainId]; if (!network) throw new ChainNotSupportedError(chainId, binance.name); const result = await provider.switchNetwork(network); return Boolean(result); } catch { return false; } }, async onAccountsChanged(accounts) { if (accounts.length === 0) this.onDisconnect(); else { const newAccounts = await this.getAccounts(); config.emitter.emit("change", { accounts: newAccounts }); } }, async onChainChanged(chainId) { const accounts = await this.getAccounts(); config.emitter.emit("change", { chainId, accounts }); }, async onDisconnect(_error) { config.emitter.emit("disconnect"); } })); } binance.type = "UTXO"; //#endregion export { binance }; //# sourceMappingURL=binance.js.map