@arkade-os/sdk 0.4.19 → 0.4.21

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.
Files changed (61) hide show
  1. package/dist/cjs/contracts/contractWatcher.js +33 -3
  2. package/dist/cjs/contracts/handlers/default.js +10 -3
  3. package/dist/cjs/contracts/handlers/helpers.js +47 -5
  4. package/dist/cjs/contracts/handlers/vhtlc.js +4 -2
  5. package/dist/cjs/identity/descriptor.js +98 -0
  6. package/dist/cjs/identity/descriptorProvider.js +2 -0
  7. package/dist/cjs/identity/index.js +15 -1
  8. package/dist/cjs/identity/seedIdentity.js +91 -6
  9. package/dist/cjs/identity/serialize.js +166 -0
  10. package/dist/cjs/identity/staticDescriptorProvider.js +65 -0
  11. package/dist/cjs/index.js +6 -3
  12. package/dist/cjs/providers/ark.js +71 -46
  13. package/dist/cjs/providers/electrum.js +663 -0
  14. package/dist/cjs/providers/indexer.js +60 -43
  15. package/dist/cjs/providers/utils.js +62 -12
  16. package/dist/cjs/wallet/ramps.js +1 -1
  17. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +10 -0
  18. package/dist/cjs/wallet/serviceWorker/wallet.js +137 -91
  19. package/dist/cjs/wallet/vtxo-manager.js +56 -8
  20. package/dist/cjs/wallet/wallet.js +130 -156
  21. package/dist/cjs/worker/messageBus.js +200 -56
  22. package/dist/esm/contracts/contractWatcher.js +33 -3
  23. package/dist/esm/contracts/handlers/default.js +10 -3
  24. package/dist/esm/contracts/handlers/helpers.js +47 -5
  25. package/dist/esm/contracts/handlers/vhtlc.js +4 -2
  26. package/dist/esm/identity/descriptor.js +92 -0
  27. package/dist/esm/identity/descriptorProvider.js +1 -0
  28. package/dist/esm/identity/index.js +6 -1
  29. package/dist/esm/identity/seedIdentity.js +89 -6
  30. package/dist/esm/identity/serialize.js +159 -0
  31. package/dist/esm/identity/staticDescriptorProvider.js +61 -0
  32. package/dist/esm/index.js +2 -1
  33. package/dist/esm/providers/ark.js +72 -47
  34. package/dist/esm/providers/electrum.js +658 -0
  35. package/dist/esm/providers/indexer.js +61 -44
  36. package/dist/esm/providers/utils.js +61 -12
  37. package/dist/esm/wallet/ramps.js +1 -1
  38. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +10 -0
  39. package/dist/esm/wallet/serviceWorker/wallet.js +137 -91
  40. package/dist/esm/wallet/vtxo-manager.js +56 -8
  41. package/dist/esm/wallet/wallet.js +130 -156
  42. package/dist/esm/worker/messageBus.js +201 -57
  43. package/dist/types/contracts/contractWatcher.d.ts +3 -0
  44. package/dist/types/contracts/handlers/default.d.ts +1 -1
  45. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  46. package/dist/types/contracts/types.d.ts +11 -3
  47. package/dist/types/identity/descriptor.d.ts +35 -0
  48. package/dist/types/identity/descriptorProvider.d.ts +28 -0
  49. package/dist/types/identity/index.d.ts +7 -1
  50. package/dist/types/identity/seedIdentity.d.ts +41 -4
  51. package/dist/types/identity/serialize.d.ts +84 -0
  52. package/dist/types/identity/staticDescriptorProvider.d.ts +18 -0
  53. package/dist/types/index.d.ts +4 -2
  54. package/dist/types/providers/electrum.d.ts +212 -0
  55. package/dist/types/providers/utils.d.ts +10 -5
  56. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +11 -2
  57. package/dist/types/wallet/serviceWorker/wallet.d.ts +27 -10
  58. package/dist/types/wallet/vtxo-manager.d.ts +2 -0
  59. package/dist/types/wallet/wallet.d.ts +7 -6
  60. package/dist/types/worker/messageBus.d.ts +68 -8
  61. package/package.json +3 -2
