@arkade-os/sdk 0.4.70 → 0.4.71

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 (73) hide show
  1. package/dist/adapters/expo.cjs +5 -5
  2. package/dist/adapters/expo.d.cts +2 -2
  3. package/dist/adapters/expo.d.ts +2 -2
  4. package/dist/adapters/expo.js +3 -3
  5. package/dist/adapters/indexedDB.cjs +5 -5
  6. package/dist/adapters/indexedDB.js +4 -4
  7. package/dist/{asyncStorageTaskQueue-BgUJN-3X.d.ts → asyncStorageTaskQueue-CjKAUiuj.d.ts} +2 -2
  8. package/dist/{asyncStorageTaskQueue-Cstx6hS7.d.cts → asyncStorageTaskQueue-DgXf4iuU.d.cts} +2 -2
  9. package/dist/{chunk-TXSF2DKX.js → chunk-2ZX4Z2IP.js} +3 -3
  10. package/dist/{chunk-TXSF2DKX.js.map → chunk-2ZX4Z2IP.js.map} +1 -1
  11. package/dist/{chunk-57636V35.cjs → chunk-5J5PDZRR.cjs} +3 -3
  12. package/dist/{chunk-57636V35.cjs.map → chunk-5J5PDZRR.cjs.map} +1 -1
  13. package/dist/{chunk-B73Q75IL.cjs → chunk-7PHMT3T4.cjs} +10 -10
  14. package/dist/{chunk-B73Q75IL.cjs.map → chunk-7PHMT3T4.cjs.map} +1 -1
  15. package/dist/{chunk-6UM55KPZ.js → chunk-ALZ2CZ3T.js} +3 -3
  16. package/dist/{chunk-6UM55KPZ.js.map → chunk-ALZ2CZ3T.js.map} +1 -1
  17. package/dist/{chunk-JVHO6XHG.js → chunk-E5JNYFOF.js} +272 -31
  18. package/dist/chunk-E5JNYFOF.js.map +1 -0
  19. package/dist/{chunk-3KW4TWP2.cjs → chunk-FM263GKH.cjs} +17 -17
  20. package/dist/{chunk-3KW4TWP2.cjs.map → chunk-FM263GKH.cjs.map} +1 -1
  21. package/dist/{chunk-JJ7AXR4O.cjs → chunk-I7ZNWBBU.cjs} +17 -17
  22. package/dist/{chunk-JJ7AXR4O.cjs.map → chunk-I7ZNWBBU.cjs.map} +1 -1
  23. package/dist/{chunk-XTCOSZ34.cjs → chunk-MK5EPTTB.cjs} +704 -462
  24. package/dist/chunk-MK5EPTTB.cjs.map +1 -0
  25. package/dist/{chunk-IUFTICRY.js → chunk-NOWVA5CM.js} +4 -4
  26. package/dist/{chunk-IUFTICRY.js.map → chunk-NOWVA5CM.js.map} +1 -1
  27. package/dist/{chunk-3OKEUDHU.cjs → chunk-P6EXRY5L.cjs} +49 -49
  28. package/dist/{chunk-3OKEUDHU.cjs.map → chunk-P6EXRY5L.cjs.map} +1 -1
  29. package/dist/{chunk-UG3EZDLF.js → chunk-SCSLCU66.js} +4 -4
  30. package/dist/{chunk-UG3EZDLF.js.map → chunk-SCSLCU66.js.map} +1 -1
  31. package/dist/{chunk-F5E7LI6G.js → chunk-ZT3EM4CE.js} +3 -3
  32. package/dist/{chunk-F5E7LI6G.js.map → chunk-ZT3EM4CE.js.map} +1 -1
  33. package/dist/contracts/handlers/index.cjs +9 -9
  34. package/dist/contracts/handlers/index.d.cts +3 -3
  35. package/dist/contracts/handlers/index.d.ts +3 -3
  36. package/dist/contracts/handlers/index.js +2 -2
  37. package/dist/{delegate-BPdzTbwN.d.ts → delegate-CKJdsC99.d.ts} +1 -1
  38. package/dist/{delegate-DrwIar11.d.cts → delegate-D-gEEqrP.d.cts} +1 -1
  39. package/dist/{hdWalletCapable-DyxCiNVE.d.ts → hdWalletCapable-BJ4pvkai.d.ts} +2 -2
  40. package/dist/{hdWalletCapable-D4WH35z0.d.cts → hdWalletCapable-CwLPmWct.d.cts} +2 -2
  41. package/dist/{index-BqhpAqqj.d.cts → index-BE1uFXrV.d.cts} +2 -2
  42. package/dist/{index-TZJvbIaA.d.ts → index-Boppyqav.d.ts} +2 -2
  43. package/dist/{index-dWRqYSdS.d.ts → index-CyGnhCSS.d.cts} +98 -2
  44. package/dist/{index-dWRqYSdS.d.cts → index-CyGnhCSS.d.ts} +98 -2
  45. package/dist/index.cjs +301 -297
  46. package/dist/index.d.cts +46 -11
  47. package/dist/index.d.ts +46 -11
  48. package/dist/index.js +4 -4
  49. package/dist/repositories/realm/index.cjs +19 -19
  50. package/dist/repositories/realm/index.d.cts +2 -2
  51. package/dist/repositories/realm/index.d.ts +2 -2
  52. package/dist/repositories/realm/index.js +5 -5
  53. package/dist/repositories/sqlite/index.cjs +18 -18
  54. package/dist/repositories/sqlite/index.d.cts +2 -2
  55. package/dist/repositories/sqlite/index.d.ts +2 -2
  56. package/dist/repositories/sqlite/index.js +5 -5
  57. package/dist/{taskRunner-CzYKyJ9c.d.cts → taskRunner-CjmMH_rW.d.cts} +2 -2
  58. package/dist/{taskRunner-D2fnbqYw.d.ts → taskRunner-l3zyfW_Q.d.ts} +2 -2
  59. package/dist/wallet/expo/background.cjs +14 -14
  60. package/dist/wallet/expo/background.d.cts +3 -3
  61. package/dist/wallet/expo/background.d.ts +3 -3
  62. package/dist/wallet/expo/background.js +6 -6
  63. package/dist/wallet/expo/index.cjs +14 -14
  64. package/dist/wallet/expo/index.d.cts +4 -4
  65. package/dist/wallet/expo/index.d.ts +4 -4
  66. package/dist/wallet/expo/index.js +5 -5
  67. package/dist/worker/expo/index.cjs +9 -9
  68. package/dist/worker/expo/index.d.cts +4 -4
  69. package/dist/worker/expo/index.d.ts +4 -4
  70. package/dist/worker/expo/index.js +5 -5
  71. package/package.json +1 -1
  72. package/dist/chunk-JVHO6XHG.js.map +0 -1
  73. package/dist/chunk-XTCOSZ34.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
