@omnity/ree-client-ts-sdk 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ree-sdk.cjs.js → index.cjs.js} +23 -23
- package/dist/{ree-sdk.es.js → index.es.js} +415 -415
- package/dist/react.cjs.js +1 -0
- package/dist/react.d.ts +691 -0
- package/dist/react.es.js +322 -0
- package/package.json +15 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("react/jsx-runtime"),e=require("react"),g=require("./index.cjs.js"),E=e.createContext(null);function w({children:t,config:s}){if(!s)throw new Error("ReeProvider: config is required");if(!s.network)throw new Error("ReeProvider: config.network is required");if(!s.maestroApiKey)throw new Error("ReeProvider: config.maestroApiKey is required");if(!s.exchangeIdlFactory)throw new Error("ReeProvider: config.exchangeIdlFactory is required");if(!s.exchangeCanisterId)throw new Error("ReeProvider: config.exchangeCanisterId is required");const[r,c]=e.useState({address:"",paymentAddress:"",publicKey:"",paymentPublicKey:""}),a=e.useCallback(u=>{c(f=>({...f,...u}))},[]),n=e.useMemo(()=>new g.ReeClient(s),[s]),d=e.useCallback(async u=>{if(!n)throw new Error("Client not available");if(!r.address||!r.paymentAddress)throw new Error("Wallet not connected");return n.createTransaction({address:r.address,paymentAddress:r.paymentAddress,feeRate:u?.feeRate,mergeSelfRuneBtcOutputs:u?.mergeSelfRuneBtcOutputs})},[n,r]),o=e.useMemo(()=>({client:n,...r,exchange:n.exchange,updateWallet:a,createTransaction:d}),[n,r,a,d]);return m.jsx(E.Provider,{value:o,children:t})}function y(){const t=e.useContext(E);if(!t)throw new Error("useRee must be used within ReeProvider");return t}function v(t={}){const{refreshInterval:s=0,autoRefresh:r=!0}=t,{client:c,paymentAddress:a}=y(),[n,d]=e.useState(null),[o,u]=e.useState(!1),[f,h]=e.useState(null),l=e.useCallback(async()=>{if(!a){d(null),h("Payment address not set");return}u(!0),h(null);try{const i=await c.getBtcBalance(a);d(i)}catch(i){h(i instanceof Error?i.message:"Failed to fetch BTC balance"),d(null)}finally{u(!1)}},[c,a]);return e.useEffect(()=>{r&&l()},[a,l,r]),e.useEffect(()=>{if(s>0){const i=setInterval(l,s);return()=>clearInterval(i)}},[s,a,l]),{balance:n,loading:o,error:f,refetch:l}}function S(t,s={}){const{refreshInterval:r=0,autoRefresh:c=!0}=s,{client:a,address:n}=y(),[d,o]=e.useState(null),[u,f]=e.useState(!1),[h,l]=e.useState(null),i=e.useCallback(async()=>{if(!n){o(null),l("Address not set");return}if(!t){o(null),l("Rune ID is required");return}f(!0),l(null);try{const R=await a.getRuneBalance(n,t);o(R??null)}catch(R){l(R instanceof Error?R.message:"Failed to fetch rune balance"),o(null)}finally{f(!1)}},[a,n,t]);return e.useEffect(()=>{c&&t&&i()},[n,t,i,c]),e.useEffect(()=>{if(r>0&&t){const R=setInterval(i,r);return()=>clearInterval(R)}},[r,n,t,i]),{balance:d,loading:u,error:h,refetch:i}}function x(t={}){const{refreshInterval:s=0,autoRefresh:r=!0}=t,{client:c,paymentAddress:a}=y(),[n,d]=e.useState([]),[o,u]=e.useState(!1),[f,h]=e.useState(null),l=e.useCallback(async()=>{if(!a){d([]),h("Payment address not set");return}u(!0),h(null);try{const i=await c.getBtcUtxos(a);d(i)}catch(i){h(i instanceof Error?i.message:"Failed to fetch BTC UTXOs"),d([])}finally{u(!1)}},[c,a]);return e.useEffect(()=>{r&&a&&l()},[a,l,r]),e.useEffect(()=>{if(s>0&&a){const i=setInterval(l,s);return()=>clearInterval(i)}},[s,a,l]),{utxos:n,loading:o,error:f,refetch:l}}function P(t,s={}){const{refreshInterval:r=0,autoRefresh:c=!0}=s,{client:a,address:n}=y(),[d,o]=e.useState([]),[u,f]=e.useState(!1),[h,l]=e.useState(null),i=e.useCallback(async()=>{if(!n){o([]),l("Address not set");return}if(!t){o([]),l("Rune ID is required");return}f(!0),l(null);try{const R=await a.getRuneUtxos(n,t);o(R)}catch(R){l(R instanceof Error?R.message:"Failed to fetch rune UTXOs"),o([])}finally{f(!1)}},[a,n,t]);return e.useEffect(()=>{c&&n&&t&&i()},[n,t,i,c]),e.useEffect(()=>{if(r>0&&n&&t){const R=setInterval(i,r);return()=>clearInterval(R)}},[r,n,t,i]),{utxos:d,loading:u,error:h,refetch:i}}function b(){const{client:t}=y();return e.useCallback(async r=>{const c=r;if(!c)throw new Error("Search keyword is required");return await t.searchRunes(c)},[t])}function B(t){const{client:s}=y(),[r,c]=e.useState(null),[a,n]=e.useState(!1),[d,o]=e.useState(null),u=e.useCallback(async()=>{if(!t){c(null),o("Rune ID is required");return}n(!0),o(null);try{const f=await s.getRuneInfo(t);c(f||null)}catch(f){o(f instanceof Error?f.message:"Failed to fetch rune info"),c(null)}finally{n(!1)}},[s,t]);return{runeInfo:r,loading:a,error:d,refetch:u}}function C(){const{client:t}=y(),[s,r]=e.useState([]),[c,a]=e.useState(!1),[n,d]=e.useState(null),o=e.useCallback(async()=>{a(!0),d(null);try{const u=await t.getPoolList();r(u)}catch(u){d(u instanceof Error?u.message:"Failed to fetch pool list"),r([])}finally{a(!1)}},[t]);return e.useEffect(()=>{o()},[o]),{pools:s,loading:c,error:n,refetch:o}}function I(t){const{client:s}=y(),[r,c]=e.useState(null),[a,n]=e.useState(!1),[d,o]=e.useState(null),u=e.useCallback(async()=>{if(!t){c(null),o("Pool address is required");return}n(!0),o(null);try{const f=await s.getPoolInfo(t);c(f)}catch(f){o(f instanceof Error?f.message:"Failed to fetch pool info"),c(null)}finally{n(!1)}},[s,t]);return e.useEffect(()=>{u()},[t]),{poolInfo:r,loading:a,error:d,refetch:u}}function k(t={}){const{refreshInterval:s=0,autoRefresh:r=!0}=t,{client:c}=y(),[a,n]=e.useState(null),[d,o]=e.useState(!1),[u,f]=e.useState(null),h=e.useCallback(async()=>{o(!0),f(null);try{const l=await c.getRecommendedFeeRate();n(l)}catch(l){f(l instanceof Error?l.message:"Failed to fetch recommended fee rate"),n(null)}finally{o(!1)}},[c]);return e.useEffect(()=>{r&&h()},[r,h]),e.useEffect(()=>{if(s>0){const l=setInterval(h,s);return()=>clearInterval(l)}},[s,h]),{feeRate:a,loading:d,error:u,refetch:h}}exports.Network=g.Network;exports.utils=g.utils;exports.ReeProvider=w;exports.useBtcBalance=v;exports.useBtcUtxos=x;exports.usePoolInfo=I;exports.usePoolList=C;exports.useRecommendedFeeRate=k;exports.useRee=y;exports.useRuneBalance=S;exports.useRuneInfo=B;exports.useRuneUtxos=P;exports.useSearchRunes=b;
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
import { ActorSubclass } from '@dfinity/agent';
|
|
2
|
+
import * as bitcoin from 'bitcoinjs-lib';
|
|
3
|
+
import { IDL } from '@dfinity/candid';
|
|
4
|
+
import { JSX as JSX_2 } from 'react/jsx-runtime';
|
|
5
|
+
import { ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
export declare const AddressType: {
|
|
8
|
+
P2PKH: {
|
|
9
|
+
P2PKH: null;
|
|
10
|
+
};
|
|
11
|
+
P2SH_P2WPKH: {
|
|
12
|
+
P2SH_P2WPKH: null;
|
|
13
|
+
};
|
|
14
|
+
P2WPKH: {
|
|
15
|
+
P2WPKH: null;
|
|
16
|
+
};
|
|
17
|
+
P2WSH: {
|
|
18
|
+
P2WSH: null;
|
|
19
|
+
};
|
|
20
|
+
P2SH: {
|
|
21
|
+
P2SH: null;
|
|
22
|
+
};
|
|
23
|
+
P2TR: {
|
|
24
|
+
P2TR: null;
|
|
25
|
+
};
|
|
26
|
+
UNKNOWN: {
|
|
27
|
+
UNKNOWN: null;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export declare type AddressType = (typeof AddressType)[keyof typeof AddressType] | {
|
|
32
|
+
OpReturn: bigint;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
declare function bytesToHex(bytes: Uint8Array): string;
|
|
36
|
+
|
|
37
|
+
declare type CoinBalance = {
|
|
38
|
+
id: string;
|
|
39
|
+
value: bigint;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export declare type Config = {
|
|
43
|
+
network: Network;
|
|
44
|
+
maestroApiKey: string;
|
|
45
|
+
exchangeIdlFactory: IDL.InterfaceFactory;
|
|
46
|
+
exchangeId: string;
|
|
47
|
+
exchangeCanisterId: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
declare function formatPoolUtxo(poolAddress: string, input: {
|
|
51
|
+
coins: [{
|
|
52
|
+
id: string;
|
|
53
|
+
value: bigint;
|
|
54
|
+
}];
|
|
55
|
+
sats: bigint;
|
|
56
|
+
txid: string;
|
|
57
|
+
vout: number;
|
|
58
|
+
}, network: Network): Utxo;
|
|
59
|
+
|
|
60
|
+
declare function getAddressType(address: string): AddressType;
|
|
61
|
+
|
|
62
|
+
declare function getScriptByAddress(address: string, network?: Network): Uint8Array<ArrayBufferLike>;
|
|
63
|
+
|
|
64
|
+
declare function getUtxoProof(utxos: Utxo[], network: Network): Promise<number[] | null>;
|
|
65
|
+
|
|
66
|
+
declare function hexToBytes(hex: string): Uint8Array;
|
|
67
|
+
|
|
68
|
+
declare type InputCoin = {
|
|
69
|
+
coin: CoinBalance;
|
|
70
|
+
from: string;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
declare type Intention = {
|
|
74
|
+
exchangeId?: string;
|
|
75
|
+
inputCoins: InputCoin[];
|
|
76
|
+
outputCoins: OutputCoin[];
|
|
77
|
+
action: string;
|
|
78
|
+
actionParams?: string;
|
|
79
|
+
poolAddress: string;
|
|
80
|
+
poolUtxos?: Utxo[];
|
|
81
|
+
nonce: bigint;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
declare class Maestro {
|
|
85
|
+
private axios;
|
|
86
|
+
constructor(params: {
|
|
87
|
+
baseUrl: string;
|
|
88
|
+
apiKey: string;
|
|
89
|
+
});
|
|
90
|
+
utxosByAddress(address: string, cursor?: string | null, excludeMetaprotocols?: boolean): Promise<{
|
|
91
|
+
next_cursor: string | null;
|
|
92
|
+
last_updated: {
|
|
93
|
+
block_hash: string;
|
|
94
|
+
block_height: bigint;
|
|
95
|
+
};
|
|
96
|
+
data: RawBtcUtxo[];
|
|
97
|
+
}>;
|
|
98
|
+
utxosByAddressMempoolAware(address: string, cursor?: string | null, excludeMetaprotocols?: boolean): Promise<{
|
|
99
|
+
next_cursor: string | null;
|
|
100
|
+
last_updated: {
|
|
101
|
+
block_hash: string;
|
|
102
|
+
block_height: bigint;
|
|
103
|
+
};
|
|
104
|
+
data: RawBtcUtxo[];
|
|
105
|
+
}>;
|
|
106
|
+
inscriptionIdsByCollectionSymbol(collection: string, cursor?: string | null): Promise<{
|
|
107
|
+
next_cursor: string | null;
|
|
108
|
+
last_updated: {
|
|
109
|
+
block_hash: string;
|
|
110
|
+
block_height: bigint;
|
|
111
|
+
};
|
|
112
|
+
data: string[];
|
|
113
|
+
}>;
|
|
114
|
+
runeUtxosByAddress(address: string, rune: string, cursor?: string | null): Promise<{
|
|
115
|
+
next_cursor: string | null;
|
|
116
|
+
last_updated: {
|
|
117
|
+
block_hash: string;
|
|
118
|
+
block_height: bigint;
|
|
119
|
+
};
|
|
120
|
+
data: RawRuneUtxo[];
|
|
121
|
+
}>;
|
|
122
|
+
runeInfo(runeId: string): Promise<{
|
|
123
|
+
last_updated: {
|
|
124
|
+
block_hash: string;
|
|
125
|
+
block_height: bigint;
|
|
126
|
+
};
|
|
127
|
+
data: RawRuneInfo;
|
|
128
|
+
}>;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export declare const Network: {
|
|
132
|
+
readonly Mainnet: "mainnet";
|
|
133
|
+
readonly Testnet: "testnet";
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export declare type Network = (typeof Network)[keyof typeof Network];
|
|
137
|
+
|
|
138
|
+
declare type OutputCoin = {
|
|
139
|
+
coin: CoinBalance;
|
|
140
|
+
to: string;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export declare type Pool = {
|
|
144
|
+
name: string;
|
|
145
|
+
address: string;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export declare type PoolInfo = {
|
|
149
|
+
address: string;
|
|
150
|
+
attributes: string;
|
|
151
|
+
btc_reserved: bigint;
|
|
152
|
+
coin_reserved: {
|
|
153
|
+
id: string;
|
|
154
|
+
value: bigint;
|
|
155
|
+
}[];
|
|
156
|
+
key: string;
|
|
157
|
+
name: string;
|
|
158
|
+
nonce: bigint;
|
|
159
|
+
utxos: {
|
|
160
|
+
coins: {
|
|
161
|
+
id: string;
|
|
162
|
+
value: bigint;
|
|
163
|
+
}[];
|
|
164
|
+
sats: bigint;
|
|
165
|
+
txid: string;
|
|
166
|
+
vout: number;
|
|
167
|
+
}[];
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
declare type RawBtcUtxo = {
|
|
171
|
+
txid: string;
|
|
172
|
+
vout: number;
|
|
173
|
+
script_pubkey: string;
|
|
174
|
+
satoshis: string;
|
|
175
|
+
confirmations: bigint;
|
|
176
|
+
height: bigint;
|
|
177
|
+
runes: {
|
|
178
|
+
rune_id: string;
|
|
179
|
+
amount: string;
|
|
180
|
+
}[];
|
|
181
|
+
inscriptions: {
|
|
182
|
+
offset: bigint;
|
|
183
|
+
inscription_id: string;
|
|
184
|
+
}[];
|
|
185
|
+
address: string;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
declare type RawRuneInfo = {
|
|
189
|
+
id: string;
|
|
190
|
+
symbol: string;
|
|
191
|
+
spaced_name: string;
|
|
192
|
+
divisibility: number;
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
declare type RawRuneUtxo = {
|
|
196
|
+
txid: string;
|
|
197
|
+
vout: number;
|
|
198
|
+
satoshis: string;
|
|
199
|
+
confirmations: bigint;
|
|
200
|
+
height: bigint;
|
|
201
|
+
runes: {
|
|
202
|
+
rune_id: string;
|
|
203
|
+
amount: string;
|
|
204
|
+
}[];
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Main client for interacting with the Ree protocol
|
|
209
|
+
* Provides methods for Bitcoin UTXO management, Rune operations, and transaction creation
|
|
210
|
+
*/
|
|
211
|
+
declare class ReeClient {
|
|
212
|
+
/** Maestro API client for Bitcoin data */
|
|
213
|
+
readonly maestro: Maestro;
|
|
214
|
+
/** Configuration object */
|
|
215
|
+
readonly config: Config;
|
|
216
|
+
/** Exchange canister actor for pool operations */
|
|
217
|
+
readonly exchange: ActorSubclass;
|
|
218
|
+
/** Orchestrator canister actor for transaction processing */
|
|
219
|
+
readonly orchestrator: ActorSubclass;
|
|
220
|
+
/**
|
|
221
|
+
* Initialize ReeClient with wallet addresses and configuration
|
|
222
|
+
* @param config - Client configuration including network and API keys
|
|
223
|
+
*/
|
|
224
|
+
constructor(config: Config);
|
|
225
|
+
/**
|
|
226
|
+
* Filter out UTXOs that have already been spent or are being used in pending transactions
|
|
227
|
+
* Queries the orchestrator to get a list of used outpoints and removes them from the UTXO set
|
|
228
|
+
* @param address - The Bitcoin (or Ordinals) address to check used outpoints for
|
|
229
|
+
* @param utxos - Array of UTXOs to filter
|
|
230
|
+
* @returns Filtered array of UTXOs excluding spent/used ones
|
|
231
|
+
*/
|
|
232
|
+
private filterSpentUtxos;
|
|
233
|
+
/**
|
|
234
|
+
* Get pending (zero-confirmation) Bitcoin UTXOs for a payment address
|
|
235
|
+
* These are UTXOs from Ree protocol transactions that have been broadcast but not yet confirmed
|
|
236
|
+
* Filters out UTXOs that contain runes to get pure Bitcoin UTXOs only
|
|
237
|
+
* @param paymentAddress - The Bitcoin payment address to check for pending UTXOs
|
|
238
|
+
* @returns Array of pending Bitcoin UTXOs without runes from Ree transactions
|
|
239
|
+
*/
|
|
240
|
+
private getPendingBtcUtxos;
|
|
241
|
+
/**
|
|
242
|
+
* Get pending (zero-confirmation) Rune UTXOs for an ordinals address
|
|
243
|
+
* These are UTXOs from Ree protocol transactions that have been broadcast but not yet confirmed
|
|
244
|
+
* Filters to include only UTXOs that contain runes
|
|
245
|
+
* @param address - The ordinals address to check for pending rune UTXOs
|
|
246
|
+
* @returns Array of pending UTXOs containing runes from Ree transactions
|
|
247
|
+
*/
|
|
248
|
+
private getPendingRuneUtxos;
|
|
249
|
+
/**
|
|
250
|
+
* Get all Bitcoin UTXOs for the payment address
|
|
251
|
+
* Handles pagination automatically to fetch all available UTXOs
|
|
252
|
+
* @returns Array of Bitcoin UTXOs
|
|
253
|
+
*/
|
|
254
|
+
getBtcUtxos(paymentAddress: string, excludeMetaprotocols?: boolean): Promise<Utxo[]>;
|
|
255
|
+
/**
|
|
256
|
+
* Get UTXOs containing a specific rune for the user's address
|
|
257
|
+
* @param runeId - The rune ID to filter UTXOs by
|
|
258
|
+
* @returns Array of UTXOs containing the specified rune
|
|
259
|
+
*/
|
|
260
|
+
getRuneUtxos(address: string, runeId: string): Promise<Utxo[]>;
|
|
261
|
+
/**
|
|
262
|
+
* Search for runes by keyword or rune ID
|
|
263
|
+
* Supports both exact rune ID matches and fuzzy name matching
|
|
264
|
+
* @param keyword - Search term (rune ID or partial name)
|
|
265
|
+
* @returns Array of matching rune information
|
|
266
|
+
*/
|
|
267
|
+
searchRunes(keyword: string): Promise<RuneInfo[]>;
|
|
268
|
+
/**
|
|
269
|
+
* Get detailed information for a specific rune by ID
|
|
270
|
+
* @param runeId - The rune ID to look up
|
|
271
|
+
* @returns Rune information or undefined if not found
|
|
272
|
+
*/
|
|
273
|
+
getRuneInfo(runeId: string): Promise<RuneInfo | undefined>;
|
|
274
|
+
/**
|
|
275
|
+
* Get total Bitcoin balance from all UTXOs
|
|
276
|
+
* @returns Total balance in satoshis
|
|
277
|
+
*/
|
|
278
|
+
getBtcBalance(paymentAddress: string): Promise<number>;
|
|
279
|
+
/**
|
|
280
|
+
* Get the balance of a specific rune for the user's address
|
|
281
|
+
* Calculates total rune amount across all UTXOs and applies divisibility
|
|
282
|
+
* @param runeId - The rune ID to get balance for (format: "block:index")
|
|
283
|
+
* @returns Rune balance as a number, or undefined if rune not found
|
|
284
|
+
*/
|
|
285
|
+
getRuneBalance(address: string, runeId: string): Promise<number | undefined>;
|
|
286
|
+
/**
|
|
287
|
+
* Get list of all available liquidity pools
|
|
288
|
+
* @returns Array of pool information
|
|
289
|
+
*/
|
|
290
|
+
getPoolList(): Promise<Pool[]>;
|
|
291
|
+
/**
|
|
292
|
+
* Get detailed information about a specific liquidity pool
|
|
293
|
+
* @param poolAddress - The pool's Bitcoin address
|
|
294
|
+
* @returns Pool information including UTXOs and balances
|
|
295
|
+
* @throws Error if pool is not found
|
|
296
|
+
*/
|
|
297
|
+
getPoolInfo(poolAddress: string): Promise<PoolInfo>;
|
|
298
|
+
/**
|
|
299
|
+
* Create a transaction for trading with a liquidity pool
|
|
300
|
+
* @param params - Transaction parameters
|
|
301
|
+
* @param params.address - Bitcoin address
|
|
302
|
+
* @param params.paymentAddress - Ordinals address
|
|
303
|
+
* @param params.involvedRuneId - Optional rune ID for rune swaps
|
|
304
|
+
* @returns Transaction instance
|
|
305
|
+
*/
|
|
306
|
+
createTransaction({ address, paymentAddress, feeRate, mergeSelfRuneBtcOutputs, }: {
|
|
307
|
+
address: string;
|
|
308
|
+
paymentAddress: string;
|
|
309
|
+
feeRate?: number;
|
|
310
|
+
mergeSelfRuneBtcOutputs?: boolean;
|
|
311
|
+
}): Promise<Transaction>;
|
|
312
|
+
getRecommendedFeeRate(): Promise<{
|
|
313
|
+
min: number;
|
|
314
|
+
max: number;
|
|
315
|
+
}>;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
declare interface ReeContextValue {
|
|
319
|
+
client: ReeClient;
|
|
320
|
+
exchange: ActorSubclass;
|
|
321
|
+
address: string;
|
|
322
|
+
paymentAddress: string;
|
|
323
|
+
updateWallet: (wallet: {
|
|
324
|
+
address?: string;
|
|
325
|
+
paymentAddress?: string;
|
|
326
|
+
}) => void;
|
|
327
|
+
createTransaction: (params?: {
|
|
328
|
+
feeRate?: number;
|
|
329
|
+
mergeSelfRuneBtcOutputs?: boolean;
|
|
330
|
+
}) => Promise<Transaction>;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
export declare function ReeProvider({ children, config }: ReeProviderProps): JSX_2.Element;
|
|
334
|
+
|
|
335
|
+
declare interface ReeProviderProps {
|
|
336
|
+
children: ReactNode;
|
|
337
|
+
config: Config;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export declare interface RuneInfo {
|
|
341
|
+
runeId: string;
|
|
342
|
+
spacedRune: string;
|
|
343
|
+
symbol: string;
|
|
344
|
+
divisibility: number;
|
|
345
|
+
etching: string;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
declare function toBitcoinNetwork(network: Network): bitcoin.networks.Network;
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Transaction builder for Bitcoin and Rune transactions
|
|
352
|
+
* Handles PSBT creation, UTXO selection, and fee calculation
|
|
353
|
+
*/
|
|
354
|
+
declare class Transaction {
|
|
355
|
+
private psbt;
|
|
356
|
+
private client;
|
|
357
|
+
private inputAddressTypes;
|
|
358
|
+
private outputAddressTypes;
|
|
359
|
+
private config;
|
|
360
|
+
/** Track dust amounts from user input UTXOs for fee calculation */
|
|
361
|
+
private userInputUtxoDusts;
|
|
362
|
+
private intentions;
|
|
363
|
+
private txFee;
|
|
364
|
+
private additionalDustNeeded;
|
|
365
|
+
private inputUtxos;
|
|
366
|
+
constructor(config: TransactionConfig, client: ReeClient);
|
|
367
|
+
/**
|
|
368
|
+
* Add a UTXO as transaction input
|
|
369
|
+
* @param utxo - The UTXO to add as input
|
|
370
|
+
*/
|
|
371
|
+
private addInput;
|
|
372
|
+
/**
|
|
373
|
+
* Add a standard output to the transaction
|
|
374
|
+
* @param address - Recipient address
|
|
375
|
+
* @param amount - Amount in satoshis
|
|
376
|
+
*/
|
|
377
|
+
private addOutput;
|
|
378
|
+
/**
|
|
379
|
+
* Add an OP_RETURN script output (for Runestone)
|
|
380
|
+
* @param script - The script buffer to include
|
|
381
|
+
*/
|
|
382
|
+
private addScriptOutput;
|
|
383
|
+
/**
|
|
384
|
+
* Select UTXOs containing specific runes for the transaction
|
|
385
|
+
* @param runeUtxos - Available rune UTXOs
|
|
386
|
+
* @param runeId - Target rune ID
|
|
387
|
+
* @param runeAmount - Required rune amount
|
|
388
|
+
* @returns Selected UTXOs that contain the required runes
|
|
389
|
+
*/
|
|
390
|
+
private selectRuneUtxos;
|
|
391
|
+
/**
|
|
392
|
+
* Select BTC UTXOs for the transaction
|
|
393
|
+
* @param btcUtxos - Available BTC UTXOs
|
|
394
|
+
* @param btcAmount - Required BTC amount in satoshis
|
|
395
|
+
* @returns Selected UTXOs that contain enough BTC
|
|
396
|
+
*/
|
|
397
|
+
private selectBtcUtxos;
|
|
398
|
+
/**
|
|
399
|
+
* Add BTC outputs and calculate transaction fees
|
|
400
|
+
* @param btcUtxos - Available BTC UTXOs
|
|
401
|
+
* @param btcAmount - Required BTC amount
|
|
402
|
+
* @param paymentAddress - Address for change output
|
|
403
|
+
* @param additionalDustNeeded - Additional dust needed for rune outputs
|
|
404
|
+
* @returns Fee calculation result
|
|
405
|
+
*/
|
|
406
|
+
private addBtcAndFees;
|
|
407
|
+
/**
|
|
408
|
+
* Resolve and fetch all UTXOs required by the current intention set, grouped by address.
|
|
409
|
+
*
|
|
410
|
+
* How it works:
|
|
411
|
+
* - Scans every intention to determine, per address, whether BTC UTXOs are needed and which rune IDs are needed.
|
|
412
|
+
* • For inputCoins, uses their `from` address.
|
|
413
|
+
* • For outputCoins, uses their `to` address.
|
|
414
|
+
* • Pool address is always considered “involved” for any coin that appears in the intention.
|
|
415
|
+
* • The user's payment address is always flagged as needing BTC (to pay fees/change).
|
|
416
|
+
* - Deduplicates addresses and rune IDs, then fetches UTXOs in parallel via the client:
|
|
417
|
+
* • BTC UTXOs: client.getBtcUtxos(address)
|
|
418
|
+
* • Rune UTXOs: client.getRuneUtxos(address, runeId)
|
|
419
|
+
* - Any fetch error is treated as an empty list for robustness.
|
|
420
|
+
*
|
|
421
|
+
* Returns:
|
|
422
|
+
* - An object with two maps:
|
|
423
|
+
* • btc: Record<address, Utxo[]>
|
|
424
|
+
* • rune: Record<address, Record<runeId, Utxo[]>>
|
|
425
|
+
*/
|
|
426
|
+
private getInvolvedAddressUtxos;
|
|
427
|
+
/**
|
|
428
|
+
* Select inputs (UTXOs) according to the intentions and compute the coin outputs per address.
|
|
429
|
+
*
|
|
430
|
+
* Inputs:
|
|
431
|
+
* - addressUtxos: UTXOs grouped as returned by getInvolvedAddressUtxos().
|
|
432
|
+
*
|
|
433
|
+
* Algorithm (high level):
|
|
434
|
+
* 1) Validate there is at least one intention.
|
|
435
|
+
* 2) For each intention, ensure symmetry between inputCoins and outputCoins around the pool:
|
|
436
|
+
* - If a coin is sent from an address to the pool but not listed as output to the pool, add an output-to-pool entry.
|
|
437
|
+
* - If a coin is received from the pool by an address but not listed as input-from-pool, add an input-from-pool entry.
|
|
438
|
+
* 3) Aggregate per-address input and output coin amounts (addressInputCoinAmounts, addressOutputCoinAmounts).
|
|
439
|
+
* 4) For each [address, coinId] in the input amounts:
|
|
440
|
+
* - BTC (coinId === BITCOIN_ID):
|
|
441
|
+
* • If address is the user's payment address, we treat it specially by decrementing its BTC in addressOutputCoinAmounts
|
|
442
|
+
* (the actual funding and fee handling will be done later in addBtcAndFees).
|
|
443
|
+
* • Otherwise, select BTC UTXOs (preferring rune-free for non-pool addresses), add them as inputs, compute change and
|
|
444
|
+
* add that change to addressOutputCoinAmounts[address]. If the address is a pool, also credit any rune balances
|
|
445
|
+
* contained in selected pool BTC UTXOs to addressOutputCoinAmounts for later distribution.
|
|
446
|
+
* - Rune (coinId !== BITCOIN_ID): select rune UTXOs for the required runeId, add as inputs, compute rune change and add
|
|
447
|
+
* to addressOutputCoinAmounts[address].
|
|
448
|
+
* 5) Ensure all pool UTXOs are included: for pool addresses that only appear on the receiving side, add all their BTC/rune
|
|
449
|
+
* UTXOs as inputs and credit their total balances into addressOutputCoinAmounts accordingly.
|
|
450
|
+
*
|
|
451
|
+
* Returns:
|
|
452
|
+
* - addressOutputCoinAmounts: Record<address, Record<coinId, bigint>> — the final coin amounts to be sent to each address.
|
|
453
|
+
*/
|
|
454
|
+
private addInputsAndCalculateOutputs;
|
|
455
|
+
/**
|
|
456
|
+
* Materialize outputs from the computed addressReceiveCoinAmounts.
|
|
457
|
+
*
|
|
458
|
+
* Steps:
|
|
459
|
+
* 1) Collect all rune IDs present across recipients. If any runes are to be transferred, first build a Runestone (edicts)
|
|
460
|
+
* and add an OP_RETURN output (at index 0). Edicts reference subsequent output indices.
|
|
461
|
+
* 2) For each address that receives runes, also ensure a BTC output exists at that index:
|
|
462
|
+
* - If an explicit BTC amount is provided for the address and the address is not the user's own rune address, use it.
|
|
463
|
+
* - Otherwise, add a dust-sized BTC output (UTXO_DUST) to carry the runes, and track additionalDustNeeded for fees.
|
|
464
|
+
* After using an explicit BTC amount for a rune recipient, remove it from the remaining BTC-only outputs map.
|
|
465
|
+
* 3) Finally, add any remaining BTC-only outputs where amount > 0.
|
|
466
|
+
*
|
|
467
|
+
* Notes:
|
|
468
|
+
* - Output values are bigint; scripts use Uint8Array, compatible with bitcoinjs-lib v7.
|
|
469
|
+
* - Output ordering: OP_RETURN (if any) first, then rune recipients in the order we build edicts, then remaining BTC outputs.
|
|
470
|
+
*/
|
|
471
|
+
private addOutputs;
|
|
472
|
+
/**
|
|
473
|
+
* Add an intention to the transaction
|
|
474
|
+
* Multiple intentions can be added to create complex, atomic transactions
|
|
475
|
+
*
|
|
476
|
+
* @param intention - The intention object containing:
|
|
477
|
+
* - poolAddress: Target pool address
|
|
478
|
+
* - inputCoins: Coins being sent to the pool
|
|
479
|
+
* - outputCoins: Coins expected from the pool
|
|
480
|
+
* - action: Action type (swap, deposit, withdraw, etc.)
|
|
481
|
+
* - nonce: Unique identifier for this intention
|
|
482
|
+
*
|
|
483
|
+
* @example
|
|
484
|
+
* ```typescript
|
|
485
|
+
* // Add a swap intention
|
|
486
|
+
* transaction.addIntention({
|
|
487
|
+
* poolAddress: "bc1q...",
|
|
488
|
+
* inputCoins: [{ id: "0:0", value: BigInt(100000) }], // Send BTC
|
|
489
|
+
* outputCoins: [{ id: "840000:3", value: BigInt(1000) }], // Receive runes
|
|
490
|
+
* action: "swap",
|
|
491
|
+
* nonce: BigInt(Date.now()),
|
|
492
|
+
* });
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
addIntention(intention: Intention): void;
|
|
496
|
+
/**
|
|
497
|
+
* Build the complete PSBT with all added intentions
|
|
498
|
+
* This method processes all intentions atomically and calculates:
|
|
499
|
+
* - Required inputs from user and pools
|
|
500
|
+
* - Output distributions to user and pools
|
|
501
|
+
* - Transaction fees and change outputs
|
|
502
|
+
* - Runestone for rune transfers
|
|
503
|
+
*
|
|
504
|
+
* @returns Promise resolving to the built PSBT ready for signing
|
|
505
|
+
* @throws Error if insufficient funds or invalid intentions
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* ```typescript
|
|
509
|
+
* // After adding intentions
|
|
510
|
+
* const { psbt, txid } = await transaction.build();
|
|
511
|
+
* const signedPsbt = await wallet.signPsbt(psbt);
|
|
512
|
+
* ```
|
|
513
|
+
*/
|
|
514
|
+
build(): Promise<{
|
|
515
|
+
psbt: bitcoin.Psbt;
|
|
516
|
+
txid: string;
|
|
517
|
+
fee: bigint;
|
|
518
|
+
}>;
|
|
519
|
+
private static estimateTxVirtualSize;
|
|
520
|
+
private static parseAddressType;
|
|
521
|
+
private static varIntSize;
|
|
522
|
+
/**
|
|
523
|
+
* Submit the signed transaction to the orchestrator for execution
|
|
524
|
+
* This method sends the signed PSBT along with the intention set to the orchestrator canister
|
|
525
|
+
*
|
|
526
|
+
* @param signedPsbtHex - The signed PSBT in hexadecimal format from the user's wallet
|
|
527
|
+
* @returns Promise that resolves to the orchestrator's response on success
|
|
528
|
+
* @throws Error if intention set is not available or if the orchestrator returns an error
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```typescript
|
|
532
|
+
* // After building and signing the transaction
|
|
533
|
+
* const signedPsbt = await wallet.signPsbt(psbt);
|
|
534
|
+
* const result = await transaction.send(signedPsbt.toHex());
|
|
535
|
+
* ```
|
|
536
|
+
*/
|
|
537
|
+
send(signedPsbtHex: string): Promise<any>;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
declare interface TransactionConfig {
|
|
541
|
+
network: Network;
|
|
542
|
+
exchangeId: string;
|
|
543
|
+
address: string;
|
|
544
|
+
paymentAddress: string;
|
|
545
|
+
clientInfo?: string;
|
|
546
|
+
/** Optional manual fee rate in satoshis per virtual byte */
|
|
547
|
+
feeRate?: number;
|
|
548
|
+
/**
|
|
549
|
+
* When true, rune outputs to the local rune address reuse existing BTC value
|
|
550
|
+
* instead of emitting a separate dust output. Defaults to false.
|
|
551
|
+
*/
|
|
552
|
+
mergeSelfRuneBtcOutputs?: boolean;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
declare interface UseBalanceOptions {
|
|
556
|
+
/** Auto-refresh interval in milliseconds (0 to disable) */
|
|
557
|
+
refreshInterval?: number;
|
|
558
|
+
/** Enable automatic refresh when wallet changes */
|
|
559
|
+
autoRefresh?: boolean;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Hook to get and manage Bitcoin balance
|
|
564
|
+
* @returns Object with balance, loading state, error, and refresh function
|
|
565
|
+
*/
|
|
566
|
+
export declare function useBtcBalance(options?: UseBalanceOptions): {
|
|
567
|
+
balance: number | null;
|
|
568
|
+
loading: boolean;
|
|
569
|
+
error: string | null;
|
|
570
|
+
refetch: () => Promise<void>;
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Hook to get and manage Bitcoin UTXOs
|
|
575
|
+
* @returns Object with UTXOs, loading state, error, and refresh function
|
|
576
|
+
*/
|
|
577
|
+
export declare function useBtcUtxos(options?: UseBalanceOptions): {
|
|
578
|
+
utxos: Utxo[];
|
|
579
|
+
loading: boolean;
|
|
580
|
+
error: string | null;
|
|
581
|
+
refetch: () => Promise<void>;
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Hook to get pool information by address
|
|
586
|
+
* @param poolAddress - The pool address to get info for
|
|
587
|
+
* @returns Object with pool info, loading state, error, and refetch function
|
|
588
|
+
*/
|
|
589
|
+
export declare function usePoolInfo(poolAddress?: string): {
|
|
590
|
+
poolInfo: PoolInfo | null;
|
|
591
|
+
loading: boolean;
|
|
592
|
+
error: string | null;
|
|
593
|
+
refetch: () => Promise<void>;
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Hook to get list of all pools
|
|
598
|
+
* @returns Object with pools, loading state, error, and refetch function
|
|
599
|
+
*/
|
|
600
|
+
export declare function usePoolList(): {
|
|
601
|
+
pools: Pool[];
|
|
602
|
+
loading: boolean;
|
|
603
|
+
error: string | null;
|
|
604
|
+
refetch: () => Promise<void>;
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Hook to retrieve the recommended fee rate range
|
|
609
|
+
* @returns Object with minimum/maximum fee rates, loading state, error, and refetch function
|
|
610
|
+
*/
|
|
611
|
+
export declare function useRecommendedFeeRate(options?: UseBalanceOptions): {
|
|
612
|
+
feeRate: {
|
|
613
|
+
min: number;
|
|
614
|
+
max: number;
|
|
615
|
+
} | null;
|
|
616
|
+
loading: boolean;
|
|
617
|
+
error: string | null;
|
|
618
|
+
refetch: () => Promise<void>;
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
export declare function useRee(): ReeContextValue;
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Hook to get and manage Rune balance for a specific rune
|
|
625
|
+
* @param runeId - The rune ID to get balance for
|
|
626
|
+
* @returns Object with balance, loading state, error, and refresh function
|
|
627
|
+
*/
|
|
628
|
+
export declare function useRuneBalance(runeId: string | undefined, options?: UseBalanceOptions): {
|
|
629
|
+
balance: number | null;
|
|
630
|
+
loading: boolean;
|
|
631
|
+
error: string | null;
|
|
632
|
+
refetch: () => Promise<void>;
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Hook to get rune information by ID
|
|
637
|
+
* @param runeId - The rune ID to get info for
|
|
638
|
+
* @returns Object with rune info, loading state, error, and refetch function
|
|
639
|
+
*/
|
|
640
|
+
export declare function useRuneInfo(runeId?: string): {
|
|
641
|
+
runeInfo: RuneInfo | null;
|
|
642
|
+
loading: boolean;
|
|
643
|
+
error: string | null;
|
|
644
|
+
refetch: () => Promise<void>;
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Hook to get and manage Rune UTXOs for a specific rune
|
|
649
|
+
* @param runeId - The rune ID to get UTXOs for
|
|
650
|
+
* @returns Object with UTXOs, loading state, error, and refresh function
|
|
651
|
+
*/
|
|
652
|
+
export declare function useRuneUtxos(runeId: string, options?: UseBalanceOptions): {
|
|
653
|
+
utxos: Utxo[];
|
|
654
|
+
loading: boolean;
|
|
655
|
+
error: string | null;
|
|
656
|
+
refetch: () => Promise<void>;
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Hook to search for runes by keyword
|
|
661
|
+
* @param keyword - Search term (rune ID or partial name)
|
|
662
|
+
* @returns Object with runes, loading state, error, and search function
|
|
663
|
+
*/
|
|
664
|
+
export declare function useSearchRunes(): (searchKeyword?: string) => Promise<RuneInfo[]>;
|
|
665
|
+
|
|
666
|
+
export declare namespace utils {
|
|
667
|
+
export {
|
|
668
|
+
hexToBytes,
|
|
669
|
+
bytesToHex,
|
|
670
|
+
toBitcoinNetwork,
|
|
671
|
+
getScriptByAddress,
|
|
672
|
+
getAddressType,
|
|
673
|
+
formatPoolUtxo,
|
|
674
|
+
getUtxoProof
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
export declare type Utxo = {
|
|
679
|
+
txid: string;
|
|
680
|
+
vout: number;
|
|
681
|
+
satoshis: string;
|
|
682
|
+
height?: number;
|
|
683
|
+
runes: {
|
|
684
|
+
id: string;
|
|
685
|
+
amount: string;
|
|
686
|
+
}[];
|
|
687
|
+
address: string;
|
|
688
|
+
scriptPk: string;
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
export { }
|