@omnity/ree-client-ts-sdk 0.3.0 → 0.3.3
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/README.md +111 -67
- package/dist/index.d.ts +94 -33
- package/dist/ree-sdk.cjs.js +123 -5
- package/dist/ree-sdk.es.js +30565 -4340
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -68,20 +68,31 @@ const poolInfo = await client.getPoolInfo("pool-address");
|
|
|
68
68
|
```typescript
|
|
69
69
|
// Create a transaction for a single pool operation
|
|
70
70
|
const transaction = await client.createTransaction({
|
|
71
|
-
address: "
|
|
71
|
+
address: "bc1p...", // Bitcoin address for runes
|
|
72
72
|
paymentAddress: "bc1q...", // Payment address for BTC
|
|
73
|
-
involvedPoolAddresses: ["bc1q..."], // Pool addresses involved
|
|
74
|
-
involvedRuneIds: ["840000:3"], // Optional: rune IDs if trading runes
|
|
75
73
|
});
|
|
76
74
|
|
|
77
75
|
// Add a single intention (e.g., swap BTC for runes)
|
|
78
76
|
transaction.addIntention({
|
|
79
|
-
poolAddress: "
|
|
77
|
+
poolAddress: "bc1p...",
|
|
78
|
+
poolUtxos: [],
|
|
80
79
|
inputCoins: [
|
|
81
|
-
{
|
|
80
|
+
{
|
|
81
|
+
coin: {
|
|
82
|
+
id: "0:0",
|
|
83
|
+
value: BigInt(100000),
|
|
84
|
+
}, // Send 0.001 BTC,
|
|
85
|
+
from: paymentAddress,
|
|
86
|
+
},
|
|
82
87
|
],
|
|
83
88
|
outputCoins: [
|
|
84
|
-
{
|
|
89
|
+
{
|
|
90
|
+
coin: {
|
|
91
|
+
id: "840000:3",
|
|
92
|
+
value: BigInt(1000),
|
|
93
|
+
}, // Receive 1000 runes,
|
|
94
|
+
to: address,
|
|
95
|
+
},
|
|
85
96
|
],
|
|
86
97
|
action: "swap",
|
|
87
98
|
nonce: BigInt(1234),
|
|
@@ -98,18 +109,23 @@ const result = await transaction.send(signedPsbt.toHex());
|
|
|
98
109
|
```typescript
|
|
99
110
|
// Create a complex transaction with multiple operations
|
|
100
111
|
const transaction = await client.createTransaction({
|
|
101
|
-
address: "
|
|
112
|
+
address: "bc1p...",
|
|
102
113
|
paymentAddress: "bc1q...",
|
|
103
|
-
involvedPoolAddresses: ["bc1q...pool1", "bc1q...pool2"],
|
|
104
|
-
involvedRuneIds: ["840000:3", "840000:5"],
|
|
105
114
|
});
|
|
106
115
|
|
|
107
116
|
// Add multiple intentions in a single transaction
|
|
108
117
|
// Intention 1: Deposit BTC to Pool 1
|
|
109
118
|
transaction.addIntention({
|
|
110
|
-
poolAddress: "
|
|
119
|
+
poolAddress: "bc1p...pool1",
|
|
111
120
|
inputCoins: [
|
|
112
|
-
{
|
|
121
|
+
{
|
|
122
|
+
// Deposit 0.0005 BTC
|
|
123
|
+
coin: {
|
|
124
|
+
id: "0:0",
|
|
125
|
+
value: BigInt(50000),
|
|
126
|
+
},
|
|
127
|
+
from: paymentAddress,
|
|
128
|
+
},
|
|
113
129
|
],
|
|
114
130
|
outputCoins: [],
|
|
115
131
|
action: "deposit",
|
|
@@ -120,10 +136,24 @@ transaction.addIntention({
|
|
|
120
136
|
transaction.addIntention({
|
|
121
137
|
poolAddress: "bc1q...pool2",
|
|
122
138
|
inputCoins: [
|
|
123
|
-
{
|
|
139
|
+
{
|
|
140
|
+
// Send 500 of rune A,
|
|
141
|
+
coin: {
|
|
142
|
+
id: "840000:3",
|
|
143
|
+
value: BigInt(500),
|
|
144
|
+
},
|
|
145
|
+
from: address,
|
|
146
|
+
},
|
|
124
147
|
],
|
|
125
148
|
outputCoins: [
|
|
126
|
-
{
|
|
149
|
+
{
|
|
150
|
+
// Receive 250 of rune B,
|
|
151
|
+
coin: {
|
|
152
|
+
id: "840000:5",
|
|
153
|
+
value: BigInt(250),
|
|
154
|
+
},
|
|
155
|
+
to: address,
|
|
156
|
+
},
|
|
127
157
|
],
|
|
128
158
|
action: "swap",
|
|
129
159
|
nonce: BigInt(Date.now() + 1),
|
|
@@ -149,7 +179,7 @@ function App() {
|
|
|
149
179
|
}
|
|
150
180
|
|
|
151
181
|
function WalletComponent() {
|
|
152
|
-
const { client, address, updateWallet, createTransaction } = useRee();
|
|
182
|
+
const { client, address, paymentAddress, updateWallet, createTransaction } = useRee();
|
|
153
183
|
const { balance: btcBalance } = useBtcBalance();
|
|
154
184
|
|
|
155
185
|
const connectWallet = () => {
|
|
@@ -161,24 +191,45 @@ function WalletComponent() {
|
|
|
161
191
|
|
|
162
192
|
const executeComplexTransaction = async () => {
|
|
163
193
|
// Create transaction with multiple pools
|
|
164
|
-
const tx = await createTransaction(
|
|
165
|
-
involvedPoolAddresses: ["pool1", "pool2"],
|
|
166
|
-
involvedRuneIds: ["840000:3"],
|
|
167
|
-
});
|
|
194
|
+
const tx = await createTransaction();
|
|
168
195
|
|
|
169
196
|
// Add multiple intentions
|
|
170
197
|
tx.addIntention({
|
|
171
198
|
poolAddress: "pool1",
|
|
172
|
-
inputCoins: [{
|
|
173
|
-
|
|
199
|
+
inputCoins: [{
|
|
200
|
+
coin: {
|
|
201
|
+
id: "0:0",
|
|
202
|
+
value: BigInt(100000)
|
|
203
|
+
},
|
|
204
|
+
from: paymentAddress
|
|
205
|
+
}],
|
|
206
|
+
outputCoins: [
|
|
207
|
+
coint: {
|
|
208
|
+
id: "840000:3",
|
|
209
|
+
value: BigInt(1000)
|
|
210
|
+
},
|
|
211
|
+
to: address
|
|
212
|
+
],
|
|
174
213
|
action: "swap",
|
|
175
214
|
nonce: BigInt(Date.now()),
|
|
176
215
|
});
|
|
177
216
|
|
|
178
217
|
tx.addIntention({
|
|
179
218
|
poolAddress: "pool2",
|
|
180
|
-
inputCoins: [{
|
|
181
|
-
|
|
219
|
+
inputCoins: [{
|
|
220
|
+
coin: {
|
|
221
|
+
id: "840000:3",
|
|
222
|
+
value: BigInt(500)
|
|
223
|
+
},
|
|
224
|
+
from: address
|
|
225
|
+
}],
|
|
226
|
+
outputCoins: [{
|
|
227
|
+
coin: {
|
|
228
|
+
id: "0:0",
|
|
229
|
+
value: BigInt(50000)
|
|
230
|
+
},
|
|
231
|
+
to: paymentAddress
|
|
232
|
+
}],
|
|
182
233
|
action: "swap",
|
|
183
234
|
nonce: BigInt(Date.now() + 1),
|
|
184
235
|
});
|
|
@@ -228,13 +279,19 @@ function MyComponent({ children }) {
|
|
|
228
279
|
value: depositBtcAmount,
|
|
229
280
|
});
|
|
230
281
|
|
|
231
|
-
const tx = await createTransaction(
|
|
232
|
-
involvedPoolAddresses: ["bc1q..."],
|
|
233
|
-
});
|
|
282
|
+
const tx = await createTransaction();
|
|
234
283
|
|
|
235
284
|
tx.addIntention({
|
|
236
285
|
poolAddress: "bc1q...",
|
|
237
|
-
inputCoins: [
|
|
286
|
+
inputCoins: [
|
|
287
|
+
{
|
|
288
|
+
coin: {
|
|
289
|
+
id: "0:0",
|
|
290
|
+
value: depositBtcAmount,
|
|
291
|
+
},
|
|
292
|
+
from: paymentAddress,
|
|
293
|
+
},
|
|
294
|
+
],
|
|
238
295
|
outputCoins: [],
|
|
239
296
|
action: "deposit",
|
|
240
297
|
nonce: depositOffer.nonce,
|
|
@@ -307,7 +364,7 @@ new ReeClient(config: Config)
|
|
|
307
364
|
|
|
308
365
|
##### Transaction Methods
|
|
309
366
|
|
|
310
|
-
- `createTransaction(
|
|
367
|
+
- `createTransaction(): Promise<Transaction>` - Create a transaction
|
|
311
368
|
|
|
312
369
|
### Transaction
|
|
313
370
|
|
|
@@ -323,18 +380,37 @@ Transaction builder for Bitcoin and Rune transactions with multi-intention suppo
|
|
|
323
380
|
|
|
324
381
|
```typescript
|
|
325
382
|
interface Intention {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
383
|
+
// Target pool address
|
|
384
|
+
poolAddress: string;
|
|
385
|
+
// the UTXOs obtained through the pool’s pre methods
|
|
386
|
+
// if not provided, will be fetched via the maestro API.
|
|
387
|
+
poolUtxos?: [];
|
|
388
|
+
// Coins being sent to the pool
|
|
389
|
+
inputCoins: InputCoin[];
|
|
390
|
+
// Coins expected from the pool
|
|
391
|
+
outputCoins: InputCoin[];
|
|
392
|
+
// Action type (swap, deposit, withdraw, etc.)
|
|
393
|
+
action: string;
|
|
394
|
+
// Optional action parameters
|
|
395
|
+
actionParams?: string;
|
|
396
|
+
// Unique nonce for the intention
|
|
397
|
+
nonce: bigint;
|
|
332
398
|
}
|
|
333
399
|
|
|
334
|
-
|
|
400
|
+
type CoinBalance = {
|
|
335
401
|
id: string; // Coin ID ("0:0" for BTC, "840000:3" for runes)
|
|
336
402
|
value: bigint; // Amount in smallest unit
|
|
337
|
-
}
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
type InputCoin = {
|
|
406
|
+
coin: CoinBalance;
|
|
407
|
+
from: string;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
type OutputCoin = {
|
|
411
|
+
coin: CoinBalance;
|
|
412
|
+
to: string;
|
|
413
|
+
};
|
|
338
414
|
```
|
|
339
415
|
|
|
340
416
|
### Multi-Intention Transaction Benefits
|
|
@@ -494,35 +570,3 @@ enum Network {
|
|
|
494
570
|
Testnet = "testnet",
|
|
495
571
|
}
|
|
496
572
|
```
|
|
497
|
-
|
|
498
|
-
## Error Handling
|
|
499
|
-
|
|
500
|
-
```typescript
|
|
501
|
-
try {
|
|
502
|
-
const transaction = await client.createTransaction({
|
|
503
|
-
address: "bc1q...",
|
|
504
|
-
paymentAddress: "bc1q...",
|
|
505
|
-
involvedPoolAddresses: ["bc1q..."],
|
|
506
|
-
});
|
|
507
|
-
|
|
508
|
-
transaction.addIntention({
|
|
509
|
-
poolAddress: "bc1q...",
|
|
510
|
-
inputCoins: [{ id: "0:0", value: BigInt(100000) }],
|
|
511
|
-
outputCoins: [{ id: "840000:3", value: BigInt(1000) }],
|
|
512
|
-
action: "swap",
|
|
513
|
-
nonce: BigInt(Date.now()),
|
|
514
|
-
});
|
|
515
|
-
|
|
516
|
-
const psbt = await transaction.build();
|
|
517
|
-
const signedPsbt = await wallet.signPsbt(psbt);
|
|
518
|
-
const result = await transaction.send(signedPsbt.toHex());
|
|
519
|
-
} catch (error) {
|
|
520
|
-
if (error.message.includes("INSUFFICIENT")) {
|
|
521
|
-
console.error("Insufficient funds:", error);
|
|
522
|
-
} else if (error.message.includes("Pool")) {
|
|
523
|
-
console.error("Pool error:", error);
|
|
524
|
-
} else {
|
|
525
|
-
console.error("Transaction failed:", error);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
```
|
package/dist/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare type AddressType = (typeof AddressType)[keyof typeof AddressType]
|
|
|
34
34
|
|
|
35
35
|
declare function bytesToHex(bytes: Uint8Array): string;
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
declare type CoinBalance = {
|
|
38
38
|
id: string;
|
|
39
39
|
value: bigint;
|
|
40
40
|
};
|
|
@@ -47,13 +47,23 @@ export declare type Config = {
|
|
|
47
47
|
exchangeCanisterId: string;
|
|
48
48
|
};
|
|
49
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
|
+
|
|
50
60
|
declare function getAddressType(address: string): AddressType;
|
|
51
61
|
|
|
52
62
|
declare function getScriptByAddress(address: string, network?: Network): Uint8Array<ArrayBufferLike>;
|
|
53
63
|
|
|
54
64
|
declare function hexToBytes(hex: string): Uint8Array;
|
|
55
65
|
|
|
56
|
-
declare type InputCoin = {
|
|
66
|
+
export declare type InputCoin = {
|
|
57
67
|
coin: CoinBalance;
|
|
58
68
|
from: string;
|
|
59
69
|
};
|
|
@@ -64,6 +74,7 @@ export declare type Intention = {
|
|
|
64
74
|
action: string;
|
|
65
75
|
actionParams?: string;
|
|
66
76
|
poolAddress: string;
|
|
77
|
+
poolUtxos?: Utxo[];
|
|
67
78
|
nonce: bigint;
|
|
68
79
|
};
|
|
69
80
|
|
|
@@ -73,7 +84,7 @@ declare class Maestro {
|
|
|
73
84
|
baseUrl: string;
|
|
74
85
|
apiKey: string;
|
|
75
86
|
});
|
|
76
|
-
utxosByAddress(address: string, cursor?: string | null): Promise<{
|
|
87
|
+
utxosByAddress(address: string, cursor?: string | null, excludeMetaprotocols?: boolean): Promise<{
|
|
77
88
|
next_cursor: string | null;
|
|
78
89
|
last_updated: {
|
|
79
90
|
block_hash: string;
|
|
@@ -81,29 +92,28 @@ declare class Maestro {
|
|
|
81
92
|
};
|
|
82
93
|
data: RawBtcUtxo[];
|
|
83
94
|
}>;
|
|
84
|
-
|
|
95
|
+
inscriptionIdsByCollectionSymbol(collection: string, cursor?: string | null): Promise<{
|
|
85
96
|
next_cursor: string | null;
|
|
86
97
|
last_updated: {
|
|
87
98
|
block_hash: string;
|
|
88
99
|
block_height: bigint;
|
|
89
100
|
};
|
|
90
|
-
data:
|
|
101
|
+
data: string[];
|
|
91
102
|
}>;
|
|
92
|
-
|
|
103
|
+
runeUtxosByAddress(address: string, rune: string, cursor?: string | null): Promise<{
|
|
93
104
|
next_cursor: string | null;
|
|
94
105
|
last_updated: {
|
|
95
106
|
block_hash: string;
|
|
96
107
|
block_height: bigint;
|
|
97
108
|
};
|
|
98
|
-
data:
|
|
109
|
+
data: RawRuneUtxo[];
|
|
99
110
|
}>;
|
|
100
|
-
|
|
101
|
-
next_cursor: string | null;
|
|
111
|
+
runeInfo(runeId: string): Promise<{
|
|
102
112
|
last_updated: {
|
|
103
113
|
block_hash: string;
|
|
104
114
|
block_height: bigint;
|
|
105
115
|
};
|
|
106
|
-
data:
|
|
116
|
+
data: RawRuneInfo;
|
|
107
117
|
}>;
|
|
108
118
|
}
|
|
109
119
|
|
|
@@ -114,7 +124,7 @@ export declare const Network: {
|
|
|
114
124
|
|
|
115
125
|
export declare type Network = (typeof Network)[keyof typeof Network];
|
|
116
126
|
|
|
117
|
-
declare type OutputCoin = {
|
|
127
|
+
export declare type OutputCoin = {
|
|
118
128
|
coin: CoinBalance;
|
|
119
129
|
to: string;
|
|
120
130
|
};
|
|
@@ -164,14 +174,11 @@ declare type RawBtcUtxo = {
|
|
|
164
174
|
address: string;
|
|
165
175
|
};
|
|
166
176
|
|
|
167
|
-
declare type
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
utxo_vout: number;
|
|
173
|
-
utxo_block_height: number;
|
|
174
|
-
utxo_confirmations: string;
|
|
177
|
+
declare type RawRuneInfo = {
|
|
178
|
+
id: string;
|
|
179
|
+
symbol: string;
|
|
180
|
+
spaced_name: string;
|
|
181
|
+
divisibility: number;
|
|
175
182
|
};
|
|
176
183
|
|
|
177
184
|
declare type RawRuneUtxo = {
|
|
@@ -217,7 +224,7 @@ export declare class ReeClient {
|
|
|
217
224
|
* Handles pagination automatically to fetch all available UTXOs
|
|
218
225
|
* @returns Array of Bitcoin UTXOs
|
|
219
226
|
*/
|
|
220
|
-
getBtcUtxos(paymentAddress: string): Promise<Utxo[]>;
|
|
227
|
+
getBtcUtxos(paymentAddress: string, excludeMetaprotocols?: boolean): Promise<Utxo[]>;
|
|
221
228
|
/**
|
|
222
229
|
* Get UTXOs containing a specific rune for the user's address
|
|
223
230
|
* @param runeId - The rune ID to filter UTXOs by
|
|
@@ -284,10 +291,7 @@ declare interface ReeContextValue {
|
|
|
284
291
|
address?: string;
|
|
285
292
|
paymentAddress?: string;
|
|
286
293
|
}) => void;
|
|
287
|
-
createTransaction: (
|
|
288
|
-
involvedRuneIds?: string[];
|
|
289
|
-
involvedPoolAddresses: string[];
|
|
290
|
-
}) => Promise<Transaction>;
|
|
294
|
+
createTransaction: () => Promise<Transaction>;
|
|
291
295
|
}
|
|
292
296
|
|
|
293
297
|
export declare function ReeProvider({ children, config }: ReeProviderProps): JSX_2.Element;
|
|
@@ -313,23 +317,17 @@ declare function toBitcoinNetwork(network: Network): bitcoin.networks.Network;
|
|
|
313
317
|
*/
|
|
314
318
|
export declare class Transaction {
|
|
315
319
|
private psbt;
|
|
320
|
+
private client;
|
|
316
321
|
private inputAddressTypes;
|
|
317
322
|
private outputAddressTypes;
|
|
318
323
|
private config;
|
|
319
324
|
/** Track dust amounts from user input UTXOs for fee calculation */
|
|
320
325
|
private userInputUtxoDusts;
|
|
321
|
-
/** Orchestrator actor for fee estimation */
|
|
322
|
-
readonly orchestrator: ActorSubclass;
|
|
323
326
|
private intentions;
|
|
324
327
|
private txFee;
|
|
325
328
|
private additionalDustNeeded;
|
|
326
329
|
private inputUtxos;
|
|
327
|
-
|
|
328
|
-
private getRuneUtxos;
|
|
329
|
-
constructor(config: TransactionConfig, orchestrator: ActorSubclass, utxoFetchers: {
|
|
330
|
-
btc: (address: string) => Promise<Utxo[]>;
|
|
331
|
-
rune: (address: string, runeId: string) => Promise<Utxo[]>;
|
|
332
|
-
});
|
|
330
|
+
constructor(config: TransactionConfig, client: ReeClient);
|
|
333
331
|
/**
|
|
334
332
|
* Add a UTXO as transaction input
|
|
335
333
|
* @param utxo - The UTXO to add as input
|
|
@@ -370,8 +368,70 @@ export declare class Transaction {
|
|
|
370
368
|
* @returns Fee calculation result
|
|
371
369
|
*/
|
|
372
370
|
private addBtcAndFees;
|
|
371
|
+
/**
|
|
372
|
+
* Resolve and fetch all UTXOs required by the current intention set, grouped by address.
|
|
373
|
+
*
|
|
374
|
+
* How it works:
|
|
375
|
+
* - Scans every intention to determine, per address, whether BTC UTXOs are needed and which rune IDs are needed.
|
|
376
|
+
* • For inputCoins, uses their `from` address.
|
|
377
|
+
* • For outputCoins, uses their `to` address.
|
|
378
|
+
* • Pool address is always considered “involved” for any coin that appears in the intention.
|
|
379
|
+
* • The user's payment address is always flagged as needing BTC (to pay fees/change).
|
|
380
|
+
* - Deduplicates addresses and rune IDs, then fetches UTXOs in parallel via the client:
|
|
381
|
+
* • BTC UTXOs: client.getBtcUtxos(address)
|
|
382
|
+
* • Rune UTXOs: client.getRuneUtxos(address, runeId)
|
|
383
|
+
* - Any fetch error is treated as an empty list for robustness.
|
|
384
|
+
*
|
|
385
|
+
* Returns:
|
|
386
|
+
* - An object with two maps:
|
|
387
|
+
* • btc: Record<address, Utxo[]>
|
|
388
|
+
* • rune: Record<address, Record<runeId, Utxo[]>>
|
|
389
|
+
*/
|
|
373
390
|
private getInvolvedAddressUtxos;
|
|
391
|
+
/**
|
|
392
|
+
* Select inputs (UTXOs) according to the intentions and compute the coin outputs per address.
|
|
393
|
+
*
|
|
394
|
+
* Inputs:
|
|
395
|
+
* - addressUtxos: UTXOs grouped as returned by getInvolvedAddressUtxos().
|
|
396
|
+
*
|
|
397
|
+
* Algorithm (high level):
|
|
398
|
+
* 1) Validate there is at least one intention.
|
|
399
|
+
* 2) For each intention, ensure symmetry between inputCoins and outputCoins around the pool:
|
|
400
|
+
* - 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.
|
|
401
|
+
* - If a coin is received from the pool by an address but not listed as input-from-pool, add an input-from-pool entry.
|
|
402
|
+
* 3) Aggregate per-address input and output coin amounts (addressInputCoinAmounts, addressOutputCoinAmounts).
|
|
403
|
+
* 4) For each [address, coinId] in the input amounts:
|
|
404
|
+
* - BTC (coinId === BITCOIN_ID):
|
|
405
|
+
* • If address is the user's payment address, we treat it specially by decrementing its BTC in addressOutputCoinAmounts
|
|
406
|
+
* (the actual funding and fee handling will be done later in addBtcAndFees).
|
|
407
|
+
* • Otherwise, select BTC UTXOs (preferring rune-free for non-pool addresses), add them as inputs, compute change and
|
|
408
|
+
* add that change to addressOutputCoinAmounts[address]. If the address is a pool, also credit any rune balances
|
|
409
|
+
* contained in selected pool BTC UTXOs to addressOutputCoinAmounts for later distribution.
|
|
410
|
+
* - Rune (coinId !== BITCOIN_ID): select rune UTXOs for the required runeId, add as inputs, compute rune change and add
|
|
411
|
+
* to addressOutputCoinAmounts[address].
|
|
412
|
+
* 5) Ensure all pool UTXOs are included: for pool addresses that only appear on the receiving side, add all their BTC/rune
|
|
413
|
+
* UTXOs as inputs and credit their total balances into addressOutputCoinAmounts accordingly.
|
|
414
|
+
*
|
|
415
|
+
* Returns:
|
|
416
|
+
* - addressOutputCoinAmounts: Record<address, Record<coinId, bigint>> — the final coin amounts to be sent to each address.
|
|
417
|
+
*/
|
|
374
418
|
private addInputsAndCalculateOutputs;
|
|
419
|
+
/**
|
|
420
|
+
* Materialize outputs from the computed addressReceiveCoinAmounts.
|
|
421
|
+
*
|
|
422
|
+
* Steps:
|
|
423
|
+
* 1) Collect all rune IDs present across recipients. If any runes are to be transferred, first build a Runestone (edicts)
|
|
424
|
+
* and add an OP_RETURN output (at index 0). Edicts reference subsequent output indices.
|
|
425
|
+
* 2) For each address that receives runes, also ensure a BTC output exists at that index:
|
|
426
|
+
* - If an explicit BTC amount is provided for the address and the address is not the user's own rune address, use it.
|
|
427
|
+
* - Otherwise, add a dust-sized BTC output (UTXO_DUST) to carry the runes, and track additionalDustNeeded for fees.
|
|
428
|
+
* After using an explicit BTC amount for a rune recipient, remove it from the remaining BTC-only outputs map.
|
|
429
|
+
* 3) Finally, add any remaining BTC-only outputs where amount > 0.
|
|
430
|
+
*
|
|
431
|
+
* Notes:
|
|
432
|
+
* - Output values are bigint; scripts use Uint8Array, compatible with bitcoinjs-lib v7.
|
|
433
|
+
* - Output ordering: OP_RETURN (if any) first, then rune recipients in the order we build edicts, then remaining BTC outputs.
|
|
434
|
+
*/
|
|
375
435
|
private addOutputs;
|
|
376
436
|
/**
|
|
377
437
|
* Add an intention to the transaction
|
|
@@ -544,7 +604,8 @@ export declare namespace utils {
|
|
|
544
604
|
bytesToHex,
|
|
545
605
|
toBitcoinNetwork,
|
|
546
606
|
getScriptByAddress,
|
|
547
|
-
getAddressType
|
|
607
|
+
getAddressType,
|
|
608
|
+
formatPoolUtxo
|
|
548
609
|
}
|
|
549
610
|
}
|
|
550
611
|
|