From 3b92fc282c600ba0cbd0f6deeca83015dcd6a9e4 Mon Sep 17 00:00:00 2001 From: ByteZhang Date: Wed, 4 Mar 2026 22:34:17 +0800 Subject: [PATCH] feat(btc-provider): add disconnect, getBalanceV2, getBitcoinUtxos and sendBitcoin memo support Add missing UniSat-compatible APIs: disconnect(), getBalanceV2() for available/unavailable balance, getBitcoinUtxos() for UTXO pagination, and memo/memos options for sendBitcoin OP_RETURN data. Includes corresponding example dApp test entries. --- packages/core/src/versionInfo.ts | 2 +- .../example/components/chains/btc/example.tsx | 34 +++++++++++++++++-- .../example/components/chains/btc/params.ts | 26 ++++++++++++++ .../example/components/chains/btc/types.ts | 11 +++++- .../onekey-btc-provider/src/ProviderBtc.ts | 34 ++++++++++++++++++- .../onekey-btc-provider/src/types.ts | 12 +++++-- 6 files changed, 112 insertions(+), 7 deletions(-) diff --git a/packages/core/src/versionInfo.ts b/packages/core/src/versionInfo.ts index 7c4bcab6a..b76318c1d 100644 --- a/packages/core/src/versionInfo.ts +++ b/packages/core/src/versionInfo.ts @@ -1,5 +1,5 @@ -const version = '2.2.61'; +const version = '2.2.62'; const versionBuild = '2020-0101-1'; export default { diff --git a/packages/example/components/chains/btc/example.tsx b/packages/example/components/chains/btc/example.tsx index da3125cad..c74956fdf 100644 --- a/packages/example/components/chains/btc/example.tsx +++ b/packages/example/components/chains/btc/example.tsx @@ -121,6 +121,16 @@ export default function BTCExample() { }} /> + { + await provider?.disconnect(); + return 'disconnected'; + }} + /> + + { + const res = await provider?.getBalanceV2(); + return JSON.stringify(res); + }} + /> + { + const obj = JSON.parse(request) as { cursor?: number; size?: number }; + const res = await provider?.getBitcoinUtxos(obj.cursor, obj.size); + return JSON.stringify(res); + }} + /> + { - const obj = JSON.parse(request) as { toAddress: string; satoshis: number }; - const res = await provider?.sendBitcoin(obj.toAddress, obj.satoshis); + const obj = JSON.parse(request) as { toAddress: string; satoshis: number; options?: { feeRate?: number; memo?: string; memos?: string[] } }; + const res = await provider?.sendBitcoin(obj.toAddress, obj.satoshis, obj.options); return JSON.stringify(res); }} /> diff --git a/packages/example/components/chains/btc/params.ts b/packages/example/components/chains/btc/params.ts index 8491c2a3d..96b03aab9 100644 --- a/packages/example/components/chains/btc/params.ts +++ b/packages/example/components/chains/btc/params.ts @@ -43,6 +43,21 @@ export default { value: 'FRACTAL_BITCOIN_TESTNET', }, ], + getBitcoinUtxos: [ + { + id: 'getBitcoinUtxos-no-params', + name: 'getBitcoinUtxos (no params)', + value: JSON.stringify({}), + }, + { + id: 'getBitcoinUtxos', + name: 'getBitcoinUtxos (first 20)', + value: JSON.stringify({ + cursor: 0, + size: 20, + }), + }, + ], signMessage: [ { id: 'signMessage ecdsa default', @@ -77,6 +92,17 @@ export default { satoshis: 1000, }), }, + { + id: 'sendBitcoin-with-memo', + name: 'SendBitcoin with memo', + value: JSON.stringify({ + toAddress: address, + satoshis: 1000, + options: { + memo: 'Hello OneKey', + }, + }), + }, ], pushTx: [ { diff --git a/packages/example/components/chains/btc/types.ts b/packages/example/components/chains/btc/types.ts index 9190237ad..f76eb8741 100644 --- a/packages/example/components/chains/btc/types.ts +++ b/packages/example/components/chains/btc/types.ts @@ -3,6 +3,7 @@ export interface IProviderApi { on(event: string, listener: (...args: any[]) => void): this; removeListener(event: string, listener: (...args: any[]) => void): this; requestAccounts(): Promise; + disconnect(): Promise; getAccounts(): Promise; getNetwork(): Promise; switchNetwork(network: string): Promise; @@ -14,12 +15,20 @@ export interface IProviderApi { unconfirmed: number; total: number; }>; + getBalanceV2(): Promise<{ + available: number; + unavailable: number; + total: number; + }>; + getBitcoinUtxos(cursor?: number, size?: number): Promise<{ txid: string; vout: number }[]>; signMessage(msg: string, type: string): Promise; sendBitcoin( toAddress: string, satoshis: number, options?: { - feeRate: number; + feeRate?: number; + memo?: string; + memos?: string[]; }, ): Promise; pushTx(options: { rawtx: string }): Promise; diff --git a/packages/providers/onekey-btc-provider/src/ProviderBtc.ts b/packages/providers/onekey-btc-provider/src/ProviderBtc.ts index 52f9c2b4c..e8d670c76 100644 --- a/packages/providers/onekey-btc-provider/src/ProviderBtc.ts +++ b/packages/providers/onekey-btc-provider/src/ProviderBtc.ts @@ -13,6 +13,8 @@ import { ProviderEventsMap, MessageType, BalanceInfo, + BalanceInfoV2, + BitcoinUtxo, InscriptionInfo, Chain, } from './types'; @@ -171,6 +173,12 @@ class ProviderBtc extends ProviderBtcBase implements IProviderBtc { }); } + async disconnect() { + return this._request({ + method: ProviderMethods.DISCONNECT, + }); + } + async getAccounts() { return this._request({ method: ProviderMethods.GET_ACCOUNTS, @@ -221,6 +229,22 @@ class ProviderBtc extends ProviderBtcBase implements IProviderBtc { }); } + async getBalanceV2() { + return this._request({ + method: ProviderMethods.GET_BALANCE_V2, + }); + } + + async getBitcoinUtxos(cursor: number | undefined, size: number | undefined) { + return this._request({ + method: ProviderMethods.GET_BITCOIN_UTXOS, + params: { + cursor, + size, + }, + }); + } + async getInscriptions(cursor = 0, size = 20) { return this._request<{ total: number; @@ -234,13 +258,19 @@ class ProviderBtc extends ProviderBtcBase implements IProviderBtc { }); } - async sendBitcoin(toAddress: string, satoshis: number, options?: { feeRate: number }) { + async sendBitcoin( + toAddress: string, + satoshis: number, + options?: { feeRate?: number; memo?: string; memos?: string[] }, + ) { return this._request({ method: ProviderMethods.SEND_BITCOIN, params: { toAddress, satoshis, feeRate: options?.feeRate, + memo: options?.memo, + memos: options?.memos, }, }); } @@ -344,5 +374,7 @@ export { ProviderEventsMap, MessageType, BalanceInfo, + BalanceInfoV2, + BitcoinUtxo, InscriptionInfo, }; diff --git a/packages/providers/onekey-btc-provider/src/types.ts b/packages/providers/onekey-btc-provider/src/types.ts index a2d00ce21..47f0452e6 100644 --- a/packages/providers/onekey-btc-provider/src/types.ts +++ b/packages/providers/onekey-btc-provider/src/types.ts @@ -6,6 +6,8 @@ import { ProviderBtcBase } from './ProviderBtcBase'; export type MessageType = 'ecdsa' | 'bip322-simple'; export type NetworkType = 'livenet' | 'testnet'; export type BalanceInfo = { 'confirmed': number; 'unconfirmed': number; 'total': number }; +export type BalanceInfoV2 = { 'available': number; 'unavailable': number; 'total': number }; +export type BitcoinUtxo = { 'txid': string; 'vout': number }; export type InscriptionInfo = { inscriptionId: string; inscriptionNumber: number; @@ -37,7 +39,7 @@ export enum ProviderEvents { CLOSE = 'close', ACCOUNTS_CHANGED = 'accountsChanged', ACCOUNT_CHANGED = 'accountChanged', - NETWORK_CHANGED = 'networkChanged', + NETWORK_CHANGED = 'chainChanged', MESSAGE_LOW_LEVEL = 'message_low_level', } @@ -59,6 +61,9 @@ export enum ProviderMethods { SIGN_PSBTS = 'signPsbts', PUSH_PSBT = 'pushPsbt', GET_PROVIDER_STATE = 'getProviderState', + DISCONNECT = 'disconnect', + GET_BALANCE_V2 = 'getBalanceV2', + GET_BITCOIN_UTXOS = 'getBitcoinUtxos', INSCRIBE_TRANSFER = 'inscribeTransfer', /** @@ -123,6 +128,7 @@ export interface IProviderBtc extends ProviderBtcBase { readonly isOneKey: boolean; requestAccounts(): Promise; + disconnect(): Promise; getAccounts(): Promise; getNetwork(): Promise; switchNetwork(network: NetworkType): Promise; @@ -130,6 +136,8 @@ export interface IProviderBtc extends ProviderBtcBase { switchChain(chain: string): Promise; getPublicKey(): Promise; getBalance(): Promise; + getBalanceV2(): Promise; + getBitcoinUtxos(cursor?: number, size?: number): Promise; getInscriptions( cursor?: number, size?: number, @@ -137,7 +145,7 @@ export interface IProviderBtc extends ProviderBtcBase { total: number; list: InscriptionInfo[]; }>; - sendBitcoin(toAddress: string, satoshis: number, options?: { feeRate: number }): Promise; + sendBitcoin(toAddress: string, satoshis: number, options?: { feeRate?: number; memo?: string; memos?: string[] }): Promise; sendInscription( toAddress: string, inscriptionId: string,