@arkade-os/sdk 0.4.24 → 0.4.26

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 (212) hide show
  1. package/dist/cjs/contracts/contractManager.js +44 -8
  2. package/dist/cjs/contracts/contractWatcher.js +2 -2
  3. package/dist/cjs/contracts/vtxoOwnership.js +18 -0
  4. package/dist/cjs/repositories/inMemory/walletRepository.js +35 -0
  5. package/dist/cjs/repositories/indexedDB/walletRepository.js +117 -0
  6. package/dist/cjs/repositories/realm/walletRepository.js +28 -0
  7. package/dist/cjs/repositories/sqlite/walletRepository.js +23 -0
  8. package/dist/cjs/script/address.js +2 -2
  9. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +14 -3
  10. package/dist/cjs/wallet/serviceWorker/wallet.js +10 -0
  11. package/dist/cjs/wallet/vtxo-manager.js +112 -16
  12. package/dist/cjs/wallet/wallet.js +3 -17
  13. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +1 -1
  14. package/dist/esm/adapters/asyncStorage.js +1 -1
  15. package/dist/esm/adapters/expo.js +2 -2
  16. package/dist/esm/adapters/fileSystem.js +1 -1
  17. package/dist/esm/adapters/indexedDB.js +1 -1
  18. package/dist/esm/adapters/localStorage.js +1 -1
  19. package/dist/esm/arkfee/index.js +1 -1
  20. package/dist/esm/arknote/index.js +1 -1
  21. package/dist/esm/bip322/index.js +2 -2
  22. package/dist/esm/contracts/arkcontract.js +2 -2
  23. package/dist/esm/contracts/contractManager.js +49 -13
  24. package/dist/esm/contracts/contractWatcher.js +5 -5
  25. package/dist/esm/contracts/handlers/default.js +4 -4
  26. package/dist/esm/contracts/handlers/delegate.js +4 -4
  27. package/dist/esm/contracts/handlers/helpers.js +2 -2
  28. package/dist/esm/contracts/handlers/index.js +8 -8
  29. package/dist/esm/contracts/handlers/vhtlc.js +3 -3
  30. package/dist/esm/contracts/index.js +8 -8
  31. package/dist/esm/contracts/vtxoOwnership.js +16 -0
  32. package/dist/esm/extension/asset/assetGroup.js +7 -7
  33. package/dist/esm/extension/asset/assetId.js +2 -2
  34. package/dist/esm/extension/asset/assetInput.js +2 -2
  35. package/dist/esm/extension/asset/assetOutput.js +1 -1
  36. package/dist/esm/extension/asset/assetRef.js +3 -3
  37. package/dist/esm/extension/asset/index.js +8 -8
  38. package/dist/esm/extension/asset/metadata.js +1 -1
  39. package/dist/esm/extension/asset/packet.js +3 -3
  40. package/dist/esm/extension/index.js +4 -4
  41. package/dist/esm/forfeit.js +2 -2
  42. package/dist/esm/identity/index.js +5 -5
  43. package/dist/esm/identity/seedIdentity.js +2 -2
  44. package/dist/esm/identity/serialize.js +2 -2
  45. package/dist/esm/identity/singleKey.js +1 -1
  46. package/dist/esm/identity/staticDescriptorProvider.js +2 -2
  47. package/dist/esm/index.js +47 -47
  48. package/dist/esm/intent/index.js +3 -3
  49. package/dist/esm/musig2/index.js +3 -3
  50. package/dist/esm/musig2/sign.js +1 -1
  51. package/dist/esm/providers/ark.js +3 -3
  52. package/dist/esm/providers/delegator.js +1 -1
  53. package/dist/esm/providers/electrum.js +2 -2
  54. package/dist/esm/providers/expoArk.js +2 -2
  55. package/dist/esm/providers/expoIndexer.js +3 -3
  56. package/dist/esm/providers/indexer.js +3 -3
  57. package/dist/esm/repositories/inMemory/walletRepository.js +35 -0
  58. package/dist/esm/repositories/index.js +9 -9
  59. package/dist/esm/repositories/indexedDB/contractRepository.js +4 -4
  60. package/dist/esm/repositories/indexedDB/db.js +2 -2
  61. package/dist/esm/repositories/indexedDB/schema.js +1 -1
  62. package/dist/esm/repositories/indexedDB/walletRepository.js +122 -5
  63. package/dist/esm/repositories/migrations/fromStorageAdapter.js +1 -1
  64. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +1 -1
  65. package/dist/esm/repositories/realm/index.js +3 -3
  66. package/dist/esm/repositories/realm/schemas.js +1 -1
  67. package/dist/esm/repositories/realm/walletRepository.js +30 -2
  68. package/dist/esm/repositories/scriptFromAddress.js +1 -1
  69. package/dist/esm/repositories/sqlite/index.js +2 -2
  70. package/dist/esm/repositories/sqlite/walletRepository.js +25 -2
  71. package/dist/esm/script/address.js +3 -3
  72. package/dist/esm/script/base.js +3 -3
  73. package/dist/esm/script/default.js +2 -2
  74. package/dist/esm/script/delegate.js +3 -3
  75. package/dist/esm/script/tapscript.js +1 -1
  76. package/dist/esm/script/vhtlc.js +2 -2
  77. package/dist/esm/storage/indexedDB.js +1 -1
  78. package/dist/esm/tree/signingSession.js +2 -2
  79. package/dist/esm/tree/validation.js +2 -2
  80. package/dist/esm/utils/arkTransaction.js +7 -7
  81. package/dist/esm/utils/transactionHistory.js +1 -1
  82. package/dist/esm/utils/unknownFields.js +1 -1
  83. package/dist/esm/wallet/asset-manager.js +5 -5
  84. package/dist/esm/wallet/asset.js +1 -1
  85. package/dist/esm/wallet/batch.js +2 -2
  86. package/dist/esm/wallet/delegator.js +6 -6
  87. package/dist/esm/wallet/expo/background.js +5 -5
  88. package/dist/esm/wallet/expo/index.js +2 -2
  89. package/dist/esm/wallet/expo/wallet.js +8 -8
  90. package/dist/esm/wallet/hdDescriptorProvider.js +2 -2
  91. package/dist/esm/wallet/onchain.js +7 -7
  92. package/dist/esm/wallet/ramps.js +3 -3
  93. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +20 -9
  94. package/dist/esm/wallet/serviceWorker/wallet.js +17 -7
  95. package/dist/esm/wallet/unroll.js +7 -7
  96. package/dist/esm/wallet/utils.js +2 -2
  97. package/dist/esm/wallet/validation.js +2 -2
  98. package/dist/esm/wallet/vtxo-manager.js +120 -24
  99. package/dist/esm/wallet/wallet.js +36 -50
  100. package/dist/esm/worker/expo/index.js +4 -4
  101. package/dist/esm/worker/expo/processors/contractPollProcessor.js +2 -2
  102. package/dist/esm/worker/expo/processors/index.js +1 -1
  103. package/dist/esm/worker/expo/taskRunner.js +1 -1
  104. package/dist/esm/worker/messageBus.js +6 -6
  105. package/dist/types/adapters/asyncStorage.d.ts +2 -2
  106. package/dist/types/adapters/expo.d.ts +4 -4
  107. package/dist/types/adapters/fileSystem.d.ts +2 -2
  108. package/dist/types/adapters/indexedDB.d.ts +2 -2
  109. package/dist/types/adapters/localStorage.d.ts +2 -2
  110. package/dist/types/arkfee/index.d.ts +2 -2
  111. package/dist/types/arknote/index.d.ts +2 -2
  112. package/dist/types/bip322/index.d.ts +1 -1
  113. package/dist/types/contracts/arkcontract.d.ts +1 -1
  114. package/dist/types/contracts/contractManager.d.ts +22 -6
  115. package/dist/types/contracts/contractWatcher.d.ts +3 -3
  116. package/dist/types/contracts/handlers/default.d.ts +3 -3
  117. package/dist/types/contracts/handlers/delegate.d.ts +3 -3
  118. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  119. package/dist/types/contracts/handlers/index.d.ts +7 -7
  120. package/dist/types/contracts/handlers/registry.d.ts +1 -1
  121. package/dist/types/contracts/handlers/vhtlc.d.ts +3 -3
  122. package/dist/types/contracts/index.d.ts +14 -14
  123. package/dist/types/contracts/types.d.ts +3 -3
  124. package/dist/types/contracts/vtxoOwnership.d.ts +9 -1
  125. package/dist/types/extension/asset/assetGroup.d.ts +6 -6
  126. package/dist/types/extension/asset/assetId.d.ts +1 -1
  127. package/dist/types/extension/asset/assetInput.d.ts +2 -2
  128. package/dist/types/extension/asset/assetOutput.d.ts +1 -1
  129. package/dist/types/extension/asset/assetRef.d.ts +3 -3
  130. package/dist/types/extension/asset/index.d.ts +8 -8
  131. package/dist/types/extension/asset/metadata.d.ts +1 -1
  132. package/dist/types/extension/asset/packet.d.ts +2 -2
  133. package/dist/types/extension/index.d.ts +6 -6
  134. package/dist/types/forfeit.d.ts +1 -1
  135. package/dist/types/identity/descriptorProvider.d.ts +1 -1
  136. package/dist/types/identity/hdCapableIdentity.d.ts +3 -3
  137. package/dist/types/identity/index.d.ts +11 -11
  138. package/dist/types/identity/seedIdentity.d.ts +5 -5
  139. package/dist/types/identity/serialize.d.ts +1 -1
  140. package/dist/types/identity/singleKey.d.ts +3 -3
  141. package/dist/types/identity/staticDescriptorProvider.d.ts +3 -3
  142. package/dist/types/index.d.ts +57 -57
  143. package/dist/types/intent/index.d.ts +2 -2
  144. package/dist/types/musig2/index.d.ts +4 -4
  145. package/dist/types/providers/ark.d.ts +5 -5
  146. package/dist/types/providers/delegator.d.ts +2 -2
  147. package/dist/types/providers/electrum.d.ts +5 -5
  148. package/dist/types/providers/expoArk.d.ts +1 -1
  149. package/dist/types/providers/expoIndexer.d.ts +1 -1
  150. package/dist/types/providers/indexer.d.ts +1 -1
  151. package/dist/types/providers/onchain.d.ts +2 -2
  152. package/dist/types/repositories/contractRepository.d.ts +1 -1
  153. package/dist/types/repositories/inMemory/contractRepository.d.ts +2 -2
  154. package/dist/types/repositories/inMemory/walletRepository.d.ts +5 -2
  155. package/dist/types/repositories/index.d.ts +9 -9
  156. package/dist/types/repositories/indexedDB/contractRepository.d.ts +2 -2
  157. package/dist/types/repositories/indexedDB/db.d.ts +3 -3
  158. package/dist/types/repositories/indexedDB/walletRepository.d.ts +5 -2
  159. package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +3 -3
  160. package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +2 -2
  161. package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +3 -3
  162. package/dist/types/repositories/realm/contractRepository.d.ts +3 -3
  163. package/dist/types/repositories/realm/index.d.ts +4 -4
  164. package/dist/types/repositories/realm/walletRepository.d.ts +6 -3
  165. package/dist/types/repositories/serialization.d.ts +11 -11
  166. package/dist/types/repositories/sqlite/contractRepository.d.ts +3 -3
  167. package/dist/types/repositories/sqlite/index.d.ts +3 -3
  168. package/dist/types/repositories/sqlite/walletRepository.d.ts +6 -3
  169. package/dist/types/repositories/walletRepository.d.ts +22 -1
  170. package/dist/types/script/address.d.ts +2 -2
  171. package/dist/types/script/base.d.ts +2 -2
  172. package/dist/types/script/default.d.ts +2 -2
  173. package/dist/types/script/delegate.d.ts +3 -3
  174. package/dist/types/script/vhtlc.d.ts +2 -2
  175. package/dist/types/storage/asyncStorage.d.ts +1 -1
  176. package/dist/types/storage/fileSystem.d.ts +1 -1
  177. package/dist/types/storage/inMemory.d.ts +1 -1
  178. package/dist/types/storage/indexedDB.d.ts +1 -1
  179. package/dist/types/storage/localStorage.d.ts +1 -1
  180. package/dist/types/tree/signingSession.d.ts +2 -2
  181. package/dist/types/tree/validation.d.ts +1 -1
  182. package/dist/types/utils/arkTransaction.d.ts +5 -5
  183. package/dist/types/utils/syncCursors.d.ts +1 -1
  184. package/dist/types/utils/timelock.d.ts +1 -1
  185. package/dist/types/utils/transaction.d.ts +2 -2
  186. package/dist/types/utils/transactionHistory.d.ts +1 -1
  187. package/dist/types/utils/txSizeEstimator.d.ts +1 -1
  188. package/dist/types/wallet/asset-manager.d.ts +3 -3
  189. package/dist/types/wallet/asset.d.ts +2 -2
  190. package/dist/types/wallet/batch.d.ts +2 -2
  191. package/dist/types/wallet/delegator.d.ts +5 -5
  192. package/dist/types/wallet/expo/background.d.ts +4 -4
  193. package/dist/types/wallet/expo/index.d.ts +4 -4
  194. package/dist/types/wallet/expo/wallet.d.ts +8 -8
  195. package/dist/types/wallet/hdDescriptorProvider.d.ts +4 -4
  196. package/dist/types/wallet/index.d.ts +29 -26
  197. package/dist/types/wallet/onchain.d.ts +6 -6
  198. package/dist/types/wallet/ramps.d.ts +2 -2
  199. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +21 -9
  200. package/dist/types/wallet/serviceWorker/wallet.d.ts +10 -10
  201. package/dist/types/wallet/unroll.d.ts +6 -6
  202. package/dist/types/wallet/utils.d.ts +5 -5
  203. package/dist/types/wallet/validation.d.ts +3 -3
  204. package/dist/types/wallet/vtxo-manager.d.ts +34 -7
  205. package/dist/types/wallet/wallet.d.ts +20 -20
  206. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
  207. package/dist/types/worker/expo/index.d.ts +7 -7
  208. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
  209. package/dist/types/worker/expo/processors/index.d.ts +1 -1
  210. package/dist/types/worker/expo/taskRunner.d.ts +7 -7
  211. package/dist/types/worker/messageBus.d.ts +6 -6
  212. package/package.json +2 -2
