@arkade-os/sdk 0.4.25 → 0.4.27

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 (222) hide show
  1. package/README.md +5 -25
  2. package/dist/cjs/contracts/contractManager.js +31 -11
  3. package/dist/cjs/contracts/contractWatcher.js +2 -2
  4. package/dist/cjs/identity/hdCapableIdentity.js +18 -0
  5. package/dist/cjs/identity/index.js +3 -1
  6. package/dist/cjs/identity/seedIdentity.js +16 -0
  7. package/dist/cjs/index.js +4 -2
  8. package/dist/cjs/script/address.js +2 -2
  9. package/dist/cjs/wallet/delegator.js +10 -4
  10. package/dist/cjs/wallet/hdDescriptorProvider.js +29 -0
  11. package/dist/cjs/wallet/inputSignerRouter.js +98 -0
  12. package/dist/cjs/wallet/serviceWorker/wallet.js +1 -0
  13. package/dist/cjs/wallet/signingErrors.js +32 -0
  14. package/dist/cjs/wallet/unroll.js +5 -1
  15. package/dist/cjs/wallet/wallet.js +232 -86
  16. package/dist/cjs/wallet/walletReceiveRotator.js +547 -0
  17. package/dist/cjs/worker/messageBus.js +1 -0
  18. package/dist/esm/adapters/asyncStorage.js +1 -1
  19. package/dist/esm/adapters/expo.js +2 -2
  20. package/dist/esm/adapters/fileSystem.js +1 -1
  21. package/dist/esm/adapters/indexedDB.js +1 -1
  22. package/dist/esm/adapters/localStorage.js +1 -1
  23. package/dist/esm/arkfee/index.js +1 -1
  24. package/dist/esm/arknote/index.js +1 -1
  25. package/dist/esm/bip322/index.js +2 -2
  26. package/dist/esm/contracts/arkcontract.js +2 -2
  27. package/dist/esm/contracts/contractManager.js +36 -16
  28. package/dist/esm/contracts/contractWatcher.js +5 -5
  29. package/dist/esm/contracts/handlers/default.js +4 -4
  30. package/dist/esm/contracts/handlers/delegate.js +4 -4
  31. package/dist/esm/contracts/handlers/helpers.js +2 -2
  32. package/dist/esm/contracts/handlers/index.js +8 -8
  33. package/dist/esm/contracts/handlers/vhtlc.js +3 -3
  34. package/dist/esm/contracts/index.js +8 -8
  35. package/dist/esm/extension/asset/assetGroup.js +7 -7
  36. package/dist/esm/extension/asset/assetId.js +2 -2
  37. package/dist/esm/extension/asset/assetInput.js +2 -2
  38. package/dist/esm/extension/asset/assetOutput.js +1 -1
  39. package/dist/esm/extension/asset/assetRef.js +3 -3
  40. package/dist/esm/extension/asset/index.js +8 -8
  41. package/dist/esm/extension/asset/metadata.js +1 -1
  42. package/dist/esm/extension/asset/packet.js +3 -3
  43. package/dist/esm/extension/index.js +4 -4
  44. package/dist/esm/forfeit.js +2 -2
  45. package/dist/esm/identity/hdCapableIdentity.js +17 -1
  46. package/dist/esm/identity/index.js +6 -5
  47. package/dist/esm/identity/seedIdentity.js +18 -2
  48. package/dist/esm/identity/serialize.js +2 -2
  49. package/dist/esm/identity/singleKey.js +1 -1
  50. package/dist/esm/identity/staticDescriptorProvider.js +2 -2
  51. package/dist/esm/index.js +48 -48
  52. package/dist/esm/intent/index.js +3 -3
  53. package/dist/esm/musig2/index.js +3 -3
  54. package/dist/esm/musig2/sign.js +1 -1
  55. package/dist/esm/providers/ark.js +3 -3
  56. package/dist/esm/providers/delegator.js +1 -1
  57. package/dist/esm/providers/electrum.js +2 -2
  58. package/dist/esm/providers/expoArk.js +2 -2
  59. package/dist/esm/providers/expoIndexer.js +3 -3
  60. package/dist/esm/providers/indexer.js +3 -3
  61. package/dist/esm/repositories/inMemory/walletRepository.js +1 -1
  62. package/dist/esm/repositories/index.js +9 -9
  63. package/dist/esm/repositories/indexedDB/contractRepository.js +4 -4
  64. package/dist/esm/repositories/indexedDB/db.js +2 -2
  65. package/dist/esm/repositories/indexedDB/schema.js +1 -1
  66. package/dist/esm/repositories/indexedDB/walletRepository.js +6 -6
  67. package/dist/esm/repositories/migrations/fromStorageAdapter.js +1 -1
  68. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +1 -1
  69. package/dist/esm/repositories/realm/index.js +3 -3
  70. package/dist/esm/repositories/realm/schemas.js +1 -1
  71. package/dist/esm/repositories/realm/walletRepository.js +3 -3
  72. package/dist/esm/repositories/scriptFromAddress.js +1 -1
  73. package/dist/esm/repositories/sqlite/index.js +2 -2
  74. package/dist/esm/repositories/sqlite/walletRepository.js +3 -3
  75. package/dist/esm/script/address.js +3 -3
  76. package/dist/esm/script/base.js +3 -3
  77. package/dist/esm/script/default.js +2 -2
  78. package/dist/esm/script/delegate.js +3 -3
  79. package/dist/esm/script/tapscript.js +1 -1
  80. package/dist/esm/script/vhtlc.js +2 -2
  81. package/dist/esm/storage/indexedDB.js +1 -1
  82. package/dist/esm/tree/signingSession.js +2 -2
  83. package/dist/esm/tree/validation.js +2 -2
  84. package/dist/esm/utils/arkTransaction.js +7 -7
  85. package/dist/esm/utils/transactionHistory.js +1 -1
  86. package/dist/esm/utils/unknownFields.js +1 -1
  87. package/dist/esm/wallet/asset-manager.js +5 -5
  88. package/dist/esm/wallet/asset.js +1 -1
  89. package/dist/esm/wallet/batch.js +2 -2
  90. package/dist/esm/wallet/delegator.js +16 -10
  91. package/dist/esm/wallet/expo/background.js +5 -5
  92. package/dist/esm/wallet/expo/index.js +2 -2
  93. package/dist/esm/wallet/expo/wallet.js +8 -8
  94. package/dist/esm/wallet/hdDescriptorProvider.js +31 -2
  95. package/dist/esm/wallet/inputSignerRouter.js +94 -0
  96. package/dist/esm/wallet/onchain.js +7 -7
  97. package/dist/esm/wallet/ramps.js +3 -3
  98. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +6 -6
  99. package/dist/esm/wallet/serviceWorker/wallet.js +8 -7
  100. package/dist/esm/wallet/signingErrors.js +27 -0
  101. package/dist/esm/wallet/unroll.js +12 -8
  102. package/dist/esm/wallet/utils.js +2 -2
  103. package/dist/esm/wallet/validation.js +2 -2
  104. package/dist/esm/wallet/vtxo-manager.js +9 -9
  105. package/dist/esm/wallet/wallet.js +262 -117
  106. package/dist/esm/wallet/walletReceiveRotator.js +540 -0
  107. package/dist/esm/worker/expo/index.js +4 -4
  108. package/dist/esm/worker/expo/processors/contractPollProcessor.js +1 -1
  109. package/dist/esm/worker/expo/processors/index.js +1 -1
  110. package/dist/esm/worker/expo/taskRunner.js +1 -1
  111. package/dist/esm/worker/messageBus.js +7 -6
  112. package/dist/types/adapters/asyncStorage.d.ts +2 -2
  113. package/dist/types/adapters/expo.d.ts +4 -4
  114. package/dist/types/adapters/fileSystem.d.ts +2 -2
  115. package/dist/types/adapters/indexedDB.d.ts +2 -2
  116. package/dist/types/adapters/localStorage.d.ts +2 -2
  117. package/dist/types/arkfee/index.d.ts +2 -2
  118. package/dist/types/arknote/index.d.ts +2 -2
  119. package/dist/types/bip322/index.d.ts +1 -1
  120. package/dist/types/contracts/arkcontract.d.ts +1 -1
  121. package/dist/types/contracts/contractManager.d.ts +39 -9
  122. package/dist/types/contracts/contractWatcher.d.ts +3 -3
  123. package/dist/types/contracts/handlers/default.d.ts +3 -3
  124. package/dist/types/contracts/handlers/delegate.d.ts +3 -3
  125. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  126. package/dist/types/contracts/handlers/index.d.ts +7 -7
  127. package/dist/types/contracts/handlers/registry.d.ts +1 -1
  128. package/dist/types/contracts/handlers/vhtlc.d.ts +3 -3
  129. package/dist/types/contracts/index.d.ts +14 -14
  130. package/dist/types/contracts/types.d.ts +21 -4
  131. package/dist/types/contracts/vtxoOwnership.d.ts +3 -3
  132. package/dist/types/extension/asset/assetGroup.d.ts +6 -6
  133. package/dist/types/extension/asset/assetId.d.ts +1 -1
  134. package/dist/types/extension/asset/assetInput.d.ts +2 -2
  135. package/dist/types/extension/asset/assetOutput.d.ts +1 -1
  136. package/dist/types/extension/asset/assetRef.d.ts +3 -3
  137. package/dist/types/extension/asset/index.d.ts +8 -8
  138. package/dist/types/extension/asset/metadata.d.ts +1 -1
  139. package/dist/types/extension/asset/packet.d.ts +2 -2
  140. package/dist/types/extension/index.d.ts +6 -6
  141. package/dist/types/forfeit.d.ts +1 -1
  142. package/dist/types/identity/descriptorProvider.d.ts +8 -1
  143. package/dist/types/identity/hdCapableIdentity.d.ts +33 -6
  144. package/dist/types/identity/index.d.ts +12 -11
  145. package/dist/types/identity/seedIdentity.d.ts +21 -5
  146. package/dist/types/identity/serialize.d.ts +1 -1
  147. package/dist/types/identity/singleKey.d.ts +3 -3
  148. package/dist/types/identity/staticDescriptorProvider.d.ts +3 -3
  149. package/dist/types/index.d.ts +59 -59
  150. package/dist/types/intent/index.d.ts +2 -2
  151. package/dist/types/musig2/index.d.ts +4 -4
  152. package/dist/types/providers/ark.d.ts +5 -5
  153. package/dist/types/providers/delegator.d.ts +2 -2
  154. package/dist/types/providers/electrum.d.ts +5 -5
  155. package/dist/types/providers/expoArk.d.ts +1 -1
  156. package/dist/types/providers/expoIndexer.d.ts +1 -1
  157. package/dist/types/providers/indexer.d.ts +1 -1
  158. package/dist/types/providers/onchain.d.ts +2 -2
  159. package/dist/types/repositories/contractRepository.d.ts +1 -1
  160. package/dist/types/repositories/inMemory/contractRepository.d.ts +2 -2
  161. package/dist/types/repositories/inMemory/walletRepository.d.ts +2 -2
  162. package/dist/types/repositories/index.d.ts +9 -9
  163. package/dist/types/repositories/indexedDB/contractRepository.d.ts +2 -2
  164. package/dist/types/repositories/indexedDB/db.d.ts +3 -3
  165. package/dist/types/repositories/indexedDB/walletRepository.d.ts +2 -2
  166. package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +3 -3
  167. package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +2 -2
  168. package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +3 -3
  169. package/dist/types/repositories/realm/contractRepository.d.ts +3 -3
  170. package/dist/types/repositories/realm/index.d.ts +4 -4
  171. package/dist/types/repositories/realm/walletRepository.d.ts +3 -3
  172. package/dist/types/repositories/serialization.d.ts +11 -11
  173. package/dist/types/repositories/sqlite/contractRepository.d.ts +3 -3
  174. package/dist/types/repositories/sqlite/index.d.ts +3 -3
  175. package/dist/types/repositories/sqlite/walletRepository.d.ts +3 -3
  176. package/dist/types/repositories/walletRepository.d.ts +1 -1
  177. package/dist/types/script/address.d.ts +2 -2
  178. package/dist/types/script/base.d.ts +2 -2
  179. package/dist/types/script/default.d.ts +2 -2
  180. package/dist/types/script/delegate.d.ts +3 -3
  181. package/dist/types/script/vhtlc.d.ts +2 -2
  182. package/dist/types/storage/asyncStorage.d.ts +1 -1
  183. package/dist/types/storage/fileSystem.d.ts +1 -1
  184. package/dist/types/storage/inMemory.d.ts +1 -1
  185. package/dist/types/storage/indexedDB.d.ts +1 -1
  186. package/dist/types/storage/localStorage.d.ts +1 -1
  187. package/dist/types/tree/signingSession.d.ts +2 -2
  188. package/dist/types/tree/validation.d.ts +1 -1
  189. package/dist/types/utils/arkTransaction.d.ts +5 -5
  190. package/dist/types/utils/syncCursors.d.ts +1 -1
  191. package/dist/types/utils/timelock.d.ts +1 -1
  192. package/dist/types/utils/transaction.d.ts +2 -2
  193. package/dist/types/utils/transactionHistory.d.ts +1 -1
  194. package/dist/types/utils/txSizeEstimator.d.ts +1 -1
  195. package/dist/types/wallet/asset-manager.d.ts +3 -3
  196. package/dist/types/wallet/asset.d.ts +2 -2
  197. package/dist/types/wallet/batch.d.ts +2 -2
  198. package/dist/types/wallet/delegator.d.ts +5 -5
  199. package/dist/types/wallet/expo/background.d.ts +4 -4
  200. package/dist/types/wallet/expo/index.d.ts +4 -4
  201. package/dist/types/wallet/expo/wallet.d.ts +8 -8
  202. package/dist/types/wallet/hdDescriptorProvider.d.ts +26 -5
  203. package/dist/types/wallet/index.d.ts +63 -26
  204. package/dist/types/wallet/inputSignerRouter.d.ts +35 -0
  205. package/dist/types/wallet/onchain.d.ts +6 -6
  206. package/dist/types/wallet/ramps.d.ts +2 -2
  207. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +7 -7
  208. package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -10
  209. package/dist/types/wallet/signingErrors.d.ts +19 -0
  210. package/dist/types/wallet/unroll.d.ts +6 -6
  211. package/dist/types/wallet/utils.d.ts +5 -5
  212. package/dist/types/wallet/validation.d.ts +3 -3
  213. package/dist/types/wallet/vtxo-manager.d.ts +2 -2
  214. package/dist/types/wallet/wallet.d.ts +71 -22
  215. package/dist/types/wallet/walletReceiveRotator.d.ts +306 -0
  216. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
  217. package/dist/types/worker/expo/index.d.ts +7 -7
  218. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
  219. package/dist/types/worker/expo/processors/index.d.ts +1 -1
  220. package/dist/types/worker/expo/taskRunner.d.ts +7 -7
  221. package/dist/types/worker/messageBus.d.ts +7 -6
  222. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Wallet = exports.ReadonlyWallet = exports.getArkadeServerUrl = void 0;
