@arkade-os/sdk 0.4.47 → 0.4.48-rc.0

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 (51) hide show
  1. package/dist/adapters/expo.cjs +4 -4
  2. package/dist/adapters/expo.js +2 -2
  3. package/dist/adapters/indexedDB.cjs +3 -3
  4. package/dist/adapters/indexedDB.js +2 -2
  5. package/dist/{asyncStorageTaskQueue-Dowyo59a.d.cts → asyncStorageTaskQueue-CwknfM_j.d.cts} +2 -2
  6. package/dist/{asyncStorageTaskQueue-Z3aFoXCl.d.ts → asyncStorageTaskQueue-D2Zl7yAB.d.ts} +2 -2
  7. package/dist/{chunk-JAYOXOLT.cjs → chunk-3HUZAIKI.cjs} +11 -11
  8. package/dist/{chunk-JAYOXOLT.cjs.map → chunk-3HUZAIKI.cjs.map} +1 -1
  9. package/dist/{chunk-3N5I6GT6.js → chunk-4AIHKC65.js} +3 -3
  10. package/dist/{chunk-3N5I6GT6.js.map → chunk-4AIHKC65.js.map} +1 -1
  11. package/dist/{chunk-HHV5FPC6.cjs → chunk-CFQO5MCM.cjs} +3 -3
  12. package/dist/chunk-CFQO5MCM.cjs.map +1 -0
  13. package/dist/{chunk-VE67GMGM.cjs → chunk-EA3IWZ4W.cjs} +7 -7
  14. package/dist/{chunk-VE67GMGM.cjs.map → chunk-EA3IWZ4W.cjs.map} +1 -1
  15. package/dist/{chunk-CDDWXBEM.js → chunk-GM6JRQP5.js} +3 -3
  16. package/dist/chunk-GM6JRQP5.js.map +1 -0
  17. package/dist/{chunk-WTTLIFS7.cjs → chunk-RJMFTTRJ.cjs} +486 -108
  18. package/dist/chunk-RJMFTTRJ.cjs.map +1 -0
  19. package/dist/{chunk-OCS5S3L3.js → chunk-SV4PCGKM.js} +383 -7
  20. package/dist/chunk-SV4PCGKM.js.map +1 -0
  21. package/dist/{chunk-AJQ4AOT3.js → chunk-ZRY2KSK5.js} +3 -3
  22. package/dist/{chunk-AJQ4AOT3.js.map → chunk-ZRY2KSK5.js.map} +1 -1
  23. package/dist/index.cjs +154 -146
  24. package/dist/index.d.cts +39 -6
  25. package/dist/index.d.ts +39 -6
  26. package/dist/index.js +2 -2
  27. package/dist/repositories/realm/index.cjs +17 -17
  28. package/dist/repositories/realm/index.js +3 -3
  29. package/dist/repositories/sqlite/index.cjs +16 -16
  30. package/dist/repositories/sqlite/index.js +3 -3
  31. package/dist/{taskRunner-Dz-TI4Rb.d.ts → taskRunner-Df8YQpn1.d.ts} +1 -1
  32. package/dist/{taskRunner-Dz47k0lp.d.cts → taskRunner-RYihSj9E.d.cts} +1 -1
  33. package/dist/wallet/expo/background.cjs +12 -12
  34. package/dist/wallet/expo/background.d.cts +2 -2
  35. package/dist/wallet/expo/background.d.ts +2 -2
  36. package/dist/wallet/expo/background.js +4 -4
  37. package/dist/wallet/expo/index.cjs +12 -12
  38. package/dist/wallet/expo/index.d.cts +2 -2
  39. package/dist/wallet/expo/index.d.ts +2 -2
  40. package/dist/wallet/expo/index.js +3 -3
  41. package/dist/{wallet-Oxz_wLxo.d.cts → wallet-B6s7_5bJ.d.cts} +124 -1
  42. package/dist/{wallet-x7egmXq6.d.ts → wallet-C61huH8i.d.ts} +124 -1
  43. package/dist/worker/expo/index.cjs +7 -7
  44. package/dist/worker/expo/index.d.cts +3 -3
  45. package/dist/worker/expo/index.d.ts +3 -3
  46. package/dist/worker/expo/index.js +3 -3
  47. package/package.json +1 -1
  48. package/dist/chunk-CDDWXBEM.js.map +0 -1
  49. package/dist/chunk-HHV5FPC6.cjs.map +0 -1
  50. package/dist/chunk-OCS5S3L3.js.map +0 -1
  51. package/dist/chunk-WTTLIFS7.cjs.map +0 -1
