@bigmi/client
Version:
Reactive primitives for Bitcoin apps.
118 lines (117 loc) • 4.83 kB
JavaScript
import { ConnectorChainIdDetectionError } from "../errors/connectors.js";
import { createConnector } from "../factories/createConnector.js";
import { MethodNotSupportedRpcError, ProviderNotFoundError, UserRejectedRequestError, getAddressChainId, getAddressInfo } from "@bigmi/core";
//#region src/connectors/okx.ts
function okx(parameters = {}) {
const { chainId, shimDisconnect = true } = parameters;
let accountsChanged;
return createConnector((config) => ({
id: "com.okex.wallet.bitcoin",
name: "OKX Wallet",
type: okx.type,
icon: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMiIgaGVpZ2h0PSIzMiIgZmlsbD0ibm9uZSI+CiAgICA8cGF0aCBmaWxsPSIjMDAwIiBkPSJNMCAwaDMydjMySDB6Ii8+CiAgICA8cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTIuNiA3SDcuNGEuNC40IDAgMCAwLS40LjR2NS4yYzAgLjIyLjE3OS40LjQuNGg1LjJhLjQuNCAwIDAgMCAuNC0uNFY3LjRhLjQuNCAwIDAgMC0uNC0uNE0xOC42MDIgMTMuMDAyaC01LjJhLjQuNCAwIDAgMC0uNC40djUuMmMwIC4yMi4xNzkuNC40LjRoNS4yYS40LjQgMCAwIDAgLjQtLjR2LTUuMmEuNC40IDAgMCAwLS40LS40TTE5LjQgN2g1LjJhLjQuNCAwIDAgMSAuNC40djUuMmEuNC40IDAgMCAxLS40LjRoLTUuMmEuNC40IDAgMCAxLS40LS40VjcuNGEuNC40IDAgMCAxIC40LS40TTEyLjYgMTlINy40YS40LjQgMCAwIDAtLjQuNHY1LjJjMCAuMjIuMTc5LjQuNC40aDUuMmEuNC40IDAgMCAwIC40LS40di01LjJhLjQuNCAwIDAgMC0uNC0uNE0xOS40IDE5aDUuMmEuNC40IDAgMCAxIC40LjR2NS4yYS40LjQgMCAwIDEtLjQuNGgtNS4yYS40LjQgMCAwIDEtLjQtLjR2LTUuMmEuNC40IDAgMCAxIC40LS40Ii8+Cjwvc3ZnPgo=",
async setup() {},
async getInternalProvider() {
if (typeof window === "undefined") return;
if ("okxwallet" in window) {
const internalProvider = window.okxwallet?.bitcoin;
if (internalProvider?.isOkxWallet) return internalProvider;
}
},
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(method);
}
},
async connect() {
const provider = await this.getInternalProvider();
if (!provider) throw new ProviderNotFoundError();
try {
await provider.requestAccounts();
const chainId = await this.getChainId();
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: await this.getAccounts(),
chainId
};
} catch (error) {
await this.disconnect();
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 publicKey = await provider.getPublicKey();
const address = (await provider.getAccounts())[0];
const { type, purpose } = getAddressInfo(address);
return [{
address,
addressType: type,
publicKey,
purpose
}];
},
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 {
if (shimDisconnect) return Boolean(await config.storage?.getItem(`${this.id}.connected`));
return !!(await this.getAccounts()).length;
} catch {
return false;
}
},
async onAccountsChanged(addresses) {
if (addresses.length === 0) this.onDisconnect();
else {
if (!await this.getInternalProvider()) throw new ProviderNotFoundError();
const accounts = await this.getAccounts();
config.emitter.emit("change", { accounts });
}
},
onChainChanged(chainId) {
config.emitter.emit("change", { chainId });
},
async onDisconnect(_error) {
config.emitter.emit("disconnect");
}
}));
}
okx.type = "UTXO";
//#endregion
export { okx };
//# sourceMappingURL=okx.js.map