3
+ exports.Wallet = exports.ReadonlyWallet = exports.MissingSigningDescriptorError = exports.DescriptorSigningProviderMissingError = exports.getArkadeServerUrl = void 0;
4
4
  exports.selectVirtualCoins = selectVirtualCoins;
5
5
  exports.waitForIncomingFunds = waitForIncomingFunds;
6
6
  const base_1 = require("@scure/base");
@@ -15,7 +15,6 @@ const ark_1 = require("../providers/ark");
15
15
  const forfeit_1 = require("../forfeit");
16
16
  const validation_1 = require("../tree/validation");
17
17
  const validation_2 = require("./validation");
18
- const identity_1 = require("../identity");
19
18
  const _1 = require(".");
20
19
  const asset_1 = require("./asset");
21
20
  const base_2 = require("../script/base");
@@ -40,8 +39,35 @@ const handlers_1 = require("../contracts/handlers");
40
39
  const timelock_1 = require("../utils/timelock");
41
40
  const syncCursors_1 = require("../utils/syncCursors");
42
41
  const vtxoOwnership_1 = require("../contracts/vtxoOwnership");
42
+ const walletReceiveRotator_1 = require("./walletReceiveRotator");
43
+ const inputSignerRouter_1 = require("./inputSignerRouter");
44
+ const signingErrors_1 = require("./signingErrors");
45
+ Object.defineProperty(exports, "DescriptorSigningProviderMissingError", { enumerable: true, get: function () { return signingErrors_1.DescriptorSigningProviderMissingError; } });
46
+ Object.defineProperty(exports, "MissingSigningDescriptorError", { enumerable: true, get: function () { return signingErrors_1.MissingSigningDescriptorError; } });
43
47
  const getArkadeServerUrl = ({ arkServerUrl, }) => arkServerUrl || _1.DEFAULT_ARKADE_SERVER_URL;