- import { AssetId, AssetGroup, AssetInput, AssetOutput, Metadata, Packet, BufferReader, BufferWriter, AssetRef, RestIndexerProvider } from './chunk-F5E7LI6G.js';
2
- import { witnessRefToBytes, validateProgram, toASM, stringifyArtifact, serializeArkadeContractParams, resolveAsm, parseArtifact, getOpcodeValue, getOpcodeName, fromASM, deserializeArkadeContractParams, computeArkadeScriptPublicKey, bytesToASM, asmToBytes, arkadeWitnessHash, arkadeScriptHash, SUPPORTED_PROGRAM_VERSION, OPCODE_VALUES, OPCODE_NAMES, bignum_exports, ArkadeScript, ArkadeProgramScript, ARKADE_OPS, ARKADE_OPCODE_VALUES, ARKADE_OPCODE_NAMES, ARKADE_OPCODES, ARKADE_OP, toXOnly, inputName, contractHandlers, isMainnetDescriptor, descriptorIsOurs, deriveDescriptorLeafPubKey, deriveDescriptorLeafCompressedPubKey, parseHDDescriptor, identityDescriptor, DefaultVtxo, speculativeReceiveMetadata, DelegateVtxo, WALLET_RECEIVE_SOURCE, BoardingContractHandler } from './chunk-6UM55KPZ.js';
3
- import { VtxoScript, Transaction, isRecoverable, CSVMultisigTapscript, DEFAULT_NETWORK, resolveEmulatorPubkey, hasTerminalSpend, getNormalizedVtxos, setArkPsbtField, PrevArkTxField, ConditionWitness, craftToSpendTx, ArkAddress, isVirtualCoin, getArkPsbtFields, CosignerPublicKey, ServerResponseMismatchError, OP_RETURN_EMPTY_PKSCRIPT, canSweepOnchain, sequenceToTimelock, decodeTapscript, scriptFromTapLeafScript, CLTVMultisigTapscript, VtxoTaprootTree, timelockToSequence, assertAllowedSighashTypes, baseFetch, Intent, rateGate, DEFAULT_NETWORK_NAME, formatSighash, normalizeVtxo, getSequence, toBatchExpiry, maybeArkError, isArkError, ArkErrorName, toOffchainInputFeeParams, canRecoverOnchain, getNetwork, MultisigTapscript, isEventSourceError, isEventSourceUnavailableError, isRetryableProviderError, getAllNormalizedVtxos, DEFAULT_PAGE_SIZE, RestArkProvider, toVirtualStatus, ArkError, TapTreeCoder, resolveTimeHeight, canSpendOffchain, parseLegacyExpiry, isExpired, PrevoutTxField, DEFAULT_ARKADE_SERVER_URL, ProviderUnavailableError, networks as networks$1, isPastExpiry, fetchVtxoCreatedAtByTxid } from './chunk-TXSF2DKX.js';
1
+ import { AssetId, AssetGroup, AssetInput, AssetOutput, Metadata, Packet, BufferReader, BufferWriter, AssetRef, RestIndexerProvider } from './chunk-ZT3EM4CE.js';
2
+ import { witnessRefToBytes, validateProgram, toASM, stringifyArtifact, serializeArkadeContractParams, resolveAsm, parseArtifact, getOpcodeValue, getOpcodeName, fromASM, deserializeArkadeContractParams, computeArkadeScriptPublicKey, bytesToASM, asmToBytes, arkadeWitnessHash, arkadeScriptHash, SUPPORTED_PROGRAM_VERSION, OPCODE_VALUES, OPCODE_NAMES, bignum_exports, ArkadeScript, ArkadeProgramScript, ARKADE_OPS, ARKADE_OPCODE_VALUES, ARKADE_OPCODE_NAMES, ARKADE_OPCODES, ARKADE_OP, toXOnly, inputName, contractHandlers, isMainnetDescriptor, descriptorIsOurs, deriveDescriptorLeafPubKey, deriveDescriptorLeafCompressedPubKey, parseHDDescriptor, identityDescriptor, DefaultVtxo, speculativeReceiveMetadata, DelegateVtxo, WALLET_RECEIVE_SOURCE, BoardingContractHandler } from './chunk-ALZ2CZ3T.js';
3
+ import { VtxoScript, Transaction, isRecoverable, CSVMultisigTapscript, DEFAULT_NETWORK, resolveEmulatorPubkey, hasTerminalSpend, getNormalizedVtxos, setArkPsbtField, PrevArkTxField, ConditionWitness, craftToSpendTx, ArkAddress, isVirtualCoin, getArkPsbtFields, CosignerPublicKey, ServerResponseMismatchError, OP_RETURN_EMPTY_PKSCRIPT, canSweepOnchain, sequenceToTimelock, decodeTapscript, scriptFromTapLeafScript, CLTVMultisigTapscript, VtxoTaprootTree, timelockToSequence, assertAllowedSighashTypes, baseFetch, Intent, rateGate, DEFAULT_NETWORK_NAME, formatSighash, normalizeVtxo, getSequence, toBatchExpiry, maybeArkError, isArkError, ArkErrorName, toOffchainInputFeeParams, canRecoverOnchain, getNetwork, MultisigTapscript, isEventSourceError, isEventSourceUnavailableError, getAllNormalizedVtxos, isPastExpiry, isRetryableProviderError, DEFAULT_PAGE_SIZE, RestArkProvider, toVirtualStatus, ArkError, TapTreeCoder, resolveTimeHeight, canSpendOffchain, parseLegacyExpiry, isExpired, PrevoutTxField, DEFAULT_ARKADE_SERVER_URL, ProviderUnavailableError, networks as networks$1, fetchVtxoCreatedAtByTxid } from './chunk-2ZX4Z2IP.js';
4
4
  import { __export } from './chunk-NSBPE2FW.js';