@@ -1,10 +1,10 @@
1
- import { Transaction, setArkPsbtField, PrevArkTxField, ConditionWitness, AssetId, AssetGroup, AssetInput, AssetOutput, Metadata, Packet, craftToSpendTx, getArkPsbtFields, CosignerPublicKey, BufferReader, BufferWriter, OP_RETURN_EMPTY_PKSCRIPT, VtxoTaprootTree, baseFetch, Intent, maybeArkError, isArkError, ArkErrorName, ProviderUnavailableError, FetchError, isFetchTimeoutError, AssetRef, isEventSourceError, RestArkProvider, RestIndexerProvider, ArkError } from './chunk-CDDWXBEM.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, DEFAULT_PAGE_SIZE, DelegateVtxo, WALLET_RECEIVE_SOURCE, deriveDescriptorLeafPubKey, DefaultVtxo, BoardingContractHandler } from './chunk-XN3554FT.js';
1
+ import { Transaction, setArkPsbtField, PrevArkTxField, ConditionWitness, AssetId, AssetGroup, AssetInput, AssetOutput, Metadata, Packet, craftToSpendTx, getArkPsbtFields, CosignerPublicKey, BufferReader, BufferWriter, OP_RETURN_EMPTY_PKSCRIPT, VtxoTaprootTree, baseFetch, Intent, maybeArkError, isArkError, ArkErrorName, ProviderUnavailableError, FetchError, isFetchTimeoutError, AssetRef, isEventSourceError, RestArkProvider, RestIndexerProvider, ArkError } from './chunk-GM6JRQP5.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, DEFAULT_PAGE_SIZE, DelegateVtxo, WALLET_RECEIVE_SOURCE, deriveDescriptorLeafPubKey, BoardingContractHandler } from './chunk-XN3554FT.js';
3
3
  import { VtxoScript, CSVMultisigTapscript, DEFAULT_NETWORK, ArkAddress, sequenceToTimelock, decodeTapscript, scriptFromTapLeafScript, CLTVMultisigTapscript, timelockToSequence, DEFAULT_NETWORK_NAME, getSequence, getNetwork, MultisigTapscript, networks as networks$1, DEFAULT_ARKADE_SERVER_URL } from './chunk-C7TXXTMS.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';
6
6
  import { SigHash, Script, OP, OutScript, Address, RawWitness, p2tr, p2wpkh, TaprootControlBlock, DEFAULT_SEQUENCE, Transaction as Transaction$2 } from '@scure/btc-signer';
7
- import { hex, base58, base64 } from '@scure/base';
7
+ import { hex, base58, base64, bech32m } from '@scure/base';
8
8
  import * as musig2 from '@scure/btc-signer/musig2.js';
9
9
  import { equalBytes as equalBytes$1, bytesToNumberBE } from '@noble/curves/utils.js';
10
10
  import { signAsync, schnorr as schnorr$1, Point } from '@noble/secp256k1';
@@ -2437,6 +2437,15 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks) {
2437
2437
  await hooks?.afterFinalize?.();
2438
2438
  return { arkTxid, signedCheckpointTxs };
2439
2439
  }
2440
+ async function signAndSubmitOffchainTx(params) {
2441
+ const offchainTx = buildOffchainTx(params.inputs, params.outputs, params.serverUnrollScript);
2442
+ const signer = {
2443
+ signArkTx: async (arkTx) => ({ arkTx: await params.identity.sign(arkTx) }),
2444
+ signCheckpoint: (checkpoint) => params.identity.sign(checkpoint)
2445
+ };
2446
+ const { arkTxid } = await submitOffchainTx(params.provider, offchainTx, signer);
2447
+ return arkTxid;
2448
+ }
2440
2449
  var AmountVariableName = "amount";
2441
2450
  var ExpiryVariableName = "expiry";
2442
2451
  var BirthVariableName = "birth";