@@ -10,6 +10,8 @@ const base_1 = require("@scure/base");
10
10
  const base_2 = require("../script/base");
11
11
  const transaction_1 = require("../utils/transaction");
12
12
  const txSizeEstimator_1 = require("../utils/txSizeEstimator");
13
+ const arkfee_1 = require("../arkfee");
14
+ const address_1 = require("../script/address");
13
15
  /**
14
16
  * Return whether a wallet exposes the properties required for boarding input sweep operations.
15
17
  *
@@ -19,6 +21,7 @@ const txSizeEstimator_1 = require("../utils/txSizeEstimator");
19
21
  function isSweepCapable(wallet) {
20
22
  return ("boardingTapscript" in wallet &&
21
23
  "onchainProvider" in wallet &&
24
+ "arkProvider" in wallet &&
22
25
  "network" in wallet);
23
26
  }
24
27
  /**
@@ -29,7 +32,7 @@ function isSweepCapable(wallet) {
29
32
  */
30
33
  function assertSweepCapable(wallet) {
31
34
  if (!isSweepCapable(wallet)) {
32
- throw new Error("Boarding UTXO sweep requires a Wallet instance with boardingTapscript, onchainProvider, and network");
35
+ throw new Error("Boarding UTXO sweep requires a Wallet instance with boardingTapscript, onchainProvider, arkProvider, and network");
33
36
  }
34
37
  }
35
38
  /**
@@ -627,6 +630,10 @@ class VtxoManager {
627
630
  getOnchainProvider() {
628
631
  return this.getSweepWallet().onchainProvider;
629
632
  }
633
+ /** Returns the Ark provider for intent fee and server info lookups. */
634
+ getArkProvider() {
635
+ return this.getSweepWallet().arkProvider;
636
+ }
630
637
  /** Returns the Bitcoin network configuration from the wallet. */
