@arkade-os/sdk 0.4.11 → 0.4.12

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.
@@ -149,7 +149,15 @@ class ContractManager {
149
149
  // Persist
150
150
  await this.config.contractRepository.saveContract(contract);
151
151
  // fetch all VTXOs (including spent/swept) for this contract
152
+ const requestStartedAt = Date.now();
152
153
  await this.fetchContractVxosFromIndexer([contract], true);
154
+ // Advance the sync cursor so that the watcher's vtxo_received
155
+ // event (triggered by addContract below) doesn't re-bootstrap
156
+ // the same script via deltaSyncContracts.
157
+ const cutoff = (0, syncCursors_1.cursorCutoff)(requestStartedAt);
158
+ await (0, syncCursors_1.advanceSyncCursors)(this.config.walletRepository, {
159
+ [contract.script]: cutoff,
160
+ });
153
161
  // Add to watcher
154
162
  await this.watcher.addContract(contract);
155
163
  return contract;
@@ -309,8 +309,21 @@ class ReadonlyWallet {
309
309
  * Delta-sync wallet VTXOs: fetch only changed VTXOs since the last
310
310
  * cursor, or do a full bootstrap when no cursor exists. Upserts
311
311
  * the result into the cache and advances the sync cursors.
312
+ *
313
+ * Concurrent calls are deduplicated: if a sync is already in flight,
314
+ * subsequent callers receive the same promise instead of triggering
315
+ * a second network round-trip.
312
316
  */
313
- async syncVtxos() {
317
+ syncVtxos() {
318
+ if (this._syncVtxosInflight)
319
+ return this._syncVtxosInflight;
320
+ const p = this.doSyncVtxos().finally(() => {
321
+ this._syncVtxosInflight = undefined;
322
+ });
323
+ this._syncVtxosInflight = p;
324
+ return p;
325
+ }
326
+ async doSyncVtxos() {
314
327
  const address = await this.getAddress();
315
328
  // Batch cursor read with script map to avoid extra async hops
316
329
  // before the fetch (background operations may run between hops).
@@ -146,7 +146,15 @@ export class ContractManager {
146
146
  // Persist
147
147
  await this.config.contractRepository.saveContract(contract);
148
148
  // fetch all VTXOs (including spent/swept) for this contract
149
+ const requestStartedAt = Date.now();
149
150
  await this.fetchContractVxosFromIndexer([contract], true);
151
+ // Advance the sync cursor so that the watcher's vtxo_received
152
+ // event (triggered by addContract below) doesn't re-bootstrap
153
+ // the same script via deltaSyncContracts.
154
+ const cutoff = cursorCutoff(requestStartedAt);
155
+ await advanceSyncCursors(this.config.walletRepository, {
156
+ [contract.script]: cutoff,
157
+ });
150
158
  // Add to watcher
151
159
  await this.watcher.addContract(contract);
152
160
  return contract;
@@ -304,8 +304,21 @@ export class ReadonlyWallet {
304
304
  * Delta-sync wallet VTXOs: fetch only changed VTXOs since the last
305
305
  * cursor, or do a full bootstrap when no cursor exists. Upserts
306
306
  * the result into the cache and advances the sync cursors.
307
+ *
308
+ * Concurrent calls are deduplicated: if a sync is already in flight,
309
+ * subsequent callers receive the same promise instead of triggering
310
+ * a second network round-trip.
307
311
  */
308
- async syncVtxos() {
312
+ syncVtxos() {
313
+ if (this._syncVtxosInflight)
314
+ return this._syncVtxosInflight;
315
+ const p = this.doSyncVtxos().finally(() => {
316
+ this._syncVtxosInflight = undefined;
317
+ });
318
+ this._syncVtxosInflight = p;
319
+ return p;
320
+ }
321
+ async doSyncVtxos() {
309
322
  const address = await this.getAddress();
310
323
  // Batch cursor read with script map to avoid extra async hops
311
324
  // before the fetch (background operations may run between hops).
@@ -43,6 +43,7 @@ export declare class ReadonlyWallet implements IReadonlyWallet {
43
43
  private _contractManagerInitializing?;
44
44
  protected readonly watcherConfig?: ReadonlyWalletConfig["watcherConfig"];
45
45
  private readonly _assetManager;
46
+ private _syncVtxosInflight?;
46
47
  get assetManager(): IReadonlyAssetManager;
47
48
  protected constructor(identity: ReadonlyIdentity, network: Network, onchainProvider: OnchainProvider, indexerProvider: IndexerProvider, arkServerPublicKey: Bytes, offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script, boardingTapscript: DefaultVtxo.Script, dustAmount: bigint, walletRepository: WalletRepository, contractRepository: ContractRepository, delegatorProvider?: DelegatorProvider | undefined, watcherConfig?: ReadonlyWalletConfig["watcherConfig"]);
48
49
  /**
@@ -80,8 +81,13 @@ export declare class ReadonlyWallet implements IReadonlyWallet {
80
81
  * Delta-sync wallet VTXOs: fetch only changed VTXOs since the last
81
82
  * cursor, or do a full bootstrap when no cursor exists. Upserts
82
83
  * the result into the cache and advances the sync cursors.
84
+ *
85
+ * Concurrent calls are deduplicated: if a sync is already in flight,
86
+ * subsequent callers receive the same promise instead of triggering
87
+ * a second network round-trip.
83
88
  */
84
89
  private syncVtxos;
90
+ private doSyncVtxos;
85
91
  /**
86
92
  * Clear all VTXO sync cursors, forcing a full re-bootstrap on next sync.
87
93
  * Useful for recovery after indexer reprocessing or debugging.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/sdk",
3
- "version": "0.4.11",
3
+ "version": "0.4.12",
4
4
  "description": "Bitcoin wallet SDK with Taproot and Ark integration",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",