@@ -2744,6 +2753,7 @@ async function runWithCrossInstanceLock(name, fn) {
2744
2753
  });
2745
2754
  }
2746
2755
  var MAX_VTXOS_PER_SETTLEMENT = 50;
2756
+ var MAX_INPUTS_PER_INTENT = 20;
2747
2757
  function byValueDescending(vtxos) {
2748
2758
  return [...vtxos].sort((a, b) => b.value - a.value);
2749
2759
  }
@@ -4333,6 +4343,96 @@ function readUInt32BE(array, offset) {
4333
4343
  function noteTapscript(preimageHash) {
4334
4344
  return Script.encode(["SHA256", preimageHash, "EQUAL"]);
4335
4345
  }
4346
+ var ArkCash = class _ArkCash {
4347
+ constructor(privateKey, serverPubKey, csvTimelock, hrp = _ArkCash.DefaultHRP) {
4348
+ this.csvTimelock = csvTimelock;
4349
+ this.hrp = hrp;
4350
+ if (privateKey.length !== 32) {
4351
+ throw new Error(
4352
+ `Invalid private key length: expected 32 bytes, got ${privateKey.length}`
4353
+ );
4354
+ }
4355
+ if (serverPubKey.length !== 32) {
4356
+ throw new Error(
4357
+ `Invalid server public key length: expected 32 bytes, got ${serverPubKey.length}`
4358
+ );
4359
+ }
4360
+ this._privateKey = privateKey.slice();
4361
+ this._serverPubKey = serverPubKey.slice();
4362
+ this._publicKey = pubSchnorr(this._privateKey);
4363
+ }
4364
+ csvTimelock;
4365
+ hrp;
4366
+ static DefaultHRP = "arkcash";
4367
+ static Version = 0;
4368
+ static PayloadLength = 1 + 32 + 32 + 4;
4369
+ // 69 bytes
4370
+ // Keys are held as private copies so a caller mutating the array it passed
4371
+ // in — or one it reads back from a getter — cannot alter this note's
4372
+ // identity or the outputs derived from it.
4373
+ _privateKey;
4374
+ _serverPubKey;
4375
+ _publicKey;
4376
+ /** The note's private key. Returns a fresh copy; mutating it is a no-op. */
4377
+ get privateKey() {
4378
+ return this._privateKey.slice();
4379
+ }
4380
+ /** The server's public key. Returns a fresh copy; mutating it is a no-op. */
4381
+ get serverPubKey() {
4382
+ return this._serverPubKey.slice();
4383
+ }
4384
+ /** The note's public key. Returns a fresh copy; mutating it is a no-op. */
4385
+ get publicKey() {
4386
+ return this._publicKey.slice();
4387
+ }
4388
+ static generate(serverPubKey, csvTimelock, hrp) {
4389
+ return new _ArkCash(randomPrivateKeyBytes(), serverPubKey, csvTimelock, hrp);
4390
+ }
4391
+ static fromString(encoded) {
4392
+ const decoded = bech32m.decodeUnsafe(encoded.trim().toLowerCase(), 1023);
4393
+ if (!decoded) {
4394
+ throw new Error("Invalid arkcash string: failed to decode bech32m");
4395
+ }
4396
+ const data = new Uint8Array(bech32m.fromWords(decoded.words));
4397
+ if (data.length !== _ArkCash.PayloadLength) {
4398
+ throw new Error(
4399
+ `Invalid arkcash data length: expected ${_ArkCash.PayloadLength} bytes, got ${data.length}`
4400
+ );
4401
+ }
4402
+ const version = data[0];
4403
+ if (version !== _ArkCash.Version) {
4404
+ throw new Error(`Unsupported arkcash version: ${version}`);
4405
+ }
4406
+ const privateKey = data.slice(1, 33);
4407
+ const serverPubKey = data.slice(33, 65);
4408
+ const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
4409
+ const csvTimelock = sequenceToTimelock(sequence);
4410
+ return new _ArkCash(privateKey, serverPubKey, csvTimelock, decoded.prefix);
4411
+ }
4412
+ toString() {
4413
+ const data = new Uint8Array(_ArkCash.PayloadLength);
4414
+ data[0] = _ArkCash.Version;
4415
+ data.set(this._privateKey, 1);
4416
+ data.set(this._serverPubKey, 33);
4417
+ const sequence = timelockToSequence(this.csvTimelock);
4418
+ new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
4419
+ const words = bech32m.toWords(data);
4420
+ return bech32m.encode(this.hrp, words, 1023);
4421
+ }
4422
+ get identity() {
4423
+ return SingleKey.fromPrivateKey(this._privateKey);
4424
+ }
4425
+ get vtxoScript() {
4426
+ return new DefaultVtxo.Script({
4427
+ pubKey: this._publicKey,
4428
+ serverPubKey: this._serverPubKey,
4429
+ csvTimelock: this.csvTimelock
4430
+ });
4431
+ }
4432
+ address(addressHrp) {
4433
+ return this.vtxoScript.address(addressHrp, this._serverPubKey);
4434
+ }
4435
+ };
4336
4436
 
4337
4437
  // src/repositories/intentRepository.ts
4338
4438
  var ALL_INTENT_STATES = [
@@ -10127,6 +10227,24 @@ async function spendableVtxosExcludingLocked(vtxos, intentRepository) {
10127
10227
  }
10128
10228
  return excludeLockedOutpoints(vtxos, locked);
10129
10229
  }
10230
+ var cashReport = (vtxo, reason) => ({
10231
+ txid: vtxo.txid,
10232
+ vout: vtxo.vout,
10233
+ value: vtxo.value,
10234
+ reason
10235
+ });
10236
+ var ArkCashCreateError = class extends Error {
10237
+ constructor(cash, cause) {
10238
+ super(
10239
+ `Failed to create ArkCash: send failed after the note may have been submitted. Recover with claimCash using the token on this error's \`cash\` field.`
10240
+ );
10241
+ this.cash = cash;
10242
+ this.cause = cause;
10243
+ this.name = "ArkCashCreateError";
10244
+ }
10245
+ cash;
10246
+ cause;
10247
+ };
10130
10248
  var ReadonlyWallet = class _ReadonlyWallet {
10131
10249
  constructor(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegateProvider, watcherConfig, walletContractTimelocks) {
10132
10250
  this.identity = identity;
@@ -12586,7 +12704,6 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
12586
12704
  if (!hasPending) {
12587
12705
  return { finalized: [], pending: [] };
12588
12706
  }
12589
- const MAX_INPUTS_PER_INTENT = 20;
12590
12707
  if (!vtxos || vtxos.length === 0) {
12591
12708
  const scriptMap = await this.getScriptMap();
12592
12709
  const allExtended = [];
@@ -12696,6 +12813,265 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
12696
12813
  settings: { ...state.settings, hasPendingTx: value }
12697
12814
  }));
12698
12815
  }
