@arkade-os/sdk 0.4.49 → 0.4.51
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.
- package/README.md +33 -8
- package/dist/adapters/expo.cjs +4 -4
- package/dist/adapters/expo.d.cts +2 -2
- package/dist/adapters/expo.d.ts +2 -2
- package/dist/adapters/expo.js +2 -2
- package/dist/adapters/indexedDB.cjs +3 -3
- package/dist/adapters/indexedDB.js +2 -2
- package/dist/{ark-nkSiPYNf.d.cts → ark-9V45Anrs.d.cts} +164 -53
- package/dist/{ark-nkSiPYNf.d.ts → ark-9V45Anrs.d.ts} +164 -53
- package/dist/{asyncStorageTaskQueue-DdxhsEz6.d.cts → asyncStorageTaskQueue-B6nXJv7m.d.cts} +1 -1
- package/dist/{asyncStorageTaskQueue-DCaEE83p.d.ts → asyncStorageTaskQueue-BZjR843B.d.ts} +1 -1
- package/dist/{chunk-CPO2UB7L.js → chunk-3AOTJZQ4.js} +3 -3
- package/dist/{chunk-CPO2UB7L.js.map → chunk-3AOTJZQ4.js.map} +1 -1
- package/dist/{chunk-6UI5BFE7.cjs → chunk-3E4GDBYU.cjs} +7 -7
- package/dist/{chunk-6UI5BFE7.cjs.map → chunk-3E4GDBYU.cjs.map} +1 -1
- package/dist/{chunk-BLJQV3N4.js → chunk-4KGT3IP2.js} +3 -3
- package/dist/{chunk-BLJQV3N4.js.map → chunk-4KGT3IP2.js.map} +1 -1
- package/dist/{chunk-XOLH3LFO.cjs → chunk-5AT2NV5G.cjs} +11 -11
- package/dist/{chunk-XOLH3LFO.cjs.map → chunk-5AT2NV5G.cjs.map} +1 -1
- package/dist/{chunk-HN25T276.js → chunk-6T5BBPKO.js} +3 -3
- package/dist/{chunk-HN25T276.js.map → chunk-6T5BBPKO.js.map} +1 -1
- package/dist/{chunk-2LAJ3RTH.cjs → chunk-6XF6ZATZ.cjs} +458 -203
- package/dist/chunk-6XF6ZATZ.cjs.map +1 -0
- package/dist/{chunk-QDXQULVM.cjs → chunk-FHDUEBBC.cjs} +3 -3
- package/dist/{chunk-QDXQULVM.cjs.map → chunk-FHDUEBBC.cjs.map} +1 -1
- package/dist/{chunk-5QVBJUOG.js → chunk-TS2MTRP4.js} +354 -99
- package/dist/chunk-TS2MTRP4.js.map +1 -0
- package/dist/contracts/handlers/index.d.cts +3 -3
- package/dist/contracts/handlers/index.d.ts +3 -3
- package/dist/{delegate-D6Orvyq7.d.ts → delegate-CJkolr2s.d.ts} +1 -1
- package/dist/{delegate-Cqqw1T1J.d.cts → delegate-tVTPM4fm.d.cts} +1 -1
- package/dist/{index-CWoogah0.d.ts → index-B5Fdwzs_.d.ts} +2 -2
- package/dist/{index-Yd4hecbM.d.cts → index-BBAffp_8.d.cts} +2 -2
- package/dist/index.cjs +145 -145
- package/dist/index.d.cts +24 -8
- package/dist/index.d.ts +24 -8
- package/dist/index.js +2 -2
- package/dist/repositories/realm/index.cjs +17 -17
- package/dist/repositories/realm/index.d.cts +2 -2
- package/dist/repositories/realm/index.d.ts +2 -2
- package/dist/repositories/realm/index.js +3 -3
- package/dist/repositories/sqlite/index.cjs +16 -16
- package/dist/repositories/sqlite/index.d.cts +2 -2
- package/dist/repositories/sqlite/index.d.ts +2 -2
- package/dist/repositories/sqlite/index.js +3 -3
- package/dist/{taskRunner-BjB5QINR.d.cts → taskRunner-4CrJaWHv.d.cts} +1 -1
- package/dist/{taskRunner-Dw7xs60Q.d.ts → taskRunner-TgdjRf_b.d.ts} +1 -1
- package/dist/wallet/expo/background.cjs +12 -12
- package/dist/wallet/expo/background.d.cts +3 -3
- package/dist/wallet/expo/background.d.ts +3 -3
- package/dist/wallet/expo/background.js +4 -4
- package/dist/wallet/expo/index.cjs +12 -12
- package/dist/wallet/expo/index.d.cts +4 -4
- package/dist/wallet/expo/index.d.ts +4 -4
- package/dist/wallet/expo/index.js +3 -3
- package/dist/{wallet-DyUHrPyN.d.ts → wallet-BBfhZx_Z.d.cts} +22 -3
- package/dist/{wallet-CGkWu3xV.d.cts → wallet-CSSTN8Yc.d.ts} +22 -3
- package/dist/worker/expo/index.cjs +7 -7
- package/dist/worker/expo/index.d.cts +4 -4
- package/dist/worker/expo/index.d.ts +4 -4
- package/dist/worker/expo/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-2LAJ3RTH.cjs.map +0 -1
- package/dist/chunk-5QVBJUOG.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Transaction, setArkPsbtField, PrevArkTxField, ConditionWitness, AssetId, AssetGroup, AssetInput, AssetOutput, Metadata, Packet, craftToSpendTx, getArkPsbtFields, CosignerPublicKey, BufferReader, BufferWriter, OP_RETURN_EMPTY_PKSCRIPT, VtxoTaprootTree, baseFetch, Intent, rateGate, maybeArkError, isArkError, ArkErrorName, ProviderUnavailableError, FetchError, isFetchTimeoutError, AssetRef, isEventSourceError, RestArkProvider, RestIndexerProvider, ArkError } from './chunk-
|
|
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, inputName, contractHandlers, isMainnetDescriptor, descriptorIsOurs, DefaultVtxo, DelegateVtxo,
|
|
1
|
+
import { Transaction, setArkPsbtField, PrevArkTxField, ConditionWitness, AssetId, AssetGroup, AssetInput, AssetOutput, Metadata, Packet, craftToSpendTx, getArkPsbtFields, CosignerPublicKey, BufferReader, BufferWriter, OP_RETURN_EMPTY_PKSCRIPT, VtxoTaprootTree, baseFetch, Intent, rateGate, maybeArkError, isArkError, ArkErrorName, ProviderUnavailableError, FetchError, isFetchTimeoutError, AssetRef, isEventSourceError, RestArkProvider, RestIndexerProvider, ArkError } from './chunk-3AOTJZQ4.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, inputName, contractHandlers, isMainnetDescriptor, descriptorIsOurs, DefaultVtxo, DelegateVtxo, deriveDescriptorLeafPubKey, WALLET_RECEIVE_SOURCE, BoardingContractHandler } from './chunk-MBSYQ3WX.js';
|
|
3
3
|
import { VtxoScript, isRecoverable, CSVMultisigTapscript, DEFAULT_NETWORK, hasTerminalSpend, getNormalizedVtxos, isVirtualCoin, ArkAddress, sequenceToTimelock, decodeTapscript, scriptFromTapLeafScript, CLTVMultisigTapscript, timelockToSequence, DEFAULT_NETWORK_NAME, normalizeVtxo, getSequence, toBatchExpiry, toOffchainInputFeeParams, canRecoverOnchain, getNetwork, MultisigTapscript, getAllNormalizedVtxos, DEFAULT_PAGE_SIZE, canSpendOffchain, toVirtualStatus, resolveTimeHeight, parseLegacyExpiry, networks as networks$1, isExpired, DEFAULT_ARKADE_SERVER_URL, isPastExpiry } from './chunk-EFNLTS6Q.js';
|
|
4
4
|
import { __export } from './chunk-NSBPE2FW.js';
|
|
5
5
|
import { sha256, equalBytes, hash160, sha256x2, concatBytes, randomPrivateKeyBytes, pubECDSA, pubSchnorr } from '@scure/btc-signer/utils.js';
|
|
@@ -8114,10 +8114,10 @@ var ContractWatcher = class {
|
|
|
8114
8114
|
/**
|
|
8115
8115
|
* Add a contract to be watched.
|
|
8116
8116
|
*
|
|
8117
|
-
*
|
|
8117
|
+
* Once watching, every contract is subscribed and polled whatever
|
|
8118
|
+
* its state.
|
|
8118
8119
|
*
|
|
8119
|
-
*
|
|
8120
|
-
* (which may cause them to be watched even if inactive).
|
|
8120
|
+
* @see getWatchedContracts
|
|
8121
8121
|
*/
|
|
8122
8122
|
async addContract(contract) {
|
|
8123
8123
|
const state = {
|
|
@@ -8185,18 +8185,18 @@ var ContractWatcher = class {
|
|
|
8185
8185
|
return Array.from(this.contracts.values()).map((s) => s.contract);
|
|
8186
8186
|
}
|
|
8187
8187
|
/**
|
|
8188
|
-
*
|
|
8189
|
-
* - all active contracts, plus
|
|
8190
|
-
* - inactive contracts that still hold known virtual outputs
|
|
8191
|
-
* (the subscription keeps watching them so `vtxo_spent` events for
|
|
8192
|
-
* those unspent outputs are still observed).
|
|
8188
|
+
* Every registered contract, retired (`inactive`) ones included.
|
|
8193
8189
|
*
|
|
8194
|
-
*
|
|
8195
|
-
*
|
|
8196
|
-
*
|
|
8190
|
+
* Feeds both the subscription and the indexer sweep scope, so
|
|
8191
|
+
* narrowing it drops a contract from every background channel at
|
|
8192
|
+
* once. Nothing may be narrowed out: an Ark receive address can be
|
|
8193
|
+
* paid again after the wallet has rotated past it, and a payment
|
|
8194
|
+
* that lands outside every background channel is invisible until
|
|
8195
|
+
* some foreground read happens to sweep it. Retirement therefore
|
|
8196
|
+
* governs receive-address selection, not coverage.
|
|
8197
8197
|
*/
|
|
8198
8198
|
getWatchedContracts() {
|
|
8199
|
-
return
|
|
8199
|
+
return this.getAllContracts();
|
|
8200
8200
|
}
|
|
8201
8201
|
/**
|
|
8202
8202
|
* Get virtual outputs for contracts, grouped by contract script.
|
|
@@ -8225,7 +8225,7 @@ var ContractWatcher = class {
|
|
|
8225
8225
|
return new Map(results.flat(1));
|
|
8226
8226
|
}
|
|
8227
8227
|
/**
|
|
8228
|
-
* Start watching for virtual output events across all
|
|
8228
|
+
* Start watching for virtual output events across all watched contracts.
|
|
8229
8229
|
*/
|
|
8230
8230
|
async startWatching(callback) {
|
|
8231
8231
|
if (this.isWatching) {
|
|
@@ -8276,7 +8276,7 @@ var ContractWatcher = class {
|
|
|
8276
8276
|
return this.connectionState;
|
|
8277
8277
|
}
|
|
8278
8278
|
/**
|
|
8279
|
-
* Force a poll of all
|
|
8279
|
+
* Force a poll of all watched contracts.
|
|
8280
8280
|
* Useful for manual refresh or after app resume.
|
|
8281
8281
|
*/
|
|
8282
8282
|
async forcePoll() {
|
|
@@ -8464,7 +8464,7 @@ var ContractWatcher = class {
|
|
|
8464
8464
|
/**
|
|
8465
8465
|
* Update the subscription with scripts that should be watched.
|
|
8466
8466
|
*
|
|
8467
|
-
*
|
|
8467
|
+
* @see getWatchedContracts
|
|
8468
8468
|
*/
|
|
8469
8469
|
async updateSubscription() {
|
|
8470
8470
|
const scriptsToWatch = this.getWatchedContracts().map((c) => c.script);
|
|
@@ -8713,6 +8713,9 @@ function dedupeOutpoints(outpoints) {
|
|
|
8713
8713
|
function areCoalescibleContractTypes(a, b) {
|
|
8714
8714
|
return a === "default" && b === "boarding" || a === "boarding" && b === "default";
|
|
8715
8715
|
}
|
|
8716
|
+
function toWatchOnlyContract(params) {
|
|
8717
|
+
return { ...params, state: params.state ?? "active", createdAt: Date.now() };
|
|
8718
|
+
}
|
|
8716
8719
|
var SCAN_MAX_INDEX = 1e4;
|
|
8717
8720
|
var DEFAULT_SCAN_BATCH = 10;
|
|
8718
8721
|
var ContractManager = class _ContractManager {
|
|
@@ -8725,6 +8728,12 @@ var ContractManager = class _ContractManager {
|
|
|
8725
8728
|
syncDegradedReason;
|
|
8726
8729
|
/** Epoch-ms of the last successful provider sync, if any. */
|
|
8727
8730
|
lastSyncedAt;
|
|
8731
|
+
/** Speculative look-ahead scripts, keyed by script. @see LookAheadEntry */
|
|
8732
|
+
lookAheadEntries = /* @__PURE__ */ new Map();
|
|
8733
|
+
/** In-flight look-ahead drain, if any. @see scheduleLookAheadDrain */
|
|
8734
|
+
lookAheadDrain;
|
|
8735
|
+
/** A refill was requested while a drain was running. */
|
|
8736
|
+
lookAheadDirty = false;
|
|
8728
8737
|
constructor(config) {
|
|
8729
8738
|
this.config = config;
|
|
8730
8739
|
this.watcher = new ContractWatcher({
|
|
@@ -8737,8 +8746,8 @@ var ContractManager = class _ContractManager {
|
|
|
8737
8746
|
* Static factory method for creating a new ContractManager.
|
|
8738
8747
|
* Initialize the manager by loading persisted contracts and starting to watch.
|
|
8739
8748
|
*
|
|
8740
|
-
* After initialization, the manager automatically watches
|
|
8741
|
-
*
|
|
8749
|
+
* After initialization, the manager automatically watches every persisted
|
|
8750
|
+
* contract. Use `onContractEvent()` to register event callbacks.
|
|
8742
8751
|
*
|
|
8743
8752
|
* @param config ContractManagerConfig
|
|
8744
8753
|
*/
|
|
@@ -8775,6 +8784,7 @@ var ContractManager = class _ContractManager {
|
|
|
8775
8784
|
for (const contract of contracts) {
|
|
8776
8785
|
await this.watcher.addContract(contract);
|
|
8777
8786
|
}
|
|
8787
|
+
await this.scheduleLookAheadDrain();
|
|
8778
8788
|
try {
|
|
8779
8789
|
await this.reconcileWatched();
|
|
8780
8790
|
this.markSyncOnline();
|
|
@@ -8826,6 +8836,156 @@ var ContractManager = class _ContractManager {
|
|
|
8826
8836
|
console.error("ContractManager: intent reconciliation failed", e);
|
|
8827
8837
|
}
|
|
8828
8838
|
}
|
|
8839
|
+
/** @see IContractManager.refillLookAhead */
|
|
8840
|
+
refillLookAhead() {
|
|
8841
|
+
return this.scheduleLookAheadDrain();
|
|
8842
|
+
}
|
|
8843
|
+
/**
|
|
8844
|
+
* Serialized drain of the look-ahead band: concurrent callers join the
|
|
8845
|
+
* active drain and mark it dirty, an idle call starts a new one. Promotion
|
|
8846
|
+
* can uncover more funded indices, and boot / SSE / rotate / reconnect can
|
|
8847
|
+
* all request a refill at once, so the loop coalesces them instead of
|
|
8848
|
+
* recursing.
|
|
8849
|
+
*/
|
|
8850
|
+
scheduleLookAheadDrain() {
|
|
8851
|
+
if (!this.config.lookAhead) return Promise.resolve();
|
|
8852
|
+
if (this.lookAheadDrain) {
|
|
8853
|
+
this.lookAheadDirty = true;
|
|
8854
|
+
return this.lookAheadDrain;
|
|
8855
|
+
}
|
|
8856
|
+
const drain = (async () => {
|
|
8857
|
+
do {
|
|
8858
|
+
this.lookAheadDirty = false;
|
|
8859
|
+
await this.ensureLookAhead();
|
|
8860
|
+
} while (this.lookAheadDirty);
|
|
8861
|
+
})().finally(() => {
|
|
8862
|
+
this.lookAheadDrain = void 0;
|
|
8863
|
+
});
|
|
8864
|
+
this.lookAheadDrain = drain;
|
|
8865
|
+
return drain;
|
|
8866
|
+
}
|
|
8867
|
+
/**
|
|
8868
|
+
* Request a drain without awaiting it. Used from inside a sync (promotion),
|
|
8869
|
+
* where awaiting the drain that the sync itself is part of would deadlock.
|
|
8870
|
+
*/
|
|
8871
|
+
requestLookAheadDrain() {
|
|
8872
|
+
if (!this.config.lookAhead) return;
|
|
8873
|
+
if (this.lookAheadDrain) {
|
|
8874
|
+
this.lookAheadDirty = true;
|
|
8875
|
+
return;
|
|
8876
|
+
}
|
|
8877
|
+
void this.scheduleLookAheadDrain().catch((err) => {
|
|
8878
|
+
console.error("ContractManager: look-ahead refill failed", err);
|
|
8879
|
+
});
|
|
8880
|
+
}
|
|
8881
|
+
/**
|
|
8882
|
+
* Rebuild the speculative watch band around the allocation watermark.
|
|
8883
|
+
*
|
|
8884
|
+
* NArk needs no analogue because it *is* the address issuer: it persists a
|
|
8885
|
+
* contract row at derivation time, so its watched set is a superset of
|
|
8886
|
+
* every address it ever advertised. This SDK, when a third party issues
|
|
8887
|
+
* addresses from the shared seed, cannot observe those allocations at all —
|
|
8888
|
+
* the window is how a non-issuer compensates.
|
|
8889
|
+
*
|
|
8890
|
+
* Entries are registered with the watcher but NOT persisted: they become
|
|
8891
|
+
* repository rows only once funded (see {@link promoteLookAheadHits}).
|
|
8892
|
+
*/
|
|
8893
|
+
async ensureLookAhead() {
|
|
8894
|
+
const lookAhead = this.config.lookAhead;
|
|
8895
|
+
if (!lookAhead) return;
|
|
8896
|
+
const watermark = await lookAhead.currentWatermark();
|
|
8897
|
+
const from = Math.max(0, watermark - lookAhead.size);
|
|
8898
|
+
const to = watermark + lookAhead.size;
|
|
8899
|
+
const band = /* @__PURE__ */ new Map();
|
|
8900
|
+
for (let index = from; index <= to; index++) {
|
|
8901
|
+
const params = lookAhead.materialize(index);
|
|
8902
|
+
band.set(params.script, { index, params });
|
|
8903
|
+
}
|
|
8904
|
+
await this.watcher.withCoalescedSubscription(async () => {
|
|
8905
|
+
const persisted = await this.config.contractRepository.getContracts({
|
|
8906
|
+
script: [...band.keys()]
|
|
8907
|
+
});
|
|
8908
|
+
const persistedScripts = new Set(persisted.map((c) => c.script));
|
|
8909
|
+
for (const [script, { index, params }] of band) {
|
|
8910
|
+
if (persistedScripts.has(script)) {
|
|
8911
|
+
this.lookAheadEntries.delete(script);
|
|
8912
|
+
continue;
|
|
8913
|
+
}
|
|
8914
|
+
if (this.lookAheadEntries.has(script)) continue;
|
|
8915
|
+
const contract = toWatchOnlyContract(params);
|
|
8916
|
+
this.lookAheadEntries.set(script, {
|
|
8917
|
+
index,
|
|
8918
|
+
params,
|
|
8919
|
+
contract,
|
|
8920
|
+
catchUpPending: true
|
|
8921
|
+
});
|
|
8922
|
+
await this.watcher.addContract(contract);
|
|
8923
|
+
}
|
|
8924
|
+
const stale = [...this.lookAheadEntries.keys()].filter((s) => !band.has(s));
|
|
8925
|
+
if (stale.length > 0) {
|
|
8926
|
+
const rows = await this.config.contractRepository.getContracts({ script: stale });
|
|
8927
|
+
const nowPersisted = new Set(rows.map((c) => c.script));
|
|
8928
|
+
for (const script of stale) {
|
|
8929
|
+
this.lookAheadEntries.delete(script);
|
|
8930
|
+
if (!nowPersisted.has(script)) await this.watcher.removeContract(script);
|
|
8931
|
+
}
|
|
8932
|
+
}
|
|
8933
|
+
});
|
|
8934
|
+
await this.runLookAheadCatchUp();
|
|
8935
|
+
}
|
|
8936
|
+
/**
|
|
8937
|
+
* One-time full-history sync for speculative entries the manager has not
|
|
8938
|
+
* successfully caught up on yet.
|
|
8939
|
+
*
|
|
8940
|
+
* Every normal sync uses the cursor-derived delta window and SSE only
|
|
8941
|
+
* delivers events after a script is subscribed, so a script first
|
|
8942
|
+
* registered after its funding time would otherwise be skipped forever
|
|
8943
|
+
* (upgrade migration, or a band that slid over an already-funded index).
|
|
8944
|
+
* The entries are passed as in-memory contracts because `refreshVtxos`
|
|
8945
|
+
* resolves scripts through the repository, where they deliberately do not
|
|
8946
|
+
* exist. Targeted + explicitly windowed, so the global cursor stays put.
|
|
8947
|
+
*/
|
|
8948
|
+
async runLookAheadCatchUp() {
|
|
8949
|
+
const pending = [...this.lookAheadEntries.values()].filter((e) => e.catchUpPending);
|
|
8950
|
+
if (pending.length === 0) return;
|
|
8951
|
+
try {
|
|
8952
|
+
await this.syncContracts({
|
|
8953
|
+
contracts: pending.map((e) => e.contract),
|
|
8954
|
+
window: { after: 0 }
|
|
8955
|
+
});
|
|
8956
|
+
for (const entry of pending) entry.catchUpPending = false;
|
|
8957
|
+
} catch (err) {
|
|
8958
|
+
if (!isRetryableProviderError(err)) throw err;
|
|
8959
|
+
this.markSyncDegraded(err);
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8962
|
+
/**
|
|
8963
|
+
* Promote every look-ahead entry funded by `vtxos` into a real repository
|
|
8964
|
+
* row, returning the persisted rows keyed by script.
|
|
8965
|
+
*
|
|
8966
|
+
* MUST run on each raw indexer fetch before `annotateVtxos`:
|
|
8967
|
+
* `extendVirtualCoinForContract` throws when a VTXO's script has no
|
|
8968
|
+
* contract row, so a funded window entry has to be persisted before its
|
|
8969
|
+
* VTXOs are annotated and saved. Callers also swap the returned rows into
|
|
8970
|
+
* the local contract maps they built pre-promotion, so `saveVtxosForContract`
|
|
8971
|
+
* and `onVtxosPersisted` never see the synthetic watcher object.
|
|
8972
|
+
*/
|
|
8973
|
+
async promoteLookAheadHits(vtxos) {
|
|
8974
|
+
const promoted = /* @__PURE__ */ new Map();
|
|
8975
|
+
if (this.lookAheadEntries.size === 0) return promoted;
|
|
8976
|
+
const hits = /* @__PURE__ */ new Map();
|
|
8977
|
+
for (const vtxo of vtxos) {
|
|
8978
|
+
const entry = this.lookAheadEntries.get(vtxo.script);
|
|
8979
|
+
if (entry) hits.set(vtxo.script, entry);
|
|
8980
|
+
}
|
|
8981
|
+
if (hits.size === 0) return promoted;
|
|
8982
|
+
for (const [script, entry] of hits) {
|
|
8983
|
+
promoted.set(script, await this.persistAndWatchContract(entry.params));
|
|
8984
|
+
await this.config.lookAhead?.onPromoted?.(entry.index);
|
|
8985
|
+
}
|
|
8986
|
+
this.requestLookAheadDrain();
|
|
8987
|
+
return promoted;
|
|
8988
|
+
}
|
|
8829
8989
|
/**
|
|
8830
8990
|
* Create and register a new contract.
|
|
8831
8991
|
*
|
|
@@ -8871,6 +9031,11 @@ var ContractManager = class _ContractManager {
|
|
|
8871
9031
|
* `persisted` is `true`.
|
|
8872
9032
|
*/
|
|
8873
9033
|
async upsertContract(params) {
|
|
9034
|
+
const result = await this.upsertContractRow(params);
|
|
9035
|
+
this.lookAheadEntries.delete(params.script);
|
|
9036
|
+
return result;
|
|
9037
|
+
}
|
|
9038
|
+
async upsertContractRow(params) {
|
|
8874
9039
|
const handler = contractHandlers.get(params.type);
|
|
8875
9040
|
if (!handler) {
|
|
8876
9041
|
throw new Error(`No handler registered for contract type '${params.type}'`);
|
|
@@ -9185,13 +9350,17 @@ var ContractManager = class _ContractManager {
|
|
|
9185
9350
|
return updated;
|
|
9186
9351
|
}
|
|
9187
9352
|
/**
|
|
9188
|
-
* Set a contract's state.
|
|
9353
|
+
* Set a contract's state. Retiring (`inactive`) keeps it watched;
|
|
9354
|
+
* see {@link ContractState}. To stop watching, use
|
|
9355
|
+
* {@link deleteContract}.
|
|
9189
9356
|
*/
|
|
9190
9357
|
async setContractState(script, state) {
|
|
9191
9358
|
await this.updateContract(script, { state });
|
|
9192
9359
|
}
|
|
9193
9360
|
/**
|
|
9194
|
-
* Delete a contract.
|
|
9361
|
+
* Delete a contract. Also removes it from the watcher — the only way
|
|
9362
|
+
* to stop watching a contract (retiring it via
|
|
9363
|
+
* {@link setContractState} does not).
|
|
9195
9364
|
*
|
|
9196
9365
|
* @param script - Contract script
|
|
9197
9366
|
*/
|
|
@@ -9266,22 +9435,10 @@ var ContractManager = class _ContractManager {
|
|
|
9266
9435
|
/**
|
|
9267
9436
|
* Force refresh virtual outputs from the indexer.
|
|
9268
9437
|
*
|
|
9269
|
-
* Without options, re-fetches
|
|
9270
|
-
*
|
|
9271
|
-
*
|
|
9272
|
-
*
|
|
9273
|
-
* cursor is not advanced because contracts outside the list may
|
|
9274
|
-
* have data we'd skip).
|
|
9275
|
-
*
|
|
9276
|
-
* `includeInactive: true` (and no `scripts`) widens the refresh to
|
|
9277
|
-
* every contract in the repository, including ones marked
|
|
9278
|
-
* `inactive` and ones that have dropped out of the watcher's
|
|
9279
|
-
* active set. This is a *superset* of the watched set, so the
|
|
9280
|
-
* cursor invariant still holds and the cursor advances normally.
|
|
9281
|
-
*
|
|
9282
|
-
* `after` / `before` apply a caller-supplied time window. The
|
|
9283
|
-
* cursor never advances on a windowed query because the window
|
|
9284
|
-
* may skip data outside its bounds.
|
|
9438
|
+
* Without options, re-fetches the watcher's watched set and
|
|
9439
|
+
* advances the global cursor. Each option narrows or widens that
|
|
9440
|
+
* scope and may hold the cursor back — see
|
|
9441
|
+
* {@link RefreshVtxosOptions}.
|
|
9285
9442
|
*/
|
|
9286
9443
|
async refreshVtxos(opts) {
|
|
9287
9444
|
const contracts = opts?.scripts ? await this.getContracts({ script: opts.scripts }) : void 0;
|
|
@@ -9368,6 +9525,7 @@ var ContractManager = class _ContractManager {
|
|
|
9368
9525
|
}
|
|
9369
9526
|
break;
|
|
9370
9527
|
case "connection_reset":
|
|
9528
|
+
await this.scheduleLookAheadDrain();
|
|
9371
9529
|
await this.reconcileWatched();
|
|
9372
9530
|
this.markSyncOnline();
|
|
9373
9531
|
break;
|
|
@@ -9397,11 +9555,10 @@ var ContractManager = class _ContractManager {
|
|
|
9397
9555
|
* Sync virtual outputs for the given contracts against the indexer.
|
|
9398
9556
|
*
|
|
9399
9557
|
* When `options.contracts` is omitted the sync covers the full
|
|
9400
|
-
* watched set (
|
|
9401
|
-
*
|
|
9402
|
-
*
|
|
9403
|
-
*
|
|
9404
|
-
* pick up.
|
|
9558
|
+
* watched set ({@link ContractWatcher.getWatchedContracts}) and the
|
|
9559
|
+
* global cursor is advanced on success. Passing an explicit subset
|
|
9560
|
+
* leaves the cursor alone so a narrow poll can't hide data that
|
|
9561
|
+
* other contracts still need to pick up.
|
|
9405
9562
|
*/
|
|
9406
9563
|
async syncContracts(options) {
|
|
9407
9564
|
const cursor = await getSyncCursor(this.config.walletRepository);
|
|
@@ -9428,11 +9585,16 @@ var ContractManager = class _ContractManager {
|
|
|
9428
9585
|
contracts.map((c) => c.script),
|
|
9429
9586
|
{ pendingOnly: true }
|
|
9430
9587
|
);
|
|
9588
|
+
for (const [script, contract] of await this.promoteLookAheadHits(vtxos)) {
|
|
9589
|
+
scriptToContract.set(script, contract);
|
|
9590
|
+
}
|
|
9431
9591
|
const owned = vtxos.filter((v) => scriptToContract.has(v.script));
|
|
9432
9592
|
const annotated = await this.annotateVtxos(owned);
|
|
9433
9593
|
const byContract = /* @__PURE__ */ new Map();
|
|
9594
|
+
const contractByAddress = /* @__PURE__ */ new Map();
|
|
9434
9595
|
for (const vtxo of annotated) {
|
|
9435
9596
|
const contract = scriptToContract.get(vtxo.script);
|
|
9597
|
+
contractByAddress.set(contract.address, contract);
|
|
9436
9598
|
let arr = byContract.get(contract.address);
|
|
9437
9599
|
if (!arr) {
|
|
9438
9600
|
arr = [];
|
|
@@ -9444,7 +9606,7 @@ var ContractManager = class _ContractManager {
|
|
|
9444
9606
|
});
|
|
9445
9607
|
}
|
|
9446
9608
|
for (const [addr, contractVtxos] of byContract) {
|
|
9447
|
-
const contract =
|
|
9609
|
+
const contract = contractByAddress.get(addr);
|
|
9448
9610
|
const filtered = warnAndFilterVtxosForScript(
|
|
9449
9611
|
contractVtxos,
|
|
9450
9612
|
contract.script,
|
|
@@ -9465,11 +9627,15 @@ var ContractManager = class _ContractManager {
|
|
|
9465
9627
|
}
|
|
9466
9628
|
}
|
|
9467
9629
|
async fetchContractVxosFromIndexer(contracts, pageSize, syncWindow) {
|
|
9468
|
-
const
|
|
9630
|
+
const { vtxosByScript, promoted } = await this.fetchContractVtxosBulk(
|
|
9631
|
+
contracts,
|
|
9632
|
+
pageSize,
|
|
9633
|
+
syncWindow
|
|
9634
|
+
);
|
|
9469
9635
|
const result = /* @__PURE__ */ new Map();
|
|
9470
|
-
for (const [contractScript, vtxos] of
|
|
9636
|
+
for (const [contractScript, vtxos] of vtxosByScript) {
|
|
9471
9637
|
result.set(contractScript, vtxos);
|
|
9472
|
-
const contract = contracts.find((c) => c.script === contractScript);
|
|
9638
|
+
const contract = promoted.get(contractScript) ?? contracts.find((c) => c.script === contractScript);
|
|
9473
9639
|
if (contract) {
|
|
9474
9640
|
const filtered = warnAndFilterVtxosForScript(
|
|
9475
9641
|
vtxos,
|
|
@@ -9497,7 +9663,7 @@ var ContractManager = class _ContractManager {
|
|
|
9497
9663
|
}
|
|
9498
9664
|
async fetchContractVtxosBulk(contracts, pageSize = DEFAULT_PAGE_SIZE, syncWindow) {
|
|
9499
9665
|
if (contracts.length === 0) {
|
|
9500
|
-
return /* @__PURE__ */ new Map();
|
|
9666
|
+
return { vtxosByScript: /* @__PURE__ */ new Map(), promoted: /* @__PURE__ */ new Map() };
|
|
9501
9667
|
}
|
|
9502
9668
|
const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
|
|
9503
9669
|
const result = new Map(
|
|
@@ -9516,6 +9682,10 @@ var ContractManager = class _ContractManager {
|
|
|
9516
9682
|
contracts.map((c) => c.script),
|
|
9517
9683
|
{ ...windowOpts, pageSize }
|
|
9518
9684
|
);
|
|
9685
|
+
const promoted = await this.promoteLookAheadHits(vtxos);
|
|
9686
|
+
for (const [script, contract] of promoted) {
|
|
9687
|
+
scriptToContract.set(script, contract);
|
|
9688
|
+
}
|
|
9519
9689
|
const owned = vtxos.filter((v) => scriptToContract.has(v.script));
|
|
9520
9690
|
const annotated = await this.annotateVtxos(owned);
|
|
9521
9691
|
for (const vtxo of annotated) {
|
|
@@ -9524,7 +9694,7 @@ var ContractManager = class _ContractManager {
|
|
|
9524
9694
|
contractScript: vtxo.script
|
|
9525
9695
|
});
|
|
9526
9696
|
}
|
|
9527
|
-
return result;
|
|
9697
|
+
return { vtxosByScript: result, promoted };
|
|
9528
9698
|
}
|
|
9529
9699
|
/**
|
|
9530
9700
|
* Dispose of the ContractManager and release all resources.
|
|
@@ -9538,6 +9708,7 @@ var ContractManager = class _ContractManager {
|
|
|
9538
9708
|
this.stopWatcherFn?.();
|
|
9539
9709
|
this.stopWatcherFn = void 0;
|
|
9540
9710
|
this.eventCallbacks.clear();
|
|
9711
|
+
this.lookAheadEntries.clear();
|
|
9541
9712
|
this.initialized = false;
|
|
9542
9713
|
}
|
|
9543
9714
|
/**
|
|
@@ -9603,6 +9774,15 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
|
|
|
9603
9774
|
if (settings.lastIndexUsed === void 0) return void 0;
|
|
9604
9775
|
return this.materializeDescriptorAt(settings.lastIndexUsed);
|
|
9605
9776
|
}
|
|
9777
|
+
/**
|
|
9778
|
+
* The most recently allocated index, or `undefined` when nothing has ever
|
|
9779
|
+
* been allocated on this repo. Read-only peek at the watermark that
|
|
9780
|
+
* {@link getNextSigningDescriptor} advances.
|
|
9781
|
+
*/
|
|
9782
|
+
async getLastIndexUsed() {
|
|
9783
|
+
const state = await this.walletRepository.getWalletState();
|
|
9784
|
+
return this.parseSettings(state ?? {}).lastIndexUsed;
|
|
9785
|
+
}
|
|
9606
9786
|
/**
|
|
9607
9787
|
* Monotonically advance the allocation watermark so the next
|
|
9608
9788
|
* `getNextSigningDescriptor()` skips indices discovered by a restore
|
|
@@ -9985,58 +10165,26 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9985
10165
|
*/
|
|
9986
10166
|
async rotate(wallet) {
|
|
9987
10167
|
const descriptor = await this.provider.getNextSigningDescriptor();
|
|
9988
|
-
const
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
10168
|
+
const { tapscript: newTapscript, params } = buildReceiveContract(
|
|
10169
|
+
wallet.offchainTapscript,
|
|
10170
|
+
descriptor,
|
|
10171
|
+
wallet.network.hrp,
|
|
10172
|
+
true
|
|
10173
|
+
);
|
|
10174
|
+
const newScript = params.script;
|
|
9992
10175
|
const manager = await wallet.getContractManager();
|
|
9993
|
-
|
|
9994
|
-
const csvTimelockStr = timelockToSequence(csvTimelock).toString();
|
|
9995
|
-
const serverPubKeyHex = hex.encode(newTapscript.options.serverPubKey);
|
|
9996
|
-
const baseParams = {
|
|
9997
|
-
script: newScript,
|
|
9998
|
-
address: newAddress,
|
|
9999
|
-
state: "active",
|
|
10000
|
-
// Persist the materialized signing descriptor alongside the
|
|
10001
|
-
// source tag. The wallet's spending paths read this at sign
|
|
10002
|
-
// time to route inputs locked by a rotated pubkey through
|
|
10003
|
-
// `DescriptorProvider.signWithDescriptor` instead of the
|
|
10004
|
-
// identity's index-0 key. Without it, post-rotation sends
|
|
10005
|
-
// produce unsigned PSBTs that the server rejects with
|
|
10006
|
-
// `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
|
|
10007
|
-
metadata: {
|
|
10008
|
-
source: WALLET_RECEIVE_SOURCE,
|
|
10009
|
-
signingDescriptor: descriptor
|
|
10010
|
-
}
|
|
10011
|
-
};
|
|
10012
|
-
if (newTapscript instanceof DelegateVtxo.Script) {
|
|
10013
|
-
await manager.createContract({
|
|
10014
|
-
...baseParams,
|
|
10015
|
-
type: "delegate",
|
|
10016
|
-
params: {
|
|
10017
|
-
pubKey: hex.encode(pubKey),
|
|
10018
|
-
serverPubKey: serverPubKeyHex,
|
|
10019
|
-
delegatePubKey: hex.encode(newTapscript.options.delegatePubKey),
|
|
10020
|
-
csvTimelock: csvTimelockStr
|
|
10021
|
-
}
|
|
10022
|
-
});
|
|
10023
|
-
} else {
|
|
10024
|
-
await manager.createContract({
|
|
10025
|
-
...baseParams,
|
|
10026
|
-
type: "default",
|
|
10027
|
-
params: {
|
|
10028
|
-
pubKey: hex.encode(pubKey),
|
|
10029
|
-
serverPubKey: serverPubKeyHex,
|
|
10030
|
-
csvTimelock: csvTimelockStr
|
|
10031
|
-
}
|
|
10032
|
-
});
|
|
10033
|
-
}
|
|
10176
|
+
await manager.createContract(params);
|
|
10034
10177
|
wallet.setOffchainTapscriptForRotation(newTapscript);
|
|
10035
10178
|
const previousTagged = this.currentTaggedScript;
|
|
10036
10179
|
if (previousTagged !== void 0 && previousTagged !== newScript) {
|
|
10037
10180
|
await manager.setContractState(previousTagged, "inactive");
|
|
10038
10181
|
}
|
|
10039
10182
|
this.currentTaggedScript = newScript;
|
|
10183
|
+
try {
|
|
10184
|
+
await manager.refillLookAhead();
|
|
10185
|
+
} catch (err) {
|
|
10186
|
+
this.logger.error("WalletReceiveRotator: look-ahead refill failed", err);
|
|
10187
|
+
}
|
|
10040
10188
|
}
|
|
10041
10189
|
};
|
|
10042
10190
|
function deriveLeafPubkey(descriptor) {
|
|
@@ -10049,6 +10197,45 @@ function deriveLeafPubkey(descriptor) {
|
|
|
10049
10197
|
);
|
|
10050
10198
|
}
|
|
10051
10199
|
}
|
|
10200
|
+
function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
10201
|
+
const pubKey = deriveLeafPubkey(descriptor);
|
|
10202
|
+
const tapscript = rebuildTapscript(current, pubKey);
|
|
10203
|
+
const serverPubKey = tapscript.options.serverPubKey;
|
|
10204
|
+
const csvTimelock = timelockToSequence(tapscript.options.csvTimelock).toString();
|
|
10205
|
+
const base = {
|
|
10206
|
+
script: hex.encode(tapscript.pkScript),
|
|
10207
|
+
address: tapscript.address(hrp, serverPubKey).encode(),
|
|
10208
|
+
state: "active",
|
|
10209
|
+
// The materialized signing descriptor is read at sign time to route
|
|
10210
|
+
// inputs locked by a rotated pubkey through
|
|
10211
|
+
// `DescriptorProvider.signWithDescriptor` instead of the identity's
|
|
10212
|
+
// index-0 key. Without it, spends produce unsigned PSBTs that the
|
|
10213
|
+
// server rejects with `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
|
|
10214
|
+
metadata: {
|
|
10215
|
+
...tagSource && { source: WALLET_RECEIVE_SOURCE },
|
|
10216
|
+
signingDescriptor: descriptor
|
|
10217
|
+
}
|
|
10218
|
+
};
|
|
10219
|
+
const params = tapscript instanceof DelegateVtxo.Script ? {
|
|
10220
|
+
...base,
|
|
10221
|
+
type: "delegate",
|
|
10222
|
+
params: {
|
|
10223
|
+
pubKey: hex.encode(pubKey),
|
|
10224
|
+
serverPubKey: hex.encode(serverPubKey),
|
|
10225
|
+
delegatePubKey: hex.encode(tapscript.options.delegatePubKey),
|
|
10226
|
+
csvTimelock
|
|
10227
|
+
}
|
|
10228
|
+
} : {
|
|
10229
|
+
...base,
|
|
10230
|
+
type: "default",
|
|
10231
|
+
params: {
|
|
10232
|
+
pubKey: hex.encode(pubKey),
|
|
10233
|
+
serverPubKey: hex.encode(serverPubKey),
|
|
10234
|
+
csvTimelock
|
|
10235
|
+
}
|
|
10236
|
+
};
|
|
10237
|
+
return { tapscript, params };
|
|
10238
|
+
}
|
|
10052
10239
|
function rebuildTapscript(current, pubKey) {
|
|
10053
10240
|
if (current instanceof DelegateVtxo.Script) {
|
|
10054
10241
|
return new DelegateVtxo.Script({ ...current.options, pubKey });
|
|
@@ -10251,6 +10438,7 @@ function extractArkProviderUrl(provider) {
|
|
|
10251
10438
|
const serverUrl = provider.serverUrl;
|
|
10252
10439
|
return typeof serverUrl === "string" && serverUrl.length > 0 ? serverUrl : void 0;
|
|
10253
10440
|
}
|
|
10441
|
+
var DEFAULT_LOOK_AHEAD_WINDOW = 20;
|
|
10254
10442
|
var MAINNET_UNILATERAL_EXIT_DELAY = 605184n;
|
|
10255
10443
|
function toXOnlyPubKey(pubkey) {
|
|
10256
10444
|
if (pubkey.length === 33) return pubkey.slice(1);
|
|
@@ -11306,6 +11494,14 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11306
11494
|
this._contractManagerInitializing = void 0;
|
|
11307
11495
|
}
|
|
11308
11496
|
}
|
|
11497
|
+
/**
|
|
11498
|
+
* HD look-ahead configuration for the contract manager. Readonly wallets
|
|
11499
|
+
* have no descriptor provider, hence no watermark to look ahead of.
|
|
11500
|
+
* @see Wallet.lookAheadConfig
|
|
11501
|
+
*/
|
|
11502
|
+
lookAheadConfig() {
|
|
11503
|
+
return void 0;
|
|
11504
|
+
}
|
|
11309
11505
|
async initializeContractManager() {
|
|
11310
11506
|
const virtualTxRepository = this.virtualTxRepository;
|
|
11311
11507
|
let onVtxosPersisted;
|
|
@@ -11340,7 +11536,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11340
11536
|
intentRepository: this.intentRepository,
|
|
11341
11537
|
onVtxosPersisted,
|
|
11342
11538
|
onVtxosSpent,
|
|
11343
|
-
watcherConfig: this.watcherConfig
|
|
11539
|
+
watcherConfig: this.watcherConfig,
|
|
11540
|
+
lookAhead: this.lookAheadConfig()
|
|
11344
11541
|
});
|
|
11345
11542
|
const baselinePubkey = await this.identity.xOnlyPublicKey();
|
|
11346
11543
|
const delegatePubKey = this.offchainTapscript instanceof DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
@@ -11434,7 +11631,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11434
11631
|
}
|
|
11435
11632
|
};
|
|
11436
11633
|
var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
11437
|
-
constructor(identity, network, onchainProvider, arkProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, dustAmount, walletRepository, contractRepository, renewalConfig, delegateProvider, watcherConfig, settlementConfig, walletContractTimelocks, receiveRotator, descriptorProvider) {
|
|
11634
|
+
constructor(identity, network, onchainProvider, arkProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, serverUnrollScript, forfeitOutputScript, forfeitPubkey, dustAmount, walletRepository, contractRepository, renewalConfig, delegateProvider, watcherConfig, settlementConfig, walletContractTimelocks, receiveRotator, descriptorProvider, lookAheadWindow) {
|
|
11438
11635
|
super(
|
|
11439
11636
|
identity,
|
|
11440
11637
|
network,
|
|
@@ -11474,6 +11671,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11474
11671
|
this._serverUnrollScript = serverUnrollScript;
|
|
11475
11672
|
this._receiveRotator = receiveRotator;
|
|
11476
11673
|
this._descriptorProvider = descriptorProvider;
|
|
11674
|
+
this._lookAheadWindow = lookAheadWindow ?? DEFAULT_LOOK_AHEAD_WINDOW;
|
|
11477
11675
|
this._signerRouter = new InputSignerRouter({
|
|
11478
11676
|
identity,
|
|
11479
11677
|
contractRepository,
|
|
@@ -11546,6 +11744,36 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11546
11744
|
* paths only ever take the identity-sign branch.
|
|
11547
11745
|
*/
|
|
11548
11746
|
_descriptorProvider;
|
|
11747
|
+
/** Per-side width of the HD look-ahead band. @see WalletConfig.lookAheadWindow */
|
|
11748
|
+
_lookAheadWindow;
|
|
11749
|
+
/**
|
|
11750
|
+
* Watch a band of missing offchain receive scripts around the HD watermark
|
|
11751
|
+
* so payments to an externally-issued address land without a `restore()`.
|
|
11752
|
+
* Only HD wallets have a watermark to look ahead of; static / `auto`
|
|
11753
|
+
* wallets keep a single index-0 receive address, so the feature stays off.
|
|
11754
|
+
*
|
|
11755
|
+
* `materialize` reads `this.offchainTapscript` at call time, so a refill
|
|
11756
|
+
* after {@link rotateServerSigner} rebuilds the band under the active
|
|
11757
|
+
* signer (persisted old-signer rows stay watched through the repository).
|
|
11758
|
+
*/
|
|
11759
|
+
lookAheadConfig() {
|
|
11760
|
+
const provider = this._descriptorProvider;
|
|
11761
|
+
if (!(provider instanceof HDDescriptorProvider)) return void 0;
|
|
11762
|
+
return {
|
|
11763
|
+
size: this._lookAheadWindow,
|
|
11764
|
+
currentWatermark: async () => await provider.getLastIndexUsed() ?? -1,
|
|
11765
|
+
materialize: (index) => buildReceiveContract(
|
|
11766
|
+
this.offchainTapscript,
|
|
11767
|
+
provider.materializeDescriptorAt(index),
|
|
11768
|
+
this.network.hrp,
|
|
11769
|
+
// Never tagged: a promoted entry was generated by someone
|
|
11770
|
+
// else, and the tag would make the next boot advertise a
|
|
11771
|
+
// third party's invoice address as our own.
|
|
11772
|
+
false
|
|
11773
|
+
).params,
|
|
11774
|
+
onPromoted: (index) => provider.advanceLastIndexUsed(index)
|
|
11775
|
+
};
|
|
11776
|
+
}
|
|
11549
11777
|
_signerRouter;
|
|
11550
11778
|
/**
|
|
11551
11779
|
* @internal Sole write path for `offchainTapscript` after construction.
|
|
@@ -11658,6 +11886,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11658
11886
|
}
|
|
11659
11887
|
});
|
|
11660
11888
|
this.setBoardingTapscriptForRotation(newBoarding);
|
|
11889
|
+
try {
|
|
11890
|
+
await manager.refillLookAhead();
|
|
11891
|
+
} catch (e) {
|
|
11892
|
+
console.warn("look-ahead refill after boarding allocation failed", e);
|
|
11893
|
+
}
|
|
11661
11894
|
return newBoarding.onchainAddress(this.network);
|
|
11662
11895
|
}
|
|
11663
11896
|
/**
|
|
@@ -11779,6 +12012,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11779
12012
|
this.setBoardingTapscriptForRotation(newBoarding);
|
|
11780
12013
|
this.setArkServerPublicKeyForRotation(xonly);
|
|
11781
12014
|
this.setServerUnrollScriptForRotation(newServerUnrollScript);
|
|
12015
|
+
try {
|
|
12016
|
+
await manager.refillLookAhead();
|
|
12017
|
+
} catch (e) {
|
|
12018
|
+
console.warn("look-ahead refill after server-signer rotation failed", e);
|
|
12019
|
+
}
|
|
11782
12020
|
}
|
|
11783
12021
|
/**
|
|
11784
12022
|
* Async mutex that serializes all operations submitting VTXOs to the Arkade
|
|
@@ -11894,6 +12132,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11894
12132
|
if (hd && result.highestConfirmedUsedIndex >= 0) {
|
|
11895
12133
|
await provider.advanceLastIndexUsed(result.highestConfirmedUsedIndex);
|
|
11896
12134
|
}
|
|
12135
|
+
await manager.refillLookAhead();
|
|
11897
12136
|
await manager.refreshVtxos({ includeInactive: true, after: 0 });
|
|
11898
12137
|
const causes = result.handlerErrors.map(
|
|
11899
12138
|
(e) => e.error instanceof Error ? e.error : new Error(String(e.error))
|
|
@@ -11985,6 +12224,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11985
12224
|
* ```
|
|
11986
12225
|
*/
|
|
11987
12226
|
static async create(config) {
|
|
12227
|
+
if (config.lookAheadWindow !== void 0 && (!Number.isInteger(config.lookAheadWindow) || config.lookAheadWindow <= 0)) {
|
|
12228
|
+
throw new Error(
|
|
12229
|
+
`lookAheadWindow must be a positive integer (got ${String(config.lookAheadWindow)})`
|
|
12230
|
+
);
|
|
12231
|
+
}
|
|
11988
12232
|
const pubkey = await config.identity.xOnlyPublicKey();
|
|
11989
12233
|
if (!pubkey) {
|
|
11990
12234
|
throw new Error("Invalid configured public key");
|
|
@@ -12022,7 +12266,8 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12022
12266
|
config.settlementConfig,
|
|
12023
12267
|
setup.walletContractTimelocks,
|
|
12024
12268
|
boot?.rotator,
|
|
12025
|
-
boot?.provider
|
|
12269
|
+
boot?.provider,
|
|
12270
|
+
config.lookAheadWindow
|
|
12026
12271
|
);
|
|
12027
12272
|
wallet._serverInfoSource = setup.serverInfoSource;
|
|
12028
12273
|
if (setup.serverInfoSource === "live") {
|
|
@@ -14016,7 +14261,8 @@ var MessageBus = class {
|
|
|
14016
14261
|
delegateProvider,
|
|
14017
14262
|
settlementConfig: config.settlementConfig,
|
|
14018
14263
|
walletMode: config.walletMode,
|
|
14019
|
-
watcherConfig: config.watcherConfig
|
|
14264
|
+
watcherConfig: config.watcherConfig,
|
|
14265
|
+
lookAheadWindow: config.lookAheadWindow
|
|
14020
14266
|
});
|
|
14021
14267
|
return { wallet, arkProvider, readonlyWallet: wallet };
|
|
14022
14268
|
}
|
|
@@ -16481,6 +16727,9 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
16481
16727
|
)
|
|
16482
16728
|
);
|
|
16483
16729
|
},
|
|
16730
|
+
refillLookAhead() {
|
|
16731
|
+
return Promise.resolve();
|
|
16732
|
+
},
|
|
16484
16733
|
async isWatching() {
|
|
16485
16734
|
const message = {
|
|
16486
16735
|
type: "IS_CONTRACT_MANAGER_WATCHING",
|
|
@@ -16530,6 +16779,11 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
16530
16779
|
return serializeSigningIdentity(this.identity);
|
|
16531
16780
|
}
|
|
16532
16781
|
static async create(options) {
|
|
16782
|
+
if (options.lookAheadWindow !== void 0 && (!Number.isInteger(options.lookAheadWindow) || options.lookAheadWindow <= 0)) {
|
|
16783
|
+
throw new Error(
|
|
16784
|
+
`lookAheadWindow must be a positive integer (got ${String(options.lookAheadWindow)})`
|
|
16785
|
+
);
|
|
16786
|
+
}
|
|
16533
16787
|
const walletRepository = options.storage?.walletRepository ?? new IndexedDBWalletRepository();
|
|
16534
16788
|
const contractRepository = options.storage?.contractRepository ?? new IndexedDBContractRepository();
|
|
16535
16789
|
if (!isSigningCapable(options.identity)) {
|
|
@@ -16579,6 +16833,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
16579
16833
|
settlementConfig: options.settlementConfig,
|
|
16580
16834
|
walletMode: options.walletMode,
|
|
16581
16835
|
watcherConfig: options.watcherConfig,
|
|
16836
|
+
lookAheadWindow: options.lookAheadWindow,
|
|
16582
16837
|
messageTimeouts
|
|
16583
16838
|
};
|
|
16584
16839
|
await initializeMessageBus(
|
|
@@ -19887,5 +20142,5 @@ function isArkContract(str) {
|
|
|
19887
20142
|
}
|
|
19888
20143
|
|
|
19889
20144
|
export { ARKADE_MAGIC, ActivityRegistry, ArkNote, ArkadeCash, ArkadeCashCreateError, AssetManager, BIP322, Batch, ChainedTxType, ContractManager, ContractRepositoryImpl, ContractWatcher, DB_VERSION, DEFAULT_MESSAGE_TIMEOUTS, DelegateManagerImpl, DelegateNotConfiguredError, DelegatorManagerImpl, DelegatorNotConfiguredError, DescriptorSigningProviderMissingError, DustChangeError, ELECTRUM_TCP_HOST, ELECTRUM_WS_URL, ESPLORA_URL, ElectrumOnchainProvider, EmulatorPacket, EsploraProvider, Estimator, Extension, ExtensionNotFoundError, HDDescriptorProvider, INTENT_TERMINAL_STATES, InMemoryContractRepository, InMemoryIntentRepository, InMemoryVirtualTxRepository, InMemoryWalletRepository, IndexedDBContractRepository, IndexedDBIntentRepository, IndexedDBVirtualTxRepository, IndexedDBWalletRepository, MESSAGE_BUS_INITIALIZING, MESSAGE_BUS_NOT_INITIALIZED, MIGRATION_KEY, MessageBus, MessageBusInitializingError, MessageBusNotInitializedError, MissingSigningDescriptorError, MnemonicIdentity, OnchainWallet, P2A, Ramps, ReadonlyAssetManager, ReadonlyDescriptorIdentity, ReadonlySingleKey, ReadonlyWallet, ReadonlyWalletError, RestDelegateProvider, RestDelegatorProvider, RestEmulatorProvider, SeedIdentity, ServiceWorkerReadonlyWallet, ServiceWorkerTimeoutError, ServiceWorkerWallet, SingleKey, TxTree, TxType, TxWeightEstimator, UnilateralExit, UnknownPacket, Unroll, VtxoManager, Wallet2 as Wallet, WalletMessageHandler, WalletNotInitializedError, WalletRepositoryImpl, WsElectrumChainSource, arkade_exports, assertIntentIdUnique, boardingResolver, buildForfeitTx, buildOffchainTx, classifyAgainstSignerSet, classifyContractSigner, closeDatabase, combineTapscriptSigs, contractFromArkContract, contractFromArkContractWithAddress, createAssetPacket, createDefaultActivityRegistry, createExitChainResolver, decodeArkContract, deserializeAssets, deserializeExitPackage, deserializeUtxo, deserializeVtxo, encodeArkContract, extendVirtualCoinForContract, getMigrationStatus, getRandomId, hasBoardingTxExpired, intentMatchesFilter, intentPageBounds, isArkContract, isBatchSignable, isCooperativelyMigratable, isDiscoverable, isRetryableProviderError, isSubdust, isTerminalIntentState, isValidArkAddress, isVtxoExpiringSoon, isVtxoForScript, mergeChainedTxType, migrateWalletRepository, openDatabase, requiresMigration, rollbackMigration, saveVtxosForContract, scriptFromArkAddress, selectCoinsWithAsset, selectVirtualCoins, serializeAssets, serializeExitPackage, serializeUtxo, serializeVtxo, setupServiceWorker, signerSetFromInfo, toXOnlySignerHex, validateConnectorsTxGraph, validateVtxoTxGraph, verifyTapscriptSignatures, waitForIncomingFunds, warnAndFilterVtxosForScript };
|
|
19890
|
-
//# sourceMappingURL=chunk-
|
|
19891
|
-
//# sourceMappingURL=chunk-
|
|
20145
|
+
//# sourceMappingURL=chunk-TS2MTRP4.js.map
|
|
20146
|
+
//# sourceMappingURL=chunk-TS2MTRP4.js.map
|