opnet 1.8.2 → 1.8.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/CHANGELOG.md +25 -0
- package/browser/_version.d.ts +1 -1
- package/browser/contracts/CallResult.d.ts +1 -0
- package/browser/contracts/interfaces/IProviderForCallResult.d.ts +2 -0
- package/browser/index.js +9930 -10100
- package/browser/noble-curves.js +3049 -2135
- package/browser/noble-hashes.js +1812 -2504
- package/browser/opnet.d.ts +1 -0
- package/browser/protobuf.js +2695 -2103
- package/browser/providers/AbstractRpcProvider.d.ts +2 -0
- package/browser/providers/interfaces/JSONRpcMethods.d.ts +1 -0
- package/browser/providers/websocket/types/WebSocketOpcodes.d.ts +2 -0
- package/browser/rolldown-runtime.js +35 -0
- package/browser/transactions/interfaces/BroadcastedTransactionPackage.d.ts +48 -0
- package/browser/utxos/UTXOsManager.d.ts +1 -0
- package/browser/vendors.js +36998 -45617
- package/browser/worker_threads-browser.js +7 -9
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/contracts/CallResult.d.ts +1 -0
- package/build/contracts/CallResult.js +59 -30
- package/build/contracts/interfaces/IProviderForCallResult.d.ts +2 -0
- package/build/opnet.d.ts +1 -0
- package/build/opnet.js +1 -0
- package/build/providers/AbstractRpcProvider.d.ts +2 -0
- package/build/providers/AbstractRpcProvider.js +15 -2
- package/build/providers/WebsocketRpcProvider.js +5 -0
- package/build/providers/interfaces/JSONRpcMethods.d.ts +1 -0
- package/build/providers/interfaces/JSONRpcMethods.js +1 -0
- package/build/providers/websocket/MethodMapping.js +6 -0
- package/build/providers/websocket/types/WebSocketOpcodes.d.ts +2 -0
- package/build/providers/websocket/types/WebSocketOpcodes.js +2 -0
- package/build/transactions/interfaces/BroadcastedTransactionPackage.d.ts +48 -0
- package/build/transactions/interfaces/BroadcastedTransactionPackage.js +1 -0
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/build/utxos/UTXOsManager.d.ts +1 -0
- package/build/utxos/UTXOsManager.js +37 -28
- package/docs/api-reference/provider-api.md +16 -0
- package/docs/api-reference/types-interfaces.md +91 -0
- package/docs/api-reference/utxo-manager-api.md +4 -2
- package/docs/svg/tx-broadcast-flow.svg +201 -0
- package/docs/transactions/broadcasting.md +124 -9
- package/package.json +18 -13
- package/src/_version.ts +1 -1
- package/src/contracts/CallResult.ts +92 -35
- package/src/contracts/Contract.ts +11 -4
- package/src/contracts/interfaces/IProviderForCallResult.ts +5 -0
- package/src/opnet.ts +1 -0
- package/src/providers/AbstractRpcProvider.ts +52 -5
- package/src/providers/WebsocketRpcProvider.ts +7 -0
- package/src/providers/interfaces/JSONRpcMethods.ts +1 -0
- package/src/providers/websocket/MethodMapping.ts +6 -0
- package/src/providers/websocket/types/WebSocketOpcodes.ts +2 -0
- package/src/transactions/interfaces/BroadcastedTransactionPackage.ts +72 -0
- package/src/utxos/UTXOsManager.ts +82 -46
|
@@ -11,6 +11,7 @@ export declare class UTXOsManager {
|
|
|
11
11
|
getUTXOs({ address, isCSV, optimize, mergePendingUTXOs, filterSpentUTXOs, olderThan, }: RequestUTXOsParams): Promise<UTXOs>;
|
|
12
12
|
getUTXOsForAmount({ address, amount, csvAddress, optimize, mergePendingUTXOs, filterSpentUTXOs, throwErrors, olderThan, maxUTXOs, throwIfUTXOsLimitReached, }: RequestUTXOsParamsWithAmount): Promise<UTXOs>;
|
|
13
13
|
getMultipleUTXOs({ requests, mergePendingUTXOs, filterSpentUTXOs, }: RequestMultipleUTXOsParams): Promise<Record<string, UTXOs>>;
|
|
14
|
+
private selectUTXOsGreedily;
|
|
14
15
|
private fetchMultipleUTXOs;
|
|
15
16
|
private getAddressData;
|
|
16
17
|
private maybeFetchUTXOs;
|
|
@@ -96,44 +96,31 @@ export class UTXOsManager {
|
|
|
96
96
|
return finalUTXOs;
|
|
97
97
|
}
|
|
98
98
|
async getUTXOsForAmount({ address, amount, csvAddress, optimize = true, mergePendingUTXOs = true, filterSpentUTXOs = true, throwErrors = false, olderThan, maxUTXOs = 5000, throwIfUTXOsLimitReached = false, }) {
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
99
|
+
const selected = [];
|
|
100
|
+
let currentValue = 0n;
|
|
101
|
+
const normalUTXOs = await this.getUTXOs({
|
|
102
|
+
address,
|
|
103
|
+
optimize,
|
|
104
|
+
mergePendingUTXOs,
|
|
105
|
+
filterSpentUTXOs,
|
|
106
|
+
olderThan,
|
|
107
|
+
});
|
|
108
|
+
currentValue = this.selectUTXOsGreedily(normalUTXOs, selected, currentValue, amount, maxUTXOs, throwIfUTXOsLimitReached);
|
|
109
|
+
if (currentValue < amount && csvAddress) {
|
|
110
|
+
const csvUTXOs = await this.getUTXOs({
|
|
102
111
|
address: csvAddress,
|
|
103
112
|
optimize: true,
|
|
104
113
|
mergePendingUTXOs: false,
|
|
105
114
|
filterSpentUTXOs: true,
|
|
106
115
|
olderThan: 1n,
|
|
107
116
|
isCSV: true,
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
utxosPromises.push(this.getUTXOs({
|
|
111
|
-
address,
|
|
112
|
-
optimize,
|
|
113
|
-
mergePendingUTXOs,
|
|
114
|
-
filterSpentUTXOs,
|
|
115
|
-
olderThan,
|
|
116
|
-
}));
|
|
117
|
-
const combinedUTXOs = (await Promise.all(utxosPromises)).flat();
|
|
118
|
-
const utxoUntilAmount = [];
|
|
119
|
-
let currentValue = 0n;
|
|
120
|
-
for (const utxo of combinedUTXOs) {
|
|
121
|
-
if (maxUTXOs && utxoUntilAmount.length >= maxUTXOs) {
|
|
122
|
-
if (throwIfUTXOsLimitReached) {
|
|
123
|
-
throw new Error(`Woah. You must consolidate your UTXOs (${combinedUTXOs.length})! This transaction is too large.`);
|
|
124
|
-
}
|
|
125
|
-
break;
|
|
126
|
-
}
|
|
127
|
-
utxoUntilAmount.push(utxo);
|
|
128
|
-
currentValue += utxo.value;
|
|
129
|
-
if (currentValue >= amount) {
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
117
|
+
});
|
|
118
|
+
currentValue = this.selectUTXOsGreedily(csvUTXOs, selected, currentValue, amount, maxUTXOs, throwIfUTXOsLimitReached);
|
|
132
119
|
}
|
|
133
120
|
if (currentValue < amount && throwErrors) {
|
|
134
121
|
throw new Error(`Insufficient UTXOs to cover amount. Available: ${currentValue}, Needed: ${amount}`);
|
|
135
122
|
}
|
|
136
|
-
return
|
|
123
|
+
return selected;
|
|
137
124
|
}
|
|
138
125
|
async getMultipleUTXOs({ requests, mergePendingUTXOs = true, filterSpentUTXOs = true, }) {
|
|
139
126
|
if (requests.length === 0) {
|
|
@@ -190,6 +177,28 @@ export class UTXOsManager {
|
|
|
190
177
|
}
|
|
191
178
|
return result;
|
|
192
179
|
}
|
|
180
|
+
selectUTXOsGreedily(candidates, selected, currentValue, amount, maxUTXOs, throwIfLimitReached) {
|
|
181
|
+
candidates.sort((a, b) => {
|
|
182
|
+
if (b.value > a.value)
|
|
183
|
+
return 1;
|
|
184
|
+
if (b.value < a.value)
|
|
185
|
+
return -1;
|
|
186
|
+
return 0;
|
|
187
|
+
});
|
|
188
|
+
for (const utxo of candidates) {
|
|
189
|
+
if (currentValue >= amount)
|
|
190
|
+
break;
|
|
191
|
+
if (maxUTXOs && selected.length >= maxUTXOs) {
|
|
192
|
+
if (throwIfLimitReached) {
|
|
193
|
+
throw new Error(`Woah. You must consolidate your UTXOs (${candidates.length + selected.length})! This transaction is too large.`);
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
selected.push(utxo);
|
|
198
|
+
currentValue += utxo.value;
|
|
199
|
+
}
|
|
200
|
+
return currentValue;
|
|
201
|
+
}
|
|
193
202
|
async fetchMultipleUTXOs(requests) {
|
|
194
203
|
const payloads = requests.map((request) => {
|
|
195
204
|
const data = [request.address, request.optimize ?? true];
|
|
@@ -218,6 +218,22 @@ Broadcast multiple transactions.
|
|
|
218
218
|
sendRawTransactions(txs: string[]): Promise<BroadcastedTransaction[]>
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
+
### sendRawTransactionPackage
|
|
222
|
+
|
|
223
|
+
Broadcast a package of raw transactions atomically via Bitcoin Core's `submitpackage` RPC, or fall back to validated sequential broadcast.
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
sendRawTransactionPackage(
|
|
227
|
+
txs: string[],
|
|
228
|
+
isPackage?: boolean
|
|
229
|
+
): Promise<BroadcastedTransactionPackage>
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
| Parameter | Type | Default | Description |
|
|
233
|
+
|-----------|------|---------|-------------|
|
|
234
|
+
| `txs` | `string[]` | Required | Raw transactions as hex strings (max 25) |
|
|
235
|
+
| `isPackage` | `boolean` | `true` | Use atomic `submitpackage` (`true`) or validated sequential broadcast (`false`) |
|
|
236
|
+
|
|
221
237
|
### getChallenge
|
|
222
238
|
|
|
223
239
|
Get the current PoW challenge.
|
|
@@ -274,6 +274,97 @@ interface BroadcastedTransaction {
|
|
|
274
274
|
}
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
+
### BroadcastedTransactionPackage
|
|
278
|
+
|
|
279
|
+
Result of a package broadcast via [`sendRawTransactionPackage()`](./provider-api.md#sendrawtransactionpackage).
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
interface BroadcastedTransactionPackage {
|
|
283
|
+
/** Whether the overall package broadcast succeeded. */
|
|
284
|
+
readonly success: boolean;
|
|
285
|
+
/** Error message if the broadcast failed. */
|
|
286
|
+
readonly error?: string;
|
|
287
|
+
/** Present when testMempoolAccept was used (sequential or single tx path). */
|
|
288
|
+
readonly testResults?: readonly TestMempoolAcceptResult[];
|
|
289
|
+
/** Present when submitPackage was used successfully. */
|
|
290
|
+
readonly packageResult?: PackageResult;
|
|
291
|
+
/** Per-transaction results for sequential or single tx broadcasts. */
|
|
292
|
+
readonly sequentialResults?: readonly SequentialBroadcastTxResult[];
|
|
293
|
+
/** True when submitPackage failed and the node fell back to sequential broadcast. */
|
|
294
|
+
readonly fellBackToSequential?: boolean;
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### SequentialBroadcastTxResult
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
interface SequentialBroadcastTxResult {
|
|
302
|
+
readonly txid: string;
|
|
303
|
+
readonly success: boolean;
|
|
304
|
+
readonly error?: string;
|
|
305
|
+
readonly peers?: number;
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### TestMempoolAcceptResult
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
interface TestMempoolAcceptResult {
|
|
313
|
+
readonly txid: string;
|
|
314
|
+
readonly wtxid: string;
|
|
315
|
+
readonly allowed?: boolean;
|
|
316
|
+
readonly vsize?: number;
|
|
317
|
+
readonly packageError?: string;
|
|
318
|
+
readonly rejectReason?: string;
|
|
319
|
+
readonly rejectDetails?: string;
|
|
320
|
+
readonly fees?: TestMempoolAcceptFees;
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### TestMempoolAcceptFees
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
interface TestMempoolAcceptFees {
|
|
328
|
+
readonly base: number;
|
|
329
|
+
readonly effectiveFeerate: number;
|
|
330
|
+
readonly effectiveIncludes: readonly string[];
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### PackageResult
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
interface PackageResult {
|
|
338
|
+
readonly packageMsg: string;
|
|
339
|
+
readonly txResults: {
|
|
340
|
+
readonly [wtxid: string]: PackageTxResult;
|
|
341
|
+
};
|
|
342
|
+
readonly replacedTransactions?: readonly string[];
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### PackageTxResult
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
interface PackageTxResult {
|
|
350
|
+
readonly txid: string;
|
|
351
|
+
readonly otherWtxid?: string;
|
|
352
|
+
readonly vsize?: number;
|
|
353
|
+
readonly fees?: PackageTxFees;
|
|
354
|
+
readonly error?: string;
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### PackageTxFees
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
interface PackageTxFees {
|
|
362
|
+
readonly base: number;
|
|
363
|
+
readonly effectiveFeerate?: number;
|
|
364
|
+
readonly effectiveIncludes?: readonly string[];
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
277
368
|
---
|
|
278
369
|
|
|
279
370
|
## Contract Types
|
|
@@ -53,12 +53,14 @@ async getUTXOsForAmount(
|
|
|
53
53
|
interface RequestUTXOsParamsWithAmount extends RequestUTXOsParams {
|
|
54
54
|
readonly amount: bigint; // Amount to cover
|
|
55
55
|
readonly throwErrors?: boolean; // Throw if insufficient
|
|
56
|
-
readonly csvAddress?: string; // CSV address
|
|
57
|
-
readonly maxUTXOs?: number; // Max UTXOs to select
|
|
56
|
+
readonly csvAddress?: string; // CSV address as fallback
|
|
57
|
+
readonly maxUTXOs?: number; // Max UTXOs to select (default: 5000)
|
|
58
58
|
readonly throwIfUTXOsLimitReached?: boolean; // Throw if limit reached
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
> **Note:** `getUTXOsForAmount` prioritizes normal UTXOs first and only falls back to CSV UTXOs if normal ones cannot cover the requested amount. UTXOs are sorted by value descending (largest first) for greedy selection.
|
|
63
|
+
|
|
62
64
|
### spentUTXO
|
|
63
65
|
|
|
64
66
|
Mark UTXOs as spent and register new UTXOs (for tracking).
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 860 1080" font-family="'Segoe UI','Helvetica Neue',sans-serif">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="0.3" y2="1">
|
|
4
|
+
<stop offset="0%" stop-color="#1a1520"/>
|
|
5
|
+
<stop offset="50%" stop-color="#151119"/>
|
|
6
|
+
<stop offset="100%" stop-color="#0e0b12"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<linearGradient id="card" x1="0" y1="0" x2="0" y2="1">
|
|
9
|
+
<stop offset="0%" stop-color="#2a2233"/>
|
|
10
|
+
<stop offset="100%" stop-color="#1f1928"/>
|
|
11
|
+
</linearGradient>
|
|
12
|
+
<linearGradient id="entryGrad" x1="0" y1="0" x2="1" y2="1">
|
|
13
|
+
<stop offset="0%" stop-color="#c084fc"/>
|
|
14
|
+
<stop offset="100%" stop-color="#a855f7"/>
|
|
15
|
+
</linearGradient>
|
|
16
|
+
<filter id="softGlow">
|
|
17
|
+
<feGaussianBlur stdDeviation="6" result="blur"/>
|
|
18
|
+
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
19
|
+
</filter>
|
|
20
|
+
<filter id="cardShadow">
|
|
21
|
+
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.35"/>
|
|
22
|
+
</filter>
|
|
23
|
+
<marker id="arrW" markerWidth="7" markerHeight="5" refX="7" refY="2.5" orient="auto">
|
|
24
|
+
<path d="M0,0 L7,2.5 L0,5" fill="none" stroke="#7c6f8a" stroke-width="1.2" stroke-linejoin="round"/>
|
|
25
|
+
</marker>
|
|
26
|
+
<marker id="arrG" markerWidth="7" markerHeight="5" refX="7" refY="2.5" orient="auto">
|
|
27
|
+
<path d="M0,0 L7,2.5 L0,5" fill="none" stroke="#4ade80" stroke-width="1.2" stroke-linejoin="round"/>
|
|
28
|
+
</marker>
|
|
29
|
+
<marker id="arrR" markerWidth="7" markerHeight="5" refX="7" refY="2.5" orient="auto">
|
|
30
|
+
<path d="M0,0 L7,2.5 L0,5" fill="none" stroke="#fb7185" stroke-width="1.2" stroke-linejoin="round"/>
|
|
31
|
+
</marker>
|
|
32
|
+
<marker id="arrO" markerWidth="7" markerHeight="5" refX="7" refY="2.5" orient="auto">
|
|
33
|
+
<path d="M0,0 L7,2.5 L0,5" fill="none" stroke="#fbbf24" stroke-width="1.2" stroke-linejoin="round"/>
|
|
34
|
+
</marker>
|
|
35
|
+
</defs>
|
|
36
|
+
|
|
37
|
+
<!-- Background -->
|
|
38
|
+
<rect width="860" height="1080" fill="url(#bg)" rx="16"/>
|
|
39
|
+
|
|
40
|
+
<!-- Decorative ambient circles -->
|
|
41
|
+
<circle cx="780" cy="80" r="120" fill="#a855f7" opacity="0.03"/>
|
|
42
|
+
<circle cx="60" cy="950" r="160" fill="#4ade80" opacity="0.025"/>
|
|
43
|
+
<circle cx="430" cy="540" r="300" fill="#a855f7" opacity="0.012"/>
|
|
44
|
+
|
|
45
|
+
<!-- ====== TITLE ====== -->
|
|
46
|
+
<text x="430" y="52" text-anchor="middle" fill="#e8dff0" font-size="22" font-weight="600" letter-spacing="0.5">How Transactions Get Broadcast</text>
|
|
47
|
+
<text x="430" y="76" text-anchor="middle" fill="#7c6f8a" font-size="13">From your wallet to the Bitcoin network</text>
|
|
48
|
+
|
|
49
|
+
<!-- ====== ENTRY PILL ====== -->
|
|
50
|
+
<rect x="295" y="104" width="270" height="52" rx="26" fill="url(#entryGrad)" filter="url(#softGlow)" opacity="0.9"/>
|
|
51
|
+
<text x="430" y="127" text-anchor="middle" fill="#fff" font-size="14" font-weight="600">You submit transactions</text>
|
|
52
|
+
<text x="430" y="145" text-anchor="middle" fill="#ede2ff" font-size="11" opacity="0.85">one or more, as an ordered batch</text>
|
|
53
|
+
|
|
54
|
+
<!-- Arrow down -->
|
|
55
|
+
<line x1="430" y1="156" x2="430" y2="194" stroke="#7c6f8a" stroke-width="1.5" marker-end="url(#arrW)"/>
|
|
56
|
+
|
|
57
|
+
<!-- ====== DECISION: How many? ====== -->
|
|
58
|
+
<rect x="320" y="198" width="220" height="48" rx="24" fill="url(#card)" stroke="#3d3350" stroke-width="1" filter="url(#cardShadow)"/>
|
|
59
|
+
<text x="430" y="220" text-anchor="middle" fill="#d4bfea" font-size="13" font-weight="500">How many transactions?</text>
|
|
60
|
+
<text x="430" y="237" text-anchor="middle" fill="#7c6f8a" font-size="11">checking the batch size</text>
|
|
61
|
+
|
|
62
|
+
<!-- ====== PATH A: Just One (left branch) ====== -->
|
|
63
|
+
<line x1="320" y1="222" x2="150" y2="222" stroke="#4ade80" stroke-width="1.5" marker-end="url(#arrG)"/>
|
|
64
|
+
<rect x="128" y="206" width="48" height="20" rx="10" fill="#1a2e1a"/>
|
|
65
|
+
<text x="152" y="220" text-anchor="middle" fill="#4ade80" font-size="10" font-weight="600">JUST 1</text>
|
|
66
|
+
|
|
67
|
+
<rect x="22" y="258" width="220" height="120" rx="14" fill="url(#card)" stroke="#2d4a2d" stroke-width="1" filter="url(#cardShadow)"/>
|
|
68
|
+
<circle cx="50" cy="286" r="12" fill="#1a2e1a" stroke="#4ade80" stroke-width="1"/>
|
|
69
|
+
<text x="50" y="291" text-anchor="middle" fill="#4ade80" font-size="14">1</text>
|
|
70
|
+
<text x="72" y="291" fill="#d4bfea" font-size="13" font-weight="500">Simple Path</text>
|
|
71
|
+
<line x1="38" y1="306" x2="226" y2="306" stroke="#2d4a2d" stroke-width="0.7"/>
|
|
72
|
+
<text x="132" y="326" text-anchor="middle" fill="#b8a5cc" font-size="11.5">First, validate the transaction</text>
|
|
73
|
+
<text x="132" y="344" text-anchor="middle" fill="#b8a5cc" font-size="11.5">against the mempool.</text>
|
|
74
|
+
<text x="132" y="365" text-anchor="middle" fill="#b8a5cc" font-size="11.5">If it passes, send it out.</text>
|
|
75
|
+
|
|
76
|
+
<line x1="132" y1="378" x2="132" y2="410" stroke="#4ade80" stroke-width="1.2" marker-end="url(#arrG)"/>
|
|
77
|
+
<rect x="82" y="414" width="100" height="30" rx="15" fill="#0f2a14" stroke="#22c55e" stroke-width="1"/>
|
|
78
|
+
<text x="132" y="434" text-anchor="middle" fill="#4ade80" font-size="12" font-weight="500">Done</text>
|
|
79
|
+
|
|
80
|
+
<!-- ====== Multiple txs (down branch) ====== -->
|
|
81
|
+
<line x1="430" y1="246" x2="430" y2="294" stroke="#7c6f8a" stroke-width="1.5" marker-end="url(#arrW)"/>
|
|
82
|
+
<rect x="380" y="252" width="82" height="20" rx="10" fill="#1f1928"/>
|
|
83
|
+
<text x="421" y="266" text-anchor="middle" fill="#b8a5cc" font-size="10">MULTIPLE</text>
|
|
84
|
+
|
|
85
|
+
<!-- ====== DECISION: Package mode? ====== -->
|
|
86
|
+
<rect x="310" y="298" width="240" height="48" rx="24" fill="url(#card)" stroke="#3d3350" stroke-width="1" filter="url(#cardShadow)"/>
|
|
87
|
+
<text x="430" y="320" text-anchor="middle" fill="#d4bfea" font-size="13" font-weight="500">Try package mode?</text>
|
|
88
|
+
<text x="430" y="337" text-anchor="middle" fill="#7c6f8a" font-size="11">on by default</text>
|
|
89
|
+
|
|
90
|
+
<!-- ====== PATH B: Package Submission (right branch) ====== -->
|
|
91
|
+
<line x1="550" y1="322" x2="618" y2="322" stroke="#4ade80" stroke-width="1.5" marker-end="url(#arrG)"/>
|
|
92
|
+
<rect x="560" y="306" width="44" height="20" rx="10" fill="#1a2e1a"/>
|
|
93
|
+
<text x="582" y="320" text-anchor="middle" fill="#4ade80" font-size="10" font-weight="600">YES</text>
|
|
94
|
+
|
|
95
|
+
<rect x="622" y="270" width="216" height="142" rx="14" fill="url(#card)" stroke="#2d4a2d" stroke-width="1" filter="url(#cardShadow)"/>
|
|
96
|
+
<circle cx="650" cy="298" r="12" fill="#1a2e1a" stroke="#4ade80" stroke-width="1"/>
|
|
97
|
+
<text x="650" y="303" text-anchor="middle" fill="#4ade80" font-size="14">2</text>
|
|
98
|
+
<text x="672" y="303" fill="#d4bfea" font-size="13" font-weight="500">Package Relay</text>
|
|
99
|
+
<line x1="638" y1="318" x2="822" y2="318" stroke="#2d4a2d" stroke-width="0.7"/>
|
|
100
|
+
<text x="730" y="339" text-anchor="middle" fill="#b8a5cc" font-size="11.5">Submit all transactions as</text>
|
|
101
|
+
<text x="730" y="357" text-anchor="middle" fill="#b8a5cc" font-size="11.5">a single atomic package.</text>
|
|
102
|
+
<text x="730" y="378" text-anchor="middle" fill="#b8a5cc" font-size="11.5">The network validates them</text>
|
|
103
|
+
<text x="730" y="396" text-anchor="middle" fill="#b8a5cc" font-size="11.5">together, including fees.</text>
|
|
104
|
+
|
|
105
|
+
<!-- Package success -->
|
|
106
|
+
<line x1="838" y1="341" x2="852" y2="341" stroke="#4ade80" stroke-width="1"/>
|
|
107
|
+
<line x1="852" y1="341" x2="852" y2="430" stroke="#4ade80" stroke-width="1"/>
|
|
108
|
+
<line x1="852" y1="430" x2="790" y2="430" stroke="#4ade80" stroke-width="1.2" marker-end="url(#arrG)"/>
|
|
109
|
+
<rect x="690" y="416" width="95" height="30" rx="15" fill="#0f2a14" stroke="#22c55e" stroke-width="1"/>
|
|
110
|
+
<text x="737" y="436" text-anchor="middle" fill="#4ade80" font-size="12" font-weight="500">Done</text>
|
|
111
|
+
<text x="848" y="390" fill="#4ade80" font-size="10" font-weight="500">OK</text>
|
|
112
|
+
|
|
113
|
+
<!-- Package failure: fallback -->
|
|
114
|
+
<line x1="730" y1="412" x2="730" y2="482" stroke="#fbbf24" stroke-width="1.5" stroke-dasharray="5,4" marker-end="url(#arrO)"/>
|
|
115
|
+
<rect x="688" y="454" width="84" height="20" rx="10" fill="#2e2510"/>
|
|
116
|
+
<text x="730" y="468" text-anchor="middle" fill="#fbbf24" font-size="10" font-weight="600">FAILED</text>
|
|
117
|
+
|
|
118
|
+
<rect x="640" y="486" width="180" height="56" rx="12" fill="#2a2010" stroke="#92400e" stroke-width="1" filter="url(#cardShadow)"/>
|
|
119
|
+
<text x="730" y="510" text-anchor="middle" fill="#fbbf24" font-size="12" font-weight="500">Falls back gracefully</text>
|
|
120
|
+
<text x="730" y="528" text-anchor="middle" fill="#a08050" font-size="10.5">tries the one-by-one approach</text>
|
|
121
|
+
|
|
122
|
+
<!-- Fallback arrow merges into sequential path -->
|
|
123
|
+
<path d="M640,514 Q560,560 500,580" fill="none" stroke="#fbbf24" stroke-width="1.2" stroke-dasharray="5,4" marker-end="url(#arrO)"/>
|
|
124
|
+
|
|
125
|
+
<!-- ====== PATH C: Sequential (down from package decision) ====== -->
|
|
126
|
+
<line x1="430" y1="346" x2="430" y2="488" stroke="#fb7185" stroke-width="1.5" marker-end="url(#arrR)"/>
|
|
127
|
+
<rect x="408" y="352" width="38" height="20" rx="10" fill="#2e1a1f"/>
|
|
128
|
+
<text x="427" y="366" text-anchor="middle" fill="#fb7185" font-size="10" font-weight="600">NO</text>
|
|
129
|
+
|
|
130
|
+
<!-- Merge zone label -->
|
|
131
|
+
<rect x="126" y="480" width="410" height="28" rx="14" fill="none" stroke="#3d3350" stroke-width="0.8" stroke-dasharray="6,4"/>
|
|
132
|
+
<text x="331" y="499" text-anchor="middle" fill="#7c6f8a" font-size="10.5">One-by-one approach (or fallback from package failure)</text>
|
|
133
|
+
|
|
134
|
+
<!-- Step 3: Validate all -->
|
|
135
|
+
<rect x="250" y="530" width="290" height="100" rx="14" fill="url(#card)" stroke="#3d2d4a" stroke-width="1" filter="url(#cardShadow)"/>
|
|
136
|
+
<circle cx="282" cy="560" r="14" fill="#2a1a38" stroke="#a855f7" stroke-width="1"/>
|
|
137
|
+
<text x="282" y="565" text-anchor="middle" fill="#c084fc" font-size="13" font-weight="600">3</text>
|
|
138
|
+
<text x="306" y="565" fill="#d4bfea" font-size="13" font-weight="500">Validate Everything First</text>
|
|
139
|
+
<line x1="266" y1="580" x2="524" y2="580" stroke="#3d2d4a" stroke-width="0.7"/>
|
|
140
|
+
<text x="395" y="600" text-anchor="middle" fill="#b8a5cc" font-size="11.5">Check every transaction against</text>
|
|
141
|
+
<text x="395" y="618" text-anchor="middle" fill="#b8a5cc" font-size="11.5">the mempool before sending any.</text>
|
|
142
|
+
|
|
143
|
+
<line x1="395" y1="630" x2="395" y2="668" stroke="#7c6f8a" stroke-width="1.5" marker-end="url(#arrW)"/>
|
|
144
|
+
|
|
145
|
+
<rect x="290" y="672" width="210" height="42" rx="21" fill="url(#card)" stroke="#3d3350" stroke-width="1"/>
|
|
146
|
+
<text x="395" y="698" text-anchor="middle" fill="#d4bfea" font-size="12.5">Did they all pass?</text>
|
|
147
|
+
|
|
148
|
+
<!-- Fail left -->
|
|
149
|
+
<line x1="290" y1="693" x2="180" y2="693" stroke="#fb7185" stroke-width="1.5" marker-end="url(#arrR)"/>
|
|
150
|
+
<rect x="236" y="680" width="42" height="18" rx="9" fill="#2e1a1f"/>
|
|
151
|
+
<text x="257" y="693" text-anchor="middle" fill="#fb7185" font-size="10" font-weight="600">NO</text>
|
|
152
|
+
|
|
153
|
+
<rect x="36" y="676" width="140" height="42" rx="12" fill="#2a0f15" stroke="#9f1239" stroke-width="1" filter="url(#cardShadow)"/>
|
|
154
|
+
<text x="106" y="695" text-anchor="middle" fill="#fb7185" font-size="12" font-weight="500">Rejected</text>
|
|
155
|
+
<text x="106" y="710" text-anchor="middle" fill="#885060" font-size="10">tells you what failed</text>
|
|
156
|
+
|
|
157
|
+
<!-- Pass down -->
|
|
158
|
+
<line x1="395" y1="714" x2="395" y2="758" stroke="#4ade80" stroke-width="1.5" marker-end="url(#arrG)"/>
|
|
159
|
+
<rect x="370" y="722" width="44" height="18" rx="9" fill="#1a2e1a"/>
|
|
160
|
+
<text x="392" y="735" text-anchor="middle" fill="#4ade80" font-size="10" font-weight="600">YES</text>
|
|
161
|
+
|
|
162
|
+
<!-- Step 4: Send one by one -->
|
|
163
|
+
<rect x="250" y="762" width="290" height="118" rx="14" fill="url(#card)" stroke="#3d2d4a" stroke-width="1" filter="url(#cardShadow)"/>
|
|
164
|
+
<circle cx="282" cy="792" r="14" fill="#2a1a38" stroke="#a855f7" stroke-width="1"/>
|
|
165
|
+
<text x="282" y="797" text-anchor="middle" fill="#c084fc" font-size="13" font-weight="600">4</text>
|
|
166
|
+
<text x="306" y="797" fill="#d4bfea" font-size="13" font-weight="500">Send One by One</text>
|
|
167
|
+
<line x1="266" y1="812" x2="524" y2="812" stroke="#3d2d4a" stroke-width="0.7"/>
|
|
168
|
+
<text x="395" y="832" text-anchor="middle" fill="#b8a5cc" font-size="11.5">Send each transaction in order.</text>
|
|
169
|
+
<text x="395" y="852" text-anchor="middle" fill="#b8a5cc" font-size="11.5">If one fails, stop immediately</text>
|
|
170
|
+
<text x="395" y="870" text-anchor="middle" fill="#b8a5cc" font-size="11.5">since later ones depend on it.</text>
|
|
171
|
+
|
|
172
|
+
<!-- Fail branch from send loop -->
|
|
173
|
+
<line x1="250" y1="840" x2="180" y2="840" stroke="#fb7185" stroke-width="1.2" marker-end="url(#arrR)"/>
|
|
174
|
+
<rect x="36" y="822" width="140" height="42" rx="12" fill="#2a0f15" stroke="#9f1239" stroke-width="1" filter="url(#cardShadow)"/>
|
|
175
|
+
<text x="106" y="841" text-anchor="middle" fill="#fb7185" font-size="12" font-weight="500">Stopped early</text>
|
|
176
|
+
<text x="106" y="856" text-anchor="middle" fill="#885060" font-size="10">partial results returned</text>
|
|
177
|
+
|
|
178
|
+
<!-- Loop indicator -->
|
|
179
|
+
<path d="M540,800 C574,800 574,864 540,864" fill="none" stroke="#7c6f8a" stroke-width="1" stroke-dasharray="3,3"/>
|
|
180
|
+
<text x="582" y="836" fill="#7c6f8a" font-size="10">repeats</text>
|
|
181
|
+
|
|
182
|
+
<!-- Success from send loop -->
|
|
183
|
+
<line x1="395" y1="880" x2="395" y2="920" stroke="#4ade80" stroke-width="1.5" marker-end="url(#arrG)"/>
|
|
184
|
+
|
|
185
|
+
<!-- Final success -->
|
|
186
|
+
<rect x="335" y="924" width="120" height="36" rx="18" fill="#0f2a14" stroke="#22c55e" stroke-width="1.2" filter="url(#softGlow)"/>
|
|
187
|
+
<text x="395" y="948" text-anchor="middle" fill="#4ade80" font-size="13" font-weight="600">All sent</text>
|
|
188
|
+
|
|
189
|
+
<!-- ====== LEGEND ====== -->
|
|
190
|
+
<rect x="50" y="990" width="760" height="70" rx="14" fill="#1a1520" stroke="#2a2233" stroke-width="1"/>
|
|
191
|
+
<circle cx="100" cy="1025" r="8" fill="#0f2a14" stroke="#22c55e" stroke-width="1"/>
|
|
192
|
+
<text x="118" y="1030" fill="#9a8aaa" font-size="11">Success</text>
|
|
193
|
+
<circle cx="220" cy="1025" r="8" fill="#2a0f15" stroke="#f43f5e" stroke-width="1"/>
|
|
194
|
+
<text x="238" y="1030" fill="#9a8aaa" font-size="11">Failure</text>
|
|
195
|
+
<circle cx="340" cy="1025" r="8" fill="#2a2010" stroke="#f59e0b" stroke-width="1"/>
|
|
196
|
+
<text x="358" y="1030" fill="#9a8aaa" font-size="11">Fallback</text>
|
|
197
|
+
<line x1="460" y1="1025" x2="490" y2="1025" stroke="#7c6f8a" stroke-width="1.5" marker-end="url(#arrW)"/>
|
|
198
|
+
<text x="500" y="1030" fill="#9a8aaa" font-size="11">Flow</text>
|
|
199
|
+
<line x1="570" y1="1025" x2="600" y2="1025" stroke="#fbbf24" stroke-width="1.5" stroke-dasharray="5,4" marker-end="url(#arrO)"/>
|
|
200
|
+
<text x="610" y="1030" fill="#9a8aaa" font-size="11">Graceful retry</text>
|
|
201
|
+
</svg>
|
|
@@ -6,15 +6,7 @@ This guide covers broadcasting raw transactions on OPNet.
|
|
|
6
6
|
|
|
7
7
|
After building and signing a transaction, it needs to be broadcast to the network. OPNet supports both single and batch transaction broadcasting.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
flowchart LR
|
|
11
|
-
A[Signed Transaction] --> B[sendRawTransaction]
|
|
12
|
-
B --> C[Network]
|
|
13
|
-
C --> D[BroadcastedTransaction]
|
|
14
|
-
D --> E{Success?}
|
|
15
|
-
E -->|Yes| F[Propagated]
|
|
16
|
-
E -->|No| G[Error]
|
|
17
|
-
```
|
|
9
|
+

|
|
18
10
|
|
|
19
11
|
---
|
|
20
12
|
|
|
@@ -81,6 +73,129 @@ interface BroadcastedTransaction {
|
|
|
81
73
|
|
|
82
74
|
---
|
|
83
75
|
|
|
76
|
+
## Send Transaction Package
|
|
77
|
+
|
|
78
|
+
### Atomic Package Broadcasting
|
|
79
|
+
|
|
80
|
+
Use `sendRawTransactionPackage` to broadcast an ordered array of raw transactions atomically via Bitcoin Core's `submitpackage` RPC. This is ideal for CPFP (Child-Pays-For-Parent) chains or any set of dependent transactions that must be accepted together.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { JSONRpcProvider, BroadcastedTransactionPackage } from 'opnet';
|
|
84
|
+
import { networks } from '@btc-vision/bitcoin';
|
|
85
|
+
|
|
86
|
+
const network = networks.regtest;
|
|
87
|
+
const provider = new JSONRpcProvider({ url: 'https://regtest.opnet.org', network });
|
|
88
|
+
|
|
89
|
+
const parentTx = '02000000000101...';
|
|
90
|
+
const childTx = '02000000000101...';
|
|
91
|
+
|
|
92
|
+
// Atomic package submission (uses submitpackage RPC)
|
|
93
|
+
const result: BroadcastedTransactionPackage = await provider.sendRawTransactionPackage(
|
|
94
|
+
[parentTx, childTx],
|
|
95
|
+
true, // isPackage=true (default) for atomic submission
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
if (result.success) {
|
|
99
|
+
console.log('Package broadcast successfully!');
|
|
100
|
+
|
|
101
|
+
if (result.packageResult) {
|
|
102
|
+
console.log('Package message:', result.packageResult.packageMsg);
|
|
103
|
+
for (const [wtxid, txResult] of Object.entries(result.packageResult.txResults)) {
|
|
104
|
+
console.log(` ${wtxid}: txid=${txResult.txid}, vsize=${txResult.vsize}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (result.sequentialResults) {
|
|
109
|
+
for (const seq of result.sequentialResults) {
|
|
110
|
+
console.log(`${seq.txid}: success=${seq.success}, peers=${seq.peers}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
console.log('Package broadcast failed:', result.error);
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Sequential Validated Broadcasting
|
|
119
|
+
|
|
120
|
+
Set `isPackage=false` to use validated sequential broadcast instead. This first validates all transactions with `testmempoolaccept`, then broadcasts each one individually.
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Sequential broadcast (testmempoolaccept + sendrawtransaction)
|
|
124
|
+
const result = await provider.sendRawTransactionPackage(
|
|
125
|
+
[tx1, tx2, tx3],
|
|
126
|
+
false, // sequential validated broadcast
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
if (result.success) {
|
|
130
|
+
if (result.testResults) {
|
|
131
|
+
for (const test of result.testResults) {
|
|
132
|
+
console.log(`${test.txid}: allowed=${test.allowed}, vsize=${test.vsize}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (result.sequentialResults) {
|
|
137
|
+
for (const seq of result.sequentialResults) {
|
|
138
|
+
console.log(`${seq.txid}: success=${seq.success}, peers=${seq.peers}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Check if the node fell back to sequential from package
|
|
144
|
+
if (result.fellBackToSequential) {
|
|
145
|
+
console.log('submitpackage failed, fell back to sequential broadcast');
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Method Signature
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
async sendRawTransactionPackage(
|
|
153
|
+
txs: string[], // Raw transactions as hex strings (max 25)
|
|
154
|
+
isPackage?: boolean // Use atomic submitpackage (default: true)
|
|
155
|
+
): Promise<BroadcastedTransactionPackage>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## BroadcastedTransactionPackage Result
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
interface BroadcastedTransactionPackage {
|
|
164
|
+
success: boolean; // Whether the overall broadcast succeeded
|
|
165
|
+
error?: string; // Error message if failed
|
|
166
|
+
testResults?: readonly TestMempoolAcceptResult[]; // From testmempoolaccept validation
|
|
167
|
+
packageResult?: PackageResult; // From submitpackage (atomic path)
|
|
168
|
+
sequentialResults?: readonly SequentialBroadcastTxResult[]; // Per-tx results (sequential path)
|
|
169
|
+
fellBackToSequential?: boolean; // True if submitpackage failed and fell back
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
interface SequentialBroadcastTxResult {
|
|
173
|
+
txid: string; // The txid of the transaction
|
|
174
|
+
success: boolean; // Whether the individual transaction was broadcast
|
|
175
|
+
error?: string; // Error message if this transaction failed
|
|
176
|
+
peers?: number; // Number of peers that received the transaction
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
interface TestMempoolAcceptResult {
|
|
180
|
+
txid: string;
|
|
181
|
+
wtxid: string;
|
|
182
|
+
allowed?: boolean;
|
|
183
|
+
vsize?: number;
|
|
184
|
+
fees?: TestMempoolAcceptFees;
|
|
185
|
+
packageError?: string;
|
|
186
|
+
rejectReason?: string;
|
|
187
|
+
rejectDetails?: string;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface PackageResult {
|
|
191
|
+
packageMsg: string;
|
|
192
|
+
txResults: { [wtxid: string]: PackageTxResult };
|
|
193
|
+
replacedTransactions?: readonly string[];
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
84
199
|
## Send Multiple Transactions
|
|
85
200
|
|
|
86
201
|
### Batch Broadcasting
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opnet",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.4",
|
|
5
5
|
"author": "OP_NET",
|
|
6
6
|
"description": "The perfect library for building Bitcoin-based applications.",
|
|
7
7
|
"engines": {
|
|
@@ -104,22 +104,23 @@
|
|
|
104
104
|
"@babel/preset-env": "^7.29.0",
|
|
105
105
|
"@babel/preset-typescript": "^7.28.5",
|
|
106
106
|
"@eslint/js": "^10.0.1",
|
|
107
|
-
"@microsoft/api-extractor": "7.57.
|
|
108
|
-
"@types/node": "^25.
|
|
109
|
-
"@vitest/browser": "^4.0
|
|
110
|
-
"@vitest/browser-playwright": "^4.0
|
|
111
|
-
"@vitest/ui": "^4.0
|
|
107
|
+
"@microsoft/api-extractor": "7.57.7",
|
|
108
|
+
"@types/node": "^25.5.0",
|
|
109
|
+
"@vitest/browser": "^4.1.0",
|
|
110
|
+
"@vitest/browser-playwright": "^4.1.0",
|
|
111
|
+
"@vitest/ui": "^4.1.0",
|
|
112
|
+
"esbuild": "^0.27.4",
|
|
112
113
|
"eslint": "^10.0.3",
|
|
113
114
|
"madge": "^8.0.0",
|
|
114
115
|
"playwright": "^1.58.2",
|
|
115
116
|
"stream-browserify": "^3.0.0",
|
|
116
117
|
"typedoc": "^0.28.17",
|
|
117
118
|
"typescript": "^5.9.3",
|
|
118
|
-
"typescript-eslint": "^8.
|
|
119
|
-
"vite": "^
|
|
119
|
+
"typescript-eslint": "^8.57.0",
|
|
120
|
+
"vite": "^8.0.0",
|
|
120
121
|
"vite-plugin-dts": "4.5.4",
|
|
121
122
|
"vite-plugin-node-polyfills": "^0.25.0",
|
|
122
|
-
"vitest": "^4.0
|
|
123
|
+
"vitest": "^4.1.0"
|
|
123
124
|
},
|
|
124
125
|
"peerDependencies": {
|
|
125
126
|
"react-native-worklets": ">=0.7.0"
|
|
@@ -132,17 +133,21 @@
|
|
|
132
133
|
"dependencies": {
|
|
133
134
|
"@btc-vision/bip32": "^7.1.2",
|
|
134
135
|
"@btc-vision/bitcoin": "^7.0.0",
|
|
135
|
-
"@btc-vision/bitcoin-rpc": "^1.1.
|
|
136
|
+
"@btc-vision/bitcoin-rpc": "^1.1.2",
|
|
136
137
|
"@btc-vision/ecpair": "^4.0.5",
|
|
137
138
|
"@btc-vision/logger": "^1.0.8",
|
|
138
|
-
"@btc-vision/transaction": "^1.8.
|
|
139
|
+
"@btc-vision/transaction": "^1.8.2",
|
|
139
140
|
"@noble/hashes": "^2.0.1",
|
|
140
141
|
"bignumber.js": "^10.0.2",
|
|
141
142
|
"long": "^5.3.2",
|
|
142
|
-
"opnet": "^1.8.1-rc.3",
|
|
143
143
|
"p-limit": "^7.3.0",
|
|
144
144
|
"pako": "^2.1.0",
|
|
145
145
|
"protobufjs": "^8.0.0",
|
|
146
|
-
"undici": "^7.
|
|
146
|
+
"undici": "^7.24.0"
|
|
147
|
+
},
|
|
148
|
+
"overrides": {
|
|
149
|
+
"vite-plugin-node-polyfills": {
|
|
150
|
+
"vite": "$vite"
|
|
151
|
+
}
|
|
147
152
|
}
|
|
148
153
|
}
|