12816
+ /**
12817
+ * Create an ArkCash bearer instrument.
12818
+ *
12819
+ * Generates a fresh keypair, sends the specified amount to a DefaultVtxo
12820
+ * controlled by the new key, and returns the encoded arkcash string.
12821
+ * The receiver can claim the funds using `claimCash()` without ever
12822
+ * sharing their address.
12823
+ *
12824
+ * ArkCash is a short-lived instrument: it carries a private key, so it is
12825
+ * meant to be handed over and claimed promptly, not held. A note left
12826
+ * unclaimed past its batch expiry is swept by the server and `claimCash`
12827
+ * can only report it, not move it.
12828
+ *
12829
+ * @param amount - Amount in satoshis to send. Must be a whole number of
12830
+ * sats at or above the dust threshold — a below-dust amount would mint an
12831
+ * OP_RETURN output that is unspendable as cash.
12832
+ * @returns The encoded arkcash string (e.g., "arkcash1...")
12833
+ */
12834
+ async createCash(amount) {
12835
+ if (!Number.isSafeInteger(amount) || amount < Number(this.dustAmount)) {
12836
+ throw new Error(
12837
+ `Invalid ArkCash amount ${amount}: must be a whole number of sats >= dust (${this.dustAmount})`
12838
+ );
12839
+ }
12840
+ const cashHrp = this.network.hrp.replace(/ark$/, "arkcash");
12841
+ const cash = ArkCash.generate(
12842
+ this.arkServerPublicKey,
12843
+ this.offchainTapscript.options.csvTimelock,
12844
+ cashHrp
12845
+ );
12846
+ const address = cash.address(this.network.hrp).encode();
12847
+ const cashStr = cash.toString();
12848
+ try {
12849
+ await this.send({ address, amount });
12850
+ } catch (error) {
12851
+ throw new ArkCashCreateError(cashStr, error);
12852
+ }
12853
+ return cashStr;
12854
+ }
12855
+ /**
12856
+ * Claim an ArkCash bearer instrument: sweep what can be swept, report the
12857
+ * rest.
12858
+ *
12859
+ * Every spendable VTXO at the arkcash address is swept to this wallet in
12860
+ * its own offchain transaction, signed with the key carried by the arkcash
12861
+ * string. Nothing is ever persisted: no contract is imported, and the
12862
+ * arkcash key is not stored. Anything that cannot be swept — server-swept,
12863
+ * subdust, already claimed, or asset-bearing — is returned in `unclaimed`
12864
+ * with a per-VTXO reason and otherwise ignored.
12865
+ *
12866
+ * The arkcash string is the recovery token: a claim interrupted between
12867
+ * submit and finalize is completed by simply re-running `claimCash`, which
12868
+ * drains any pending arkcash transaction on the server before sweeping.
12869
+ *
12870
+ * @param cashStr - The encoded arkcash string (e.g., "arkcash1...")
12871
+ * @returns The swept total and the report of what was left behind. The
12872
+ * shape is open: further buckets may be added alongside `unclaimed`.
12873
+ */
12874
+ async claimCash(cashStr) {
12875
+ const cash = ArkCash.fromString(cashStr);
12876
+ const cashScript = cash.vtxoScript;
12877
+ const cashPkScript = hex.encode(cashScript.pkScript);
12878
+ const scripts = [cashPkScript];
12879
+ let vtxos = await this.fetchAllVtxos(scripts);
12880
+ if (vtxos.length === 0) {
12881
+ throw new Error("No VTXOs found for this arkcash");
12882
+ }
12883
+ const myPkScript = ArkAddress.decode(await this.getAddress()).pkScript;
12884
+ let { spendable, unclaimed } = this.classifyCashVtxos(vtxos);
12885
+ let swept = 0;
12886
+ const drainable = vtxos.filter((vtxo) => !isSubdust(vtxo, this.dustAmount));
12887
+ if (drainable.length > 0) {
12888
+ let drained = { count: 0, swept: 0, claimed: /* @__PURE__ */ new Set() };
12889
+ try {
12890
+ drained = await this.finalizePendingCashTxs(
12891
+ cash,
12892
+ drainable,
12893
+ cashScript,
12894
+ myPkScript
12895
+ );
12896
+ } catch (error) {
12897
+ console.error("Failed to drain pending arkcash txs:", error);
12898
+ }
12899
+ if (drained.count > 0) {
12900
+ vtxos = await this.fetchAllVtxos(scripts);
12901
+ ({ spendable, unclaimed } = this.classifyCashVtxos(vtxos));
12902
+ swept += drained.swept;
12903
+ unclaimed = unclaimed.filter(
12904
+ (vtxo) => !drained.claimed.has(`${vtxo.txid}:${vtxo.vout}`)
12905
+ );
12906
+ }
12907
+ }
12908
+ if (spendable.length > 0) {
12909
+ const info = await this.arkProvider.getInfo();
12910
+ const serverUnrollScript = CSVMultisigTapscript.decode(
12911
+ hex.decode(info.checkpointTapscript)
12912
+ );
12913
+ for (const vtxo of spendable) {
12914
+ try {
12915
+ await signAndSubmitOffchainTx({
12916
+ identity: cash.identity,
12917
+ provider: this.arkProvider,
12918
+ inputs: [
12919
+ {
12920
+ txid: vtxo.txid,
12921
+ vout: vtxo.vout,
12922
+ value: vtxo.value,
12923
+ tapLeafScript: cashScript.forfeit(),
12924
+ tapTree: cashScript.encode()
12925
+ }
12926
+ ],
12927
+ outputs: [{ script: myPkScript, amount: BigInt(vtxo.value) }],
12928
+ serverUnrollScript
12929
+ });
12930
+ swept += vtxo.value;
12931
+ } catch (error) {
12932
+ console.error(`Failed to sweep arkcash VTXO ${vtxo.txid}:${vtxo.vout}:`, error);
12933
+ unclaimed.push(cashReport(vtxo, "sweep-failed"));
12934
+ }
12935
+ }
12936
+ }
12937
+ return {
12938
+ swept,
12939
+ unclaimed: {
12940
+ amount: unclaimed.reduce((total, vtxo) => total + vtxo.value, 0),
12941
+ vtxos: unclaimed
12942
+ }
12943
+ };
12944
+ }
12945
+ /**
12946
+ * Split the VTXOs at an arkcash address into the ones the thin sweep can
12947
+ * move and the ones it can only report.
12948
+ */
12949
+ classifyCashVtxos(vtxos) {
12950
+ const spendable = [];
12951
+ const unclaimed = [];
12952
+ for (const vtxo of vtxos) {
12953
+ if (!isSpendable(vtxo)) {
12954
+ unclaimed.push(cashReport(vtxo, "already-spent"));
12955
+ } else if (isSubdust(vtxo, this.dustAmount)) {
12956
+ unclaimed.push(cashReport(vtxo, "subdust"));
12957
+ } else if (isRecoverable(vtxo)) {
12958
+ unclaimed.push(cashReport(vtxo, "swept"));
12959
+ } else if (vtxo.assets && vtxo.assets.length > 0) {
12960
+ unclaimed.push(cashReport(vtxo, "has-assets"));
12961
+ } else {
12962
+ spendable.push(vtxo);
12963
+ }
12964
+ }
12965
+ return { spendable, unclaimed };
12966
+ }
12967
+ /** Read every page of an unfiltered VTXO query for the given scripts. */
12968
+ async fetchAllVtxos(scripts) {
12969
+ const pageSize = 100;
12970
+ const all = [];
12971
+ const seen = /* @__PURE__ */ new Set();
12972
+ for (let pageIndex = 0; ; pageIndex++) {
12973
+ const { vtxos, page } = await this.indexerProvider.getVtxos({
12974
+ scripts,
12975
+ pageIndex,
12976
+ pageSize
12977
+ });
12978
+ for (const vtxo of vtxos) {
12979
+ const outpoint = `${vtxo.txid}:${vtxo.vout}`;
12980
+ if (seen.has(outpoint)) continue;
12981
+ seen.add(outpoint);
12982
+ all.push(vtxo);
12983
+ }
12984
+ if (!page || vtxos.length < pageSize) return all;
12985
+ }
12986
+ }
12987
+ /**
12988
+ * Complete any sweep a previous `claimCash` registered but never finalized.
12989
+ * A thin variant of {@link finalizePendingTxs}, scoped to the arkcash key:
12990
+ * the intent is signed with it, and so are the returned checkpoints.
12991
+ *
12992
+ * A drained sweep is not automatically *ours*. Whoever registered it chose
12993
+ * the destination, so a tx a different claimer left half-finished pays that
12994
+ * claimer — finalizing it is still right (the input is spent either way, and
12995
+ * completing it unsticks the funds), but only the value it actually pays to
12996
+ * `myPkScript` may be counted as claimed here.
12997
+ *
12998
+ * @param vtxos - VTXOs at the arkcash contract's own pkScript, spent ones
12999
+ * included (a registered sweep marks its input spent). Any other outpoint —
13000
+ * subdust above all — would make the proof invalid, since it describes every
13001
+ * input by that pkScript.
13002
+ * @returns The number of pending txs finalized, the sats among them paid to
13003
+ * this wallet, and the outpoints those txs consumed to pay it.
13004
+ */
13005
+ async finalizePendingCashTxs(cash, vtxos, cashScript, myPkScript) {
13006
+ const result = { count: 0, swept: 0, claimed: /* @__PURE__ */ new Set() };
13007
+ const inputs = vtxos.map((vtxo) => ({
13008
+ ...vtxo,
13009
+ forfeitTapLeafScript: cashScript.forfeit(),
13010
+ intentTapLeafScript: cashScript.forfeit(),
13011
+ tapTree: cashScript.encode()
13012
+ }));
13013
+ if (inputs.length === 0) return result;
13014
+ const identity = cash.identity;
13015
+ const seenTxids = /* @__PURE__ */ new Set();
13016
+ const pendingTxs = [];
13017
+ for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
13018
+ const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
13019
+ const message = { type: "get-pending-tx", expire_at: 0 };
13020
+ const proof = Intent.create(message, batch, []);
13021
+ const signedProof = await identity.sign(
13022
+ proof,
13023
+ Array.from({ length: batch.length + 1 }, (_, j) => j)
13024
+ );
13025
+ const batchPending = await this.arkProvider.getPendingTxs({
13026
+ proof: base64.encode(signedProof.toPSBT()),
13027
+ message
13028
+ });
13029
+ for (const pendingTx of batchPending) {
13030
+ if (seenTxids.has(pendingTx.arkTxid)) continue;
13031
+ seenTxids.add(pendingTx.arkTxid);
13032
+ pendingTxs.push(pendingTx);
13033
+ }
13034
+ }
13035
+ const myPkScriptHex = hex.encode(myPkScript);
13036
+ for (const pendingTx of pendingTxs) {
13037
+ try {
13038
+ const checkpointTxs = pendingTx.signedCheckpointTxs.map(
13039
+ (checkpoint) => Transaction$2.fromPSBT(base64.decode(checkpoint))
13040
+ );
13041
+ const finalCheckpoints = await Promise.all(
13042
+ checkpointTxs.map(
13043
+ async (checkpoint) => base64.encode((await identity.sign(checkpoint)).toPSBT())
13044
+ )
13045
+ );
13046
+ await this.arkProvider.finalizeTx(pendingTx.arkTxid, finalCheckpoints);
13047
+ result.count++;
13048
+ const paidToMe = this.arkTxAmountPaidTo(pendingTx.finalArkTx, myPkScriptHex);
13049
+ if (paidToMe === 0) continue;
13050
+ result.swept += paidToMe;
13051
+ for (const checkpoint of checkpointTxs) {
13052
+ for (let i = 0; i < checkpoint.inputsLength; i++) {
13053
+ const input = checkpoint.getInput(i);
13054
+ if (!input.txid) continue;
13055
+ result.claimed.add(`${hex.encode(input.txid)}:${input.index}`);
13056
+ }
13057
+ }
13058
+ } catch (error) {
13059
+ console.error(`Failed to finalize pending arkcash tx ${pendingTx.arkTxid}:`, error);
13060
+ }
13061
+ }
13062
+ return result;
13063
+ }
13064
+ /** Sum the outputs of an ark tx PSBT that pay the given scriptPubKey. */
13065
+ arkTxAmountPaidTo(arkTxPsbt, pkScriptHex) {
13066
+ const arkTx = Transaction$2.fromPSBT(base64.decode(arkTxPsbt));
13067
+ let total = 0;
13068
+ for (let i = 0; i < arkTx.outputsLength; i++) {
13069
+ const output = arkTx.getOutput(i);
13070
+ if (!output.script || output.amount === void 0) continue;
13071
+ if (hex.encode(output.script) === pkScriptHex) total += Number(output.amount);
13072
+ }
13073
+ return total;
13074
+ }
12699
13075
  /**
12700
13076
  * Send BTC and/or assets to one or more recipients.
12701
13077
  *
@@ -19412,6 +19788,6 @@ function isArkContract(str) {
19412
19788
  return str.startsWith(ARKCONTRACT_PREFIX + "=");
19413
19789
  }
19414
19790
 
19415
- export { ARKADE_MAGIC, ActivityRegistry, ArkNote, 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, isExpired, isRecoverable, isRetryableProviderError, isSpendable, 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 };
19416
- //# sourceMappingURL=chunk-OCS5S3L3.js.map
19417
- //# sourceMappingURL=chunk-OCS5S3L3.js.map
19791
+ export { ARKADE_MAGIC, ActivityRegistry, ArkCash, ArkCashCreateError, ArkNote, 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, isExpired, isRecoverable, isRetryableProviderError, isSpendable, 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 };
19792
+ //# sourceMappingURL=chunk-SV4PCGKM.js.map
19793
+ //# sourceMappingURL=chunk-SV4PCGKM.js.map