631
638
  getNetwork() {
632
639
  return this.getSweepWallet().network;
@@ -896,13 +903,54 @@ class VtxoManager {
896
903
  return;
897
904
  }
898
905
  const dustAmount = getDustAmount(this.wallet);
899
- const boardingTotal = unsettledBoarding.reduce((sum, u) => sum + BigInt(u.value), 0n);
900
- const vtxoTotal = expiringVtxos.reduce((sum, v) => sum + BigInt(v.value), 0n);
901
- const totalAmount = boardingTotal + vtxoTotal;
902
- if (totalAmount < dustAmount)
906
+ // Fetch server intent-fee config so each input/output can be priced.
907
+ // Without this, settle sends `outputAmount = sum(inputs)` and the
908
+ // server rejects with INTENT_INSUFFICIENT_FEE whenever the operator
909
+ // charges non-zero intent fees.
910
+ const { fees } = await this.getArkProvider().getInfo();
911
+ const estimator = new arkfee_1.Estimator(fees.intentFee);
912
+ let totalAmount = 0n;
913
+ const filteredBoarding = [];
914
+ for (const u of unsettledBoarding) {
915
+ const inputFee = estimator.evalOnchainInput({
916
+ amount: BigInt(u.value),
917
+ });
918
+ if (inputFee.value >= BigInt(u.value)) {
919
+ // Fee exceeds input value — including it would drain the output.
920
+ continue;
921
+ }
922
+ filteredBoarding.push(u);
923
+ totalAmount += BigInt(u.value) - BigInt(inputFee.satoshis);
924
+ }
925
+ const filteredVtxos = [];
926
+ for (const v of expiringVtxos) {
927
+ const inputFee = estimator.evalOffchainInput({
928
+ amount: BigInt(v.value),
929
+ type: v.virtualStatus.state === "swept" ? "recoverable" : "vtxo",
930
+ weight: 0,
931
+ birth: v.createdAt,
932
+ expiry: v.virtualStatus.batchExpiry
933
+ ? new Date(v.virtualStatus.batchExpiry)
934
+ : undefined,
935
+ });
936
+ if (inputFee.satoshis >= v.value) {
937
+ continue;
938
+ }
939
+ filteredVtxos.push(v);
940
+ totalAmount += BigInt(v.value) - BigInt(inputFee.satoshis);
941
+ }
942
+ if (filteredBoarding.length === 0 && filteredVtxos.length === 0) {
903
943
  return;
944
+ }
904
945
  const arkAddress = await this.wallet.getAddress();
905
- const includesVtxos = expiringVtxos.length > 0;
946
+ const outputFee = estimator.evalOffchainOutput({
947
+ amount: totalAmount,
948
+ script: base_1.hex.encode(address_1.ArkAddress.decode(arkAddress).pkScript),
949
+ });
950
+ totalAmount -= BigInt(outputFee.satoshis);
951
+ if (totalAmount < dustAmount)
952
+ return;
953
+ const includesVtxos = filteredVtxos.length > 0;
906
954
  // Block the event-driven renewal path while this settle is in flight
907
955
  // when VTXOs are part of the intent. Mirrors renewVtxos()'s guard so
908
956
  // the two paths can't race on the same VTXO inputs.
@@ -914,11 +962,11 @@ class VtxoManager {
914
962
  try {
915
963
  try {
916
964
  await this.wallet.settle({
917
- inputs: [...unsettledBoarding, ...expiringVtxos],
965
+ inputs: [...filteredBoarding, ...filteredVtxos],
918
966
  outputs: [{ address: arkAddress, amount: totalAmount }],
919
967
  });
920
968
  // Mark boarding inputs as known only after successful settle.
921
- for (const u of unsettledBoarding) {
969
+ for (const u of filteredBoarding) {
922
970
  this.knownBoardingUtxos.add(`${u.txid}:${u.vout}`);
923
971
  }
924
972
  success = true;
@@ -39,10 +39,28 @@ const contractManager_1 = require("../contracts/contractManager");
39
39
  const handlers_1 = require("../contracts/handlers");
40
40
  const helpers_1 = require("../contracts/handlers/helpers");
41
41
  const syncCursors_1 = require("../utils/syncCursors");
42
- // Hardcoded unilateral exit delay for mainnet (~7 days in seconds).
43
- // Pinned here so that address derivation stays stable for existing mainnet
44
- // wallets even after the server lowers the delay it advertises.
42
+ // Historical unilateral exit delay for mainnet (~7 days in seconds).
43
+ // Kept so existing wallets can still discover and spend VTXOs sent to the
44
+ // legacy address after arkd starts advertising a different delay.
45
45
  const MAINNET_UNILATERAL_EXIT_DELAY = 605184n;
46
+ function delayToTimelock(delay) {
47
+ return {
48
+ value: delay,
49
+ type: delay < 512n ? "blocks" : "seconds",
50
+ };
51
+ }
52
+ function dedupeTimelocks(timelocks) {
53
+ const seen = new Set();
54
+ const deduped = [];
55
+ for (const timelock of timelocks) {
56
+ const sequence = (0, helpers_1.timelockToSequence)(timelock).toString();
57
+ if (seen.has(sequence))
58
+ continue;
59
+ seen.add(sequence);
60
+ deduped.push(timelock);
61
+ }
62
+ return deduped;
63
+ }
46
64
  /**
47
65
  * Type guard function to check if an identity has a toReadonly method.
48
66
  */
@@ -56,7 +74,7 @@ class ReadonlyWallet {
56
74
  get assetManager() {
57
75
  return this._assetManager;
58
76
  }
59
- constructor(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegatorProvider, watcherConfig) {
77
+ constructor(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegatorProvider, watcherConfig, walletContractTimelocks) {
60
78
  this.identity = identity;
61
79
  this.network = network;
62
80
  this.onchainProvider = onchainProvider;
@@ -89,6 +107,15 @@ class ReadonlyWallet {
89
107
  }
90
108
  this.watcherConfig = watcherConfig;
91
109
  this._assetManager = new asset_manager_1.ReadonlyAssetManager(this.indexerProvider);
110
+ // Defensive for direct-construction callers; setupWalletConfig already
111
+ // passes a deduped list through the public create() factories.
112
+ this.walletContractTimelocks =
113
+ walletContractTimelocks && walletContractTimelocks.length > 0
114
+ ? dedupeTimelocks(walletContractTimelocks)
115
+ : [
116
+ this.offchainTapscript.options.csvTimelock ??
117
+ default_1.DefaultVtxo.Script.DEFAULT_TIMELOCK,
118
+ ];
92
119
  }
93
120
  /**
94
121
  * Protected helper to set up shared wallet configuration.
@@ -144,17 +171,17 @@ class ReadonlyWallet {
144
171
  throw new Error("invalid exitTimelock");
145
172
  }
146
173
  }
147
- // On mainnet, pin the unilateral exit delay to the historical value so
148
- // that addresses derived by existing wallets remain stable even if the
149
- // server starts advertising a shorter delay.
150
- const unilateralExitDelay = info.network === "bitcoin"
151
- ? MAINNET_UNILATERAL_EXIT_DELAY
152
- : info.unilateralExitDelay;
174
+ const arkdExitTimelock = delayToTimelock(info.unilateralExitDelay);
153
175
  // create unilateral exit timelock
154
- const exitTimelock = config.exitTimelock ?? {
155
- value: unilateralExitDelay,
156
- type: unilateralExitDelay < 512n ? "blocks" : "seconds",
157
- };
176
+ const exitTimelock = config.exitTimelock ?? arkdExitTimelock;
177
+ const walletContractTimelocks = config.exitTimelock
178
+ ? [exitTimelock]
179
+ : dedupeTimelocks([
180
+ arkdExitTimelock,
181
+ ...(info.network === "bitcoin"
182
+ ? [delayToTimelock(MAINNET_UNILATERAL_EXIT_DELAY)]
183
+ : []),
184
+ ]);
158
185
  // validate boarding timelock passed in config if any
159
186
  if (config.boardingTimelock) {
160
187
  const { value, type } = config.boardingTimelock;
@@ -204,6 +231,7 @@ class ReadonlyWallet {
204
231
  contractRepository,
205
232
  info,
206
233
  delegatorProvider: config.delegatorProvider,
234
+ walletContractTimelocks,
207
235
  };
208
236
  }
209
237
  /**
@@ -218,14 +246,14 @@ class ReadonlyWallet {
218
246
  throw new Error("Invalid configured public key");
219
247
  }
220
248
  const setup = await ReadonlyWallet.setupWalletConfig(config, pubkey);
221
- return new ReadonlyWallet(config.identity, setup.network, setup.onchainProvider, setup.indexerProvider, setup.serverPubKey, setup.offchainTapscript, setup.boardingTapscript, setup.dustAmount, setup.walletRepository, setup.contractRepository, setup.delegatorProvider, config.watcherConfig);
249
+ return new ReadonlyWallet(config.identity, setup.network, setup.onchainProvider, setup.indexerProvider, setup.serverPubKey, setup.offchainTapscript, setup.boardingTapscript, setup.dustAmount, setup.walletRepository, setup.contractRepository, setup.delegatorProvider, config.watcherConfig, setup.walletContractTimelocks);
222
250
  }
223
251
  get arkAddress() {
224
252
  return this.offchainTapscript.address(this.network.hrp, this.arkServerPublicKey);
225
253
  }
226
254
  /**
227
- * Get the contract script for the wallet's default address.
228
- * This is the pkScript hex, used to identify the wallet in ContractManager.
255
+ * Get the pkScript hex for the wallet's primary offchain address.
256
+ * For the full wallet-owned script set registered in ContractManager, use getWalletScripts().
229
257
  */
230
258
  get defaultContractScript() {
231
259
  return base_1.hex.encode(this.offchainTapscript.pkScript);
@@ -469,56 +497,39 @@ class ReadonlyWallet {
469
497
  });
470
498
  }
471
499
  if (this.indexerProvider && arkAddress) {
472
- const walletScripts = await this.getWalletScripts();
473
- const subscriptionId = await this.indexerProvider.subscribeForScripts(walletScripts);
474
- const abortController = new AbortController();
475
- const subscription = this.indexerProvider.getSubscription(subscriptionId, abortController.signal);
476
- indexerStopFunc = async () => {
477
- abortController.abort();
478
- await this.indexerProvider?.unsubscribeForScripts(subscriptionId);
479
- };
480
- // Handle subscription updates asynchronously without blocking.
481
- // Subscription covers all wallet scripts (default + delegate) plus
482
- // any additional registered contracts. Virtual outputs carry a
483
- // `script` field from the indexer which the contract manager
484
- // resolves to the owning contract so the extension uses the
485
- // correct forfeit/intent tapscripts.
486
- (async () => {
487
- try {
488
- const cm = await this.getContractManager();
489
- for await (const update of subscription) {
490
- if (update.newVtxos?.length === 0 &&
491
- update.spentVtxos?.length === 0) {
492
- continue;
493
- }
494
- // Isolate per-update annotation failures (e.g. a VTXO
495
- // arriving for a contract we haven't registered yet).
496
- // Without this a single bad update would kill the
497
- // for-await loop and silently drop every subsequent
498
- // subscription event for the session.
499
- try {
500
- // Default to `[]` so a one-sided update (e.g.
501
- // only `newVtxos`) doesn't pass `undefined` into
502
- // annotateVtxos and throw on `.length`.
503
- const [newVtxos, spentVtxos] = await Promise.all([
504
- cm.annotateVtxos(update.newVtxos ?? []),
505
- cm.annotateVtxos(update.spentVtxos ?? []),
506
- ]);
507
- eventCallback({
508
- type: "vtxo",
509
- newVtxos,
510
- spentVtxos,
511
- });
512
- }
513
- catch (error) {
514
- console.warn("Dropping subscription update after annotation failed; next sync will reconcile:", error);
515
- }
516
- }
500
+ // Share the ContractWatcher's single subscription instead of
501
+ // opening a second SSE stream.
502
+ const cm = await this.getContractManager();
503
+ // Serialize annotation+notification: parallel `annotateVtxos`
504
+ // awaits could resolve out of order and deliver eventCallback
505
+ // calls in the wrong sequence (e.g. `vtxo_spent` before its
506
+ // matching `vtxo_received`).
507
+ let annotationQueue = Promise.resolve();
508
+ indexerStopFunc = cm.onContractEvent((event) => {
509
+ if (event.type !== "vtxo_received" &&
510
+ event.type !== "vtxo_spent") {
511
+ return;
517
512
  }
518
- catch (error) {
519
- console.error("Subscription error:", error);
513
+ if (event.contract.type !== "default" &&
514
+ event.contract.type !== "delegate") {
515
+ return;
520
516
  }
521
- })();
517
+ // `event.vtxos` carries placeholder tapscript fields from
518
+ // the watcher; `annotateVtxos` fills them in.
519
+ annotationQueue = annotationQueue.then(async () => {
520
+ try {
521
+ const annotated = await cm.annotateVtxos(event.vtxos);
522
+ eventCallback({
523
+ type: "vtxo",
524
+ newVtxos: event.type === "vtxo_received" ? annotated : [],
525
+ spentVtxos: event.type === "vtxo_spent" ? annotated : [],
526
+ });
527
+ }
528
+ catch (error) {
529
+ console.warn("Dropping subscription update after annotation failed; next sync will reconcile:", error);
530
+ }
531
+ });
532
+ });
522
533
  }
523
534
  const stopFunc = () => {
524
535
  onchainStopFunc?.();
@@ -545,27 +556,13 @@ class ReadonlyWallet {
545
556
  /**
546
557
  * Get all pkScript hex strings for the wallet's own addresses
547
558
  * (both delegate and non-delegate, current and historical).
548
- * Falls back to only the current script if ContractManager is not yet initialized.
549
559
  */
550
560
  async getWalletScripts() {
551
- // Only use the contract manager if it's already initialized or
552
- // currently initializing never trigger initialization here to
553
- // avoid blocking callers that don't need it.
554
- if (this._contractManager || this._contractManagerInitializing) {
555
- try {
556
- const manager = await this.getContractManager();
557
- const contracts = await manager.getContracts({
558
- type: ["default", "delegate"],
559
- });
560
- if (contracts.length > 0) {
561
- return contracts.map((c) => c.script);
562
- }
563
- }
564
- catch {
565
- // fall through to current script only
566
- }
567
- }
568
- return [base_1.hex.encode(this.offchainTapscript.pkScript)];
561
+ const manager = await this.getContractManager();
562
+ const contracts = await manager.getContracts({
563
+ type: ["default", "delegate"],
564
+ });
565
+ return contracts.map((c) => c.script);
569
566
  }
570
567
  /**
571
568
  * Build a map of scriptHex → VtxoScript for all wallet contracts,
@@ -573,26 +570,17 @@ class ReadonlyWallet {
573
570
  */
574
571
  async getScriptMap() {
575
572
  const map = new Map();
576
- // Always include the current script
577
- const currentScriptHex = base_1.hex.encode(this.offchainTapscript.pkScript);
578
- map.set(currentScriptHex, this.offchainTapscript);
579
- if (this._contractManager) {
580
- try {
581
- const contracts = await this._contractManager.getContracts({
582
- type: ["default", "delegate"],
583
- });
584
- for (const contract of contracts) {
585
- if (map.has(contract.script))
586
- continue;
587
- const handler = handlers_1.contractHandlers.get(contract.type);
588
- if (handler) {
589
- const script = handler.createScript(contract.params);
590
- map.set(contract.script, script);
591
- }
592
- }
593
- }
594
- catch {
595
- // ContractManager error — only current script in map
573
+ const manager = await this.getContractManager();
574
+ const contracts = await manager.getContracts({
575
+ type: ["default", "delegate"],
576
+ });
577
+ for (const contract of contracts) {
578
+ if (map.has(contract.script))
579
+ continue;
580
+ const handler = handlers_1.contractHandlers.get(contract.type);
581
+ if (handler) {
582
+ const script = handler.createScript(contract.params);
583
+ map.set(contract.script, script);
596
584
  }
597
585
  }
598
586
  return map;
@@ -660,62 +648,48 @@ class ReadonlyWallet {
660
648
  walletRepository: this.walletRepository,
661
649
  watcherConfig: this.watcherConfig,
662
650
  });
663
- // Register the wallet's current address as a contract
664
- const csvTimelock = this.offchainTapscript.options.csvTimelock ??
665
- default_1.DefaultVtxo.Script.DEFAULT_TIMELOCK;
666
- const csvTimelockStr = (0, helpers_1.timelockToSequence)(csvTimelock).toString();
667
- const isDelegateScript = this.offchainTapscript instanceof delegate_1.DelegateVtxo.Script;
668
- if (isDelegateScript) {
669
- const delegateScript = this
670
- .offchainTapscript;
671
- // Register the delegate contract (current address)
672
- await manager.createContract({
673
- type: "delegate",
674
- params: {
675
- pubKey: base_1.hex.encode(delegateScript.options.pubKey),
676
- serverPubKey: base_1.hex.encode(delegateScript.options.serverPubKey),
677
- delegatePubKey: base_1.hex.encode(delegateScript.options.delegatePubKey),
678
- csvTimelock: csvTimelockStr,
679
- },
680
- script: this.defaultContractScript,
681
- address: await this.getAddress(),
682
- state: "active",
683
- });
684
- // Also register the non-delegate version so old virtual outputs remain visible
685
- const nonDelegateScript = new default_1.DefaultVtxo.Script({
686
- pubKey: delegateScript.options.pubKey,
687
- serverPubKey: delegateScript.options.serverPubKey,
651
+ for (const csvTimelock of this.walletContractTimelocks) {
652
+ const csvTimelockStr = (0, helpers_1.timelockToSequence)(csvTimelock).toString();
653
+ const defaultScript = new default_1.DefaultVtxo.Script({
654
+ pubKey: this.offchainTapscript.options.pubKey,
655
+ serverPubKey: this.offchainTapscript.options.serverPubKey,
688
656
  csvTimelock,
689
657
  });
690
658
  await manager.createContract({
691
659
  type: "default",
692
660
  params: {
693
- pubKey: base_1.hex.encode(delegateScript.options.pubKey),
694
- serverPubKey: base_1.hex.encode(delegateScript.options.serverPubKey),
661
+ pubKey: base_1.hex.encode(defaultScript.options.pubKey),
662
+ serverPubKey: base_1.hex.encode(defaultScript.options.serverPubKey),
695
663
  csvTimelock: csvTimelockStr,
696
664
  },
697
- script: base_1.hex.encode(nonDelegateScript.pkScript),
698
- address: nonDelegateScript
665
+ script: base_1.hex.encode(defaultScript.pkScript),
666
+ address: defaultScript
699
667
  .address(this.network.hrp, this.arkServerPublicKey)
700
668
  .encode(),
701
669
  state: "active",
702
670
  });
703
- }
704
- else {
705
- // Register the default contract (current address)
706
- await manager.createContract({
707
- type: "default",
708
- params: {
709
- pubKey: base_1.hex.encode(this.offchainTapscript.options.pubKey),
710
- serverPubKey: base_1.hex.encode(this.offchainTapscript.options.serverPubKey),
711
- csvTimelock: csvTimelockStr,
712
- },
713
- script: this.defaultContractScript,
714
- address: await this.getAddress(),
715
- state: "active",
716
- });
717
- // Any old "delegate" contract from a prior wallet incarnation
718
- // is already loaded by ContractManager.initialize() from ContractRepository
671
+ if (this.offchainTapscript instanceof delegate_1.DelegateVtxo.Script) {
672
+ const delegateScript = new delegate_1.DelegateVtxo.Script({
673
+ pubKey: this.offchainTapscript.options.pubKey,
674
+ serverPubKey: this.offchainTapscript.options.serverPubKey,
675
+ delegatePubKey: this.offchainTapscript.options.delegatePubKey,
676
+ csvTimelock,
677
+ });
678
+ await manager.createContract({
679
+ type: "delegate",
680
+ params: {
681
+ pubKey: base_1.hex.encode(delegateScript.options.pubKey),
682
+ serverPubKey: base_1.hex.encode(delegateScript.options.serverPubKey),
683
+ delegatePubKey: base_1.hex.encode(delegateScript.options.delegatePubKey),
684
+ csvTimelock: csvTimelockStr,
685
+ },
686
+ script: base_1.hex.encode(delegateScript.pkScript),
687
+ address: delegateScript
688
+ .address(this.network.hrp, this.arkServerPublicKey)
689
+ .encode(),
690
+ state: "active",
691
+ });
692
+ }
719
693
  }
720
694
  return manager;
721
695
  }
@@ -799,8 +773,8 @@ class Wallet extends ReadonlyWallet {
799
773
  }
800
774
  constructor(identity, network, onchainProvider, arkProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, dustAmount, walletRepository, contractRepository,
801
775
  /** @deprecated Use settlementConfig */
802
- renewalConfig, delegatorProvider, watcherConfig, settlementConfig) {
803
- super(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegatorProvider, watcherConfig);
776
+ renewalConfig, delegatorProvider, watcherConfig, settlementConfig, walletContractTimelocks) {
777
+ super(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegatorProvider, watcherConfig, walletContractTimelocks);
804
778
  this.arkProvider = arkProvider;
805
779
  this.serverUnrollScript = serverUnrollScript;
806
780
  this.forfeitOutputScript = forfeitOutputScript;
@@ -920,7 +894,7 @@ class Wallet extends ReadonlyWallet {
920
894
  const forfeitPubkey = base_1.hex.decode(setup.info.forfeitPubkey).slice(1);
921
895
  const forfeitAddress = (0, btc_signer_1.Address)(setup.network).decode(setup.info.forfeitAddress);
922
896
  const forfeitOutputScript = btc_signer_1.OutScript.encode(forfeitAddress);
923
- const wallet = new Wallet(config.identity, setup.network, setup.onchainProvider, setup.arkProvider, setup.indexerProvider, setup.serverPubKey, setup.offchainTapscript, setup.boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, setup.dustAmount, setup.walletRepository, setup.contractRepository, config.renewalConfig, config.delegatorProvider, config.watcherConfig, config.settlementConfig);
897
+ const wallet = new Wallet(config.identity, setup.network, setup.onchainProvider, setup.arkProvider, setup.indexerProvider, setup.serverPubKey, setup.offchainTapscript, setup.boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, setup.dustAmount, setup.walletRepository, setup.contractRepository, config.renewalConfig, config.delegatorProvider, config.watcherConfig, config.settlementConfig, setup.walletContractTimelocks);
924
898
  await wallet.getVtxoManager();
925
899
  return wallet;
926
900
  }
@@ -946,7 +920,7 @@ class Wallet extends ReadonlyWallet {
946
920
  const readonlyIdentity = hasToReadonly(this.identity)
947
921
  ? await this.identity.toReadonly()
948
922
  : this.identity; // Identity extends ReadonlyIdentity, so this is safe
949
- return new ReadonlyWallet(readonlyIdentity, this.network, this.onchainProvider, this.indexerProvider, this.arkServerPublicKey, this.offchainTapscript, this.boardingTapscript, this.dustAmount, this.walletRepository, this.contractRepository, this.delegatorProvider, this.watcherConfig);
923
+ return new ReadonlyWallet(readonlyIdentity, this.network, this.onchainProvider, this.indexerProvider, this.arkServerPublicKey, this.offchainTapscript, this.boardingTapscript, this.dustAmount, this.walletRepository, this.contractRepository, this.delegatorProvider, this.watcherConfig, this.walletContractTimelocks);
950
924
  }
951
925
  /** Returns the delegator manager when delegation support is configured. */
952
926
  async getDelegatorManager() {
@@ -1077,10 +1051,10 @@ class Wallet extends ReadonlyWallet {
1077
1051
  weight: 0,
1078
1052
  birth: vtxo.createdAt,
1079
1053
  expiry: vtxo.virtualStatus.batchExpiry
1080
- ? new Date(vtxo.virtualStatus.batchExpiry * 1000)
1081
- : new Date(),
1054
+ ? new Date(vtxo.virtualStatus.batchExpiry)
1055
+ : undefined,
1082
1056
  });
1083
- if (inputFee.value >= vtxo.value) {
1057
+ if (inputFee.satoshis >= vtxo.value) {
1084
1058
  // skip if fees are greater than the virtual output value
1085
1059
  continue;
1086
1060
  }