5
5
  import { sha256 as sha256$1, equalBytes, hash160, sha256x2, concatBytes, randomPrivateKeyBytes, pubECDSA, pubSchnorr } from '@scure/btc-signer/utils.js';
6
6
  import { SigHash, Script, OP, OutScript, Address, RawWitness, p2tr, p2wpkh, TaprootControlBlock, DEFAULT_SEQUENCE, Transaction as Transaction$2 } from '@scure/btc-signer';
@@ -3618,6 +3618,26 @@ function claimWithPreimageIdentity(identity, preimage) {
3618
3618
  }
3619
3619
  };
3620
3620
  }
3621
+
3622
+ // src/contracts/types.ts
3623
+ function watchStateOf(contract) {
3624
+ return contract.watch ?? "watched";
3625
+ }
3626
+ function isWatchedContract(contract) {
3627
+ return watchStateOf(contract) !== "retained";
3628
+ }
3629
+ function hasCandidates(handler) {
3630
+ return !!handler && typeof handler.candidatesAt === "function";
3631
+ }
3632
+ function isDiscoverable(handler) {
3633
+ return !!handler && typeof handler.discoverAt === "function";
3634
+ }
3635
+ function isTapscriptDeriving(handler) {
3636
+ return !!handler && typeof handler.deriveTapscripts === "function";
3637
+ }
3638
+ function isContractVtxoEvent(event) {
3639
+ return "contract" in event && event.contract !== void 0;
3640
+ }
3621
3641
  var AmountVariableName = "amount";
3622
3642
  var ExpiryVariableName = "expiry";
3623
3643
  var BirthVariableName = "birth";
@@ -3773,23 +3793,6 @@ function parseProgram(text, env) {
3773
3793
  }
3774
3794
  return { program, text };
3775
3795
  }
3776
-
3777
- // src/contracts/types.ts
3778
- function watchStateOf(contract) {
3779
- return contract.watch ?? "watched";
3780
- }
3781
- function isWatchedContract(contract) {
3782
- return watchStateOf(contract) !== "retained";
3783
- }
3784
- function hasCandidates(handler) {
3785
- return !!handler && typeof handler.candidatesAt === "function";
3786
- }
3787
- function isDiscoverable(handler) {
3788
- return !!handler && typeof handler.discoverAt === "function";
3789
- }
3790
- function isTapscriptDeriving(handler) {
3791
- return !!handler && typeof handler.deriveTapscripts === "function";
3792
- }
3793
3796
  var DUST_AMOUNT = 546;
3794
3797
  var FALLBACK_WALLET_DUST_AMOUNT = 330n;
3795
3798
  function getDustAmount(wallet) {
@@ -5339,7 +5342,7 @@ var VtxoManager = class _VtxoManager {
5339
5342
  this.wallet.getAddress()
5340
5343
  ]);
