Specification
Required APIs with Examples and Common Error Codes (Using OKX as Example)
Window Global Variable Name
// Get OKX wallet instance
const okx = (window as any).okxwallet;
// Get wallet API for different networks
const getWalletApi = (network: "livenet" | "testnet") => {
const networkAttr = {
livenet: "bitcoin",
testnet: "bitcoinTestnet",
};
return okx[networkAttr[network]];
};
Connect Wallet Method
interface ConnectParams {
network: "livenet" | "testnet";
chain?: "BITCOIN_MAINNET" | "BITCOIN_TESTNET" | "BITCOIN_TESTNET4" | "FRACTAL_BITCOIN_MAINNET" | "FRACTAL_BITCOIN_TESTNET";
handleMismatchChain?: boolean;
}
interface ConnectResult {
name: "okx";
network: "livenet" | "testnet";
publicKey: string;
accounts: string[];
address: string;
btcAddress: string;
btcPublicKey: string;
balance?: {
confirmed?: number;
total?: number;
unconfirmed?: number;
};
chain?: string;
}
// Connect wallet
const connect = async (params: ConnectParams): Promise<ConnectResult> => {
const { network, chain, handleMismatchChain } = params;
const okx = getWalletApi(network);
try {
const info = await okx.connect();
const { publicKey, address, compressedPublicKey } = info;
let balance;
if (network === "livenet") {
balance = await okx.getBalance();
}
return {
name: "okx",
network,
publicKey,
accounts: [address],
address,
btcAddress: address,
btcPublicKey: compressedPublicKey,
balance,
chain,
};
} catch (error) {
throw {
code: error.code || 1,
msg: error.msg || error.message || "Connection failed",
success: false,
};
}
};
Disconnect Wallet Method
interface DisconnectParams {
network: "livenet" | "testnet";
chain?: string;
handleMismatchChain?: boolean;
}
const disconnect = async (params: DisconnectParams): Promise<void> => {
const { network, chain, handleMismatchChain } = params;
const okx = getWalletApi(network);
try {
await okx.disconnect();
} catch (error) {
throw {
code: error.code || 1,
msg: error.msg || error.message || "Disconnect failed",
success: false,
};
}
};
Sign Method
interface SignParams {
network: "livenet" | "testnet";
msg: string;
type?: string;
chain?: string;
handleMismatchChain?: boolean;
}
const sign = async (params: SignParams): Promise<string> => {
const { network, msg, type, chain, handleMismatchChain } = params;
const okx = getWalletApi(network);
try {
return await okx.signMessage(msg, type);
} catch (error) {
throw {
code: error.code || 1,
msg: error.msg || error.message || "Signing failed",
success: false,
};
}
};
Sign PSBT Method
interface SignPsbtParams {
psbt: string; // PSBT string in base64 or hex format
option?: {
autoFinalized: boolean;
toSignInputs?: {
index: number;
address: string;
publicKey: string;
sighashTypes: number[];
disableTweakSigner: boolean;
}[];
};
network: "livenet" | "testnet";
data: ConnectResult; // Wallet information
chain?: string;
handleMismatchChain?: boolean;
}
const signPsbt = async (params: SignPsbtParams): Promise<string> => {
const { psbt, option, network, data, chain, handleMismatchChain } = params;
const okx = getWalletApi(network);
try {
// Convert to hex format
let handlePsbt = psbt;
if (!/^[0-9a-fA-F]+$/.test(psbt)) {
handlePsbt = Psbt.fromBase64(psbt).toHex();
}
const res = await okx.signPsbt(handlePsbt, {
...option,
autoFinalized: false,
});
return res;
} catch (error) {
throw {
code: error.code || 1,
msg: error.msg || error.message || "PSBT signing failed",
success: false,
};
}
};
Send BTC Method
interface SendBitcoinParams {
from: string; // Sender address
address: string; // Recipient address
satoshis: number; // Amount to send (in satoshis)
option?: {
feeRate: number; // Fee rate
};
network: "livenet" | "testnet";
chain?: string;
handleMismatchChain?: boolean;
}
const sendBitcoin = async (params: SendBitcoinParams): Promise<string> => {
const { from, address, satoshis, option, network, chain, handleMismatchChain } = params;
const okx = getWalletApi(network);
try {
const sendOption: any = {
from,
to: address,
value: (satoshis / 100000000).toFixed(8), // Convert to BTC
};
if (option && option.feeRate) {
sendOption.fee = option.feeRate;
sendOption.satBytes = option.feeRate;
}
const res = await okx.send(sendOption);
return res.txhash;
} catch (error) {
throw {
code: error.code || 1,
msg: error.msg || error.message || "Send BTC failed",
success: false,
};
}
};
Sign PSBTs Method
interface SignPsbtsParams {
psbt: string[]; // Array of PSBT strings
option?: Array<{
autoFinalized: boolean;
toSignInputs?: {
index: number;
address: string;
publicKey: string;
sighashTypes: number[];
disableTweakSigner: boolean;
}[];
}>;
network: "livenet" | "testnet";
chain?: string;
handleMismatchChain?: boolean;
}
const signPsbts = async (params: SignPsbtsParams): Promise<string[]> => {
const { psbt, option = [], network, chain, handleMismatchChain } = params;
const okx = getWalletApi(network);
try {
const handleOptions = option.length === 0
? psbt.map(() => ({ autoFinalized: false }))
: option.map((item) => ({ ...item, autoFinalized: false }));
const res = await okx.signPsbts(psbt, handleOptions);
return res;
} catch (error) {
throw {
code: error.code || 1,
msg: error.msg || error.message || "Batch PSBT signing failed",
success: false,
};
}
};
Account Switch Monitoring Event
interface WalletInfo {
name: "okx";
network: "livenet" | "testnet";
publicKey: string;
accounts: string[];
address: string;
btcAddress: string;
btcPublicKey: string;
balance?: {
confirmed?: number;
total?: number;
unconfirmed?: number;
};
}
const openMonitorOkx = (
network: "livenet" | "testnet",
callback?: (data: WalletInfo) => void,
) => {
const okx = getWalletApi(network);
okx.on("accountsChanged", async (accounts: string[]) => {
if (accounts && accounts.length > 0) {
try {
const info = await okx.connect();
const { publicKey, address, compressedPublicKey } = info;
let balance;
if (network === "livenet") {
balance = await okx.getBalance();
}
callback?.({
name: "okx",
network,
publicKey,
accounts: [address],
address,
btcAddress: address,
btcPublicKey: compressedPublicKey,
balance,
});
} catch (error) {
console.error("Account switch monitoring failed:", error);
}
}
});
};
Last updated
Was this helpful?