@buildonspark/spark-sdk 0.3.9 → 0.4.0
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 +11 -0
- package/android/build.gradle +1 -1
- package/android/src/main/java/uniffi/uniffi/spark_frost/spark_frost.kt +1361 -1367
- package/android/src/main/jniLibs/arm64-v8a/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/x86/libuniffi_spark_frost.so +0 -0
- package/android/src/main/jniLibs/x86_64/libuniffi_spark_frost.so +0 -0
- package/dist/bare/index.cjs +322 -142
- package/dist/bare/index.d.cts +13 -3
- package/dist/bare/index.d.ts +13 -3
- package/dist/bare/index.js +321 -142
- package/dist/{chunk-S55NZT4P.js → chunk-27ILUWDJ.js} +1 -1
- package/dist/{chunk-O4C4HGQL.js → chunk-G3LHXHF3.js} +313 -133
- package/dist/{chunk-WRE2T22S.js → chunk-LOXWCMZL.js} +1 -1
- package/dist/{chunk-MFCM6GUD.js → chunk-WICAF6BS.js} +1 -1
- package/dist/debug.cjs +322 -143
- package/dist/debug.d.cts +5 -4
- package/dist/debug.d.ts +5 -4
- package/dist/debug.js +2 -2
- package/dist/index.cjs +323 -143
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -3
- package/dist/index.node.cjs +323 -143
- package/dist/index.node.d.cts +4 -4
- package/dist/index.node.d.ts +4 -4
- package/dist/index.node.js +4 -2
- package/dist/{logging-DDeMLsVN.d.ts → logging-BNGm6dBp.d.ts} +3 -2
- package/dist/{logging-CXhvuqJJ.d.cts → logging-D3IfXfHG.d.cts} +3 -2
- package/dist/native/index.react-native.cjs +466 -145
- package/dist/native/index.react-native.d.cts +21 -3
- package/dist/native/index.react-native.d.ts +21 -3
- package/dist/native/index.react-native.js +462 -144
- package/dist/{spark-wallet.browser-Cz8c4kOW.d.ts → spark-wallet.browser-B2rGwjuM.d.ts} +1 -1
- package/dist/{spark-wallet.browser-CbYo8A_U.d.cts → spark-wallet.browser-Ck9No4Ks.d.cts} +1 -1
- package/dist/{spark-wallet.node-CmIvxtcC.d.ts → spark-wallet.node-BqmKsGPs.d.ts} +1 -1
- package/dist/{spark-wallet.node-4WQgWwB2.d.cts → spark-wallet.node-C2TIkyt4.d.cts} +1 -1
- package/dist/tests/test-utils.cjs +321 -143
- package/dist/tests/test-utils.d.cts +16 -2
- package/dist/tests/test-utils.d.ts +16 -2
- package/dist/tests/test-utils.js +4 -4
- package/dist/{token-transactions-CV8QD3I7.d.cts → token-transactions-Db8mkjnU.d.cts} +1 -1
- package/dist/{token-transactions-Bu023ztN.d.ts → token-transactions-DoMcrxXQ.d.ts} +1 -1
- package/dist/{wallet-config-Bmk2eAn8.d.ts → wallet-config-Bg3kWltL.d.ts} +11 -2
- package/dist/{wallet-config-DQw5llqA.d.cts → wallet-config-CuZKNo9S.d.cts} +11 -2
- package/ios/spark_frostFFI.xcframework/ios-arm64/SparkFrost +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/SparkFrost +0 -0
- package/ios/spark_frostFFI.xcframework/ios-arm64_x86_64-simulator/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/ios/spark_frostFFI.xcframework/macos-arm64_x86_64/spark_frostFFI.framework/spark_frostFFI +0 -0
- package/package.json +1 -1
- package/src/index.react-native.ts +8 -2
- package/src/services/config.ts +5 -0
- package/src/services/wallet-config.ts +10 -0
- package/src/services/xhr-transport.ts +13 -3
- package/src/signer/signer.react-native.ts +73 -1
- package/src/spark-wallet/spark-wallet.ts +98 -76
- package/src/tests/integration/lightning.test.ts +0 -28
- package/src/tests/integration/static_deposit.test.ts +4 -8
- package/src/tests/integration/unilateral-exit.test.ts +117 -0
- package/src/tests/optimize.test.ts +31 -1
- package/src/tests/utils/signing.ts +33 -0
- package/src/tests/utils/test-faucet.ts +61 -0
- package/src/utils/optimize.ts +42 -0
- package/src/utils/unilateral-exit.ts +1 -40
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/bare/index.cjs
CHANGED
|
@@ -1315,6 +1315,7 @@ __export(index_exports, {
|
|
|
1315
1315
|
getTxFromRawTxHex: () => getTxFromRawTxHex,
|
|
1316
1316
|
getTxId: () => getTxId,
|
|
1317
1317
|
getTxIdNoReverse: () => getTxIdNoReverse,
|
|
1318
|
+
hash160: () => hash160,
|
|
1318
1319
|
isEphemeralAnchorOutput: () => isEphemeralAnchorOutput,
|
|
1319
1320
|
isLegacySparkAddress: () => isLegacySparkAddress,
|
|
1320
1321
|
isSafeForNumber: () => isSafeForNumber,
|
|
@@ -19555,7 +19556,11 @@ var BASE_CONFIG = {
|
|
|
19555
19556
|
console: {
|
|
19556
19557
|
otel: false
|
|
19557
19558
|
},
|
|
19558
|
-
events: {}
|
|
19559
|
+
events: {},
|
|
19560
|
+
optimizationOptions: {
|
|
19561
|
+
auto: true,
|
|
19562
|
+
multiplicity: 0
|
|
19563
|
+
}
|
|
19559
19564
|
};
|
|
19560
19565
|
var LOCAL_WALLET_CONFIG = {
|
|
19561
19566
|
...BASE_CONFIG,
|
|
@@ -19766,6 +19771,9 @@ var WalletConfigService = class {
|
|
|
19766
19771
|
getEvents() {
|
|
19767
19772
|
return this.config.events;
|
|
19768
19773
|
}
|
|
19774
|
+
getOptimizationOptions() {
|
|
19775
|
+
return this.config.optimizationOptions;
|
|
19776
|
+
}
|
|
19769
19777
|
};
|
|
19770
19778
|
|
|
19771
19779
|
// src/services/coop-exit.ts
|
|
@@ -28454,7 +28462,7 @@ var isWebExtension = (
|
|
|
28454
28462
|
"chrome" in globalThis && globalThis.chrome.runtime?.id
|
|
28455
28463
|
);
|
|
28456
28464
|
var userAgent = "navigator" in globalThis ? globalThis.navigator.userAgent || "unknown-user-agent" : void 0;
|
|
28457
|
-
var packageVersion = true ? "0.
|
|
28465
|
+
var packageVersion = true ? "0.4.0" : "unknown";
|
|
28458
28466
|
var baseEnvStr = "unknown";
|
|
28459
28467
|
if (isBun) {
|
|
28460
28468
|
const bunVersion = "version" in globalThis.Bun ? globalThis.Bun.version : "unknown-version";
|
|
@@ -29915,6 +29923,14 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29915
29923
|
async mineBlocks(numBlocks) {
|
|
29916
29924
|
return await this.generateToAddress(numBlocks, this.miningAddress);
|
|
29917
29925
|
}
|
|
29926
|
+
async mineBlocksAndWaitForMiningToComplete(numBlocks) {
|
|
29927
|
+
const startBlock = await this.getBlockCount();
|
|
29928
|
+
await this.mineBlocks(numBlocks);
|
|
29929
|
+
await this.waitForBlocksMined({
|
|
29930
|
+
startBlock,
|
|
29931
|
+
expectedIncrease: numBlocks
|
|
29932
|
+
});
|
|
29933
|
+
}
|
|
29918
29934
|
async call(method, params) {
|
|
29919
29935
|
try {
|
|
29920
29936
|
const { fetch, Headers: Headers3 } = getFetch();
|
|
@@ -29967,15 +29983,50 @@ var BitcoinFaucet = class _BitcoinFaucet {
|
|
|
29967
29983
|
async getBlock(blockHash) {
|
|
29968
29984
|
return await this.call("getblock", [blockHash, 2]);
|
|
29969
29985
|
}
|
|
29986
|
+
async getBlockCount() {
|
|
29987
|
+
return await this.call("getblockcount", []);
|
|
29988
|
+
}
|
|
29989
|
+
async waitForBlocksMined({
|
|
29990
|
+
startBlock,
|
|
29991
|
+
expectedIncrease,
|
|
29992
|
+
timeoutMs = 3e4,
|
|
29993
|
+
intervalMs = 5e3
|
|
29994
|
+
}) {
|
|
29995
|
+
const deadline = Date.now() + timeoutMs;
|
|
29996
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
29997
|
+
const start = startBlock;
|
|
29998
|
+
const target = start + expectedIncrease;
|
|
29999
|
+
while (Date.now() < deadline) {
|
|
30000
|
+
const currentBlock = await this.getBlockCount();
|
|
30001
|
+
if (currentBlock >= target) return currentBlock;
|
|
30002
|
+
await new Promise((r) => setTimeout(r, intervalMs));
|
|
30003
|
+
}
|
|
30004
|
+
throw new Error(
|
|
30005
|
+
`Timed out waiting for ${expectedIncrease} blocks (target height ${target})`
|
|
30006
|
+
);
|
|
30007
|
+
}
|
|
29970
30008
|
async broadcastTx(txHex) {
|
|
29971
30009
|
let response = await this.call("sendrawtransaction", [txHex, 0]);
|
|
29972
30010
|
return response;
|
|
29973
30011
|
}
|
|
30012
|
+
async submitPackage(txHexs) {
|
|
30013
|
+
let response = await this.call("submitpackage", [txHexs]);
|
|
30014
|
+
return response;
|
|
30015
|
+
}
|
|
29974
30016
|
async getNewAddress() {
|
|
29975
30017
|
const key = import_secp256k113.secp256k1.utils.randomPrivateKey();
|
|
29976
30018
|
const pubKey = import_secp256k113.secp256k1.getPublicKey(key);
|
|
29977
30019
|
return getP2TRAddressFromPublicKey(pubKey, 4 /* LOCAL */);
|
|
29978
30020
|
}
|
|
30021
|
+
async getNewExternalWallet() {
|
|
30022
|
+
const key = import_secp256k113.secp256k1.utils.randomPrivateKey();
|
|
30023
|
+
const pubKey = import_secp256k113.secp256k1.getPublicKey(key);
|
|
30024
|
+
return {
|
|
30025
|
+
address: getP2TRAddressFromPublicKey(pubKey, 4 /* LOCAL */),
|
|
30026
|
+
key,
|
|
30027
|
+
pubKey
|
|
30028
|
+
};
|
|
30029
|
+
}
|
|
29979
30030
|
async sendToAddress(address, amount, blocksToGenerate = 1) {
|
|
29980
30031
|
const coin = await this.fund();
|
|
29981
30032
|
if (!coin) {
|
|
@@ -30076,75 +30127,6 @@ function chunkArray(arr, size) {
|
|
|
30076
30127
|
return chunks;
|
|
30077
30128
|
}
|
|
30078
30129
|
|
|
30079
|
-
// src/utils/optimize.ts
|
|
30080
|
-
var DENOMINATIONS = Array.from({ length: 28 }, (_, i) => 2 ** i);
|
|
30081
|
-
function assert(condition, message) {
|
|
30082
|
-
if (!condition) {
|
|
30083
|
-
throw new InternalValidationError(message || "Assertion failed");
|
|
30084
|
-
}
|
|
30085
|
-
}
|
|
30086
|
-
function sum(arr) {
|
|
30087
|
-
return arr.reduce((a, b) => a + b, 0);
|
|
30088
|
-
}
|
|
30089
|
-
function sorted(arr) {
|
|
30090
|
-
return [...arr].sort((a, b) => a - b);
|
|
30091
|
-
}
|
|
30092
|
-
function equals(a, b) {
|
|
30093
|
-
return a.length === b.length && a.every((val, index) => val === b[index]);
|
|
30094
|
-
}
|
|
30095
|
-
function greedyLeaves(amount) {
|
|
30096
|
-
const leaves = [];
|
|
30097
|
-
let remaining = amount;
|
|
30098
|
-
for (let i = DENOMINATIONS.length - 1; i >= 0; i--) {
|
|
30099
|
-
const leaf = DENOMINATIONS[i];
|
|
30100
|
-
if (typeof leaf === "number" && leaf > 0) {
|
|
30101
|
-
while (remaining >= leaf) {
|
|
30102
|
-
remaining -= leaf;
|
|
30103
|
-
leaves.push(leaf);
|
|
30104
|
-
}
|
|
30105
|
-
}
|
|
30106
|
-
}
|
|
30107
|
-
assert(sum(leaves) === amount, "greedy_leaves: sum mismatch");
|
|
30108
|
-
return sorted(leaves);
|
|
30109
|
-
}
|
|
30110
|
-
var Swap = class {
|
|
30111
|
-
inLeaves;
|
|
30112
|
-
outLeaves;
|
|
30113
|
-
constructor(inLeaves, outLeaves) {
|
|
30114
|
-
this.inLeaves = [...inLeaves];
|
|
30115
|
-
this.outLeaves = [...outLeaves];
|
|
30116
|
-
assert(
|
|
30117
|
-
sum(this.inLeaves) === sum(this.outLeaves),
|
|
30118
|
-
"Swap in/out leaves must sum to same value for swap: " + this.toString()
|
|
30119
|
-
);
|
|
30120
|
-
}
|
|
30121
|
-
toString() {
|
|
30122
|
-
return `Swap(in=${JSON.stringify(this.inLeaves)}, out=${JSON.stringify(this.outLeaves)})`;
|
|
30123
|
-
}
|
|
30124
|
-
};
|
|
30125
|
-
function maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap = 64) {
|
|
30126
|
-
const swaps = [];
|
|
30127
|
-
let batch = [];
|
|
30128
|
-
let leaves = sorted(inputLeaves);
|
|
30129
|
-
while (leaves.length > 0) {
|
|
30130
|
-
batch.push(leaves.shift());
|
|
30131
|
-
const target = greedyLeaves(sum(batch));
|
|
30132
|
-
if (batch.length >= maxLeavesPerSwap || target.length >= maxLeavesPerSwap) {
|
|
30133
|
-
if (!equals(target, batch)) {
|
|
30134
|
-
swaps.push(new Swap([...batch], target));
|
|
30135
|
-
}
|
|
30136
|
-
batch = [];
|
|
30137
|
-
}
|
|
30138
|
-
}
|
|
30139
|
-
if (batch.length > 0) {
|
|
30140
|
-
const target = greedyLeaves(sum(batch));
|
|
30141
|
-
if (!equals(target, batch)) {
|
|
30142
|
-
swaps.push(new Swap([...batch], target));
|
|
30143
|
-
}
|
|
30144
|
-
}
|
|
30145
|
-
return swaps;
|
|
30146
|
-
}
|
|
30147
|
-
|
|
30148
30130
|
// src/utils/retry.ts
|
|
30149
30131
|
var DEFAULT_RETRY_CONFIG = {
|
|
30150
30132
|
maxAttempts: 5,
|
|
@@ -30221,6 +30203,199 @@ var SparkWalletEvent = {
|
|
|
30221
30203
|
StreamReconnecting: "stream:reconnecting"
|
|
30222
30204
|
};
|
|
30223
30205
|
|
|
30206
|
+
// src/utils/optimize.ts
|
|
30207
|
+
var DENOMINATIONS = Array.from({ length: 28 }, (_, i) => 2 ** i);
|
|
30208
|
+
function assert(condition, message) {
|
|
30209
|
+
if (!condition) {
|
|
30210
|
+
throw new InternalValidationError(message || "Assertion failed");
|
|
30211
|
+
}
|
|
30212
|
+
}
|
|
30213
|
+
function sum(arr) {
|
|
30214
|
+
return arr.reduce((a, b) => a + b, 0);
|
|
30215
|
+
}
|
|
30216
|
+
function sorted(arr) {
|
|
30217
|
+
return [...arr].sort((a, b) => a - b);
|
|
30218
|
+
}
|
|
30219
|
+
function equals(a, b) {
|
|
30220
|
+
return a.length === b.length && a.every((val, index) => val === b[index]);
|
|
30221
|
+
}
|
|
30222
|
+
function countOccurrences(arr) {
|
|
30223
|
+
const map = /* @__PURE__ */ new Map();
|
|
30224
|
+
for (const x of arr) {
|
|
30225
|
+
map.set(x, (map.get(x) ?? 0) + 1);
|
|
30226
|
+
}
|
|
30227
|
+
return map;
|
|
30228
|
+
}
|
|
30229
|
+
function subtractCounters(a, b) {
|
|
30230
|
+
const result = /* @__PURE__ */ new Map();
|
|
30231
|
+
for (const [key, value] of a.entries()) {
|
|
30232
|
+
const diff = value - (b.get(key) ?? 0);
|
|
30233
|
+
if (diff > 0) {
|
|
30234
|
+
result.set(key, diff);
|
|
30235
|
+
}
|
|
30236
|
+
}
|
|
30237
|
+
return result;
|
|
30238
|
+
}
|
|
30239
|
+
function counterToFlatArray(counter) {
|
|
30240
|
+
const arr = [];
|
|
30241
|
+
for (const [k, v] of Array.from(counter.entries()).sort(
|
|
30242
|
+
(a, b) => a[0] - b[0]
|
|
30243
|
+
)) {
|
|
30244
|
+
for (let i = 0; i < v; i++) {
|
|
30245
|
+
arr.push(k);
|
|
30246
|
+
}
|
|
30247
|
+
}
|
|
30248
|
+
return arr;
|
|
30249
|
+
}
|
|
30250
|
+
function greedyLeaves(amount) {
|
|
30251
|
+
const leaves = [];
|
|
30252
|
+
let remaining = amount;
|
|
30253
|
+
for (let i = DENOMINATIONS.length - 1; i >= 0; i--) {
|
|
30254
|
+
const leaf = DENOMINATIONS[i];
|
|
30255
|
+
if (typeof leaf === "number" && leaf > 0) {
|
|
30256
|
+
while (remaining >= leaf) {
|
|
30257
|
+
remaining -= leaf;
|
|
30258
|
+
leaves.push(leaf);
|
|
30259
|
+
}
|
|
30260
|
+
}
|
|
30261
|
+
}
|
|
30262
|
+
assert(sum(leaves) === amount, "greedy_leaves: sum mismatch");
|
|
30263
|
+
return sorted(leaves);
|
|
30264
|
+
}
|
|
30265
|
+
function swapMinimizingLeaves(amount, multiplicity = 1) {
|
|
30266
|
+
const leaves = [];
|
|
30267
|
+
let remaining = amount;
|
|
30268
|
+
assert(multiplicity > 0, "multiplicity must be > 0");
|
|
30269
|
+
for (const leaf of DENOMINATIONS) {
|
|
30270
|
+
if (typeof leaf === "number" && leaf > 0) {
|
|
30271
|
+
for (let i = 0; i < multiplicity; i++) {
|
|
30272
|
+
if (remaining >= leaf) {
|
|
30273
|
+
remaining -= leaf;
|
|
30274
|
+
leaves.push(leaf);
|
|
30275
|
+
}
|
|
30276
|
+
}
|
|
30277
|
+
}
|
|
30278
|
+
}
|
|
30279
|
+
leaves.push(...greedyLeaves(remaining));
|
|
30280
|
+
assert(sum(leaves) === amount, "swap_minimizing_leaves: sum mismatch");
|
|
30281
|
+
return sorted(leaves);
|
|
30282
|
+
}
|
|
30283
|
+
var Swap = class {
|
|
30284
|
+
inLeaves;
|
|
30285
|
+
outLeaves;
|
|
30286
|
+
constructor(inLeaves, outLeaves) {
|
|
30287
|
+
this.inLeaves = [...inLeaves];
|
|
30288
|
+
this.outLeaves = [...outLeaves];
|
|
30289
|
+
assert(
|
|
30290
|
+
sum(this.inLeaves) === sum(this.outLeaves),
|
|
30291
|
+
"Swap in/out leaves must sum to same value for swap: " + this.toString()
|
|
30292
|
+
);
|
|
30293
|
+
}
|
|
30294
|
+
toString() {
|
|
30295
|
+
return `Swap(in=${JSON.stringify(this.inLeaves)}, out=${JSON.stringify(this.outLeaves)})`;
|
|
30296
|
+
}
|
|
30297
|
+
};
|
|
30298
|
+
function maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap = 64) {
|
|
30299
|
+
const swaps = [];
|
|
30300
|
+
let batch = [];
|
|
30301
|
+
let leaves = sorted(inputLeaves);
|
|
30302
|
+
while (leaves.length > 0) {
|
|
30303
|
+
batch.push(leaves.shift());
|
|
30304
|
+
const target = greedyLeaves(sum(batch));
|
|
30305
|
+
if (batch.length >= maxLeavesPerSwap || target.length >= maxLeavesPerSwap) {
|
|
30306
|
+
if (!equals(target, batch)) {
|
|
30307
|
+
swaps.push(new Swap([...batch], target));
|
|
30308
|
+
}
|
|
30309
|
+
batch = [];
|
|
30310
|
+
}
|
|
30311
|
+
}
|
|
30312
|
+
if (batch.length > 0) {
|
|
30313
|
+
const target = greedyLeaves(sum(batch));
|
|
30314
|
+
if (!equals(target, batch)) {
|
|
30315
|
+
swaps.push(new Swap([...batch], target));
|
|
30316
|
+
}
|
|
30317
|
+
}
|
|
30318
|
+
return swaps;
|
|
30319
|
+
}
|
|
30320
|
+
function minimizeTransferSwap(inputLeaves, multiplicity = 1, maxLeavesPerSwap = 64) {
|
|
30321
|
+
const balance = sum(inputLeaves);
|
|
30322
|
+
const optimalLeaves = swapMinimizingLeaves(balance, multiplicity);
|
|
30323
|
+
const walletCounter = countOccurrences(inputLeaves);
|
|
30324
|
+
const optimalCounter = countOccurrences(optimalLeaves);
|
|
30325
|
+
const leavesToGive = subtractCounters(walletCounter, optimalCounter);
|
|
30326
|
+
const leavesToReceive = subtractCounters(optimalCounter, walletCounter);
|
|
30327
|
+
const leavesToGiveFlat = counterToFlatArray(leavesToGive);
|
|
30328
|
+
const leavesToReceiveFlat = counterToFlatArray(leavesToReceive);
|
|
30329
|
+
const swaps = [];
|
|
30330
|
+
let toGiveBatch = [];
|
|
30331
|
+
let toReceiveBatch = [];
|
|
30332
|
+
let give = [...leavesToGiveFlat];
|
|
30333
|
+
let receive = [...leavesToReceiveFlat];
|
|
30334
|
+
while (give.length > 0 || receive.length > 0) {
|
|
30335
|
+
if (sum(toGiveBatch) > sum(toReceiveBatch)) {
|
|
30336
|
+
if (receive.length === 0) break;
|
|
30337
|
+
toReceiveBatch.push(receive.shift());
|
|
30338
|
+
} else {
|
|
30339
|
+
if (give.length === 0) break;
|
|
30340
|
+
toGiveBatch.push(give.shift());
|
|
30341
|
+
}
|
|
30342
|
+
if (toGiveBatch.length > 0 && toReceiveBatch.length > 0 && sum(toGiveBatch) === sum(toReceiveBatch)) {
|
|
30343
|
+
if (toGiveBatch.length > maxLeavesPerSwap) {
|
|
30344
|
+
for (let i = 0; i < toGiveBatch.length; i += maxLeavesPerSwap) {
|
|
30345
|
+
const subset = toGiveBatch.slice(i, i + maxLeavesPerSwap);
|
|
30346
|
+
swaps.push(new Swap(subset, greedyLeaves(sum(subset))));
|
|
30347
|
+
}
|
|
30348
|
+
} else if (toReceiveBatch.length > maxLeavesPerSwap) {
|
|
30349
|
+
for (let cutoff = maxLeavesPerSwap; cutoff > 0; cutoff--) {
|
|
30350
|
+
const sumCut = sum(toReceiveBatch.slice(0, cutoff));
|
|
30351
|
+
const remainder = sum(toGiveBatch) - sumCut;
|
|
30352
|
+
const alternateBatch = [
|
|
30353
|
+
...toReceiveBatch.slice(0, cutoff),
|
|
30354
|
+
...greedyLeaves(remainder)
|
|
30355
|
+
];
|
|
30356
|
+
if (alternateBatch.length <= maxLeavesPerSwap) {
|
|
30357
|
+
swaps.push(new Swap([...toGiveBatch], alternateBatch));
|
|
30358
|
+
break;
|
|
30359
|
+
}
|
|
30360
|
+
}
|
|
30361
|
+
} else {
|
|
30362
|
+
swaps.push(new Swap([...toGiveBatch], [...toReceiveBatch]));
|
|
30363
|
+
}
|
|
30364
|
+
toGiveBatch = [];
|
|
30365
|
+
toReceiveBatch = [];
|
|
30366
|
+
}
|
|
30367
|
+
}
|
|
30368
|
+
return swaps;
|
|
30369
|
+
}
|
|
30370
|
+
function shouldOptimize(inputLeaves, multiplicity = 1, maxLeavesPerSwap = 64) {
|
|
30371
|
+
if (multiplicity == 0) {
|
|
30372
|
+
const swaps = maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap);
|
|
30373
|
+
const numInputs = sum(swaps.map((swap) => swap.inLeaves.length));
|
|
30374
|
+
const numOutputs = sum(swaps.map((swap) => swap.outLeaves.length));
|
|
30375
|
+
return numOutputs * 5 < numInputs;
|
|
30376
|
+
} else {
|
|
30377
|
+
const swaps = minimizeTransferSwap(
|
|
30378
|
+
inputLeaves,
|
|
30379
|
+
multiplicity,
|
|
30380
|
+
maxLeavesPerSwap
|
|
30381
|
+
);
|
|
30382
|
+
const inputCounter = countOccurrences(
|
|
30383
|
+
swaps.flatMap((swap) => swap.inLeaves)
|
|
30384
|
+
);
|
|
30385
|
+
const outputCounter = countOccurrences(
|
|
30386
|
+
swaps.flatMap((swap) => swap.outLeaves)
|
|
30387
|
+
);
|
|
30388
|
+
return Math.abs(inputCounter.size - outputCounter.size) > 1;
|
|
30389
|
+
}
|
|
30390
|
+
}
|
|
30391
|
+
function optimize(inputLeaves, multiplicity = 1, maxLeavesPerSwap = 64) {
|
|
30392
|
+
if (multiplicity == 0) {
|
|
30393
|
+
return maximizeUnilateralExit(inputLeaves, maxLeavesPerSwap);
|
|
30394
|
+
} else {
|
|
30395
|
+
return minimizeTransferSwap(inputLeaves, multiplicity, maxLeavesPerSwap);
|
|
30396
|
+
}
|
|
30397
|
+
}
|
|
30398
|
+
|
|
30224
30399
|
// src/spark-wallet/spark-wallet.ts
|
|
30225
30400
|
var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
30226
30401
|
config;
|
|
@@ -30325,8 +30500,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30325
30500
|
if (event.transfer.transfer && !(0, import_utils24.equalBytes)(senderIdentityPublicKey, receiverIdentityPublicKey)) {
|
|
30326
30501
|
await this.claimTransfer({
|
|
30327
30502
|
transfer: event.transfer.transfer,
|
|
30328
|
-
emit: true
|
|
30329
|
-
optimize: true
|
|
30503
|
+
emit: true
|
|
30330
30504
|
});
|
|
30331
30505
|
}
|
|
30332
30506
|
} else if (isDepositStreamEvent(event)) {
|
|
@@ -30617,73 +30791,84 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
30617
30791
|
}
|
|
30618
30792
|
return nodes;
|
|
30619
30793
|
}
|
|
30620
|
-
|
|
30621
|
-
const
|
|
30622
|
-
if (
|
|
30623
|
-
|
|
30794
|
+
async *optimizeLeaves(multiplicity = void 0) {
|
|
30795
|
+
const multiplicityValue = multiplicity ?? this.config.getOptimizationOptions().multiplicity ?? 0;
|
|
30796
|
+
if (multiplicityValue < 0) {
|
|
30797
|
+
throw new ValidationError("Multiplicity cannot be negative");
|
|
30798
|
+
} else if (multiplicityValue > 5) {
|
|
30799
|
+
throw new ValidationError("Multiplicity cannot be greater than 5");
|
|
30624
30800
|
}
|
|
30625
|
-
|
|
30626
|
-
|
|
30627
|
-
|
|
30628
|
-
|
|
30629
|
-
const denomination = 2 ** i;
|
|
30630
|
-
while (remainingAmount >= denomination) {
|
|
30631
|
-
remainingAmount -= denomination;
|
|
30632
|
-
optimalLeavesLength++;
|
|
30633
|
-
}
|
|
30634
|
-
}
|
|
30635
|
-
return this.leaves.length > optimalLeavesLength * 5;
|
|
30636
|
-
}
|
|
30637
|
-
async optimizeLeaves() {
|
|
30638
|
-
if (this.optimizationInProgress || !this.areLeavesInefficient()) {
|
|
30801
|
+
if (this.optimizationInProgress || !shouldOptimize(
|
|
30802
|
+
this.leaves.map((leaf) => leaf.value),
|
|
30803
|
+
multiplicityValue
|
|
30804
|
+
)) {
|
|
30639
30805
|
return;
|
|
30640
30806
|
}
|
|
30641
|
-
|
|
30807
|
+
const controller = new AbortController();
|
|
30808
|
+
const release = await this.leavesMutex.acquire();
|
|
30809
|
+
try {
|
|
30642
30810
|
this.optimizationInProgress = true;
|
|
30643
|
-
|
|
30644
|
-
|
|
30645
|
-
|
|
30646
|
-
|
|
30647
|
-
|
|
30648
|
-
|
|
30649
|
-
|
|
30650
|
-
|
|
30651
|
-
|
|
30652
|
-
|
|
30653
|
-
|
|
30654
|
-
|
|
30655
|
-
|
|
30656
|
-
|
|
30657
|
-
|
|
30658
|
-
|
|
30659
|
-
|
|
30660
|
-
|
|
30661
|
-
|
|
30662
|
-
|
|
30663
|
-
|
|
30664
|
-
|
|
30665
|
-
|
|
30666
|
-
|
|
30811
|
+
this.leaves = await this.getLeaves();
|
|
30812
|
+
const swaps = optimize(
|
|
30813
|
+
this.leaves.map((leaf) => leaf.value),
|
|
30814
|
+
multiplicityValue
|
|
30815
|
+
);
|
|
30816
|
+
if (swaps.length === 0) {
|
|
30817
|
+
return;
|
|
30818
|
+
}
|
|
30819
|
+
yield {
|
|
30820
|
+
step: 0,
|
|
30821
|
+
total: swaps.length,
|
|
30822
|
+
controller
|
|
30823
|
+
};
|
|
30824
|
+
const valueToNodes = /* @__PURE__ */ new Map();
|
|
30825
|
+
this.leaves.forEach((leaf) => {
|
|
30826
|
+
if (!valueToNodes.has(leaf.value)) {
|
|
30827
|
+
valueToNodes.set(leaf.value, []);
|
|
30828
|
+
}
|
|
30829
|
+
valueToNodes.get(leaf.value).push(leaf);
|
|
30830
|
+
});
|
|
30831
|
+
for (const swap of swaps) {
|
|
30832
|
+
if (controller.signal.aborted) {
|
|
30833
|
+
break;
|
|
30834
|
+
}
|
|
30835
|
+
const leavesToSend = [];
|
|
30836
|
+
for (const leafValue of swap.inLeaves) {
|
|
30837
|
+
const nodes = valueToNodes.get(leafValue);
|
|
30838
|
+
if (nodes && nodes.length > 0) {
|
|
30839
|
+
const node = nodes.shift();
|
|
30840
|
+
leavesToSend.push(node);
|
|
30841
|
+
} else {
|
|
30842
|
+
throw new InternalValidationError(
|
|
30843
|
+
`No unused leaf with value ${leafValue} found in leaves`
|
|
30844
|
+
);
|
|
30667
30845
|
}
|
|
30668
|
-
await this.requestLeavesSwap({
|
|
30669
|
-
leaves: leavesToSend,
|
|
30670
|
-
targetAmounts: swap.outLeaves
|
|
30671
|
-
});
|
|
30672
30846
|
}
|
|
30673
|
-
|
|
30674
|
-
|
|
30675
|
-
|
|
30847
|
+
await this.requestLeavesSwap({
|
|
30848
|
+
leaves: leavesToSend,
|
|
30849
|
+
targetAmounts: swap.outLeaves
|
|
30850
|
+
});
|
|
30851
|
+
yield {
|
|
30852
|
+
step: swaps.indexOf(swap) + 1,
|
|
30853
|
+
total: swaps.length,
|
|
30854
|
+
controller
|
|
30855
|
+
};
|
|
30676
30856
|
}
|
|
30677
|
-
|
|
30857
|
+
this.leaves = await this.getLeaves();
|
|
30858
|
+
} finally {
|
|
30859
|
+
this.optimizationInProgress = false;
|
|
30860
|
+
release();
|
|
30861
|
+
}
|
|
30678
30862
|
}
|
|
30679
30863
|
async syncWallet() {
|
|
30680
30864
|
await this.syncTokenOutputs();
|
|
30681
30865
|
let leaves = await this.getLeaves();
|
|
30682
30866
|
leaves = await this.checkRenewLeaves(leaves);
|
|
30683
30867
|
this.leaves = leaves;
|
|
30684
|
-
this.
|
|
30685
|
-
|
|
30686
|
-
|
|
30868
|
+
if (this.config.getOptimizationOptions().auto) {
|
|
30869
|
+
for await (const _ of this.optimizeLeaves()) {
|
|
30870
|
+
}
|
|
30871
|
+
}
|
|
30687
30872
|
}
|
|
30688
30873
|
async withLeaves(operation) {
|
|
30689
30874
|
const release = await this.leavesMutex.acquire();
|
|
@@ -31266,8 +31451,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
31266
31451
|
}
|
|
31267
31452
|
return await this.claimTransfer({
|
|
31268
31453
|
transfer: incomingTransfer,
|
|
31269
|
-
emit: false
|
|
31270
|
-
optimize: false
|
|
31454
|
+
emit: false
|
|
31271
31455
|
});
|
|
31272
31456
|
} catch (e) {
|
|
31273
31457
|
console.error("[processSwapBatch] Error details:", {
|
|
@@ -32296,7 +32480,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32296
32480
|
transfer.id
|
|
32297
32481
|
);
|
|
32298
32482
|
if (pending) {
|
|
32299
|
-
await this.claimTransfer({ transfer: pending
|
|
32483
|
+
await this.claimTransfer({ transfer: pending });
|
|
32300
32484
|
}
|
|
32301
32485
|
}
|
|
32302
32486
|
return {
|
|
@@ -32469,13 +32653,14 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32469
32653
|
return response.nodes;
|
|
32470
32654
|
});
|
|
32471
32655
|
}
|
|
32472
|
-
async processClaimedTransferResults(result, transfer, emit
|
|
32656
|
+
async processClaimedTransferResults(result, transfer, emit) {
|
|
32473
32657
|
result = await this.checkRenewLeaves(result);
|
|
32474
32658
|
const existingIds = new Set(this.leaves.map((leaf) => leaf.id));
|
|
32475
32659
|
const uniqueResults = result.filter((node) => !existingIds.has(node.id));
|
|
32476
32660
|
this.leaves.push(...uniqueResults);
|
|
32477
|
-
if (
|
|
32478
|
-
await this.optimizeLeaves()
|
|
32661
|
+
if (this.config.getOptimizationOptions().auto && transfer.type !== 40 /* COUNTER_SWAP */) {
|
|
32662
|
+
for await (const _ of this.optimizeLeaves()) {
|
|
32663
|
+
}
|
|
32479
32664
|
}
|
|
32480
32665
|
if (emit) {
|
|
32481
32666
|
this.emit(
|
|
@@ -32494,8 +32679,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32494
32679
|
*/
|
|
32495
32680
|
async claimTransfer({
|
|
32496
32681
|
transfer,
|
|
32497
|
-
emit
|
|
32498
|
-
optimize
|
|
32682
|
+
emit
|
|
32499
32683
|
}) {
|
|
32500
32684
|
const onError = async (context) => {
|
|
32501
32685
|
const error = context.error;
|
|
@@ -32540,12 +32724,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32540
32724
|
if (result.length === 0) {
|
|
32541
32725
|
return [];
|
|
32542
32726
|
}
|
|
32543
|
-
return await this.processClaimedTransferResults(
|
|
32544
|
-
result,
|
|
32545
|
-
transfer,
|
|
32546
|
-
emit,
|
|
32547
|
-
optimize
|
|
32548
|
-
);
|
|
32727
|
+
return await this.processClaimedTransferResults(result, transfer, emit);
|
|
32549
32728
|
} catch (error) {
|
|
32550
32729
|
console.warn(
|
|
32551
32730
|
`Failed to claim transfer after all retries. Please try reinitializing your wallet in a few minutes. Transfer ID: ${transfer.id}`,
|
|
@@ -32578,7 +32757,7 @@ var SparkWallet = class extends import_eventemitter3.EventEmitter {
|
|
|
32578
32757
|
continue;
|
|
32579
32758
|
}
|
|
32580
32759
|
promises.push(
|
|
32581
|
-
this.claimTransfer({ transfer, emit
|
|
32760
|
+
this.claimTransfer({ transfer, emit }).then(() => transfer.id).catch((error) => {
|
|
32582
32761
|
console.warn(`Failed to claim transfer ${transfer.id}:`, error);
|
|
32583
32762
|
return null;
|
|
32584
32763
|
})
|
|
@@ -35618,6 +35797,7 @@ setFetch(sparkBareFetch, Headers2);
|
|
|
35618
35797
|
getTxFromRawTxHex,
|
|
35619
35798
|
getTxId,
|
|
35620
35799
|
getTxIdNoReverse,
|
|
35800
|
+
hash160,
|
|
35621
35801
|
isEphemeralAnchorOutput,
|
|
35622
35802
|
isLegacySparkAddress,
|
|
35623
35803
|
isSafeForNumber,
|
package/dist/bare/index.d.cts
CHANGED
|
@@ -3703,6 +3703,10 @@ type SigningOperator = {
|
|
|
3703
3703
|
type ConsoleOptions = {
|
|
3704
3704
|
otel?: boolean;
|
|
3705
3705
|
};
|
|
3706
|
+
type OptimizationOptions = {
|
|
3707
|
+
readonly auto?: boolean;
|
|
3708
|
+
readonly multiplicity?: number;
|
|
3709
|
+
};
|
|
3706
3710
|
type ConfigOptions = MayHaveSspClientOptions & {
|
|
3707
3711
|
readonly network?: NetworkType;
|
|
3708
3712
|
readonly signingOperators?: Readonly<Record<string, SigningOperator>>;
|
|
@@ -3718,6 +3722,7 @@ type ConfigOptions = MayHaveSspClientOptions & {
|
|
|
3718
3722
|
readonly signerWithPreExistingKeys?: boolean;
|
|
3719
3723
|
readonly console?: ConsoleOptions;
|
|
3720
3724
|
readonly events?: Partial<SparkWalletEvents>;
|
|
3725
|
+
readonly optimizationOptions?: OptimizationOptions;
|
|
3721
3726
|
};
|
|
3722
3727
|
|
|
3723
3728
|
declare class WalletConfigService implements HasSspClientOptions {
|
|
@@ -3743,6 +3748,7 @@ declare class WalletConfigService implements HasSspClientOptions {
|
|
|
3743
3748
|
getSspIdentityPublicKey(): string;
|
|
3744
3749
|
getConsoleOptions(): ConsoleOptions;
|
|
3745
3750
|
getEvents(): Partial<SparkWalletEvents>;
|
|
3751
|
+
getOptimizationOptions(): OptimizationOptions;
|
|
3746
3752
|
}
|
|
3747
3753
|
|
|
3748
3754
|
/** Challenge represents the core challenge data */
|
|
@@ -4044,8 +4050,11 @@ declare abstract class SparkWallet extends EventEmitter<SparkWalletEvents> {
|
|
|
4044
4050
|
private popOrThrow;
|
|
4045
4051
|
private selectLeaves;
|
|
4046
4052
|
private selectLeavesForSwap;
|
|
4047
|
-
|
|
4048
|
-
|
|
4053
|
+
optimizeLeaves(multiplicity?: number | undefined): AsyncGenerator<{
|
|
4054
|
+
step: number;
|
|
4055
|
+
total: number;
|
|
4056
|
+
controller: AbortController;
|
|
4057
|
+
}, void, void>;
|
|
4049
4058
|
private syncWallet;
|
|
4050
4059
|
private withLeaves;
|
|
4051
4060
|
/**
|
|
@@ -4802,6 +4811,7 @@ interface BroadcastResult {
|
|
|
4802
4811
|
declare function isEphemeralAnchorOutput(script?: Uint8Array, amount?: bigint): boolean;
|
|
4803
4812
|
declare function constructUnilateralExitTxs(nodeHexStrings: string[], sparkClient?: SparkServiceClient, network?: any): Promise<TxChain[]>;
|
|
4804
4813
|
declare function constructUnilateralExitFeeBumpPackages(nodeHexStrings: string[], utxos: Utxo[], feeRate: FeeRate, electrsUrl: string, sparkClient?: SparkServiceClient, network?: any): Promise<FeeBumpTxChain[]>;
|
|
4814
|
+
declare function hash160(data: Uint8Array): Uint8Array;
|
|
4805
4815
|
declare function constructFeeBumpTx(txHex: string, utxos: Utxo[], feeRate: FeeRate, previousFeeBumpTx?: string): {
|
|
4806
4816
|
feeBumpPsbt: string;
|
|
4807
4817
|
usedUtxos: Utxo[];
|
|
@@ -4823,4 +4833,4 @@ declare class SparkSdkLogger {
|
|
|
4823
4833
|
static setAllEnabled(enabled: boolean): void;
|
|
4824
4834
|
}
|
|
4825
4835
|
|
|
4826
|
-
export { type AggregateFrostParams, AuthenticationError, type Bech32mTokenIdentifier, type Bech32mTokenIdentifierData, type BroadcastConfig, type BroadcastResult, ConfigurationError, DEFAULT_FEE_SATS, DIRECT_HTLC_TIMELOCK_OFFSET, DIRECT_TIMELOCK_OFFSET, type DecodedSparkAddressData, DefaultSparkSigner, type FeeBumpTxChain, type FeeBumpTxPackage, type FeeRate, HTLC_TIMELOCK_OFFSET, type IKeyPackage, INITIAL_SEQUENCE, InternalValidationError, LOGGER_NAMES, type LeafInfo, type LegacySparkAddressFormat, type LoggerName, Network, NetworkError, NetworkToProto, type NetworkType, NotImplementedError, RPCError, type SignFrostParams, type SparkAddressData, type SparkAddressFormat, SparkSDKError, SparkSdkLogger, type SparkSigner, SparkWalletBare as SparkWallet, TEST_UNILATERAL_DIRECT_SEQUENCE, TEST_UNILATERAL_SEQUENCE, TaprootOutputKeysGenerator, TaprootSparkSigner, type TxChain, UnsafeStatelessSparkSigner, type Utxo, ValidationError, type VerifiableSecretShare, addPrivateKeys, addPublicKeys, applyAdaptorToSignature, applyAdditiveTweakToPublicKey, assertBech32, bech32mDecode, bigIntToPrivateKey, checkIfSelectedOutputsAreAvailable, checkIfValidSequence, collectResponses, computeTaprootKeyNoScript, computerLagrangeCoefficients, constructFeeBumpTx, constructUnilateralExitFeeBumpPackages, constructUnilateralExitTxs, createConnectorRefundTxs, createCurrentTimelockRefundTxs, createDecrementedTimelockNodeTx, createDecrementedTimelockRefundTxs, createInitialTimelockNodeTx, createInitialTimelockRefundTxs, createRootNodeTx, createSigningCommitment, createSigningNonce, createTestUnilateralRefundTxs, createTestUnilateralTimelockNodeTx, createZeroTimelockNodeTx, decodeBech32mTokenIdentifier, decodeBytesToSigningCommitment, decodeBytesToSigningNonce, decodeSparkAddress, doesLeafNeedRefresh, doesTxnNeedRenewed, encodeBech32mTokenIdentifier, encodeSigningCommitmentToBytes, encodeSigningNonceToBytes, encodeSparkAddress, encodeSparkAddressWithSignature, evaluatePolynomial, fieldDiv, filterTokenBalanceForTokenIdentifier, generateAdaptorFromSignature, generatePolynomialForSecretSharing, generateSignatureFromExistingAdaptor, getCurrentTimelock, getEphemeralAnchorOutput, getLatestDepositTxId, getNetwork, getNetworkFromAddress, getNetworkFromBech32mTokenIdentifier, getNetworkFromSparkAddress, getNetworkFromString, getNextHTLCTransactionSequence, getNextTransactionSequence, getP2TRAddressFromPkScript, getP2TRAddressFromPublicKey, getP2TRScriptFromPublicKey, getP2WPKHAddressFromPublicKey, getRandomBigInt, getRandomSigningNonce, getSigHashFromTx, getSigningCommitmentFromNonce, getSparkAddressFromTaproot, getTransactionSequence, getTransferPackageSigningPayload, getTxEstimatedVbytesSizeByNumberOfInputsOutputs, getTxFromRawTxBytes, getTxFromRawTxHex, getTxId, getTxIdNoReverse, isEphemeralAnchorOutput, isLegacySparkAddress, isSafeForNumber, isTxBroadcast, isValidPublicKey, isValidSparkAddress, isZeroTimelock, lastKeyWithTarget, maybeApplyFee, modInverse, proofOfPossessionMessageHashForDepositAddress, protoToNetwork, recoverSecret, splitSecret, splitSecretWithProofs, subtractPrivateKeys, subtractPublicKeys, sumAvailableTokens, sumOfPrivateKeys, toProtoTimestamp, validateOutboundAdaptorSignature, validateShare, validateSparkInvoiceFields, validateSparkInvoiceSignature };
|
|
4836
|
+
export { type AggregateFrostParams, AuthenticationError, type Bech32mTokenIdentifier, type Bech32mTokenIdentifierData, type BroadcastConfig, type BroadcastResult, ConfigurationError, DEFAULT_FEE_SATS, DIRECT_HTLC_TIMELOCK_OFFSET, DIRECT_TIMELOCK_OFFSET, type DecodedSparkAddressData, DefaultSparkSigner, type FeeBumpTxChain, type FeeBumpTxPackage, type FeeRate, HTLC_TIMELOCK_OFFSET, type IKeyPackage, INITIAL_SEQUENCE, InternalValidationError, LOGGER_NAMES, type LeafInfo, type LegacySparkAddressFormat, type LoggerName, Network, NetworkError, NetworkToProto, type NetworkType, NotImplementedError, RPCError, type SignFrostParams, type SparkAddressData, type SparkAddressFormat, SparkSDKError, SparkSdkLogger, type SparkSigner, SparkWalletBare as SparkWallet, TEST_UNILATERAL_DIRECT_SEQUENCE, TEST_UNILATERAL_SEQUENCE, TaprootOutputKeysGenerator, TaprootSparkSigner, type TxChain, UnsafeStatelessSparkSigner, type Utxo, ValidationError, type VerifiableSecretShare, addPrivateKeys, addPublicKeys, applyAdaptorToSignature, applyAdditiveTweakToPublicKey, assertBech32, bech32mDecode, bigIntToPrivateKey, checkIfSelectedOutputsAreAvailable, checkIfValidSequence, collectResponses, computeTaprootKeyNoScript, computerLagrangeCoefficients, constructFeeBumpTx, constructUnilateralExitFeeBumpPackages, constructUnilateralExitTxs, createConnectorRefundTxs, createCurrentTimelockRefundTxs, createDecrementedTimelockNodeTx, createDecrementedTimelockRefundTxs, createInitialTimelockNodeTx, createInitialTimelockRefundTxs, createRootNodeTx, createSigningCommitment, createSigningNonce, createTestUnilateralRefundTxs, createTestUnilateralTimelockNodeTx, createZeroTimelockNodeTx, decodeBech32mTokenIdentifier, decodeBytesToSigningCommitment, decodeBytesToSigningNonce, decodeSparkAddress, doesLeafNeedRefresh, doesTxnNeedRenewed, encodeBech32mTokenIdentifier, encodeSigningCommitmentToBytes, encodeSigningNonceToBytes, encodeSparkAddress, encodeSparkAddressWithSignature, evaluatePolynomial, fieldDiv, filterTokenBalanceForTokenIdentifier, generateAdaptorFromSignature, generatePolynomialForSecretSharing, generateSignatureFromExistingAdaptor, getCurrentTimelock, getEphemeralAnchorOutput, getLatestDepositTxId, getNetwork, getNetworkFromAddress, getNetworkFromBech32mTokenIdentifier, getNetworkFromSparkAddress, getNetworkFromString, getNextHTLCTransactionSequence, getNextTransactionSequence, getP2TRAddressFromPkScript, getP2TRAddressFromPublicKey, getP2TRScriptFromPublicKey, getP2WPKHAddressFromPublicKey, getRandomBigInt, getRandomSigningNonce, getSigHashFromTx, getSigningCommitmentFromNonce, getSparkAddressFromTaproot, getTransactionSequence, getTransferPackageSigningPayload, getTxEstimatedVbytesSizeByNumberOfInputsOutputs, getTxFromRawTxBytes, getTxFromRawTxHex, getTxId, getTxIdNoReverse, hash160, isEphemeralAnchorOutput, isLegacySparkAddress, isSafeForNumber, isTxBroadcast, isValidPublicKey, isValidSparkAddress, isZeroTimelock, lastKeyWithTarget, maybeApplyFee, modInverse, proofOfPossessionMessageHashForDepositAddress, protoToNetwork, recoverSecret, splitSecret, splitSecretWithProofs, subtractPrivateKeys, subtractPublicKeys, sumAvailableTokens, sumOfPrivateKeys, toProtoTimestamp, validateOutboundAdaptorSignature, validateShare, validateSparkInvoiceFields, validateSparkInvoiceSignature };
|