44
48
  exports.getArkadeServerUrl = getArkadeServerUrl;
49
+ // Build per-input jobs for an intent proof. Index 0 of the proof is a
50
+ // synthetic BIP-322 toSpend reference whose witnessUtxo.script mirrors
51
+ // coin[0]'s pkScript, so we map it to the same source contract as
52
+ // coin[0]; coins 0..N-1 then map to proof inputs 1..N.
53
+ function intentProofJobs(coins) {
54
+ if (coins.length === 0)
55
+ return [];
56
+ const coinJobs = coins.map((coin, i) => ({
57
+ index: i + 1,
58
+ lookupScript: base_2.VtxoScript.decode(coin.tapTree).pkScript,
59
+ }));
60
+ return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
61
+ }
62
+ // Built-in ArkProvider implementations (Rest/Expo) expose `serverUrl`,
63
+ // but the interface itself does not declare a URL accessor — so this is a
64
+ // structural read that returns undefined for custom implementations.
65
+ function extractArkProviderUrl(provider) {
66
+ const serverUrl = provider.serverUrl;
67
+ return typeof serverUrl === "string" && serverUrl.length > 0
68
+ ? serverUrl
69
+ : undefined;
70
+ }
45
71
  // Historical unilateral exit delay for mainnet (~7 days in seconds).
46
72
  // Kept so existing wallets can still discover and spend VTXOs sent to the
47
73
  // legacy address after arkd starts advertising a different delay.
@@ -83,7 +109,6 @@ class ReadonlyWallet {
83
109
  this.onchainProvider = onchainProvider;
84
110
  this.indexerProvider = indexerProvider;
85
111
  this.arkServerPublicKey = arkServerPublicKey;
86
- this.offchainTapscript = offchainTapscript;
87
112
  this.boardingTapscript = boardingTapscript;
88
113
  this.dustAmount = dustAmount;
89
114
  this.walletRepository = walletRepository;
@@ -108,6 +133,7 @@ class ReadonlyWallet {
108
133
  `Create identity with { isMainnet: ${serverIsMainnet} } to match.`);
109
134
  }