@@ -1873,7 +1873,6 @@ class Wallet extends ReadonlyWallet {
1873
1873
  arr.push(v);
1874
1874
  spentByScript.set(v.script, arr);
1875
1875
  }
1876
- const byAddress = new Map();
1877
1876
  for (const [script, vtxos] of spentByScript) {
1878
1877
  // User-initiated send path: a wrong-script row here means the
1879
1878
  // wallet is about to record ownership against the wrong
@@ -1883,18 +1882,11 @@ class Wallet extends ReadonlyWallet {
1883
1882
  if (!targetAddr) {
1884
1883
  throw new Error(`Wallet.updateDbAfterOffchainTx: no contract owns script ${script}`);
1885
1884
  }
1886
- const bucket = byAddress.get(targetAddr) ?? [];
1887
- bucket.push(...vtxos);
1888
- byAddress.set(targetAddr, bucket);
1885
+ await (0, vtxoOwnership_1.saveVtxosForContract)(this.walletRepository, { script, address: targetAddr }, vtxos);
1889
1886
  }
1890
1887
  // Change is always primary-script by construction.
1891
1888
  if (changeVtxo) {
1892
- const bucket = byAddress.get(primaryAddr) ?? [];
1893
- bucket.push(changeVtxo);
1894
- byAddress.set(primaryAddr, bucket);
1895
- }
1896
- for (const [addr, vtxos] of byAddress) {
1897
- await this.walletRepository.saveVtxos(addr, vtxos);
1889
+ await (0, vtxoOwnership_1.saveVtxosForContract)(this.walletRepository, { script: changeVtxo.script, address: primaryAddr }, [changeVtxo]);
1898
1890
  }
1899
1891
  await this.walletRepository.saveTransactions(primaryAddr, [
1900
1892
  {
@@ -1957,7 +1949,6 @@ class Wallet extends ReadonlyWallet {
1957
1949
  // alongside the rest.
1958
1950
  const contracts = await cm.getContracts();
1959
1951
  const addrByScript = new Map(contracts.map((c) => [c.script, c.address]));
1960
- const byAddress = new Map();
1961
1952
  const byScript = new Map();
1962
1953
  for (const v of spentVtxos) {
1963
1954
  if (!v.script) {
@@ -1975,12 +1966,7 @@ class Wallet extends ReadonlyWallet {
1975
1966
  if (!targetAddr) {
1976
1967
  throw new Error(`Wallet.updateDbAfterSettle: no contract owns script ${script}`);
1977
1968
  }
1978
- const bucket = byAddress.get(targetAddr) ?? [];
1979
- bucket.push(...vtxos);
1980
- byAddress.set(targetAddr, bucket);
1981
- }
1982
- for (const [bucketAddr, vtxos] of byAddress) {
1983
- await this.walletRepository.saveVtxos(bucketAddr, vtxos);
1969
+ await (0, vtxoOwnership_1.saveVtxosForContract)(this.walletRepository, { script, address: targetAddr }, vtxos);
1984
1970
  }
1985
1971
  }
1986
1972
  if (boardingUtxoToRemove.size > 0) {
@@ -48,7 +48,7 @@ exports.contractPollProcessor = {
48
48
  // before persisting; the loop must keep going for the remaining
49
49
  // contracts even when one row is rejected.
50
50
  const filtered = (0, vtxoOwnership_1.warnAndFilterVtxosForScript)(allVtxos, contract.script, "contractPollProcessor");
51
- await walletRepository.saveVtxos(contract.address, filtered);
51
+ await (0, vtxoOwnership_1.saveVtxosForContract)(walletRepository, contract, filtered);
52
52
  vtxosSaved += filtered.length;
53
53
  contractsProcessed++;
54
54
  }
@@ -1 +1 @@
1
- export { AsyncStorageAdapter } from '../storage/asyncStorage.js';
1
+ export { AsyncStorageAdapter } from "../storage/asyncStorage.js";
@@ -1,3 +1,3 @@
1
1
  // Expo adapter for React Native/Expo environments
2
- export { ExpoArkProvider } from '../providers/expoArk.js';
3
- export { ExpoIndexerProvider } from '../providers/expoIndexer.js';
2
+ export { ExpoArkProvider } from "../providers/expoArk.js";
3
+ export { ExpoIndexerProvider } from "../providers/expoIndexer.js";
@@ -1 +1 @@
1
- export { FileSystemStorageAdapter } from '../storage/fileSystem.js';
1
+ export { FileSystemStorageAdapter } from "../storage/fileSystem.js";
@@ -1 +1 @@
1
- export { IndexedDBStorageAdapter } from '../storage/indexedDB.js';
1
+ export { IndexedDBStorageAdapter } from "../storage/indexedDB.js";
@@ -1 +1 @@
1
- export { LocalStorageAdapter } from '../storage/localStorage.js';
1
+ export { LocalStorageAdapter } from "../storage/localStorage.js";
@@ -1 +1 @@
1
- export { Estimator } from './estimator.js';
1
+ export { Estimator } from "./estimator.js";
@@ -1,7 +1,7 @@
1
1
  import { base58, hex } from "@scure/base";
2
2
  import { sha256 } from "@scure/btc-signer/utils.js";
3
3
  import { Script } from "@scure/btc-signer";
4
- import { VtxoScript } from '../script/base.js';
4
+ import { VtxoScript } from "../script/base.js";
5
5
  /**
6
6
  * ArkNotes are special virtual outputs in the Arkade protocol that
7
7
  * can be created and spent without requiring any transactions.
@@ -3,8 +3,8 @@ import { concatBytes, hash160, sha256x2, } from "@scure/btc-signer/utils.js";
3
3
  import { schnorr, secp256k1 } from "@noble/curves/secp256k1.js";
4
4
  import { equalBytes } from "@noble/curves/utils.js";
5
5
  import { base64 } from "@scure/base";
6
- import { Transaction } from '../utils/transaction.js';
7
- import { craftToSpendTx, OP_RETURN_EMPTY_PKSCRIPT } from '../intent/index.js';
6
+ import { Transaction } from "../utils/transaction.js";
7
+ import { craftToSpendTx, OP_RETURN_EMPTY_PKSCRIPT } from "../intent/index.js";
8
8
  const TAG_BIP322 = "BIP0322-signed-message";
9
9
  /**
10
10
  * BIP-322 simple message signing and verification.
@@ -1,6 +1,6 @@
1
1
  import { hex } from "@scure/base";
2
- import { contractHandlers } from './handlers/index.js';
3
- import { DEFAULT_ARKADE_HRP } from '../wallet/index.js';
2
+ import { contractHandlers } from "./handlers/index.js";
3
+ import { DEFAULT_ARKADE_HRP } from "../wallet/index.js";
4
4
  /**
5
5
  * Prefix for arkcontract strings.
6
6
  */
@@ -1,9 +1,9 @@
1
1
  import { hex } from "@scure/base";
2
- import { ContractWatcher } from './contractWatcher.js';
3
- import { contractHandlers } from './handlers/index.js';
4
- import { extendVirtualCoinForContract } from '../wallet/utils.js';
5
- import { advanceSyncCursor, computeSyncWindow, cursorCutoff, getSyncCursor, } from '../utils/syncCursors.js';
6
- import { filterVtxosForScript, warnAndFilterVtxosForScript, } from './vtxoOwnership.js';
2
+ import { ContractWatcher } from "./contractWatcher.js";
3
+ import { contractHandlers } from "./handlers/index.js";
4
+ import { extendVirtualCoinForContract } from "../wallet/utils.js";
5
+ import { advanceSyncCursor, computeSyncWindow, cursorCutoff, getSyncCursor, } from "../utils/syncCursors.js";
6
+ import { getVtxosForContract, saveVtxosForContract, warnAndFilterVtxosForScript, } from "./vtxoOwnership.js";
7
7
  const DEFAULT_PAGE_SIZE = 500;
8
8
  /**
9
9
  * Central manager for contract lifecycle and operations.
@@ -370,6 +370,46 @@ export class ContractManager {
370
370
  : undefined,
371
371
  });
372
372
  }
373
+ async refreshOutpoints(outpoints) {
374
+ if (outpoints.length === 0)
375
+ return;
376
+ const { vtxos } = await this.config.indexerProvider.getVtxos({
377
+ outpoints,
378
+ });
379
+ if (vtxos.length === 0)
380
+ return;
381
+ // Filter to outputs whose script we own. Map them to their owning
382
+ // contract so we can write through to the right per-address entry
383
+ // in the wallet repository.
384
+ const scripts = Array.from(new Set(vtxos.map((v) => v.script)));
385
+ const contracts = await this.config.contractRepository.getContracts({
386
+ script: scripts,
387
+ });
388
+ const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
389
+ const owned = vtxos.filter((v) => scriptToContract.has(v.script));
390
+ if (owned.length === 0)
391
+ return;
392
+ const annotated = await this.annotateVtxos(owned);
393
+ const byAddress = new Map();
394
+ for (const vtxo of annotated) {
395
+ const contract = scriptToContract.get(vtxo.script);
396
+ if (!contract)
397
+ continue;
398
+ const address = contract.address;
399
+ const arr = byAddress.get(address) ?? [];
400
+ arr.push(vtxo);
401
+ byAddress.set(address, arr);
402
+ }
403
+ for (const [address, addressVtxos] of byAddress) {
404
+ const contract = contracts.find((c) => c.address === address);
405
+ if (contract) {
406
+ await saveVtxosForContract(this.config.walletRepository, contract, addressVtxos);
407
+ }
408
+ else {
409
+ await this.config.walletRepository.saveVtxos(address, addressVtxos);
410
+ }
411
+ }
412
+ }
373
413
  /**
374
414
  * Check if currently watching.
375
415
  */
@@ -410,13 +450,9 @@ export class ContractManager {
410
450
  this.emitEvent(event);
411
451
  }
412
452
  async getVtxosForContracts(contracts) {
413
- const res = await Promise.all(contracts.map(({ script, address }) => this.config.walletRepository.getVtxos(address).then((vtxos) =>
414
- // Address buckets may carry legacy duplicate rows from
415
- // other contracts that once shared the same address —
416
- // gate by script so the wrong-script row never wins.
417
- filterVtxosForScript(vtxos, script).map((vtxo) => ({
453
+ const res = await Promise.all(contracts.map((contract) => getVtxosForContract(this.config.walletRepository, contract).then((vtxos) => vtxos.map((vtxo) => ({
418
454
  ...vtxo,
419
- contractScript: script,
455
+ contractScript: contract.script,
420
456
  })))));
421
457
  return res.flat();
422
458
  }
@@ -489,7 +525,7 @@ export class ContractManager {
489
525
  const filtered = warnAndFilterVtxosForScript(contractVtxos, contract.script, "ContractManager.reconcilePendingFrontier");
490
526
  if (filtered.length === 0)
491
527
  continue;
492
- await this.config.walletRepository.saveVtxos(addr, filtered);
528
+ await saveVtxosForContract(this.config.walletRepository, contract, filtered);
493
529
  }
494
530
  }
495
531
  async fetchContractVxosFromIndexer(contracts, pageSize, syncWindow) {
@@ -502,7 +538,7 @@ export class ContractManager {
502
538
  const filtered = warnAndFilterVtxosForScript(vtxos, contract.script, "ContractManager.fetchContractVxosFromIndexer");
503
539
  if (filtered.length === 0)
504
540
  continue;
505
- await this.config.walletRepository.saveVtxos(contract.address, filtered);
541
+ await saveVtxosForContract(this.config.walletRepository, contract, filtered);
506
542
  }
507
543
  }
508
544
  return result;
@@ -1,6 +1,6 @@
1
- import { extendVirtualCoinForContract } from '../wallet/utils.js';
2
- import { isEventSourceError } from '../providers/utils.js';
3
- import { filterVtxosForScript } from './vtxoOwnership.js';
1
+ import { extendVirtualCoinForContract } from "../wallet/utils.js";
2
+ import { isEventSourceError } from "../providers/utils.js";
3
+ import { getVtxosForContract } from "./vtxoOwnership.js";
4
4
  /**
5
5
  * Watches multiple contracts for virtual output state changes with resilient connection handling.
6
6
  *
@@ -91,7 +91,7 @@ export class ContractWatcher {
91
91
  // Apply the same script gate used by getContractVtxos so a legacy
92
92
  // wrong-script row in the address bucket can't seed the baseline
93
93
  // and then look "spent" on the first poll.
94
- const cached = filterVtxosForScript(await this.config.walletRepository.getVtxos(state.contract.address), state.contract.script);
94
+ const cached = await getVtxosForContract(this.config.walletRepository, state.contract);
95
95
  for (const vtxo of cached) {
96
96
  if (vtxo.isSpent)
97
97
  continue;
@@ -173,7 +173,7 @@ export class ContractWatcher {
173
173
  // Use contract address as cache key. Legacy address buckets
174
174
  // can contain rows from other contracts; gate by script before
175
175
  // converting so a wrong-script row never reaches the watcher.
176
- const cached = filterVtxosForScript(await repo.getVtxos(state.contract.address), state.contract.script);
176
+ const cached = await getVtxosForContract(repo, state.contract);
177
177
  if (cached.length > 0) {
178
178
  // Convert to ContractVtxo with contractScript
179
179
  const contractVtxos = cached.map((v) => ({
@@ -1,8 +1,8 @@
1
1
  import { hex } from "@scure/base";
2
- import { DefaultVtxo } from '../../script/default.js';
3
- import { isCsvSpendable } from './helpers.js';
4
- import { sequenceToTimelock, timelockToSequence } from '../../utils/timelock.js';
5
- import { normalizeToDescriptor, extractPubKey, } from '../../identity/descriptor.js';
2
+ import { DefaultVtxo } from "../../script/default.js";
3
+ import { isCsvSpendable } from "./helpers.js";
4
+ import { sequenceToTimelock, timelockToSequence } from "../../utils/timelock.js";
5
+ import { normalizeToDescriptor, extractPubKey, } from "../../identity/descriptor.js";
6
6
  /**
7
7
  * Extract pubkey bytes from a descriptor or hex string.
8
8
  */
@@ -1,8 +1,8 @@
1
1
  import { hex } from "@scure/base";
2
- import { DelegateVtxo } from '../../script/delegate.js';
3
- import { DefaultVtxo } from '../../script/default.js';
4
- import { isCsvSpendable } from './helpers.js';
5
- import { sequenceToTimelock, timelockToSequence } from '../../utils/timelock.js';
2
+ import { DelegateVtxo } from "../../script/delegate.js";
3
+ import { DefaultVtxo } from "../../script/default.js";
4
+ import { isCsvSpendable } from "./helpers.js";
5
+ import { sequenceToTimelock, timelockToSequence } from "../../utils/timelock.js";
6
6
  /**
7
7
  * Handler for delegate wallet virtual outputs.
8
8
  *
@@ -1,5 +1,5 @@
1
- import { sequenceToTimelock } from '../../utils/timelock.js';
2
- import { isDescriptor, extractPubKey } from '../../identity/descriptor.js';
1
+ import { sequenceToTimelock } from "../../utils/timelock.js";
2
+ import { isDescriptor, extractPubKey } from "../../identity/descriptor.js";
3
3
  /**
4
4
  * Extract raw hex pubkey from a value that may be a descriptor or raw hex.
5
5
  * Returns undefined for HD descriptors or unparseable values so role
@@ -1,12 +1,12 @@
1
- export { contractHandlers } from './registry.js';
2
- export { DefaultContractHandler } from './default.js';
3
- export { DelegateContractHandler } from './delegate.js';
4
- export { VHTLCContractHandler } from './vhtlc.js';
1
+ export { contractHandlers } from "./registry.js";
2
+ export { DefaultContractHandler } from "./default.js";
3
+ export { DelegateContractHandler } from "./delegate.js";
4
+ export { VHTLCContractHandler } from "./vhtlc.js";
5
5
  // Register built-in handlers
6
- import { contractHandlers } from './registry.js';
7
- import { DefaultContractHandler } from './default.js';
8
- import { DelegateContractHandler } from './delegate.js';
9
- import { VHTLCContractHandler } from './vhtlc.js';
6
+ import { contractHandlers } from "./registry.js";
7
+ import { DefaultContractHandler } from "./default.js";
8
+ import { DelegateContractHandler } from "./delegate.js";
9
+ import { VHTLCContractHandler } from "./vhtlc.js";
10
10
  contractHandlers.register(DefaultContractHandler);
11
11
  contractHandlers.register(DelegateContractHandler);
12
12
  contractHandlers.register(VHTLCContractHandler);
@@ -1,7 +1,7 @@
1
1
  import { hex } from "@scure/base";
2
- import { VHTLC } from '../../script/vhtlc.js';
3
- import { isCltvSatisfied, isCsvSpendable, resolveRole } from './helpers.js';
4
- import { sequenceToTimelock, timelockToSequence } from '../../utils/timelock.js';
2
+ import { VHTLC } from "../../script/vhtlc.js";
3
+ import { isCltvSatisfied, isCsvSpendable, resolveRole } from "./helpers.js";
4
+ import { sequenceToTimelock, timelockToSequence } from "../../utils/timelock.js";
5
5
  /**
6
6
  * Handler for Virtual Hash Time Lock Contract (VHTLC).
7
7
  *
@@ -1,13 +1,13 @@
1
1
  // Types
2
- export * from './types.js';
2
+ export * from "./types.js";
3
3
  // Contract handlers
4
- export { contractHandlers } from './handlers/index.js';
5
- export { DefaultContractHandler } from './handlers/index.js';
6
- export { DelegateContractHandler } from './handlers/index.js';
7
- export { VHTLCContractHandler } from './handlers/index.js';
4
+ export { contractHandlers } from "./handlers/index.js";
5
+ export { DefaultContractHandler } from "./handlers/index.js";
6
+ export { DelegateContractHandler } from "./handlers/index.js";
7
+ export { VHTLCContractHandler } from "./handlers/index.js";
8
8
  // arkcontract string codec
9
- export { encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract, } from './arkcontract.js';
9
+ export { encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract, } from "./arkcontract.js";
10
10
  // Contract watcher
11
- export { ContractWatcher } from './contractWatcher.js';
11
+ export { ContractWatcher } from "./contractWatcher.js";
12
12
  // Contract manager
13
- export { ContractManager } from './contractManager.js';
13
+ export { ContractManager } from "./contractManager.js";
@@ -51,3 +51,19 @@ export function validateVtxosForScript(vtxos, script, context) {
51
51
  .join(", ");
52
52
  throw new Error(`${context}: refusing to persist ${mismatches.length} VTXO(s) whose script does not match ${script}: ${detail}`);
53
53
  }
54
+ /**
55
+ * Tier 2 dispatch helpers: route to script-scoped repository methods when
56
+ * available, falling back to Tier 1 address-based filtering otherwise.
57
+ */
58
+ export async function getVtxosForContract(repo, contract) {
59
+ return repo.getVtxosForScript
60
+ ? repo.getVtxosForScript(contract.script)
61
+ : filterVtxosForScript(await repo.getVtxos(contract.address), contract.script);
62
+ }
63
+ export async function saveVtxosForContract(repo, contract, vtxos) {
64
+ if (repo.saveVtxosForScript) {
65
+ return repo.saveVtxosForScript({ script: contract.script, address: contract.address }, vtxos);
66
+ }
67
+ validateVtxosForScript(vtxos, contract.script, "saveVtxosForContract");
68
+ return repo.saveVtxos(contract.address, vtxos);
69
+ }
@@ -1,11 +1,11 @@
1
1
  import { hex } from "@scure/base";
2
- import { AssetInputType, MASK_ASSET_ID, MASK_CONTROL_ASSET, MASK_METADATA, } from './types.js';
3
- import { AssetId } from './assetId.js';
4
- import { AssetRef } from './assetRef.js';
5
- import { AssetInput, AssetInputs } from './assetInput.js';
6
- import { AssetOutputs } from './assetOutput.js';
7
- import { MetadataList } from './metadata.js';
8
- import { BufferReader, BufferWriter } from './utils.js';
2
+ import { AssetInputType, MASK_ASSET_ID, MASK_CONTROL_ASSET, MASK_METADATA, } from "./types.js";
3
+ import { AssetId } from "./assetId.js";
4
+ import { AssetRef } from "./assetRef.js";
5
+ import { AssetInput, AssetInputs } from "./assetInput.js";
6
+ import { AssetOutputs } from "./assetOutput.js";
7
+ import { MetadataList } from "./metadata.js";
8
+ import { BufferReader, BufferWriter } from "./utils.js";
9
9
  /**
10
10
  * An asset group contains inputs, outputs, and all data related to a given asset id.
11
11
  *
@@ -1,6 +1,6 @@
1
1
  import { hex } from "@scure/base";
2
- import { TX_HASH_SIZE, ASSET_ID_SIZE } from './types.js';
3
- import { BufferReader, BufferWriter, isZeroBytes } from './utils.js';
2
+ import { TX_HASH_SIZE, ASSET_ID_SIZE } from "./types.js";
3
+ import { BufferReader, BufferWriter, isZeroBytes } from "./utils.js";
4
4
  /**
5
5
  * AssetId identifies a specific asset.
6
6
  *
@@ -1,6 +1,6 @@
1
1
  import { hex } from "@scure/base";
2
- import { AssetInputType, TX_HASH_SIZE } from './types.js';
3
- import { BufferReader, BufferWriter, isZeroBytes } from './utils.js';
2
+ import { AssetInputType, TX_HASH_SIZE } from "./types.js";
3
+ import { BufferReader, BufferWriter, isZeroBytes } from "./utils.js";
4
4
  /**
5
5
  * AssetInput represents an input of an asset group.
6
6
  * a local input references a real transaction input and specify the amount in satoshis.
@@ -1,5 +1,5 @@
1
1
  import { hex } from "@scure/base";
2
- import { BufferReader, BufferWriter } from './utils.js';
2
+ import { BufferReader, BufferWriter } from "./utils.js";
3
3
  /**
4
4
  * AssetOutput references a real transaction output and specify the amount in satoshis.
5
5
  * it must be present in an AssetGroup.
@@ -1,7 +1,7 @@
1
1
  import { hex } from "@scure/base";
2
- import { AssetRefType } from './types.js';
3
- import { AssetId } from './assetId.js';
4
- import { BufferReader, BufferWriter } from './utils.js';
2
+ import { AssetRefType } from "./types.js";
3
+ import { AssetId } from "./assetId.js";
4
+ import { BufferReader, BufferWriter } from "./utils.js";
5
5
  /**
6
6
  * Reference to either an explicit asset id or another asset group in the same packet.
7
7
  *
@@ -1,8 +1,8 @@
1
- export { AssetInputType, AssetRefType } from './types.js';
2
- export { AssetId } from './assetId.js';
3
- export { AssetRef } from './assetRef.js';
4
- export { AssetInput, AssetInputs } from './assetInput.js';
5
- export { AssetOutput, AssetOutputs } from './assetOutput.js';
6
- export { Metadata, MetadataList } from './metadata.js';
7
- export { AssetGroup } from './assetGroup.js';
8
- export { Packet } from './packet.js';
1
+ export { AssetInputType, AssetRefType } from "./types.js";
2
+ export { AssetId } from "./assetId.js";
3
+ export { AssetRef } from "./assetRef.js";
4
+ export { AssetInput, AssetInputs } from "./assetInput.js";
5
+ export { AssetOutput, AssetOutputs } from "./assetOutput.js";
6
+ export { Metadata, MetadataList } from "./metadata.js";
7
+ export { AssetGroup } from "./assetGroup.js";
8
+ export { Packet } from "./packet.js";
@@ -1,7 +1,7 @@
1
1
  import { schnorr } from "@noble/curves/secp256k1.js";
2
2
  import { hex } from "@scure/base";
3
3
  import { compareBytes } from "@scure/btc-signer/utils.js";
4
- import { BufferReader, BufferWriter } from './utils.js';
4
+ import { BufferReader, BufferWriter } from "./utils.js";
5
5
  /**
6
6
  * Metadata represents a key-value pair.
7
7
  * @param key - the key
@@ -1,7 +1,7 @@
1
1
  import { hex } from "@scure/base";
2
- import { AssetRefType } from './types.js';
3
- import { AssetGroup } from './assetGroup.js';
4
- import { BufferReader, BufferWriter } from './utils.js';
2
+ import { AssetRefType } from "./types.js";
3
+ import { AssetGroup } from "./assetGroup.js";
4
+ import { BufferReader, BufferWriter } from "./utils.js";
5
5
  /**
6
6
  * Packet represents a collection of asset groups.
7
7
  * It encodes/decodes as raw bytes only — OP_RETURN framing is handled by the Extension module.
@@ -1,10 +1,10 @@
1
1
  import { hex } from "@scure/base";
2
2
  import { Script } from "@scure/btc-signer";
3
3
  import { equalBytes } from "@scure/btc-signer/utils.js";
4
- import { Packet } from './asset/packet.js';
5
- import { BufferReader } from './asset/utils.js';
6
- import { UnknownPacket } from './packet.js';
7
- export { UnknownPacket } from './packet.js';
4
+ import { Packet } from "./asset/packet.js";
5
+ import { BufferReader } from "./asset/utils.js";
6
+ import { UnknownPacket } from "./packet.js";
7
+ export { UnknownPacket } from "./packet.js";
8
8
  /**
9
9
  * ArkadeMagic is the 3-byte magic prefix ("ARK") that identifies an OP_RETURN
10
10
  * output as an Arkade extension blob.
@@ -1,5 +1,5 @@
1
- import { Transaction } from './utils/transaction.js';
2
- import { P2A } from './utils/anchor.js';
1
+ import { Transaction } from "./utils/transaction.js";
2
+ import { P2A } from "./utils/anchor.js";
3
3
  /**
4
4
  * Build a forfeit transaction that spends the provided inputs to a single forfeit output.
5
5
  *
@@ -3,10 +3,10 @@ export function isBatchSignable(identity) {
3
3
  return ("signMultiple" in identity &&
4
4
  typeof identity.signMultiple === "function");
5
5
  }
6
- export * from './singleKey.js';
7
- export { SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, } from './seedIdentity.js';
8
- export * from './serialize.js';
6
+ export * from "./singleKey.js";
7
+ export { SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, } from "./seedIdentity.js";
8
+ export * from "./serialize.js";
9
9
  // Descriptor utilities
10
- export { isDescriptor, normalizeToDescriptor, extractPubKey, parseHDDescriptor, } from './descriptor.js';
10
+ export { isDescriptor, normalizeToDescriptor, extractPubKey, parseHDDescriptor, } from "./descriptor.js";
11
11
  // Static descriptor provider (wrapper for legacy Identity)
12
- export { StaticDescriptorProvider } from './staticDescriptorProvider.js';
12
+ export { StaticDescriptorProvider } from "./staticDescriptorProvider.js";
@@ -3,10 +3,10 @@ import { wordlist } from "@scure/bip39/wordlists/english.js";
3
3
  import { pubECDSA, pubSchnorr } from "@scure/btc-signer/utils.js";
4
4
  import { SigHash } from "@scure/btc-signer";
5
5
  import { hex } from "@scure/base";
6
- import { TreeSignerSession } from '../tree/signingSession.js';
6
+ import { TreeSignerSession } from "../tree/signingSession.js";
7
7
  import { schnorr, signAsync } from "@noble/secp256k1";
8
8
  import { HDKey, expand, networks, scriptExpressions, } from "@bitcoinerlab/descriptors-scure";
9
- import { descriptorIsOurs, isMainnetDescriptor } from './descriptor.js';
9
+ import { descriptorIsOurs, isMainnetDescriptor } from "./descriptor.js";
10
10
  const ALL_SIGHASH = Object.values(SigHash).filter((x) => typeof x === "number");
11
11
  /**
12
12
  * Secret-bearing state for seed-backed identities, held off the public
@@ -1,6 +1,6 @@
1
1
  import { hex } from "@scure/base";
2
- import { SingleKey, ReadonlySingleKey } from './singleKey.js';
3
- import { SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, serializeSeedOwnedSigningIdentity, serializeSeedOwnedReadonlyIdentity, } from './seedIdentity.js';
2
+ import { SingleKey, ReadonlySingleKey } from "./singleKey.js";
3
+ import { SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, serializeSeedOwnedSigningIdentity, serializeSeedOwnedReadonlyIdentity, } from "./seedIdentity.js";
4
4
  /** Type guard — true for signing envelopes, false for readonly envelopes. */
5
5
  export function isSigningSerialized(s) {
6
6
  return (s.type === "single-key" || s.type === "seed" || s.type === "mnemonic");
@@ -1,7 +1,7 @@
1
1
  import { pubECDSA, pubSchnorr, randomPrivateKeyBytes, } from "@scure/btc-signer/utils.js";
2
2
  import { SigHash } from "@scure/btc-signer";
3
3
  import { hex } from "@scure/base";
4
- import { TreeSignerSession } from '../tree/signingSession.js';
4
+ import { TreeSignerSession } from "../tree/signingSession.js";
5
5
  import { schnorr, signAsync } from "@noble/secp256k1";
6
6
  const ALL_SIGHASH = Object.values(SigHash).filter((x) => typeof x === "number");
7
7
  /**
@@ -1,6 +1,6 @@
1
1
  import { hex } from "@scure/base";
2
- import { isBatchSignable } from './index.js';
3
- import { normalizeToDescriptor, extractPubKey } from './descriptor.js';
2
+ import { isBatchSignable } from "./index.js";
3
+ import { normalizeToDescriptor, extractPubKey } from "./descriptor.js";
4
4
  /**
5
5
  * Wraps a legacy Identity (single-key) as a DescriptorProvider.
6
6
  * The descriptor is always a simple tr(pubkey) format.