5341
5344
  const stopWatching = contractManager.onContractEvent((event) => {
5342
- if (event.type !== "vtxo_received") {
5345
+ if (event.type !== "vtxo_received" || !isContractVtxoEvent(event)) {
5343
5346
  return;
5344
5347
  }
5345
5348
  const msSinceLastRenewal = Date.now() - this.lastRenewalTimestamp;
@@ -8711,6 +8714,8 @@ var DEFAULT_CONTRACT_WATCHER_CONFIG = {
8711
8714
  var ContractWatcher = class {
8712
8715
  config;
8713
8716
  contracts = /* @__PURE__ */ new Map();
8717
+ /** In-memory and process-lifetime; never persisted. */
8718
+ watchedScripts = /* @__PURE__ */ new Map();
8714
8719
  subscriptionId;
8715
8720
  abortController;
8716
8721
  isWatching = false;
@@ -8831,6 +8836,47 @@ var ContractWatcher = class {
8831
8836
  getWatchedContracts() {
8832
8837
  return this.getAllContracts().filter(isWatchedContract);
8833
8838
  }
8839
+ /**
8840
+ * Every script the subscription must carry. Wider than
8841
+ * {@link getWatchedContracts}, which stays the sync scope.
8842
+ */
8843
+ getSubscribedScripts() {
8844
+ const scripts = new Set(this.getWatchedContracts().map((c) => c.script));
8845
+ for (const script of this.watchedScripts.keys()) {
8846
+ scripts.add(script);
8847
+ }
8848
+ return Array.from(scripts);
8849
+ }
8850
+ /** @see IContractManager.watchScript for the delivery and filter contract. */
8851
+ async addWatchedScript(script, options) {
8852
+ const existing = this.watchedScripts.get(script);
8853
+ if (existing) {
8854
+ if (options?.label !== void 0) existing.label = options.label;
8855
+ return;
8856
+ }
8857
+ this.watchedScripts.set(script, {
8858
+ label: options?.label,
8859
+ lastKnownVtxos: /* @__PURE__ */ new Map()
8860
+ });
8861
+ if (this.isWatching) {
8862
+ await this.pollWatchedScripts([script]);
8863
+ await this.tryUpdateSubscription();
8864
+ }
8865
+ }
8866
+ /** Stop watching a script added by {@link addWatchedScript}. */
8867
+ async removeWatchedScript(script) {
8868
+ if (!this.watchedScripts.delete(script)) return;
8869
+ if (this.isWatching) {
8870
+ await this.tryUpdateSubscription();
8871
+ }
8872
+ }
8873
+ /** Every script registered via {@link addWatchedScript}. */
8874
+ getWatchedScripts() {
8875
+ return Array.from(this.watchedScripts.entries()).map(([script, state]) => ({
8876
+ script,
8877
+ label: state.label
8878
+ }));
8879
+ }
8834
8880
  /**
8835
8881
  * Get virtual outputs for contracts, grouped by contract script.
8836
8882
  * @see WalletRepository for `repo`
@@ -9022,8 +9068,72 @@ var ContractWatcher = class {
9022
9068
  }
9023
9069
  async pollAllContracts() {
9024
9070
  const scripts = this.getWatchedContracts().map((c) => c.script);
9071
+ if (scripts.length > 0) {
9072
+ await this.pollContracts(scripts);
9073
+ }
9074
+ await this.pollWatchedScripts(Array.from(this.watchedScripts.keys()));
9075
+ }
9076
+ /**
9077
+ * Poll watch-only scripts against the indexer and emit the delta.
9078
+ *
9079
+ * Separate from {@link pollContracts} because that one diffs the wallet
9080
+ * repository, which is permanently empty for a script this wallet does not
9081
+ * own — reusing it would report every live output as spent on every tick.
9082
+ * Not a second poll loop: same timer and callers, different source.
9083
+ */
9084
+ async pollWatchedScripts(candidates) {
9085
+ if (!this.eventCallback) return;
9086
+ const scripts = candidates.filter((s) => {
9087
+ const state = this.contracts.get(s);
9088
+ return this.watchedScripts.has(s) && (state === void 0 || !isWatchedContract(state.contract));
9089
+ });
9025
9090
  if (scripts.length === 0) return;
9026
- await this.pollContracts(scripts);
9091
+ const now = Date.now();
9092
+ let current;
9093
+ try {
9094
+ current = await getAllNormalizedVtxos(this.config.indexerProvider, scripts, {
9095
+ spendableOnly: true
9096
+ });
9097
+ } catch (error) {
9098
+ console.error("ContractWatcher watch-only poll failed:", error);
9099
+ return;
9100
+ }
9101
+ const byScript = /* @__PURE__ */ new Map();
9102
+ for (const vtxo of current) {
9103
+ let bucket = byScript.get(vtxo.script);
9104
+ if (!bucket) {
9105
+ bucket = [];
9106
+ byScript.set(vtxo.script, bucket);
9107
+ }
9108
+ bucket.push(vtxo);
9109
+ }
9110
+ for (const script of scripts) {
9111
+ const state = this.watchedScripts.get(script);
9112
+ if (!state) continue;
9113
+ const currentVtxos = byScript.get(script) || [];
9114
+ const currentKeys = new Set(currentVtxos.map((v) => `${v.txid}:${v.vout}`));
9115
+ const newVtxos = [];
9116
+ for (const vtxo of currentVtxos) {
9117
+ const key = `${vtxo.txid}:${vtxo.vout}`;
9118
+ if (!state.lastKnownVtxos.has(key)) {
9119
+ newVtxos.push(vtxo);
9120
+ state.lastKnownVtxos.set(key, vtxo);
9121
+ }
9122
+ }
9123
+ const spentVtxos = [];
9124
+ for (const [key, vtxo] of state.lastKnownVtxos) {
9125
+ if (!currentKeys.has(key)) {
9126
+ spentVtxos.push(vtxo);
9127
+ state.lastKnownVtxos.delete(key);
9128
+ }
9129
+ }
9130
+ if (newVtxos.length > 0) {
9131
+ this.emitWatchedScriptEvent(script, newVtxos, "vtxo_received", now);
9132
+ }
9133
+ if (spentVtxos.length > 0) {
9134
+ this.emitWatchedScriptEvent(script, spentVtxos, "vtxo_spent", now);
9135
+ }
9136
+ }
9027
9137
  }
9028
9138
  /**
9029
9139
  * Poll specific contracts and emit events for changes.
@@ -9124,10 +9234,10 @@ var ContractWatcher = class {
9124
9234
  /**
9125
9235
  * Update the subscription with scripts that should be watched.
9126
9236
  *
9127
- * @see getWatchedContracts
9237
+ * @see getSubscribedScripts
9128
9238
  */
9129
9239
  async updateSubscription() {
9130
- const scriptsToWatch = this.getWatchedContracts().map((c) => c.script);
9240
+ const scriptsToWatch = this.getSubscribedScripts();
9131
9241
  if (scriptsToWatch.length === 0) {
9132
9242
  if (this.subscriptionId) {
9133
9243
  try {
@@ -9211,16 +9321,26 @@ var ContractWatcher = class {
9211
9321
  */
9212
9322
  processSubscriptionVtxos(vtxos, eventType, timestamp) {
9213
9323
  const byContract = /* @__PURE__ */ new Map();
9324
+ const byWatchedScript = /* @__PURE__ */ new Map();
9214
9325
  let unknownScript = 0;
9326
+ const now = { timestamp: /* @__PURE__ */ new Date() };
9215
9327
  for (const vtxo of vtxos) {
9216
- if (!this.contracts.has(vtxo.script)) {
9328
+ const state = this.contracts.get(vtxo.script);
9329
+ const watchOnly = this.watchedScripts.has(vtxo.script);
9330
+ const preferContract = state !== void 0 && (!watchOnly || isWatchedContract(state.contract));
9331
+ const target = preferContract ? byContract : watchOnly ? byWatchedScript : void 0;
9332
+ if (!target) {
9217
9333
  unknownScript++;
9218
9334
  continue;
9219
9335
  }
9220
- let bucket = byContract.get(vtxo.script);
9336
+ if (target === byWatchedScript && eventType === "vtxo_received") {
9337
+ const n = normalizeVtxo(vtxo);
9338
+ if (hasTerminalSpend(n) || n.isSwept || isPastExpiry(n, now)) continue;
9339
+ }
9340
+ let bucket = target.get(vtxo.script);
9221
9341
  if (!bucket) {
9222
9342
  bucket = [];
9223
- byContract.set(vtxo.script, bucket);
9343
+ target.set(vtxo.script, bucket);
9224
9344
  }
9225
9345
  bucket.push(vtxo);
9226
9346
  }
@@ -9243,6 +9363,29 @@ var ContractWatcher = class {
9243
9363
  }
9244
9364
  this.emitVtxoEvent(contractScript, bucketVtxos, eventType, timestamp);
9245
9365
  }
9366
+ for (const [script, bucketVtxos] of byWatchedScript) {
9367
+ const state = this.watchedScripts.get(script);
9368
+ if (state) {
9369
+ for (const vtxo of bucketVtxos) {
9370
+ const key = `${vtxo.txid}:${vtxo.vout}`;
9371
+ if (eventType === "vtxo_received") {
9372
+ state.lastKnownVtxos.set(key, vtxo);
9373
+ } else {
9374
+ state.lastKnownVtxos.delete(key);
9375
+ }
9376
+ }
9377
+ }
9378
+ this.emitWatchedScriptEvent(script, bucketVtxos, eventType, timestamp);
9379
+ }
9380
+ }
9381
+ /** As {@link emitVtxoEvent}, less the `contract` and the annotation. */
9382
+ emitWatchedScriptEvent(script, vtxos, eventType, timestamp) {
9383
+ if (!this.eventCallback) return;
9384
+ if (eventType === "vtxo_received") {
9385
+ this.eventCallback({ type: "vtxo_received", contractScript: script, vtxos, timestamp });
9386
+ return;
9387
+ }
9388
+ this.eventCallback({ type: "vtxo_spent", contractScript: script, vtxos, timestamp });
9246
9389
  }
9247
9390
  /**
9248
9391
  * Emit a virtual output event for a contract.
@@ -10398,6 +10541,18 @@ var ContractManager = class _ContractManager {
10398
10541
  async isWatching() {
10399
10542
  return this.watcher.isCurrentlyWatching();
10400
10543
  }
10544
+ /** @see IContractManager.watchScript */
10545
+ async watchScript(script, options) {
10546
+ await this.watcher.addWatchedScript(script, options);
10547
+ }
10548
+ /** @see IContractManager.unwatchScript */
10549
+ async unwatchScript(script) {
10550
+ await this.watcher.removeWatchedScript(script);
10551
+ }
10552
+ /** @see IContractManager.getWatchedScripts */
10553
+ async getWatchedScripts() {
10554
+ return this.watcher.getWatchedScripts();
10555
+ }
10401
10556
  /**
10402
10557
  * Emit an event to all registered callbacks.
10403
10558
  */
@@ -10418,11 +10573,15 @@ var ContractManager = class _ContractManager {
10418
10573
  try {
10419
10574
  switch (event.type) {
10420
10575
  // Delta-sync only the changed virtual outputs for this contract.
10576
+ // The guard below is the ownership boundary: a watch-only script
10577
+ // reports these same types, so it must precede `syncContracts`.
10421
10578
  case "vtxo_received":
10579
+ if (!isContractVtxoEvent(event)) break;
10422
10580
  await this.syncContracts({ contracts: [event.contract] });
10423
10581
  this.markSyncOnline();
10424
10582
  break;
10425
10583
  case "vtxo_spent":
10584
+ if (!isContractVtxoEvent(event)) break;
10426
10585
  await this.syncContracts({ contracts: [event.contract] });
10427
10586
  this.markSyncOnline();
10428
10587
  if (this.config.onVtxosSpent) {
@@ -13349,7 +13508,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13349
13508
  const cm = await this.getContractManager();
13350
13509
  let annotationQueue = Promise.resolve();
13351
13510
  indexerStopFunc = cm.onContractEvent((event) => {
13352
- if (event.type !== "vtxo_received" && event.type !== "vtxo_spent") {
13511
+ if (!isContractVtxoEvent(event)) {
13353
13512
  return;
13354
13513
  }
13355
13514
  if (event.contract.type !== "default" && event.contract.type !== "delegate") {
@@ -17421,6 +17580,9 @@ var DelegateNotConfiguredError = class extends Error {
17421
17580
  };
17422
17581
  var DelegatorNotConfiguredError = DelegateNotConfiguredError;
17423
17582
  var DEFAULT_MESSAGE_TAG = "WALLET_UPDATER";
17583
+ function unsupportedByManager(method) {
17584
+ return new Error(`Contract manager does not support ${method}`);
17585
+ }
17424
17586
  var serializeMigrationVtxoRef = (ref) => ({
17425
17587
  txid: ref.txid,
17426
17588
  vout: ref.vout,
@@ -17805,6 +17967,39 @@ var WalletMessageHandler = class {
17805
17967
  payload: { contracts }
17806
17968
  });
17807
17969
  }
17970
+ case "WATCH_SCRIPT": {
17971
+ const manager = await this.readonlyWallet.getContractManager();
17972
+ if (!manager.watchScript) throw unsupportedByManager("watchScript");
17973
+ await manager.watchScript(message.payload.script, {
17974
+ label: message.payload.label
17975
+ });
17976
+ return this.tagged({
17977
+ id,
17978
+ type: "SCRIPT_WATCHED",
17979
+ payload: { script: message.payload.script }
17980
+ });
17981
+ }
17982
+ case "UNWATCH_SCRIPT": {
17983
+ const manager = await this.readonlyWallet.getContractManager();
17984
+ if (!manager.unwatchScript) throw unsupportedByManager("unwatchScript");
17985
+ await manager.unwatchScript(message.payload.script);
17986
+ return this.tagged({
17987
+ id,
17988
+ type: "SCRIPT_UNWATCHED",
17989
+ payload: { script: message.payload.script }
17990
+ });
17991
+ }
17992
+ case "GET_WATCHED_SCRIPTS": {
17993
+ const manager = await this.readonlyWallet.getContractManager();
17994
+ if (!manager.getWatchedScripts) {
17995
+ throw unsupportedByManager("getWatchedScripts");
17996
+ }
17997
+ return this.tagged({
17998
+ id,
17999
+ type: "WATCHED_SCRIPTS",
18000
+ payload: { scripts: await manager.getWatchedScripts() }
18001
+ });
18002
+ }
17808
18003
  case "ANNOTATE_VTXOS": {
17809
18004
  const manager = await this.readonlyWallet.getContractManager();
17810
18005
  const annotated = await manager.annotateVtxos(message.payload.vtxos);
@@ -18608,6 +18803,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
18608
18803
  GET_TRANSACTION_HISTORY: 2e4,
18609
18804
  GET_CONTRACTS: 2e4,
18610
18805
  GET_CONTRACTS_WITH_VTXOS: 2e4,
18806
+ GET_WATCHED_SCRIPTS: 1e4,
18611
18807
  ANNOTATE_VTXOS: 2e4,
18612
18808
  GET_SPENDABLE_PATHS: 2e4,
18613
18809
  GET_ALL_SPENDING_PATHS: 2e4,
@@ -18644,6 +18840,10 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
18644
18840
  SIGN_TRANSACTION: 3e4,
18645
18841
  CREATE_CONTRACT: 3e4,
18646
18842
  UPDATE_CONTRACT: 3e4,
18843
+ // Registering a watch is an in-memory map write plus one subscription
18844
+ // update — no indexer round trip on the request path.
18845
+ WATCH_SCRIPT: 1e4,
18846
+ UNWATCH_SCRIPT: 1e4,
18647
18847
  DELETE_CONTRACT: 1e4,
18648
18848
  REFRESH_VTXOS: 3e4,
18649
18849
  REFRESH_OUTPOINTS: 3e4
@@ -18664,6 +18864,7 @@ var DEDUPABLE_REQUEST_TYPES = /* @__PURE__ */ new Set([
18664
18864
  "GET_SPENDABLE_VTXOS",
18665
18865
  "GET_CONTRACTS",
18666
18866
  "GET_CONTRACTS_WITH_VTXOS",
18867
+ "GET_WATCHED_SCRIPTS",
18667
18868
  "ANNOTATE_VTXOS",
18668
18869
  "GET_SPENDABLE_PATHS",
18669
18870
  "GET_ALL_SPENDING_PATHS",
@@ -19372,6 +19573,46 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19372
19573
  throw new Error("Failed to get contracts with vtxos");
19373
19574
  }
19374
19575
  },
19576
+ async watchScript(script, options) {
19577
+ const message = {
19578
+ type: "WATCH_SCRIPT",
19579
+ id: getRandomId(),
19580
+ tag: messageTag,
19581
+ payload: { script, label: options?.label }
19582
+ };
19583
+ try {
19584
+ await sendContractMessage(message);
19585
+ } catch (e) {
19586
+ throw new Error("Failed to watch script");
19587
+ }
19588
+ },
19589
+ async unwatchScript(script) {
19590
+ const message = {
19591
+ type: "UNWATCH_SCRIPT",
19592
+ id: getRandomId(),
19593
+ tag: messageTag,
19594
+ payload: { script }
19595
+ };
19596
+ try {
19597
+ await sendContractMessage(message);
19598
+ } catch (e) {
19599
+ throw new Error("Failed to unwatch script");
19600
+ }
19601
+ },
19602
+ async getWatchedScripts() {
19603
+ const message = {
19604
+ type: "GET_WATCHED_SCRIPTS",
19605
+ id: getRandomId(),
19606
+ tag: messageTag,
19607
+ payload: {}
19608
+ };
19609
+ try {
19610
+ const response = await sendContractMessage(message);
19611
+ return response.payload.scripts;
19612
+ } catch (e) {
19613
+ throw new Error("Failed to get watched scripts");
19614
+ }
19615
+ },
19375
19616
  getSyncState() {
19376
19617
  return syncState;
19377
19618
  },
@@ -23888,6 +24129,6 @@ function createDefaultPaymentRouter(wallet) {
23888
24129
  (*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
23889
24130
  */
23890
24131
 
23891
- export { ARKADE_MAGIC, ARKADE_SALTED_PREIMAGE_TAG, ARKADE_SWAP_PREIMAGE_TAG, ASSET_CARRIER_SATS, AbortError, ActivityRegistry, AmbiguousRouteError, ArkNote, ArkadeCash, ArkadeCashCreateError, AssetManager, BIP21, BIP21Error, BIP322, BLOCKED_UPGRADE_TIMEOUT_MS, Batch, CachingArkProvider, ChainedTxType, ConnectionDisposedError, ContractManager, ContractRepositoryImpl, ContractWatcher, DB_VERSION, DEFAULT_MESSAGE_TIMEOUTS, DEFAULT_MIN_BATCH_EXPIRY_SECONDS, DEFAULT_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, DatabaseUpgradeBlockedError, DelegateManagerImpl, DelegateNotConfiguredError, DelegatorManagerImpl, DelegatorNotConfiguredError, DescriptorIdentity, DescriptorSigningProviderMissingError, DustChangeError, ELECTRUM_TCP_HOST, ELECTRUM_WS_URL, ESPLORA_URL, ElectrumOnchainProvider, EmulatorPacket, EsploraProvider, Estimator, Extension, ExtensionNotFoundError, ForeignDescriptorError, HDDescriptorProvider, INTENT_TERMINAL_STATES, InMemoryContractRepository, InMemoryIntentRepository, InMemoryVirtualTxRepository, InMemoryWalletRepository, IndexedDBContractRepository, IndexedDBIntentRepository, IndexedDBVirtualTxRepository, IndexedDBWalletRepository, MAX_USED_SIGNING_DESCRIPTORS_LOOK_AHEAD, MESSAGE_BUS_INITIALIZING, MESSAGE_BUS_NOT_INITIALIZED, MIGRATION_KEY, MUTINYNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, MessageBus, MessageBusInitializingError, MessageBusNotInitializedError, MissingSigningDescriptorError, MnemonicIdentity, OnchainWallet, P2A, PaymentRouter, PrevTxUnavailableError, REGTEST_MIN_BATCH_EXPIRY_SECONDS, REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, Ramps, ReadonlyAssetManager, ReadonlyDescriptorIdentity, ReadonlySingleKey, ReadonlyWallet, ReadonlyWalletError, RestDelegateProvider, RestDelegatorProvider, RestEmulatorProvider, SIGNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, SeedIdentity, ServiceWorkerReadonlyWallet, ServiceWorkerTimeoutError, ServiceWorkerWallet, SingleKey, TxTree, TxType, TxWeightEstimator, UnannotatableInputError, UnilateralExit, UnknownPacket, Unroll, VtxoManager, Wallet2 as Wallet, WalletCannotAllocateAddressError, WalletCannotSignError, WalletMessageHandler, WalletNotInitializedError, WalletRepositoryImpl, WsElectrumChainSource, adoptContractDescriptor, arkAssetRail, arkRail, arkTarget, arkade_exports, assertFinalCommitmentMatchesValidated, assertIntentIdUnique, assertNoAssets, assertSendableAmount, assertSubmittedArkTxid, assertValidBatchExpiry, assertValidServerUnrollScript, assetMintResolver, assetsOf, attachPrevArkTxs, attachPrevoutTxs, awaitTransaction, boardingResolver, btcTarget, buildForfeitTx, buildOffchainTx, buildPreimageMessage, buildSaltedPreimageMessage, claimWithPreimageIdentity, classifyAgainstSignerSet, classifyContractSigner, closeDatabase, collabExitResolver, combineTapscriptSigs, contractFromArkContract, contractFromArkContractWithAddress, contractPreimage, contractSigner, createAssetPacket, createDefaultActivityRegistry, createDefaultPaymentRouter, createExitChainResolver, createManagedConnection, decodeArkContract, defaultBatchExpiryPolicy, defaultCheckpointExitDelayPolicy, deleteByIndex, deserializeAssets, deserializeExitPackage, deserializeUtxo, deserializeVtxo, encodeArkContract, exitObserverFor, extendVirtualCoinForContract, extractArkProviderUrl, gateExclusion, gatedContracts, getAllByIndexValues, getMigrationStatus, getRandomId, hasBoardingTxExpired, hasCandidates, intentMatchesFilter, intentPageBounds, invoiceTarget, isAddressAllocationCapable, isArkContract, isBatchSignable, isBtcAddress, isContractGenericallySpendable, isCooperativelyMigratable, isDeterministicSigner, isDiscoverable, isHDAllocationCapable, isHDDeterministicSignCapable, isHDWalletCapable, isLightningInvoice, isLnurl, isMessageBusInitializingError, isMessageBusNotInitializedError, isPerArtifactDescriptor, isSigningIdentity, isSubdust, isTerminalIntentState, isValidArkAddress, isVtxoExpiringSoon, isVtxoForScript, isWatchedContract, logExcludedVtxos, makeHandle, matchServerCheckpoints, mergeChainedTxType, migrateWalletRepository, notifyExitObserved, onchainRail, openDatabase, outpointExclusion, outpointReasons, promisifyRequest, provisionClaimSecret, provisionRefundKey, requiresMigration, resolveAssetAmount, resolveBatchExpiryPolicy, resolveCheckpointExitDelayPolicy, resolveDescriptorSigner, resolvePrevTxs, resolveSendAmount, rollbackMigration, saveVtxosForContract, scriptFromArkAddress, selectCoinsWithAsset, selectVirtualCoins, serializeAssets, serializeExitPackage, serializeUtxo, serializeVtxo, setupServiceWorker, signAndSubmitOffchainTx, signerSetFromInfo, signingDescriptorIndex, strictSigningDescriptorIndex, toXOnlySignerHex, tryResolveSendAmount, validateBatchRecipients, validateConnectorsTxGraph, validateVtxoTxGraph, verifyTapscriptSignatures, waitForIncomingFunds, walletFeeSource, warnAndFilterVtxosForScript, withPrevTxs };
23892
- //# sourceMappingURL=chunk-JVHO6XHG.js.map
23893
- //# sourceMappingURL=chunk-JVHO6XHG.js.map
24132
+ export { ARKADE_MAGIC, ARKADE_SALTED_PREIMAGE_TAG, ARKADE_SWAP_PREIMAGE_TAG, ASSET_CARRIER_SATS, AbortError, ActivityRegistry, AmbiguousRouteError, ArkNote, ArkadeCash, ArkadeCashCreateError, AssetManager, BIP21, BIP21Error, BIP322, BLOCKED_UPGRADE_TIMEOUT_MS, Batch, CachingArkProvider, ChainedTxType, ConnectionDisposedError, ContractManager, ContractRepositoryImpl, ContractWatcher, DB_VERSION, DEFAULT_MESSAGE_TIMEOUTS, DEFAULT_MIN_BATCH_EXPIRY_SECONDS, DEFAULT_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, DatabaseUpgradeBlockedError, DelegateManagerImpl, DelegateNotConfiguredError, DelegatorManagerImpl, DelegatorNotConfiguredError, DescriptorIdentity, DescriptorSigningProviderMissingError, DustChangeError, ELECTRUM_TCP_HOST, ELECTRUM_WS_URL, ESPLORA_URL, ElectrumOnchainProvider, EmulatorPacket, EsploraProvider, Estimator, Extension, ExtensionNotFoundError, ForeignDescriptorError, HDDescriptorProvider, INTENT_TERMINAL_STATES, InMemoryContractRepository, InMemoryIntentRepository, InMemoryVirtualTxRepository, InMemoryWalletRepository, IndexedDBContractRepository, IndexedDBIntentRepository, IndexedDBVirtualTxRepository, IndexedDBWalletRepository, MAX_USED_SIGNING_DESCRIPTORS_LOOK_AHEAD, MESSAGE_BUS_INITIALIZING, MESSAGE_BUS_NOT_INITIALIZED, MIGRATION_KEY, MUTINYNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, MessageBus, MessageBusInitializingError, MessageBusNotInitializedError, MissingSigningDescriptorError, MnemonicIdentity, OnchainWallet, P2A, PaymentRouter, PrevTxUnavailableError, REGTEST_MIN_BATCH_EXPIRY_SECONDS, REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, Ramps, ReadonlyAssetManager, ReadonlyDescriptorIdentity, ReadonlySingleKey, ReadonlyWallet, ReadonlyWalletError, RestDelegateProvider, RestDelegatorProvider, RestEmulatorProvider, SIGNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS, SeedIdentity, ServiceWorkerReadonlyWallet, ServiceWorkerTimeoutError, ServiceWorkerWallet, SingleKey, TxTree, TxType, TxWeightEstimator, UnannotatableInputError, UnilateralExit, UnknownPacket, Unroll, VtxoManager, Wallet2 as Wallet, WalletCannotAllocateAddressError, WalletCannotSignError, WalletMessageHandler, WalletNotInitializedError, WalletRepositoryImpl, WsElectrumChainSource, adoptContractDescriptor, arkAssetRail, arkRail, arkTarget, arkade_exports, assertFinalCommitmentMatchesValidated, assertIntentIdUnique, assertNoAssets, assertSendableAmount, assertSubmittedArkTxid, assertValidBatchExpiry, assertValidServerUnrollScript, assetMintResolver, assetsOf, attachPrevArkTxs, attachPrevoutTxs, awaitTransaction, boardingResolver, btcTarget, buildForfeitTx, buildOffchainTx, buildPreimageMessage, buildSaltedPreimageMessage, claimWithPreimageIdentity, classifyAgainstSignerSet, classifyContractSigner, closeDatabase, collabExitResolver, combineTapscriptSigs, contractFromArkContract, contractFromArkContractWithAddress, contractPreimage, contractSigner, createAssetPacket, createDefaultActivityRegistry, createDefaultPaymentRouter, createExitChainResolver, createManagedConnection, decodeArkContract, defaultBatchExpiryPolicy, defaultCheckpointExitDelayPolicy, deleteByIndex, deserializeAssets, deserializeExitPackage, deserializeUtxo, deserializeVtxo, encodeArkContract, exitObserverFor, extendVirtualCoinForContract, extractArkProviderUrl, gateExclusion, gatedContracts, getAllByIndexValues, getMigrationStatus, getRandomId, hasBoardingTxExpired, hasCandidates, intentMatchesFilter, intentPageBounds, invoiceTarget, isAddressAllocationCapable, isArkContract, isBatchSignable, isBtcAddress, isContractGenericallySpendable, isContractVtxoEvent, isCooperativelyMigratable, isDeterministicSigner, isDiscoverable, isHDAllocationCapable, isHDDeterministicSignCapable, isHDWalletCapable, isLightningInvoice, isLnurl, isMessageBusInitializingError, isMessageBusNotInitializedError, isPerArtifactDescriptor, isSigningIdentity, isSubdust, isTerminalIntentState, isValidArkAddress, isVtxoExpiringSoon, isVtxoForScript, isWatchedContract, logExcludedVtxos, makeHandle, matchServerCheckpoints, mergeChainedTxType, migrateWalletRepository, notifyExitObserved, onchainRail, openDatabase, outpointExclusion, outpointReasons, promisifyRequest, provisionClaimSecret, provisionRefundKey, requiresMigration, resolveAssetAmount, resolveBatchExpiryPolicy, resolveCheckpointExitDelayPolicy, resolveDescriptorSigner, resolvePrevTxs, resolveSendAmount, rollbackMigration, saveVtxosForContract, scriptFromArkAddress, selectCoinsWithAsset, selectVirtualCoins, serializeAssets, serializeExitPackage, serializeUtxo, serializeVtxo, setupServiceWorker, signAndSubmitOffchainTx, signerSetFromInfo, signingDescriptorIndex, strictSigningDescriptorIndex, toXOnlySignerHex, tryResolveSendAmount, validateBatchRecipients, validateConnectorsTxGraph, validateVtxoTxGraph, verifyTapscriptSignatures, waitForIncomingFunds, walletFeeSource, warnAndFilterVtxosForScript, withPrevTxs };
24133
+ //# sourceMappingURL=chunk-E5JNYFOF.js.map
24134
+ //# sourceMappingURL=chunk-E5JNYFOF.js.map