110
135
  }
136
+ this._offchainTapscript = offchainTapscript;
111
137
  this.watcherConfig = watcherConfig;
112
138
  this._assetManager = new asset_manager_1.ReadonlyAssetManager(this.indexerProvider);
113
139
  // Defensive for direct-construction callers; setupWalletConfig already
@@ -120,25 +146,45 @@ class ReadonlyWallet {
120
146
  default_1.DefaultVtxo.Script.DEFAULT_TIMELOCK,
121
147
  ];
122
148
  }
149
+ /**
150
+ * Currently-active receive tapscript. Read-only from the outside;
151
+ * mutated only via {@link Wallet.setOffchainTapscriptForRotation}
152
+ * by {@link WalletReceiveRotator.rotate}.
153
+ */
154
+ get offchainTapscript() {
155
+ return this._offchainTapscript;
156
+ }
123
157
  /**
124
158
  * Protected helper to set up shared wallet configuration.
125
159
  * Extracts common logic used by both ReadonlyWallet.create() and Wallet.create().
126
160
  */
127
161
  static async setupWalletConfig(config, pubKey) {
162
+ const arkadeServerUrl = (0, exports.getArkadeServerUrl)(config);
128
163
  // Use provided arkProvider instance or create a new one from arkServerUrl
129
- const arkProvider = config.arkProvider ||
130
- (() => {
131
- return new ark_1.RestArkProvider((0, exports.getArkadeServerUrl)(config));
132
- })();
133
- // Extract arkServerUrl from provider if not explicitly provided
134
- const arkServerUrl = config.arkServerUrl || arkProvider.serverUrl;
135
- if (!arkServerUrl) {
136
- throw new Error("Could not determine arkServerUrl from provider");
137
- }
138
- // Use provided indexerProvider instance or create a new one
139
- // indexerUrl defaults to arkServerUrl if not provided
140
- const indexerUrl = config.indexerUrl || arkServerUrl;
141
- const indexerProvider = config.indexerProvider || new indexer_1.RestIndexerProvider(indexerUrl);
164
+ const arkProvider = config.arkProvider ?? new ark_1.RestArkProvider(arkadeServerUrl);
165
+ // Resolve the indexer provider. If a full instance is supplied, use it
166
+ // directly. Otherwise pick a URL with priority:
167
+ // 1. explicit config.indexerUrl
168
+ // 2. URL derived from the injected arkProvider (so a custom
169
+ // arkProvider does not silently pair with the public default)
170
+ // 3. arkadeServerUrl (only when no custom arkProvider was injected)
171
+ let indexerProvider = config.indexerProvider;
172
+ if (!indexerProvider) {
173
+ let indexerUrl = config.indexerUrl;
174
+ if (!indexerUrl) {
175
+ if (config.arkProvider) {
176
+ const derived = extractArkProviderUrl(config.arkProvider);
177
+ if (!derived) {
178
+ throw new Error("indexerUrl is required when arkProvider is provided without a discoverable serverUrl");
179
+ }
180
+ indexerUrl = derived;
181
+ }
182
+ else {
183
+ indexerUrl = arkadeServerUrl;
184
+ }
185
+ }
186
+ indexerProvider = new indexer_1.RestIndexerProvider(indexerUrl);
187
+ }
142
188
  const info = await arkProvider.getInfo();
143
189
  const network = (0, networks_1.getNetwork)(info.network);
144
190
  // Guard: detect identity/server network mismatch for seed-based identities.
@@ -648,13 +694,28 @@ class ReadonlyWallet {
648
694
  walletRepository: this.walletRepository,
649
695
  watcherConfig: this.watcherConfig,
650
696
  });
