@buildonspark/spark-sdk 0.1.38 → 0.1.40
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 +12 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +1 -1
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/arm64-v8a/libspark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/arm64-v8a/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/armeabi-v7a/libspark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/armeabi-v7a/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/x86/libspark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/x86/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/x86_64/libspark_frost.so +0 -0
- package/android/build/intermediates/library_jni/debug/copyDebugJniLibsProjectOnly/jni/x86_64/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/arm64-v8a/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/arm64-v8a/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/armeabi-v7a/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/armeabi-v7a/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/x86/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/x86/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/x86_64/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_jni_libs/debug/mergeDebugJniLibFolders/out/x86_64/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/arm64-v8a/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/arm64-v8a/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/armeabi-v7a/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/armeabi-v7a/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/x86/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/x86/libuniffi_spark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/x86_64/libspark_frost.so +0 -0
- package/android/build/intermediates/merged_native_libs/debug/mergeDebugNativeLibs/out/lib/x86_64/libuniffi_spark_frost.so +0 -0
- package/dist/{RequestLightningSendInput-B4JdzclX.d.ts → RequestLightningSendInput-CJtcHOnu.d.ts} +1 -1
- package/dist/{RequestLightningSendInput-39_zGri6.d.cts → RequestLightningSendInput-DfmfqzZo.d.cts} +1 -1
- package/dist/address/index.d.cts +1 -1
- package/dist/address/index.d.ts +1 -1
- package/dist/address/index.js +2 -2
- package/dist/{chunk-W3EC5XSA.js → chunk-5MNQB2T4.js} +2 -2
- package/dist/chunk-ED3ZAFDI.js +784 -0
- package/dist/{chunk-VJTDG4BQ.js → chunk-HK6LPV6Z.js} +10 -1
- package/dist/{chunk-7WRK6WNJ.js → chunk-LHT4QTFK.js} +556 -41
- package/dist/{chunk-RAPBVYJY.js → chunk-RFCXPGDM.js} +26 -4
- package/dist/{chunk-DI7QXUQJ.js → chunk-W2VXS35Y.js} +4 -4
- package/dist/graphql/objects/index.d.cts +5 -4
- package/dist/graphql/objects/index.d.ts +5 -4
- package/dist/{index-CxAi2L8y.d.ts → index-BDEYgYxP.d.ts} +42 -4
- package/dist/{index-Dm17Ggfe.d.cts → index-CLdtdMU4.d.cts} +42 -4
- package/dist/index.cjs +1069 -40
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +33 -17
- package/dist/index.node.cjs +1069 -40
- package/dist/index.node.d.cts +6 -6
- package/dist/index.node.d.ts +6 -6
- package/dist/index.node.js +33 -17
- package/dist/native/index.cjs +1069 -40
- package/dist/native/index.d.cts +108 -5
- package/dist/native/index.d.ts +108 -5
- package/dist/native/index.js +1065 -40
- package/dist/{network-GFGEHkS4.d.cts → network-B10hBoHp.d.cts} +8 -1
- package/dist/{network-DobHpaV6.d.ts → network-CCgyIsGl.d.ts} +8 -1
- package/dist/services/config.cjs +29 -12
- package/dist/services/config.d.cts +4 -4
- package/dist/services/config.d.ts +4 -4
- package/dist/services/config.js +5 -5
- package/dist/services/connection.d.cts +4 -4
- package/dist/services/connection.d.ts +4 -4
- package/dist/services/connection.js +2 -2
- package/dist/services/index.cjs +30 -13
- package/dist/services/index.d.cts +4 -4
- package/dist/services/index.d.ts +4 -4
- package/dist/services/index.js +8 -8
- package/dist/services/lrc-connection.d.cts +4 -4
- package/dist/services/lrc-connection.d.ts +4 -4
- package/dist/services/lrc-connection.js +1 -1
- package/dist/services/token-transactions.cjs +1 -1
- package/dist/services/token-transactions.d.cts +4 -4
- package/dist/services/token-transactions.d.ts +4 -4
- package/dist/services/token-transactions.js +3 -3
- package/dist/services/wallet-config.d.cts +4 -4
- package/dist/services/wallet-config.d.ts +4 -4
- package/dist/signer/signer.cjs +23 -6
- package/dist/signer/signer.d.cts +3 -2
- package/dist/signer/signer.d.ts +3 -2
- package/dist/signer/signer.js +1 -1
- package/dist/{signer-DFGw9RRp.d.ts → signer-C5h1DpjF.d.ts} +4 -1
- package/dist/{signer-C1t40Wus.d.cts → signer-CYwn7h9U.d.cts} +4 -1
- package/dist/types/index.d.cts +4 -3
- package/dist/types/index.d.ts +4 -3
- package/dist/utils/index.cjs +891 -2
- package/dist/utils/index.d.cts +62 -6
- package/dist/utils/index.d.ts +62 -6
- package/dist/utils/index.js +23 -7
- package/package.json +1 -1
- package/src/services/deposit.ts +23 -5
- package/src/services/token-transactions.ts +1 -1
- package/src/services/transfer.ts +218 -11
- package/src/services/tree-creation.ts +29 -14
- package/src/signer/signer.ts +47 -5
- package/src/spark-wallet/spark-wallet.ts +430 -4
- package/src/tests/integration/swap.test.ts +225 -0
- package/src/tests/integration/tree-creation.test.ts +5 -1
- package/src/utils/index.ts +1 -0
- package/src/utils/mempool.ts +26 -1
- package/src/utils/network.ts +15 -0
- package/src/utils/transaction.ts +22 -2
- package/src/utils/unilateral-exit.ts +729 -0
- package/dist/chunk-E5SL7XTO.js +0 -301
- package/dist/{chunk-LIP2K6KR.js → chunk-2CDJZQN4.js} +3 -3
- package/dist/{chunk-RGWBSZIO.js → chunk-I4JI6TYN.js} +4 -4
|
@@ -244,4 +244,229 @@ describe("swap", () => {
|
|
|
244
244
|
leavesToClaim_1,
|
|
245
245
|
);
|
|
246
246
|
}, 30000);
|
|
247
|
+
|
|
248
|
+
it("test swap v2", async () => {
|
|
249
|
+
const faucet = BitcoinFaucet.getInstance();
|
|
250
|
+
// Initiate sender
|
|
251
|
+
const { wallet: senderWallet } = await SparkWalletTesting.initialize({
|
|
252
|
+
options: {
|
|
253
|
+
network: "LOCAL",
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
const senderPubkey = await senderWallet.getIdentityPublicKey();
|
|
257
|
+
|
|
258
|
+
const senderConfig = new WalletConfigService(
|
|
259
|
+
{
|
|
260
|
+
network: "LOCAL",
|
|
261
|
+
},
|
|
262
|
+
senderWallet.getSigner(),
|
|
263
|
+
);
|
|
264
|
+
const senderConnectionManager = new ConnectionManager(senderConfig);
|
|
265
|
+
const senderSigningService = new SigningService(senderConfig);
|
|
266
|
+
const senderTransferService = new TransferService(
|
|
267
|
+
senderConfig,
|
|
268
|
+
senderConnectionManager,
|
|
269
|
+
senderSigningService,
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
// Initiate receiver
|
|
273
|
+
const { wallet: receiverWallet } = await SparkWalletTesting.initialize({
|
|
274
|
+
options: {
|
|
275
|
+
network: "LOCAL",
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
const receiverPubkey = await receiverWallet.getIdentityPublicKey();
|
|
279
|
+
|
|
280
|
+
const receiverConfig = new WalletConfigService(
|
|
281
|
+
{
|
|
282
|
+
network: "LOCAL",
|
|
283
|
+
},
|
|
284
|
+
receiverWallet.getSigner(),
|
|
285
|
+
);
|
|
286
|
+
const receiverConnectionManager = new ConnectionManager(receiverConfig);
|
|
287
|
+
const receiverSigningService = new SigningService(receiverConfig);
|
|
288
|
+
const receiverTransferService = new TransferService(
|
|
289
|
+
receiverConfig,
|
|
290
|
+
receiverConnectionManager,
|
|
291
|
+
receiverSigningService,
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
const senderLeafPubKey = await senderWallet.getSigner().generatePublicKey();
|
|
295
|
+
const senderRootNode = await createNewTree(
|
|
296
|
+
senderWallet,
|
|
297
|
+
senderLeafPubKey,
|
|
298
|
+
faucet,
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
const receiverLeafPubKey = await receiverWallet
|
|
302
|
+
.getSigner()
|
|
303
|
+
.generatePublicKey();
|
|
304
|
+
const receiverRootNode = await createNewTree(
|
|
305
|
+
receiverWallet,
|
|
306
|
+
receiverLeafPubKey,
|
|
307
|
+
faucet,
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
// Sender initiates transfer
|
|
311
|
+
const senderNewLeafPubKey = await senderWallet
|
|
312
|
+
.getSigner()
|
|
313
|
+
.generatePublicKey(sha256("1"));
|
|
314
|
+
const senderTransferNode: LeafKeyTweak = {
|
|
315
|
+
leaf: senderRootNode,
|
|
316
|
+
signingPubKey: senderLeafPubKey,
|
|
317
|
+
newSigningPubKey: senderNewLeafPubKey,
|
|
318
|
+
};
|
|
319
|
+
const senderLeavesToTransfer = [senderTransferNode];
|
|
320
|
+
|
|
321
|
+
// Get signature for refunds (normal flow)
|
|
322
|
+
const {
|
|
323
|
+
transfer: senderTransfer,
|
|
324
|
+
signatureMap: senderRefundSignatureMap,
|
|
325
|
+
leafDataMap: senderLeafDataMap,
|
|
326
|
+
} = await senderTransferService.startSwapSignRefund(
|
|
327
|
+
senderLeavesToTransfer,
|
|
328
|
+
hexToBytes(receiverPubkey),
|
|
329
|
+
new Date(Date.now() + 10 * 60 * 1000),
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
expect(senderRefundSignatureMap.size).toBe(1);
|
|
333
|
+
const senderSignature = senderRefundSignatureMap.get(senderRootNode.id);
|
|
334
|
+
expect(senderSignature).toBeDefined();
|
|
335
|
+
expect(senderLeafDataMap.size).toBe(1);
|
|
336
|
+
|
|
337
|
+
const { adaptorPrivateKey } = generateAdaptorFromSignature(
|
|
338
|
+
senderSignature!,
|
|
339
|
+
);
|
|
340
|
+
const adaptorPubKey = secp256k1.getPublicKey(adaptorPrivateKey);
|
|
341
|
+
|
|
342
|
+
const receiverNewLeafPubKey = await receiverWallet
|
|
343
|
+
.getSigner()
|
|
344
|
+
.generatePublicKey(sha256("1"));
|
|
345
|
+
|
|
346
|
+
const receiverTransferNode: LeafKeyTweak = {
|
|
347
|
+
leaf: receiverRootNode,
|
|
348
|
+
signingPubKey: receiverLeafPubKey,
|
|
349
|
+
newSigningPubKey: receiverNewLeafPubKey,
|
|
350
|
+
};
|
|
351
|
+
const receiverLeavesToTransfer = [receiverTransferNode];
|
|
352
|
+
|
|
353
|
+
const {
|
|
354
|
+
transfer: receiverTransfer,
|
|
355
|
+
signatureMap: receiverRefundSignatureMap,
|
|
356
|
+
leafDataMap: receiverLeafDataMap,
|
|
357
|
+
signingResults: operatorSigningResults,
|
|
358
|
+
} = await receiverTransferService.counterSwapSignRefund(
|
|
359
|
+
receiverLeavesToTransfer,
|
|
360
|
+
hexToBytes(senderPubkey),
|
|
361
|
+
new Date(Date.now() + 10 * 60 * 1000),
|
|
362
|
+
adaptorPubKey,
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
const newReceiverRefundSignatureMap = new Map<string, Uint8Array>();
|
|
366
|
+
for (const [nodeId, signature] of receiverRefundSignatureMap.entries()) {
|
|
367
|
+
const leafData = receiverLeafDataMap.get(nodeId);
|
|
368
|
+
if (!leafData?.refundTx) {
|
|
369
|
+
throw new ValidationError("Refund transaction not found", {
|
|
370
|
+
field: "refundTx",
|
|
371
|
+
value: leafData,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
const sighash = getSigHashFromTx(
|
|
375
|
+
leafData.refundTx,
|
|
376
|
+
0,
|
|
377
|
+
leafData.tx.getOutput(leafData.vout),
|
|
378
|
+
);
|
|
379
|
+
let verifyingPubkey: Uint8Array | undefined;
|
|
380
|
+
for (const signingResult of operatorSigningResults) {
|
|
381
|
+
if (signingResult.leafId === nodeId) {
|
|
382
|
+
verifyingPubkey = signingResult.verifyingKey;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
expect(verifyingPubkey).toBeDefined();
|
|
386
|
+
const taprootKey = computeTaprootKeyNoScript(
|
|
387
|
+
verifyingPubkey!.slice(1, 33),
|
|
388
|
+
);
|
|
389
|
+
const adaptorSig = applyAdaptorToSignature(
|
|
390
|
+
taprootKey.slice(1, 33),
|
|
391
|
+
sighash,
|
|
392
|
+
signature,
|
|
393
|
+
adaptorPrivateKey,
|
|
394
|
+
);
|
|
395
|
+
newReceiverRefundSignatureMap.set(nodeId, adaptorSig);
|
|
396
|
+
}
|
|
397
|
+
const senderTransferTweakKey =
|
|
398
|
+
await senderTransferService.deliverTransferPackage(
|
|
399
|
+
senderTransfer,
|
|
400
|
+
senderLeavesToTransfer,
|
|
401
|
+
senderRefundSignatureMap,
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
const pendingTransfer =
|
|
405
|
+
await receiverTransferService.queryPendingTransfers();
|
|
406
|
+
expect(pendingTransfer.transfers.length).toBe(1);
|
|
407
|
+
const receiverPendingTransfer = pendingTransfer.transfers[0];
|
|
408
|
+
expect(receiverPendingTransfer!.id).toBe(senderTransferTweakKey.id);
|
|
409
|
+
|
|
410
|
+
const leafPrivKeyMap = await receiverTransferService.verifyPendingTransfer(
|
|
411
|
+
receiverPendingTransfer!,
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
expect(leafPrivKeyMap.size).toBe(1);
|
|
415
|
+
expect(leafPrivKeyMap.get(senderRootNode.id)).toBeDefined();
|
|
416
|
+
const bytesEqual = equalBytes(
|
|
417
|
+
leafPrivKeyMap.get(senderRootNode.id)!,
|
|
418
|
+
senderNewLeafPubKey,
|
|
419
|
+
);
|
|
420
|
+
expect(bytesEqual).toBe(true);
|
|
421
|
+
expect(receiverPendingTransfer!.leaves[0]!.leaf).toBeDefined();
|
|
422
|
+
const finalLeafPubKey = await receiverWallet
|
|
423
|
+
.getSigner()
|
|
424
|
+
.generatePublicKey(sha256("2"));
|
|
425
|
+
const claimingNode: LeafKeyTweak = {
|
|
426
|
+
leaf: receiverPendingTransfer!.leaves[0]!.leaf!,
|
|
427
|
+
signingPubKey: senderNewLeafPubKey,
|
|
428
|
+
newSigningPubKey: finalLeafPubKey,
|
|
429
|
+
};
|
|
430
|
+
const leavesToClaim = [claimingNode];
|
|
431
|
+
await receiverTransferService.claimTransfer(
|
|
432
|
+
receiverPendingTransfer!,
|
|
433
|
+
leavesToClaim,
|
|
434
|
+
);
|
|
435
|
+
await receiverTransferService.deliverTransferPackage(
|
|
436
|
+
receiverTransfer,
|
|
437
|
+
receiverLeavesToTransfer,
|
|
438
|
+
newReceiverRefundSignatureMap,
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
const sPendingTransfer =
|
|
442
|
+
await senderTransferService.queryPendingTransfers();
|
|
443
|
+
expect(sPendingTransfer.transfers.length).toBe(1);
|
|
444
|
+
const senderPendingTransfer = sPendingTransfer.transfers[0];
|
|
445
|
+
expect(senderPendingTransfer!.id).toBe(receiverTransfer.id);
|
|
446
|
+
|
|
447
|
+
const senderLeafPrivKeyMap =
|
|
448
|
+
await senderTransferService.verifyPendingTransfer(senderPendingTransfer!);
|
|
449
|
+
expect(senderLeafPrivKeyMap.size).toBe(1);
|
|
450
|
+
expect(senderLeafPrivKeyMap.get(receiverRootNode.id)).toBeDefined();
|
|
451
|
+
const bytesEqual_1 = equalBytes(
|
|
452
|
+
senderLeafPrivKeyMap.get(receiverRootNode.id)!,
|
|
453
|
+
receiverNewLeafPubKey,
|
|
454
|
+
);
|
|
455
|
+
expect(bytesEqual_1).toBe(true);
|
|
456
|
+
expect(senderPendingTransfer!.leaves[0]!.leaf).toBeDefined();
|
|
457
|
+
|
|
458
|
+
const finalLeafPubKey_1 = await senderWallet
|
|
459
|
+
.getSigner()
|
|
460
|
+
.generatePublicKey(sha256("3"));
|
|
461
|
+
const claimingNode_1: LeafKeyTweak = {
|
|
462
|
+
leaf: senderPendingTransfer!.leaves[0]!.leaf!,
|
|
463
|
+
signingPubKey: receiverNewLeafPubKey,
|
|
464
|
+
newSigningPubKey: finalLeafPubKey_1,
|
|
465
|
+
};
|
|
466
|
+
const leavesToClaim_1 = [claimingNode_1];
|
|
467
|
+
await senderTransferService.claimTransfer(
|
|
468
|
+
senderPendingTransfer!,
|
|
469
|
+
leavesToClaim_1,
|
|
470
|
+
);
|
|
471
|
+
}, 30000);
|
|
247
472
|
});
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import { describe, expect, it } from "@jest/globals";
|
|
3
3
|
import { bytesToHex } from "@noble/curves/abstract/utils";
|
|
4
|
+
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
4
5
|
import { ValidationError } from "../../errors/types.js";
|
|
5
6
|
import { getTxFromRawTxBytes, getTxId } from "../../utils/bitcoin.js";
|
|
6
7
|
import { Network } from "../../utils/network.js";
|
|
8
|
+
import { DEFAULT_FEE_SATS } from "../../utils/transaction.js";
|
|
9
|
+
import { createNewTreeWithLevels } from "../test-util.js";
|
|
7
10
|
import { SparkWalletTesting } from "../utils/spark-testing-wallet.js";
|
|
11
|
+
import { BitcoinFaucet } from "../utils/test-faucet.js";
|
|
8
12
|
|
|
9
13
|
describe("Tree Creation", () => {
|
|
10
14
|
it.skip("test tree creation address generation", async () => {
|
|
@@ -19,7 +23,7 @@ describe("Tree Creation", () => {
|
|
|
19
23
|
|
|
20
24
|
const dummyTx = createDummyTx({
|
|
21
25
|
address: depositResp.depositAddress!.address,
|
|
22
|
-
amountSats: 65536n,
|
|
26
|
+
amountSats: 65536n + DEFAULT_FEE_SATS,
|
|
23
27
|
});
|
|
24
28
|
|
|
25
29
|
const depositTxHex = bytesToHex(dummyTx.tx);
|
package/src/utils/index.ts
CHANGED
package/src/utils/mempool.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
getElectrsUrl,
|
|
4
4
|
} from "../services/wallet-config.js";
|
|
5
5
|
import { BitcoinNetwork } from "../types/index.js";
|
|
6
|
-
import { getNetworkFromAddress } from "./network.js";
|
|
6
|
+
import { Network, getNetworkFromAddress } from "./network.js";
|
|
7
7
|
|
|
8
8
|
export async function getLatestDepositTxId(
|
|
9
9
|
address: string,
|
|
@@ -42,3 +42,28 @@ export async function getLatestDepositTxId(
|
|
|
42
42
|
}
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
export async function isTxBroadcast(
|
|
47
|
+
txid: string,
|
|
48
|
+
baseUrl: string,
|
|
49
|
+
network?: any,
|
|
50
|
+
): Promise<boolean> {
|
|
51
|
+
const headers: Record<string, string> = {};
|
|
52
|
+
|
|
53
|
+
if (network === Network.REGTEST) {
|
|
54
|
+
const auth = btoa(
|
|
55
|
+
`${ELECTRS_CREDENTIALS.username}:${ELECTRS_CREDENTIALS.password}`,
|
|
56
|
+
);
|
|
57
|
+
headers["Authorization"] = `Basic ${auth}`;
|
|
58
|
+
}
|
|
59
|
+
const response = await fetch(`${baseUrl}/tx/${txid}`, {
|
|
60
|
+
headers,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const tx = await response.json();
|
|
64
|
+
if (tx.error) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return true;
|
|
69
|
+
}
|
package/src/utils/network.ts
CHANGED
|
@@ -78,3 +78,18 @@ export function getNetworkFromAddress(address: string) {
|
|
|
78
78
|
}
|
|
79
79
|
return null;
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Utility function to get the network enum value from a string.
|
|
84
|
+
*
|
|
85
|
+
* @param {string} network - The Bitcoin network to turn into an enum value
|
|
86
|
+
* @returns {Network} The enum value matching the string
|
|
87
|
+
*/
|
|
88
|
+
export function getNetworkFromString(network?: string) {
|
|
89
|
+
const net = (network ?? "REGTEST").toUpperCase();
|
|
90
|
+
if (net === "MAINNET") return Network.MAINNET;
|
|
91
|
+
if (net === "TESTNET") return Network.TESTNET;
|
|
92
|
+
if (net === "SIGNET") return Network.SIGNET;
|
|
93
|
+
if (net === "LOCAL") return Network.LOCAL;
|
|
94
|
+
return Network.REGTEST; // default
|
|
95
|
+
}
|
package/src/utils/transaction.ts
CHANGED
|
@@ -6,6 +6,22 @@ import { Network } from "./network.js";
|
|
|
6
6
|
|
|
7
7
|
const TIME_LOCK_INTERVAL = 100;
|
|
8
8
|
|
|
9
|
+
// Default fee constants matching Go implementation
|
|
10
|
+
const ESTIMATED_TX_SIZE = 191;
|
|
11
|
+
const DEFAULT_SATS_PER_VBYTE = 5;
|
|
12
|
+
export const DEFAULT_FEE_SATS = ESTIMATED_TX_SIZE * DEFAULT_SATS_PER_VBYTE;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Subtracts the default fee from the amount if it's greater than the fee.
|
|
16
|
+
* Returns the original amount if it's less than or equal to the fee.
|
|
17
|
+
*/
|
|
18
|
+
export function maybeApplyFee(amount: bigint): bigint {
|
|
19
|
+
if (amount > BigInt(DEFAULT_FEE_SATS)) {
|
|
20
|
+
return amount - BigInt(DEFAULT_FEE_SATS);
|
|
21
|
+
}
|
|
22
|
+
return amount;
|
|
23
|
+
}
|
|
24
|
+
|
|
9
25
|
export function createRefundTx(
|
|
10
26
|
sequence: number,
|
|
11
27
|
nodeOutPoint: TransactionInput,
|
|
@@ -13,7 +29,10 @@ export function createRefundTx(
|
|
|
13
29
|
receivingPubkey: Uint8Array,
|
|
14
30
|
network: Network,
|
|
15
31
|
): Transaction {
|
|
16
|
-
const newRefundTx = new Transaction({
|
|
32
|
+
const newRefundTx = new Transaction({
|
|
33
|
+
version: 3,
|
|
34
|
+
allowUnknownOutputs: true,
|
|
35
|
+
});
|
|
17
36
|
newRefundTx.addInput({
|
|
18
37
|
...nodeOutPoint,
|
|
19
38
|
sequence,
|
|
@@ -25,6 +44,7 @@ export function createRefundTx(
|
|
|
25
44
|
script: refundPkScript,
|
|
26
45
|
amount: amountSats,
|
|
27
46
|
});
|
|
47
|
+
|
|
28
48
|
newRefundTx.addOutput(getEphemeralAnchorOutput());
|
|
29
49
|
|
|
30
50
|
return newRefundTx;
|
|
@@ -55,7 +75,7 @@ export function getNextTransactionSequence(
|
|
|
55
75
|
};
|
|
56
76
|
}
|
|
57
77
|
|
|
58
|
-
if (nextTimelock
|
|
78
|
+
if (nextTimelock < 0) {
|
|
59
79
|
throw new ValidationError("timelock interval is less than or equal to 0", {
|
|
60
80
|
field: "nextTimelock",
|
|
61
81
|
value: nextTimelock,
|