697
+ // Register the wallet's baseline always-active contracts: every
698
+ // `walletContractTimelocks` entry × {default, delegate-if-enabled}.
699
+ // This matrix is bound to INDEX 0 — the identity's x-only pubkey
700
+ // — by design: it's the permanent fallback set the wallet wants
701
+ // active forever, independent of any HD rotation. Rotated
702
+ // display contracts (registered separately by
703
+ // {@link WalletReceiveRotator.rotate}) are intentionally
704
+ // single-timelock-single-pubkey at the CURRENT arkd delay, and
705
+ // get the `metadata.source = WALLET_RECEIVE_SOURCE` tag so the
706
+ // next boot can find them. We deliberately do NOT re-register
707
+ // the matrix at a rotated pubkey: doing so would dilute the
708
+ // "index-0 baseline" guarantee and turn every rotation into a
709
+ // multi-timelock matrix expansion on every boot.
710
+ const baselinePubkey = await this.identity.xOnlyPublicKey();
651
711
  for (const csvTimelock of this.walletContractTimelocks) {
652
712
  const csvTimelockStr = (0, timelock_1.timelockToSequence)(csvTimelock).toString();
653
713
  const defaultScript = new default_1.DefaultVtxo.Script({
654
- pubKey: this.offchainTapscript.options.pubKey,
714
+ pubKey: baselinePubkey,
655
715
  serverPubKey: this.offchainTapscript.options.serverPubKey,
656
716
  csvTimelock,
657
717
  });
718
+ const defaultScriptHex = base_1.hex.encode(defaultScript.pkScript);
658
719
  await manager.createContract({
659
720
  type: "default",
660
721
  params: {
@@ -662,7 +723,7 @@ class ReadonlyWallet {
662
723
  serverPubKey: base_1.hex.encode(defaultScript.options.serverPubKey),
663
724
  csvTimelock: csvTimelockStr,
664
725
  },
665
- script: base_1.hex.encode(defaultScript.pkScript),
726
+ script: defaultScriptHex,
666
727
  address: defaultScript
667
728
  .address(this.network.hrp, this.arkServerPublicKey)
668
729
  .encode(),
@@ -670,11 +731,12 @@ class ReadonlyWallet {
670
731
  });
671
732
  if (this.offchainTapscript instanceof delegate_1.DelegateVtxo.Script) {
672
733
  const delegateScript = new delegate_1.DelegateVtxo.Script({
673
- pubKey: this.offchainTapscript.options.pubKey,
734
+ pubKey: baselinePubkey,
674
735
  serverPubKey: this.offchainTapscript.options.serverPubKey,
675
736
  delegatePubKey: this.offchainTapscript.options.delegatePubKey,
676
737
  csvTimelock,
677
738
  });
739
+ const delegateScriptHex = base_1.hex.encode(delegateScript.pkScript);
678
740
  await manager.createContract({
679
741
  type: "delegate",
680
742
  params: {
@@ -683,7 +745,7 @@ class ReadonlyWallet {
683
745
  delegatePubKey: base_1.hex.encode(delegateScript.options.delegatePubKey),
684
746
  csvTimelock: csvTimelockStr,
685
747
  },
686
- script: base_1.hex.encode(delegateScript.pkScript),
748
+ script: delegateScriptHex,
687
749
  address: delegateScript
688
750
  .address(this.network.hrp, this.arkServerPublicKey)
689
751
  .encode(),
@@ -743,6 +805,15 @@ exports.ReadonlyWallet = ReadonlyWallet;
743
805
  * ```
744
806
  */
745
807
  class Wallet extends ReadonlyWallet {
808
+ /**
809
+ * @internal Sole write path for `offchainTapscript` after construction.
810
+ * Called by {@link WalletReceiveRotator.rotate} once the rotated
811
+ * display contract has been persisted. External code must treat
812
+ * `offchainTapscript` as read-only.
813
+ */
814
+ setOffchainTapscriptForRotation(tapscript) {
815
+ this._offchainTapscript = tapscript;
816
+ }
746
817
  _addPendingSpends(inputs) {
747
818
  for (const input of inputs) {
748
819
  if ("virtualStatus" in input) {
@@ -773,12 +844,13 @@ class Wallet extends ReadonlyWallet {
773
844
  }
774
845
  constructor(identity, network, onchainProvider, arkProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, dustAmount, walletRepository, contractRepository,
775
846
  /** @deprecated Use settlementConfig */
776
- renewalConfig, delegatorProvider, watcherConfig, settlementConfig, walletContractTimelocks) {
847
+ renewalConfig, delegatorProvider, watcherConfig, settlementConfig, walletContractTimelocks, receiveRotator, descriptorProvider) {
777
848
  super(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegatorProvider, watcherConfig, walletContractTimelocks);
778
849
  this.arkProvider = arkProvider;
779
850
  this.serverUnrollScript = serverUnrollScript;
780
851
  this.forfeitOutputScript = forfeitOutputScript;
781
852
  this.forfeitPubkey = forfeitPubkey;
853
+ this._receiveRotatorInstalled = false;
782
854
  /**
783
855
  * Async mutex that serializes all operations submitting VTXOs to the Arkade
784
856
  * server (`settle`, `send`, `sendBitcoin`). This prevents VtxoManager's
@@ -815,6 +887,14 @@ class Wallet extends ReadonlyWallet {
815
887
  this._delegatorManager = delegatorProvider
816
888
  ? new delegator_1.DelegatorManagerImpl(delegatorProvider, arkProvider, identity)
817
889
  : undefined;
890
+ this._receiveRotator = receiveRotator;
891
+ this._descriptorProvider = descriptorProvider;
892
+ this._signerRouter = new inputSignerRouter_1.InputSignerRouter({
893
+ identity,
894
+ contractRepository,
895
+ descriptorProvider,
896
+ boardingPkScript: boardingTapscript.pkScript,
897
+ });
818
898
  }
819
899
  get assetManager() {
820
900
  this._walletAssetManager ?? (this._walletAssetManager = new asset_manager_1.AssetManager(this));
@@ -830,18 +910,48 @@ class Wallet extends ReadonlyWallet {
830
910
  this._vtxoManagerInitializing = Promise.resolve(new vtxo_manager_1.VtxoManager(this, this.renewalConfig, this.settlementConfig));
831
911
  try {
832
912
  const manager = await this._vtxoManagerInitializing;
913
+ // First-time hookup of the HD rotator: subscribe to
914
+ // `vtxo_received` AFTER the contract manager (which is
915
+ // initialised inside the VtxoManager construction path) has
916
+ // registered the wallet's baseline contracts. The flag
917
+ // makes this idempotent across repeated `getVtxoManager`
918
+ // calls — install runs at most once per wallet instance.
919
+ // Cache the manager and flip the install flag only after
920
+ // `install()` resolves; otherwise a failing install would
921
+ // leave the manager cached and silently disable HD
922
+ // rotation for the lifetime of this wallet.
923
+ if (this._receiveRotator && !this._receiveRotatorInstalled) {
924
+ try {
925
+ await this._receiveRotator.install(this);
926
+ }
927
+ catch (installErr) {
928
+ await manager.dispose();
929
+ throw installErr;
930
+ }
931
+ this._receiveRotatorInstalled = true;
932
+ }
833
933
  this._vtxoManager = manager;
834
934
  return manager;
835
935
  }
836
- catch (error) {
837
- this._vtxoManagerInitializing = undefined;
838
- throw error;
839
- }
840
936
  finally {
841
937
  this._vtxoManagerInitializing = undefined;
842
938
  }
843
939
  }
844
940
  async dispose() {
941
+ // Tear down the rotation subscription + drain in-flight rotations
942
+ // first so no late `vtxo_received` event can queue work on a
943
+ // disposing wallet, and so any in-flight `createContract` call
944
+ // finishes before we dispose the contract manager underneath it.
945
+ // A rotator-disposal failure must not abort the rest of
946
+ // teardown — the contract manager / super still need to run on
947
+ // best-effort, so we capture and rethrow at the end.
948
+ let rotatorError;
949
+ try {
950
+ await this._receiveRotator?.dispose();
951
+ }
952
+ catch (error) {
953
+ rotatorError = error;
954
+ }
845
955
  const manager = this._vtxoManager ??
846
956
  (this._vtxoManagerInitializing
847
957
  ? await this._vtxoManagerInitializing.catch(() => undefined)
@@ -859,6 +969,9 @@ class Wallet extends ReadonlyWallet {
859
969
  this._vtxoManagerInitializing = undefined;
860
970
  await super.dispose();
861
971
  }
972
+ if (rotatorError) {
973
+ throw rotatorError;
974
+ }
862
975
  }
863
976
  /**
864
977
  * Create a full wallet and initialize its background managers.
@@ -894,7 +1007,14 @@ class Wallet extends ReadonlyWallet {
894
1007
  const forfeitPubkey = base_1.hex.decode(setup.info.forfeitPubkey).slice(1);
895
1008
  const forfeitAddress = (0, btc_signer_1.Address)(setup.network).decode(setup.info.forfeitAddress);
896
1009
  const forfeitOutputScript = btc_signer_1.OutScript.encode(forfeitAddress);
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);
1010
+ // HD wiring (boot path) resolved via the descriptor provider.
1011
+ // The rotator (when present) is handed to the constructor as
1012
+ // the last positional arg and `getVtxoManager()` lazily
1013
+ // installs its `vtxo_received` subscription on first call,
1014
+ // after the contract manager has registered the wallet's
1015
+ // baseline contracts.
1016
+ const boot = await walletReceiveRotator_1.WalletReceiveRotator.resolveBoot(config, setup);
1017
+ const wallet = new Wallet(config.identity, setup.network, setup.onchainProvider, setup.arkProvider, setup.indexerProvider, setup.serverPubKey, boot?.offchainTapscript ?? setup.offchainTapscript, setup.boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, setup.dustAmount, setup.walletRepository, setup.contractRepository, config.renewalConfig, config.delegatorProvider, config.watcherConfig, config.settlementConfig, setup.walletContractTimelocks, boot?.rotator, boot?.provider);
898
1018
  await wallet.getVtxoManager();
899
1019
  return wallet;
900
1020
  }
@@ -941,6 +1061,14 @@ class Wallet extends ReadonlyWallet {
941
1061
  }
942
1062
  if (params.selectedVtxos && params.selectedVtxos.length > 0) {
943
1063
  return this._withTxLock(async () => {
1064
+ // Snapshot the active receive tapscript synchronously
1065
+ // before any `await` so the change output's pkScript and
1066
+ // the change-VTXO metadata written later by
1067
+ // `updateDbAfterOffchainTx` are bound to the same
1068
+ // tapscript even if `WalletReceiveRotator.rotate` fires
1069
+ // during the offchain round-trip.
1070
+ const offchainTapscript = this.offchainTapscript;
1071
+ const arkAddress = offchainTapscript.address(this.network.hrp, this.arkServerPublicKey);
944
1072
  const selectedVtxoSum = params
945
1073
  .selectedVtxos.map((v) => v.value)
946
1074
  .reduce((a, b) => a + b, 0);
@@ -965,8 +1093,8 @@ class Wallet extends ReadonlyWallet {
965
1093
  // add change output if needed
966
1094
  if (selected.changeAmount > 0n) {
967
1095
  const changeOutputScript = selected.changeAmount < this.dustAmount
968
- ? this.arkAddress.subdustPkScript
969
- : this.arkAddress.pkScript;
1096
+ ? arkAddress.subdustPkScript
1097
+ : arkAddress.pkScript;
970
1098
  outputs.push({
971
1099
  script: changeOutputScript,
972
1100
  amount: BigInt(selected.changeAmount),
@@ -975,7 +1103,7 @@ class Wallet extends ReadonlyWallet {
975
1103
  this._addPendingSpends(selected.inputs);
976
1104
  try {
977
1105
  const { arkTxid, signedCheckpointTxs } = await this.buildAndSubmitOffchainTx(selected.inputs, outputs);
978
- await this.updateDbAfterOffchainTx(selected.inputs, arkTxid, signedCheckpointTxs, params.amount, selected.changeAmount, selected.changeAmount > 0n ? outputs.length - 1 : 0);
1106
+ await this.updateDbAfterOffchainTx(selected.inputs, arkTxid, signedCheckpointTxs, params.amount, selected.changeAmount, selected.changeAmount > 0n ? outputs.length - 1 : 0, offchainTapscript);
979
1107
  return arkTxid;
980
1108
  }
981
1109
  finally {
@@ -1245,9 +1373,11 @@ class Wallet extends ReadonlyWallet {
1245
1373
  settlementPsbt.updateInput(i, {
1246
1374
  tapLeafScript: [input.forfeitTapLeafScript],
1247
1375
  });
1248
- settlementPsbt = await this.identity.sign(settlementPsbt, [
1249
- i,
1250
- ]);
1376
+ const script = settlementPsbt.getInput(i).witnessUtxo?.script;
1377
+ if (!script) {
1378
+ throw new Error("The server returned incomplete data. Settlement input is missing witnessUtxo.script");
1379
+ }
1380
+ settlementPsbt = await this._signerRouter.sign(settlementPsbt, [{ index: i, lookupScript: script }]);
1251
1381
  hasBoardingUtxos = true;
1252
1382
  break;
1253
1383
  }
@@ -1296,7 +1426,12 @@ class Wallet extends ReadonlyWallet {
1296
1426
  },
1297
1427
  ], forfeitOutputScript);
1298
1428
  // do not sign the connector input
1299
- forfeitTx = await this.identity.sign(forfeitTx, [0]);
1429
+ forfeitTx = await this._signerRouter.sign(forfeitTx, [
1430
+ {
1431
+ index: 0,
1432
+ lookupScript: base_2.VtxoScript.decode(input.tapTree).pkScript,
1433
+ },
1434
+ ]);
1300
1435
  signedForfeits.push(base_1.base64.encode(forfeitTx.toPSBT()));
1301
1436
  }
1302
1437
  if (signedForfeits.length > 0 || hasBoardingUtxos) {
@@ -1399,6 +1534,22 @@ class Wallet extends ReadonlyWallet {
1399
1534
  },
1400
1535
  };
1401
1536
  }
1537
+ /**
1538
+ * Build {@link InputSigningJob}s for a tx whose signable inputs can be
1539
+ * resolved from their own `witnessUtxo.script`. Inputs without a
1540
+ * `witnessUtxo` are silently omitted, mirroring the wallet's
1541
+ * historical silent-skip behaviour for cosigner/connector inputs.
1542
+ */
1543
+ inputSigningJobsFromWitnessUtxos(tx, indexes) {
1544
+ const candidateIndexes = indexes ?? Array.from({ length: tx.inputsLength }, (_, i) => i);
1545
+ const jobs = [];
1546
+ for (const index of candidateIndexes) {
1547
+ const script = tx.getInput(index).witnessUtxo?.script;
1548
+ if (script)
1549
+ jobs.push({ index, lookupScript: script });
1550
+ }
1551
+ return jobs;
1552
+ }
1402
1553
  async safeRegisterIntent(intent, inputs) {
1403
1554
  try {
1404
1555
  return await this.arkProvider.registerIntent(intent);
@@ -1431,7 +1582,7 @@ class Wallet extends ReadonlyWallet {
1431
1582
  cosigners_public_keys: cosignerPubKeys,
1432
1583
  };
1433
1584
  const proof = intent_1.Intent.create(message, coins, outputs);
1434
- const signedProof = await this.identity.sign(proof);
1585
+ const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
1435
1586
  return {
1436
1587
  proof: base_1.base64.encode(signedProof.toPSBT()),
1437
1588
  message,
@@ -1443,7 +1594,7 @@ class Wallet extends ReadonlyWallet {
1443
1594
  expire_at: 0,
1444
1595
  };
1445
1596
  const proof = intent_1.Intent.create(message, coins, []);
1446
- const signedProof = await this.identity.sign(proof);
1597
+ const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
1447
1598
  return {
1448
1599
  proof: base_1.base64.encode(signedProof.toPSBT()),
1449
1600
  message,
@@ -1455,7 +1606,7 @@ class Wallet extends ReadonlyWallet {
1455
1606
  expire_at: 0,
1456
1607
  };
1457
1608
  const proof = intent_1.Intent.create(message, coins, []);
1458
- const signedProof = await this.identity.sign(proof);
1609
+ const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
1459
1610
  return {
1460
1611
  proof: base_1.base64.encode(signedProof.toPSBT()),
1461
1612
  message,
@@ -1520,7 +1671,7 @@ class Wallet extends ReadonlyWallet {
1520
1671
  try {
1521
1672
  const finalCheckpoints = await Promise.all(pendingTx.signedCheckpointTxs.map(async (c) => {
1522
1673
  const tx = btc_signer_1.Transaction.fromPSBT(base_1.base64.decode(c));
1523
- const signedCheckpoint = await this.identity.sign(tx);
1674
+ const signedCheckpoint = await this._signerRouter.sign(tx, this.inputSigningJobsFromWitnessUtxos(tx));
1524
1675
  return base_1.base64.encode(signedCheckpoint.toPSBT());
1525
1676
  }));
1526
1677
  await this.arkProvider.finalizeTx(pendingTx.arkTxid, finalCheckpoints);
@@ -1580,10 +1731,19 @@ class Wallet extends ReadonlyWallet {
1580
1731
  if (args.length === 0) {
1581
1732
  throw new Error("At least one receiver is required");
1582
1733
  }
1734
+ // Snapshot the active receive tapscript synchronously before any
1735
+ // `await`. `WalletReceiveRotator.rotate` mutates
1736
+ // `this.offchainTapscript` without acquiring `_txLock`, so any
1737
+ // yield between here and `updateDbAfterOffchainTx` opens a window
1738
+ // where the change-output pkScript (built from `outputAddress`
1739
+ // below) and the change-VTXO metadata (built from the snapshot
1740
+ // inside `updateDbAfterOffchainTx`) could come from different
1741
+ // tapscripts. Threading the snapshot pins both reads.
1742
+ const offchainTapscript = this.offchainTapscript;
1743
+ const outputAddress = offchainTapscript.address(this.network.hrp, this.arkServerPublicKey);
1744
+ const address = outputAddress.encode();
1583
1745
  // validate recipients and populate undefined amount with dust amount
1584
1746
  const recipients = (0, utils_1.validateRecipients)(args, Number(this.dustAmount));
1585
- const address = await this.getAddress();
1586
- const outputAddress = address_1.ArkAddress.decode(address);
1587
1747
  const virtualCoins = await this.getVtxos({
1588
1748
  withRecoverable: false,
1589
1749
  });
@@ -1714,7 +1874,7 @@ class Wallet extends ReadonlyWallet {
1714
1874
  this._addPendingSpends(selectedCoins);
1715
1875
  try {
1716
1876
  const { arkTxid, signedCheckpointTxs } = await this.buildAndSubmitOffchainTx(selectedCoins, outputs);
1717
- await this.updateDbAfterOffchainTx(selectedCoins, arkTxid, signedCheckpointTxs, sentAmount, BigInt(changeAmount), changeReceiver ? changeIndex : 0, changeReceiver?.assets);
1877
+ await this.updateDbAfterOffchainTx(selectedCoins, arkTxid, signedCheckpointTxs, sentAmount, BigInt(changeAmount), changeReceiver ? changeIndex : 0, offchainTapscript, changeReceiver?.assets);
1718
1878
  return arkTxid;
1719
1879
  }
1720
1880
  finally {
@@ -1733,47 +1893,25 @@ class Wallet extends ReadonlyWallet {
1733
1893
  tapLeafScript: input.forfeitTapLeafScript,
1734
1894
  };
1735
1895
  }), outputs, this.serverUnrollScript);
1736
- let signedVirtualTx;
1737
- let userSignedCheckpoints;
1738
- if ((0, identity_1.isBatchSignable)(this.identity)) {
1739
- // Batch-sign arkTx + all checkpoints in one wallet popup.
1740
- // Clone so the provider can't mutate originals before submitTx.
1741
- const requests = [
1742
- { tx: offchainTx.arkTx.clone() },
1743
- ...offchainTx.checkpoints.map((c) => ({ tx: c.clone() })),
1744
- ];
1745
- const signed = await this.identity.signMultiple(requests);
1746
- if (signed.length !== requests.length) {
1747
- throw new Error(`signMultiple returned ${signed.length} transactions, expected ${requests.length}`);
1748
- }
1749
- const [firstSignedTx, ...signedCheckpoints] = signed;
1750
- signedVirtualTx = firstSignedTx;
1751
- userSignedCheckpoints = signedCheckpoints;
1752
- }
1753
- else {
1754
- signedVirtualTx = await this.identity.sign(offchainTx.arkTx);
1755
- }
1896
+ // arkTx inputs spend checkpoint outputs, so each input's
1897
+ // `witnessUtxo.script` is the checkpoint pkScript — not the
1898
+ // source VTXO contract's pkScript. Build the routing jobs from
1899
+ // the source VTXO scripts (positionally aligned to `inputs[i]`)
1900
+ // so the router can resolve each input's owning contract.
1901
+ const arkTxJobs = inputs.map((input, index) => ({
1902
+ index,
1903
+ lookupScript: base_2.VtxoScript.decode(input.tapTree).pkScript,
1904
+ }));
1905
+ const signedVirtualTx = await this._signerRouter.sign(offchainTx.arkTx, arkTxJobs);
1756
1906
  // Mark pending before submitting — if we crash between submit and
1757
1907
  // finalize, the next init will recover via finalizePendingTxs.
1758
1908
  await this.setPendingTxFlag(true);
1759
1909
  const { arkTxid, signedCheckpointTxs } = await this.arkProvider.submitTx(base_1.base64.encode(signedVirtualTx.toPSBT()), offchainTx.checkpoints.map((c) => base_1.base64.encode(c.toPSBT())));
1760
- let finalCheckpoints;
1761
- if (userSignedCheckpoints) {
1762
- // Merge pre-signed user signatures onto server-signed checkpoints
1763
- finalCheckpoints = signedCheckpointTxs.map((c, i) => {
1764
- const serverSigned = btc_signer_1.Transaction.fromPSBT(base_1.base64.decode(c));
1765
- (0, arkTransaction_1.combineTapscriptSigs)(userSignedCheckpoints[i], serverSigned);
1766
- return base_1.base64.encode(serverSigned.toPSBT());
1767
- });
1768
- }
1769
- else {
1770
- // Legacy: sign each checkpoint individually (N popups)
1771
- finalCheckpoints = await Promise.all(signedCheckpointTxs.map(async (c) => {
1772
- const tx = btc_signer_1.Transaction.fromPSBT(base_1.base64.decode(c));
1773
- const signedCheckpoint = await this.identity.sign(tx);
1774
- return base_1.base64.encode(signedCheckpoint.toPSBT());
1775
- }));
1776
- }
1910
+ const finalCheckpoints = await Promise.all(signedCheckpointTxs.map(async (c) => {
1911
+ const tx = btc_signer_1.Transaction.fromPSBT(base_1.base64.decode(c));
1912
+ const signedCheckpoint = await this._signerRouter.sign(tx, this.inputSigningJobsFromWitnessUtxos(tx));
1913
+ return base_1.base64.encode(signedCheckpoint.toPSBT());
1914
+ }));
1777
1915
  await this.arkProvider.finalizeTx(arkTxid, finalCheckpoints);
1778
1916
  try {
1779
1917
  await this.setPendingTxFlag(false);
@@ -1783,8 +1921,17 @@ class Wallet extends ReadonlyWallet {
1783
1921
  }
1784
1922
  return { arkTxid, signedCheckpointTxs };
1785
1923
  }
1786
- // mark virtual outputs as spent, save change outputs if any
1787
- async updateDbAfterOffchainTx(inputs, arkTxid, signedCheckpointTxs, sentAmount, changeAmount, changeVout, changeAssets) {
1924
+ // mark virtual outputs as spent, save change outputs if any.
1925
+ // `offchainTapscript` is the snapshot the caller captured under
1926
+ // `_txLock` before any `await`; deriving both the change-VTXO
1927
+ // metadata and `primaryAddress` from it here guarantees the local
1928
+ // record matches the pkScript the server saw on the inbound
1929
+ // transaction, even if `WalletReceiveRotator.rotate` swaps
1930
+ // `this.offchainTapscript` mid-flight.
1931
+ async updateDbAfterOffchainTx(inputs, arkTxid, signedCheckpointTxs, sentAmount, changeAmount, changeVout, offchainTapscript, changeAssets) {
1932
+ const primaryAddress = offchainTapscript
1933
+ .address(this.network.hrp, this.arkServerPublicKey)
1934
+ .encode();
1788
1935
  try {
1789
1936
  const spentVtxos = [];
1790
1937
  const commitmentTxIds = new Set();
@@ -1831,7 +1978,6 @@ class Wallet extends ReadonlyWallet {
1831
1978
  }
1832
1979
  }
1833
1980
  const createdAt = Date.now();
1834
- const primaryAddr = this.arkAddress.encode();
1835
1981
  // Only save a change virtual output for preconfirmed coins (those with a batchExpiry).
1836
1982
  // Inputs without a batchExpiry are already settled/unrolled and don't need tracking.
1837
1983
  let changeVtxo;
@@ -1840,11 +1986,11 @@ class Wallet extends ReadonlyWallet {
1840
1986
  txid: arkTxid,
1841
1987
  vout: changeVout,
1842
1988
  createdAt: new Date(createdAt),
1843
- forfeitTapLeafScript: this.offchainTapscript.forfeit(),
1844
- intentTapLeafScript: this.offchainTapscript.forfeit(),
1989
+ forfeitTapLeafScript: offchainTapscript.forfeit(),
1990
+ intentTapLeafScript: offchainTapscript.forfeit(),
1845
1991
  isUnrolled: false,
1846
1992
  isSpent: false,
1847
- tapTree: this.offchainTapscript.encode(),
1993
+ tapTree: offchainTapscript.encode(),
1848
1994
  value: Number(changeAmount),
1849
1995
  virtualStatus: {
1850
1996
  state: "preconfirmed",
@@ -1855,7 +2001,7 @@ class Wallet extends ReadonlyWallet {
1855
2001
  confirmed: false,
1856
2002
  },
1857
2003
  assets: changeAssets,
1858
- script: base_1.hex.encode(this.offchainTapscript.pkScript),
2004
+ script: base_1.hex.encode(offchainTapscript.pkScript),
1859
2005
  };
1860
2006
  }
1861
2007
  // Route spent rows to their owning contract bucket. The wallet's
@@ -1886,9 +2032,9 @@ class Wallet extends ReadonlyWallet {
1886
2032
  }
1887
2033
  // Change is always primary-script by construction.
1888
2034
  if (changeVtxo) {
1889
- await (0, vtxoOwnership_1.saveVtxosForContract)(this.walletRepository, { script: changeVtxo.script, address: primaryAddr }, [changeVtxo]);
2035
+ await (0, vtxoOwnership_1.saveVtxosForContract)(this.walletRepository, { script: changeVtxo.script, address: primaryAddress }, [changeVtxo]);
1890
2036
  }
1891
- await this.walletRepository.saveTransactions(primaryAddr, [
2037
+ await this.walletRepository.saveTransactions(primaryAddress, [
1892
2038
  {
1893
2039
  key: {
1894
2040
  boardingTxid: "",