@arkade-os/sdk 0.4.34 → 0.4.36

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 (69) hide show
  1. package/dist/adapters/expo.cjs +4 -4
  2. package/dist/adapters/expo.d.cts +2 -2
  3. package/dist/adapters/expo.d.ts +2 -2
  4. package/dist/adapters/expo.js +2 -2
  5. package/dist/adapters/indexedDB.cjs +3 -3
  6. package/dist/adapters/indexedDB.js +2 -2
  7. package/dist/{ark-Dsv5Jq4E.d.cts → ark-D6sau_6-.d.cts} +458 -3
  8. package/dist/{ark-Dsv5Jq4E.d.ts → ark-D6sau_6-.d.ts} +458 -3
  9. package/dist/{asyncStorageTaskQueue-D92ch8yI.d.cts → asyncStorageTaskQueue-CpC027t_.d.cts} +2 -2
  10. package/dist/{asyncStorageTaskQueue-BH-zuth5.d.ts → asyncStorageTaskQueue-GT8fmPUG.d.ts} +2 -2
  11. package/dist/{chunk-FXFBPXV3.js → chunk-2JJKX2RK.js} +139 -41
  12. package/dist/chunk-2JJKX2RK.js.map +1 -0
  13. package/dist/{chunk-CCLNFHJ5.cjs → chunk-2XE5BSIY.cjs} +16 -10
  14. package/dist/chunk-2XE5BSIY.cjs.map +1 -0
  15. package/dist/{chunk-ZS3OZHC7.cjs → chunk-A5PY4NBP.cjs} +7 -7
  16. package/dist/{chunk-ZS3OZHC7.cjs.map → chunk-A5PY4NBP.cjs.map} +1 -1
  17. package/dist/{chunk-FSAXPBGP.cjs → chunk-C6OODRWD.cjs} +143 -40
  18. package/dist/chunk-C6OODRWD.cjs.map +1 -0
  19. package/dist/{chunk-HFXEUW55.js → chunk-HBPKIIMN.js} +1472 -202
  20. package/dist/chunk-HBPKIIMN.js.map +1 -0
  21. package/dist/{chunk-5WDBHWX3.js → chunk-KZV3FJJR.js} +10 -4
  22. package/dist/chunk-KZV3FJJR.js.map +1 -0
  23. package/dist/{chunk-XCHBQVMK.cjs → chunk-TUSGEWOX.cjs} +1540 -265
  24. package/dist/chunk-TUSGEWOX.cjs.map +1 -0
  25. package/dist/{chunk-VVGD3JIP.js → chunk-Z2VRVZW4.js} +3 -3
  26. package/dist/{chunk-VVGD3JIP.js.map → chunk-Z2VRVZW4.js.map} +1 -1
  27. package/dist/contracts/handlers/index.d.cts +3 -3
  28. package/dist/contracts/handlers/index.d.ts +3 -3
  29. package/dist/{delegate-BaS5SCIW.d.cts → delegate-C-L6gSZx.d.cts} +1 -1
  30. package/dist/{delegate-Baz_hb83.d.ts → delegate-De5__fpZ.d.ts} +1 -1
  31. package/dist/{index-FwXZveaX.d.ts → index-BETdjE_o.d.ts} +2 -2
  32. package/dist/{index-lNZ6qaO3.d.cts → index-jwQfHP6D.d.cts} +2 -2
  33. package/dist/index.cjs +129 -105
  34. package/dist/index.d.cts +69 -9
  35. package/dist/index.d.ts +69 -9
  36. package/dist/index.js +2 -2
  37. package/dist/repositories/realm/index.cjs +12 -12
  38. package/dist/repositories/realm/index.cjs.map +1 -1
  39. package/dist/repositories/realm/index.d.cts +2 -2
  40. package/dist/repositories/realm/index.d.ts +2 -2
  41. package/dist/repositories/realm/index.js +3 -3
  42. package/dist/repositories/realm/index.js.map +1 -1
  43. package/dist/repositories/sqlite/index.cjs +11 -11
  44. package/dist/repositories/sqlite/index.d.cts +1 -1
  45. package/dist/repositories/sqlite/index.d.ts +1 -1
  46. package/dist/repositories/sqlite/index.js +2 -2
  47. package/dist/{taskRunner-vFRA3F9b.d.cts → taskRunner-DCyp6Gea.d.cts} +2 -2
  48. package/dist/{taskRunner-B1NUWyWR.d.ts → taskRunner-DnxtObeq.d.ts} +2 -2
  49. package/dist/wallet/expo/background.cjs +12 -12
  50. package/dist/wallet/expo/background.d.cts +3 -3
  51. package/dist/wallet/expo/background.d.ts +3 -3
  52. package/dist/wallet/expo/background.js +4 -4
  53. package/dist/wallet/expo/index.cjs +11 -11
  54. package/dist/wallet/expo/index.d.cts +4 -4
  55. package/dist/wallet/expo/index.d.ts +4 -4
  56. package/dist/wallet/expo/index.js +3 -3
  57. package/dist/{wallet-D6uoBLmS.d.ts → wallet-BWHbd5b1.d.cts} +231 -8
  58. package/dist/{wallet-By9HIo0Q.d.cts → wallet-Bth5uucA.d.ts} +231 -8
  59. package/dist/worker/expo/index.cjs +7 -7
  60. package/dist/worker/expo/index.d.cts +4 -4
  61. package/dist/worker/expo/index.d.ts +4 -4
  62. package/dist/worker/expo/index.js +3 -3
  63. package/package.json +2 -2
  64. package/dist/chunk-5WDBHWX3.js.map +0 -1
  65. package/dist/chunk-CCLNFHJ5.cjs.map +0 -1
  66. package/dist/chunk-FSAXPBGP.cjs.map +0 -1
  67. package/dist/chunk-FXFBPXV3.js.map +0 -1
  68. package/dist/chunk-HFXEUW55.js.map +0 -1
  69. package/dist/chunk-XCHBQVMK.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { Transaction } from '@scure/btc-signer';
2
2
  import { Bytes } from '@scure/btc-signer/utils.js';
3
- import { B as BatchStartedEvent, s as TreeSigningStartedEvent, t as TxTree, u as TreeNoncesEvent, v as BatchFinalizationEvent, w as BatchFinalizedEvent, x as BatchFailedEvent, y as TreeTxEvent, z as TreeSignatureEvent, h as SettlementEvent, b as WalletConfig, W as WalletRepository, C as ContractRepository, D as DescriptorProvider, e as IContractManager, F as IReadonlyWallet, H as ReadonlyIdentity, N as Network, O as OnchainProvider, n as IndexerProvider, J as DelegateProvider, K as ReadonlyWalletConfig, o as RelativeTimelock, L as IReadonlyAssetManager, m as ArkProvider, M as NetworkName, P as ArkInfo, Q as ArkAddress, c as WalletBalance, G as GetVtxosFilter, E as ExtendedVirtualCoin, A as ArkTransaction, d as ExtendedCoin, U as Coin, X as ContractManager, I as IWallet, Y as CSVMultisigTapscript, a as Identity, Z as SettlementConfig, i as IAssetManager, _ as VtxoManager, f as IDelegateManager, S as SendBitcoinParams, g as SettleParams, R as Recipient, $ as SignerSession, a0 as SignedIntent, a1 as Intent } from './ark-Dsv5Jq4E.cjs';
3
+ import { B as BatchStartedEvent, v as TreeSigningStartedEvent, w as TxTree, x as TreeNoncesEvent, y as BatchFinalizationEvent, z as BatchFinalizedEvent, D as BatchFailedEvent, F as TreeTxEvent, H as TreeSignatureEvent, h as SettlementEvent, b as WalletConfig, W as WalletRepository, C as ContractRepository, J as DescriptorProvider, e as IContractManager, K as IReadonlyWallet, L as ReadonlyIdentity, N as Network, O as OnchainProvider, n as IndexerProvider, M as DelegateProvider, P as ReadonlyWalletConfig, o as RelativeTimelock, Q as IReadonlyAssetManager, m as ArkProvider, U as NetworkName, X as ArkInfo, Y as ArkAddress, c as WalletBalance, G as GetVtxosFilter, E as ExtendedVirtualCoin, A as ArkTransaction, d as ExtendedCoin, Z as Coin, _ as ContractManager, I as IWallet, a as Identity, $ as CSVMultisigTapscript, a0 as SettlementConfig, i as IAssetManager, a1 as VtxoManager, f as IDelegateManager, S as SendBitcoinParams, g as SettleParams, R as Recipient, a2 as SignerSession, a3 as SignedIntent, a4 as Intent } from './ark-D6sau_6-.js';
4
4
  import { TransactionOutput } from '@scure/btc-signer/psbt.js';
5
- import { D as DefaultVtxo, a as DelegateVtxo } from './delegate-BaS5SCIW.cjs';
5
+ import { D as DefaultVtxo, a as DelegateVtxo } from './delegate-De5__fpZ.js';
6
6
 
7
7
  /**
8
8
  * Batch namespace provides utilities for joining and processing batch session.
@@ -348,6 +348,15 @@ declare class WalletReceiveRotator {
348
348
  * needs to call this directly.
349
349
  */
350
350
  drain(): Promise<void>;
351
+ /**
352
+ * Run `fn` on the rotator's serialization chain, so it cannot interleave
353
+ * with a receive `rotate()`. Used by {@link Wallet.rotateServerSigner} to
354
+ * serialize server-signer rotation against HD receive rotation: both
355
+ * rebuild and swap `offchainTapscript`, so running them concurrently could
356
+ * tear the wallet's visible receive state. The chain keeps advancing even
357
+ * if `fn` rejects (its own caller still sees the rejection).
358
+ */
359
+ runExclusive<T>(fn: () => Promise<T>): Promise<T>;
351
360
  /**
352
361
  * Tear down the subscription first so no late `vtxo_received` event
353
362
  * can queue work on a disposing wallet, then drain any in-flight
@@ -385,12 +394,29 @@ type IncomingFunds = {
385
394
  spentVtxos: ExtendedVirtualCoin[];
386
395
  };
387
396
 
397
+ /**
398
+ * Boarding UTXOs grouped by the boarding address they sit on, carrying that
399
+ * address's signer association explicitly. Returned by
400
+ * {@link ReadonlyWallet.getBoardingUtxosForSigners} because a flat
401
+ * {@link ExtendedCoin} cannot carry the signer: it retains only the encoded
402
+ * leaves/tapTree the spend needs, not the owning `DefaultVtxo.Script` (and so
403
+ * not its `serverPubKey` or CSV delay). The deprecated-signer boarding
404
+ * classification reads both back from this group (Section 7).
405
+ */
406
+ interface BoardingUtxoGroup {
407
+ /** Tapscript of the boarding address the coins sit on. */
408
+ tapscript: DefaultVtxo.Script;
409
+ /** Server key of that address, normalized x-only hex. */
410
+ serverPubKey: string;
411
+ /** CSV exit timelock decoded from THIS tapscript's exit leaf. */
412
+ csvTimelock: RelativeTimelock;
413
+ coins: ExtendedCoin[];
414
+ }
388
415
  declare class ReadonlyWallet implements IReadonlyWallet {
389
416
  readonly identity: ReadonlyIdentity;
390
417
  readonly network: Network;
391
418
  readonly onchainProvider: OnchainProvider;
392
419
  readonly indexerProvider: IndexerProvider;
393
- readonly arkServerPublicKey: Bytes;
394
420
  readonly dustAmount: bigint;
395
421
  readonly walletRepository: WalletRepository;
396
422
  readonly contractRepository: ContractRepository;
@@ -399,7 +425,6 @@ declare class ReadonlyWallet implements IReadonlyWallet {
399
425
  private _contractManagerInitializing?;
400
426
  protected readonly watcherConfig?: ReadonlyWalletConfig["watcherConfig"];
401
427
  private readonly _assetManager;
402
- private _syncVtxosInflight?;
403
428
  readonly walletContractTimelocks: RelativeTimelock[];
404
429
  protected _pendingSpendOutpoints: Set<string>;
405
430
  get assetManager(): IReadonlyAssetManager;
@@ -421,13 +446,63 @@ declare class ReadonlyWallet implements IReadonlyWallet {
421
446
  * it stays the index-0 baseline for their lifetime.
422
447
  */
423
448
  protected _boardingTapscript: DefaultVtxo.Script;
449
+ /**
450
+ * Backing field for the active server signer (x-only, 32 bytes). Read via
451
+ * the public {@link arkServerPublicKey} getter; written only by
452
+ * {@link Wallet.setArkServerPublicKeyForRotation}, the sanctioned
453
+ * server-signer rotation write path (analogue of `_offchainTapscript`). It
454
+ * is a *current value*, not a fixed constructor constant, because
455
+ * mid-session server-signer rotation (plan §4) swaps it when arkd rotates
456
+ * its active signer. Wallets that never span a rotation keep their
457
+ * construction-time snapshot for their lifetime.
458
+ */
459
+ protected _arkServerPublicKey: Bytes;
424
460
  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, delegateProvider?: DelegateProvider | undefined, watcherConfig?: ReadonlyWalletConfig["watcherConfig"], walletContractTimelocks?: RelativeTimelock[]);
461
+ /**
462
+ * x-only hex of the operator's deprecated signer keys (from
463
+ * `ArkInfo.deprecatedSigners`), cached for the OFFLINE read/watch paths.
464
+ * The boarding watch/history surfaces ({@link getBoardingAddresses},
465
+ * {@link getBoardingTxs}) fan out over {current} ∪ this set so a deposit at
466
+ * a boarding address minted under a now-rotated operator signer keeps being
467
+ * watched. Refreshed from the server-info snapshot at construction (via the
468
+ * create() factories) and on a detected signer change. Deliberately NOT
469
+ * consulted by the spend path — {@link getBoardingUtxos} stays
470
+ * current-signer-only (a deprecated-signer input in a plain settle() is
471
+ * rejected; old-signer recovery goes through the migration API).
472
+ */
473
+ protected _deprecatedSigners: Map<string, bigint>;
474
+ /**
475
+ * Refresh the cached deprecated-signer set from a fresh server-info
476
+ * snapshot. Called by the create() factories at construction and by the
477
+ * server-info-change handler mid-session. Lenient: a malformed deprecated
478
+ * entry is skipped, never fatal to wallet creation.
479
+ */
480
+ refreshDeprecatedSigners(info: {
481
+ deprecatedSigners?: readonly {
482
+ pubkey?: string;
483
+ cutoffDate?: bigint;
484
+ }[];
485
+ }): void;
486
+ /**
487
+ * The signer set the boarding WATCH/HISTORY paths fan out over: the wallet's
488
+ * current signer plus every cached deprecated signer. Distinct from the
489
+ * spend path, which is current-signer-only.
490
+ */
491
+ protected watchedBoardingSigners(): Set<string>;
425
492
  /**
426
493
  * Currently-active receive tapscript. Read-only from the outside;
427
494
  * mutated only via {@link Wallet.setOffchainTapscriptForRotation}
428
495
  * by {@link WalletReceiveRotator.rotate}.
429
496
  */
430
497
  get offchainTapscript(): DefaultVtxo.Script | DelegateVtxo.Script;
498
+ /**
499
+ * The wallet's current active server signer (x-only, 32 bytes). Read-only
500
+ * from the outside; mutated only via
501
+ * {@link Wallet.setArkServerPublicKeyForRotation} during mid-session
502
+ * server-signer rotation (plan §4). Single-valued for wallets that never
503
+ * span a rotation.
504
+ */
505
+ get arkServerPublicKey(): Bytes;
431
506
  /**
432
507
  * The wallet's current boarding tapscript (the on-chain onboarding
433
508
  * target). Read-only from the outside; mutated only via
@@ -508,6 +583,15 @@ declare class ReadonlyWallet implements IReadonlyWallet {
508
583
  * @param filter - Optional flags controlling whether recoverable or unrolled VTXOs are included
509
584
  */
510
585
  getVtxos(filter?: GetVtxosFilter): Promise<ExtendedVirtualCoin[]>;
586
+ /**
587
+ * Outpoints of VTXOs whose deprecated signer is past its cutoff (EXPIRED) and
588
+ * which have not yet been swept — unspendable until they recover. Offline:
589
+ * classifies the repo's contracts against the cached signer set (active +
590
+ * {@link _deprecatedSigners}, cutoffs included). Empty fast-path when no
591
+ * signer is deprecated. Consumed by {@link getBalance} (the `pendingRecovery`
592
+ * bucket) and the send coin-selection path so neither counts nor spends them.
593
+ */
594
+ pendingRecoveryOutpoints(): Promise<Set<string>>;
511
595
  /**
512
596
  * Return wallet transaction history derived from Arkade state and boarding transactions.
513
597
  */
@@ -544,14 +628,43 @@ declare class ReadonlyWallet implements IReadonlyWallet {
544
628
  * Always includes the index-0 baseline (identity x-only key), which covers
545
629
  * the degenerate equal-delay case where the index-0 boarding row is
546
630
  * coalesced onto a `default` row and so isn't a `boarding`-typed contract.
631
+ *
632
+ * @param allowedSigners - Optional set of x-only-hex server keys whose
633
+ * persisted boarding rows are included. Defaults to `{current x-only
634
+ * signer}`, preserving today's current-signer-only discovery (and the
635
+ * foreign-ASP guard). The deprecated-signer migration path widens this to
636
+ * reach old-signer boarding addresses. The index-0 baseline and the
637
+ * current display tapscript are always included regardless of the set.
547
638
  */
548
- protected getBoardingTapscripts(): Promise<DefaultVtxo.Script[]>;
639
+ protected getBoardingTapscripts(allowedSigners?: Set<string>): Promise<DefaultVtxo.Script[]>;
640
+ /**
641
+ * Fetch and cache onchain inputs (UTXOs) received at the boarding addresses
642
+ * of the given signer set, grouped per boarding address so the caller keeps
643
+ * the address↔signer association that {@link ExtendedCoin} cannot carry
644
+ * (it retains only the encoded leaves/tapTree the spend needs, not the
645
+ * `DefaultVtxo.Script` and its `serverPubKey`/CSV delay).
646
+ *
647
+ * Per group it does exactly what {@link getBoardingUtxos} does per tapscript:
648
+ * `getCoins` → {@link extendCoinWithTapscript} → `saveUtxos`. Offline-first:
649
+ * it does not call `getInfo()`; the caller supplies the allowed signer set,
650
+ * so the only network calls are the per-address `getCoins`.
651
+ *
652
+ * @param allowedSigners - x-only-hex server keys whose boarding addresses to
653
+ * fetch (passed through to {@link getBoardingTapscripts}).
654
+ */
655
+ getBoardingUtxosForSigners(allowedSigners: Set<string>): Promise<BoardingUtxoGroup[]>;
549
656
  /**
550
657
  * Fetch and cache onchain inputs (UTXOs) received at the wallet's boarding
551
658
  * addresses — the current address plus any historical rotated boarding
552
659
  * addresses that still hold unspent UTXOs (plan §6-III.1). Each UTXO is
553
660
  * annotated with the tapscript of the address it actually sits on, so the
554
661
  * spending path forfeits / exits it with the correct per-index leaves.
662
+ *
663
+ * Current-signer only: a flatten of {@link getBoardingUtxosForSigners} over
664
+ * the wallet's current signer, so the two paths cannot drift. Old-signer
665
+ * boarding recovery goes through the deprecated-signer migration API
666
+ * instead (it would otherwise pull EXPIRED-signer inputs into a plain
667
+ * `settle()` that the server must reject).
555
668
  */
556
669
  getBoardingUtxos(): Promise<ExtendedCoin[]>;
557
670
  /**
@@ -651,7 +764,6 @@ declare class ReadonlyWallet implements IReadonlyWallet {
651
764
  */
652
765
  declare class Wallet extends ReadonlyWallet implements IWallet {
653
766
  readonly arkProvider: ArkProvider;
654
- readonly serverUnrollScript: CSVMultisigTapscript.Type;
655
767
  readonly forfeitOutputScript: Bytes;
656
768
  readonly forfeitPubkey: Bytes;
657
769
  static MIN_FEE_RATE: number;
@@ -669,6 +781,29 @@ declare class Wallet extends ReadonlyWallet implements IWallet {
669
781
  * the contract manager is up first.
670
782
  */
671
783
  private _receiveRotator?;
784
+ /**
785
+ * Unsubscribe handle for the arkProvider's `onServerInfoChanged` stream
786
+ * (mid-session signer-rotation detection). Torn down in {@link dispose}.
787
+ */
788
+ private _serverInfoUnsub?;
789
+ /**
790
+ * Tail of the serialized {@link handleServerInfoChanged} chain. Each
791
+ * `onServerInfoChanged` event chains onto it so handlers run one at a time,
792
+ * and {@link dispose} awaits it so an in-flight re-derive/rotation settles
793
+ * before the contract manager is torn down underneath it.
794
+ */
795
+ private _serverInfoInFlight;
796
+ /**
797
+ * React to a mid-session server-info change (driven by the arkProvider's
798
+ * `DIGEST_MISMATCH` detection). First refresh the cached deprecated-signer
799
+ * set so the boarding WATCH path immediately widens to the just-deprecated
800
+ * signer, then — only if the active signer actually changed — rotate the
801
+ * wallet onto it via {@link rotateServerSigner} (re-deriving the offchain +
802
+ * boarding display tapscripts and registering the current-signer rows).
803
+ * Old-signer rows stay active, so existing funds remain watched. Failures
804
+ * are logged, never thrown back into the provider's emit loop.
805
+ */
806
+ private handleServerInfoChanged;
672
807
  private _receiveRotatorInstalled;
673
808
  /**
674
809
  * Descriptor-aware signer used by {@link _signerRouter} to sign
@@ -693,6 +828,38 @@ declare class Wallet extends ReadonlyWallet implements IWallet {
693
828
  * `boardingTapscript` as read-only.
694
829
  */
695
830
  setBoardingTapscriptForRotation(tapscript: DefaultVtxo.Script): void;
831
+ /**
832
+ * @internal Sole write path for `arkServerPublicKey` after construction.
833
+ * Called by {@link Wallet.rotateServerSigner} once the rotated offchain and
834
+ * boarding contract rows have been persisted. External code must treat
835
+ * `arkServerPublicKey` as read-only.
836
+ */
837
+ setArkServerPublicKeyForRotation(serverPubKey: Bytes): void;
838
+ /**
839
+ * Output script for checkpoint transactions, decoded from the server's
840
+ * `checkpointTapscript`. Server-controlled state: pinned at construction
841
+ * and re-sourced from a fresh `ArkInfo` on server-signer rotation. Read it
842
+ * through {@link serverUnrollScript}; write it only through
843
+ * {@link setServerUnrollScriptForRotation}.
844
+ */
845
+ protected _serverUnrollScript: CSVMultisigTapscript.Type;
846
+ get serverUnrollScript(): CSVMultisigTapscript.Type;
847
+ /**
848
+ * @internal Sole write path for `serverUnrollScript` after construction.
849
+ * Called by {@link Wallet._doRotateServerSigner} with the checkpoint script
850
+ * sourced from the fresh `ArkInfo` that triggered the rotation, so the send
851
+ * path builds checkpoints against the new server epoch. External code must
852
+ * treat `serverUnrollScript` as read-only.
853
+ */
854
+ setServerUnrollScriptForRotation(script: CSVMultisigTapscript.Type): void;
855
+ /**
856
+ * Serializes {@link rotateServerSigner} for static / non-HD wallets (which
857
+ * have no {@link WalletReceiveRotator} chain to ride). Coalesces concurrent
858
+ * migration passes so two callers cannot both rebuild and swap the
859
+ * tapscripts. HD wallets serialize on the rotator's chain instead, via
860
+ * {@link WalletReceiveRotator.runExclusive}.
861
+ */
862
+ private _serverRotationChain;
696
863
  /**
697
864
  * Allocate and return a *fresh* on-chain boarding address, rotating the
698
865
  * wallet's current boarding tapscript to a new HD index.
@@ -719,6 +886,36 @@ declare class Wallet extends ReadonlyWallet implements IWallet {
719
886
  * (no rotation, no index burned).
720
887
  */
721
888
  getNewBoardingAddress(): Promise<string>;
889
+ /**
890
+ * Mid-session server-signer rotation (plan §4). When arkd rotates its
891
+ * active signer mid-session — the case the long-lived service worker and
892
+ * Expo background processes that own automatic migration must handle — a
893
+ * wallet constructed before the rotation keeps deriving old-signer receive
894
+ * addresses. Building a migration output to such an address would produce a
895
+ * VTXO the server must reject, so the wallet must first re-derive its own
896
+ * receive state under the new active signer.
897
+ *
898
+ * Follows the {@link WalletReceiveRotator.rotate} write-path pattern with
899
+ * the server key swapped instead of the user key: build the new offchain
900
+ * and boarding tapscripts locally (preserving every other option),
901
+ * register the matching `default`/`delegate` and `boarding` contract rows
902
+ * through {@link ContractManager.createContract}, and only then commit the
903
+ * new tapscripts and server key to the wallet's visible state. The signing
904
+ * metadata of the current receive/boarding rows is carried onto the new
905
+ * rows so a rotated (descriptor-backed) receive pubkey can still sign.
906
+ *
907
+ * The old-signer contract rows are intentionally left `active` and watched
908
+ * — they are exactly the deprecated-signer contracts the migration pass
909
+ * drains. Idempotent: a no-op when the wallet already tracks `xonly`.
910
+ *
911
+ * Serialized against HD receive rotation so the two paths (both of which
912
+ * rebuild and swap `offchainTapscript`) cannot interleave.
913
+ *
914
+ * @internal Invoked by the {@link VtxoManager} migration pass; not part of
915
+ * the stable public API.
916
+ */
917
+ rotateServerSigner(newServerPubKey: Bytes, checkpointTapscript: string): Promise<void>;
918
+ private _doRotateServerSigner;
722
919
  /**
723
920
  * Async mutex that serializes all operations submitting VTXOs to the Arkade
724
921
  * server (`settle`, `send`, `sendBitcoin`). This prevents VtxoManager's
@@ -911,12 +1108,38 @@ declare class Wallet extends ReadonlyWallet implements IWallet {
911
1108
  */
912
1109
  send(...args: [Recipient, ...Recipient[]]): Promise<string>;
913
1110
  private _sendImpl;
1111
+ /**
1112
+ * Shared tail of every Ark-transaction spend path (`send`, selected-VTXO
1113
+ * `sendBitcoin`, and {@link sendSelectedVtxosToSelf}): hide the inputs from
1114
+ * concurrent `getVtxos()`, build+submit the offchain tx, persist the spent
1115
+ * inputs and any wallet-owned (change / self) output, then release the
1116
+ * pending-spend hold. Callers own coin selection, output construction, and
1117
+ * the synchronous epoch snapshot; this owns the submit/persist sequence.
1118
+ */
1119
+ private _submitOffchainSpend;
1120
+ /**
1121
+ * @internal Migration primitive (deprecated-signer plan, step 1). Spend an
1122
+ * explicit set of the wallet's own deprecated-signer VTXOs into a single
1123
+ * full-value output on the wallet's *active* signer, through the Ark send
1124
+ * path (not `settle`) so arkd builds checkpoints against the active server
1125
+ * epoch. Consumed in-process by {@link VtxoManager}'s migration pass; not
1126
+ * part of the public `IWallet` API and never accepts boarding `ExtendedCoin`
1127
+ * inputs.
1128
+ *
1129
+ * The caller (`migrateCore`) must have already moved the wallet onto the
1130
+ * active signer (`ensureReceiveOnActiveSigner`) and sized the batch (caps +
1131
+ * dust floor); this method validates the inputs, preserves all input assets
1132
+ * on the self output, and persists the new active-signer VTXO even though
1133
+ * there is no separate change output. It records no `TxSent` history — the
1134
+ * funds never leave the wallet.
1135
+ */
1136
+ sendSelectedVtxosToSelf(inputs: ExtendedVirtualCoin[]): Promise<string>;
914
1137
  /**
915
1138
  * Build an offchain transaction from the given inputs and outputs,
916
1139
  * sign it, submit to the Arkade provider, and finalize.
917
1140
  * @returns The Arkade transaction id and server-signed checkpoint PSBTs (for bookkeeping)
918
1141
  */
919
- buildAndSubmitOffchainTx(inputs: ExtendedVirtualCoin[], outputs: TransactionOutput[]): Promise<{
1142
+ buildAndSubmitOffchainTx(inputs: ExtendedVirtualCoin[], outputs: TransactionOutput[], serverUnrollScript?: CSVMultisigTapscript.Type): Promise<{
920
1143
  arkTxid: string;
921
1144
  signedCheckpointTxs: string[];
922
1145
  }>;
@@ -930,4 +1153,4 @@ declare class Wallet extends ReadonlyWallet implements IWallet {
930
1153
  */
931
1154
  declare function waitForIncomingFunds(wallet: Wallet): Promise<IncomingFunds>;
932
1155
 
933
- export { Batch as B, type IncomingFunds as I, ReadonlyWallet as R, Wallet as W, type ReceiveRotatorFactory as a, type ReceiveRotatorBootOpts as b, type ReceiveRotatorBoot as c, waitForIncomingFunds as w };
1156
+ export { Batch as B, type IncomingFunds as I, ReadonlyWallet as R, Wallet as W, type ReceiveRotatorFactory as a, type ReceiveRotatorBootOpts as b, type ReceiveRotatorBoot as c, type BoardingUtxoGroup as d, waitForIncomingFunds as w };
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkZS3OZHC7_cjs = require('../../chunk-ZS3OZHC7.cjs');
4
- require('../../chunk-XCHBQVMK.cjs');
5
- require('../../chunk-FSAXPBGP.cjs');
3
+ var chunkA5PY4NBP_cjs = require('../../chunk-A5PY4NBP.cjs');
4
+ require('../../chunk-TUSGEWOX.cjs');
5
+ require('../../chunk-C6OODRWD.cjs');
6
6
  require('../../chunk-GUTKJMSF.cjs');
7
7
  require('../../chunk-CMPJR3HS.cjs');
8
8
  require('../../chunk-5BLDMQED.cjs');
@@ -120,19 +120,19 @@ var AsyncStorageTaskQueue = class {
120
120
 
121
121
  Object.defineProperty(exports, "CONTRACT_POLL_TASK_TYPE", {
122
122
  enumerable: true,
123
- get: function () { return chunkZS3OZHC7_cjs.CONTRACT_POLL_TASK_TYPE; }
123
+ get: function () { return chunkA5PY4NBP_cjs.CONTRACT_POLL_TASK_TYPE; }
124
124
  });
125
125
  Object.defineProperty(exports, "contractPollProcessor", {
126
126
  enumerable: true,
127
- get: function () { return chunkZS3OZHC7_cjs.contractPollProcessor; }
127
+ get: function () { return chunkA5PY4NBP_cjs.contractPollProcessor; }
128
128
  });
129
129
  Object.defineProperty(exports, "createTaskDependencies", {
130
130
  enumerable: true,
131
- get: function () { return chunkZS3OZHC7_cjs.createTaskDependencies; }
131
+ get: function () { return chunkA5PY4NBP_cjs.createTaskDependencies; }
132
132
  });
133
133
  Object.defineProperty(exports, "runTasks", {
134
134
  enumerable: true,
135
- get: function () { return chunkZS3OZHC7_cjs.runTasks; }
135
+ get: function () { return chunkA5PY4NBP_cjs.runTasks; }
136
136
  });
137
137
  exports.AsyncStorageTaskQueue = AsyncStorageTaskQueue;
138
138
  exports.InMemoryTaskQueue = InMemoryTaskQueue;
@@ -1,7 +1,7 @@
1
- import { T as TaskProcessor } from '../../taskRunner-vFRA3F9b.cjs';
2
- export { C as CreateTaskDependenciesOptions, I as InMemoryTaskQueue, b as TaskDependencies, c as TaskItem, a as TaskQueue, d as TaskResult, e as createTaskDependencies, r as runTasks } from '../../taskRunner-vFRA3F9b.cjs';
3
- export { a as AsyncStorageLike, A as AsyncStorageTaskQueue } from '../../asyncStorageTaskQueue-D92ch8yI.cjs';
4
- import '../../ark-Dsv5Jq4E.cjs';
1
+ import { T as TaskProcessor } from '../../taskRunner-DCyp6Gea.cjs';
2
+ export { C as CreateTaskDependenciesOptions, I as InMemoryTaskQueue, a as TaskDependencies, b as TaskItem, c as TaskQueue, d as TaskResult, e as createTaskDependencies, r as runTasks } from '../../taskRunner-DCyp6Gea.cjs';
3
+ export { A as AsyncStorageLike, a as AsyncStorageTaskQueue } from '../../asyncStorageTaskQueue-CpC027t_.cjs';
4
+ import '../../ark-D6sau_6-.cjs';
5
5
  import '@scure/btc-signer/transaction.js';
6
6
  import '@scure/btc-signer/utils.js';
7
7
  import '@scure/btc-signer/psbt.js';
@@ -1,7 +1,7 @@
1
- import { T as TaskProcessor } from '../../taskRunner-B1NUWyWR.js';
2
- export { C as CreateTaskDependenciesOptions, I as InMemoryTaskQueue, b as TaskDependencies, c as TaskItem, a as TaskQueue, d as TaskResult, e as createTaskDependencies, r as runTasks } from '../../taskRunner-B1NUWyWR.js';
3
- export { a as AsyncStorageLike, A as AsyncStorageTaskQueue } from '../../asyncStorageTaskQueue-BH-zuth5.js';
4
- import '../../ark-Dsv5Jq4E.js';
1
+ import { T as TaskProcessor } from '../../taskRunner-DnxtObeq.js';
2
+ export { C as CreateTaskDependenciesOptions, I as InMemoryTaskQueue, a as TaskDependencies, b as TaskItem, c as TaskQueue, d as TaskResult, e as createTaskDependencies, r as runTasks } from '../../taskRunner-DnxtObeq.js';
3
+ export { A as AsyncStorageLike, a as AsyncStorageTaskQueue } from '../../asyncStorageTaskQueue-GT8fmPUG.js';
4
+ import '../../ark-D6sau_6-.js';
5
5
  import '@scure/btc-signer/transaction.js';
6
6
  import '@scure/btc-signer/utils.js';
7
7
  import '@scure/btc-signer/psbt.js';
@@ -1,6 +1,6 @@
1
- export { CONTRACT_POLL_TASK_TYPE, contractPollProcessor, createTaskDependencies, runTasks } from '../../chunk-VVGD3JIP.js';
2
- import '../../chunk-HFXEUW55.js';
3
- import '../../chunk-FXFBPXV3.js';
1
+ export { CONTRACT_POLL_TASK_TYPE, contractPollProcessor, createTaskDependencies, runTasks } from '../../chunk-Z2VRVZW4.js';
2
+ import '../../chunk-HBPKIIMN.js';
3
+ import '../../chunk-2JJKX2RK.js';
4
4
  import '../../chunk-CUSABEUQ.js';
5
5
  import '../../chunk-OUVTG72A.js';
6
6
  import '../../chunk-NSBPE2FW.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/sdk",
3
- "version": "0.4.34",
3
+ "version": "0.4.36",
4
4
  "description": "TypeScript SDK for building Bitcoin wallets using the Arkade protocol",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -151,7 +151,7 @@
151
151
  "@types/better-sqlite3": "7.6.13",
152
152
  "@vitest/coverage-v8": "3.2.4",
153
153
  "better-sqlite3": "12.6.2",
154
- "typedoc": "^0.28.16"
154
+ "typedoc": "^0.28.19"
155
155
  },
156
156
  "peerDependencies": {
157
157
  "@react-native-async-storage/async-storage": ">=1.0.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/providers/expoUtils.ts","../src/providers/expoArk.ts","../src/providers/expoIndexer.ts"],"names":[],"mappings":";;;;AAIA,eAAsB,aAAa,OAAA,EAA4D;AAG3F,EAAA,IAAI;AACA,IAAA,MAAM,eAAA,GAAkB,MAAM,OAAO,YAAY,CAAA;AACjD,IAAA,OAAA,CAAQ,MAAM,gCAAgC,CAAA;AAC9C,IAAA,OAAO,eAAA,CAAgB,KAAA;AAAA,EAC3B,SAAS,KAAA,EAAO;AAQZ,IAAA,OAAA,CAAQ,IAAA;AAAA,MACJ,wGAAA;AAAA,MAEA;AAAA,KACJ;AACA,IAAA,OAAO,KAAA;AAAA,EACX;AACJ;AAYA,gBAAuB,iBAAA,CACnB,GAAA,EACA,WAAA,EACA,OAAA,EACA,SACA,SAAA,EACgC;AAChC,EAAA,MAAM,eAAA,GAAkB,IAAI,eAAA,EAAgB;AAC5C,EAAA,MAAM,OAAA,GAAU,MAAM,eAAA,CAAgB,KAAA,EAAM;AAC5C,EAAA,WAAA,EAAa,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAE9D,EAAA,IAAI;AACA,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,GAAA,EAAK;AAAA,MAChC,OAAA,EAAS;AAAA,QACL,MAAA,EAAQ,mBAAA;AAAA,QACR,GAAG;AAAA,OACP;AAAA,MACA,QAAQ,eAAA,CAAgB;AAAA,KAC3B,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,kBAAA,EAAqB,QAAA,CAAS,MAAM,CAAA,yBAAA,CAA2B,CAAA;AAAA,IACnF;AAEA,IAAA,IAAI,CAAC,SAAS,IAAA,EAAM;AAChB,MAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,IAC3C;AAEA,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,IAAA,CAAK,SAAA,EAAU;AACvC,IAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,IAAA,IAAI,MAAA,GAAS,EAAA;AAEb,IAAA,OAAO,CAAC,aAAa,OAAA,EAAS;AAC1B,MAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,MAAA,IAAI,IAAA,EAAM;AACN,QAAA;AAAA,MACJ;AAEA,MAAA,MAAA,IAAU,QAAQ,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAChD,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAE/B,MAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,GAAS,GAAG,CAAA,EAAA,EAAK;AACvC,QAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAC3B,QAAA,IAAI,CAAC,IAAA,EAAM;AAEX,QAAA,IAAI,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA,EAAG;AAC1B,UAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,CAAC,EAAE,IAAA,EAAK;AACvC,UAAA,IAAI,CAAC,OAAA,EAAS;AAEd,UAAA,IAAI;AACA,YAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAC/B,YAAA,MAAM,MAAA,GAAS,UAAU,IAAI,CAAA;AAC7B,YAAA,IAAI,WAAW,IAAA,EAAM;AACjB,cAAA,MAAM,MAAA;AAAA,YACV;AAAA,UACJ,SAAS,UAAA,EAAY;AACjB,YAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,UAAU,CAAA;AACrD,YAAA,MAAM,UAAA;AAAA,UACV;AAAA,QACJ;AAAA,MACJ;AAEA,MAAA,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA;AAAA,IACnC;AAAA,EACJ,CAAA,SAAE;AACE,IAAA,WAAA,EAAa,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAAA,EACrD;AACJ;;;ACxFO,IAAM,eAAA,GAAN,cAA8B,eAAA,CAAgB;AAAA,EACjD,WAAA,CAAY,YAAoB,yBAAA,EAA2B;AACvD,IAAA,KAAA,CAAM,SAAS,CAAA;AAAA,EACnB;AAAA,EAEA,OAAgB,cAAA,CACZ,MAAA,EACA,MAAA,EACsC;AACtC,IAAA,MAAM,SAAA,GAAY,MAAM,YAAA,EAAa;AACrC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,gBAAA,CAAA;AAC7B,IAAA,MAAM,cACF,MAAA,CAAO,MAAA,GAAS,IACV,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,CAAC,KAAA,KAAU,CAAA,OAAA,EAAU,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAE,EAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAC1E,EAAA;AAEV,IAAA,OAAO,CAAC,QAAQ,OAAA,EAAS;AACrB,MAAA,IAAI;AACA,QAAA,OAAO,iBAAA,CAAkB,MAAM,WAAA,EAAa,MAAA,EAAQ,WAAW,EAAC,EAAG,CAAC,IAAA,KAAS;AAGzE,UAAA,MAAM,SAAA,GAAY,KAAK,MAAA,IAAU,IAAA;AAGjC,UAAA,IAAI,SAAA,CAAU,cAAc,KAAA,CAAA,EAAW;AACnC,YAAA,OAAO,IAAA;AAAA,UACX;AAEA,UAAA,OAAO,IAAA,CAAK,qBAAqB,SAAS,CAAA;AAAA,QAC9C,CAAC,CAAA;AAAA,MACL,SAAS,KAAA,EAAO;AACZ,QAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACvD,UAAA;AAAA,QACJ;AAIA,QAAA,IAAI,mBAAA,CAAoB,KAAK,CAAA,EAAG;AAC5B,UAAA,OAAA,CAAQ,MAAM,uBAAuB,CAAA;AACrC,UAAA;AAAA,QACJ;AAEA,QAAA,OAAA,CAAQ,KAAA,CAAM,uBAAuB,KAAK,CAAA;AAC1C,QAAA,MAAM,KAAA;AAAA,MACV;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,OAAgB,sBAAsB,MAAA,EAGnC;AACC,IAAA,MAAM,SAAA,GAAY,MAAM,YAAA,EAAa;AACrC,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAA,OAAA,CAAA;AAE7B,IAAA,OAAO,CAAC,QAAQ,OAAA,EAAS;AACrB,MAAA,IAAI;AACA,QAAA,OAAO,kBAAkB,GAAA,EAAK,MAAA,EAAQ,WAAW,EAAC,EAAG,CAAC,IAAA,KAAS;AAC3D,UAAA,OAAO,IAAA,CAAK,4BAAA,CAA6B,IAAA,CAAK,MAAM,CAAA;AAAA,QACxD,CAAC,CAAA;AAAA,MACL,SAAS,KAAA,EAAO;AACZ,QAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACvD,UAAA;AAAA,QACJ;AAIA,QAAA,IAAI,mBAAA,CAAoB,KAAK,CAAA,EAAG;AAC5B,UAAA,OAAA,CAAQ,MAAM,uBAAuB,CAAA;AACrC,UAAA;AAAA,QACJ;AAEA,QAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,KAAK,CAAA;AAChD,QAAA,MAAM,KAAA;AAAA,MACV;AAAA,IACJ;AAAA,EACJ;AACJ;;;ACvFA,SAAS,YAAY,IAAA,EAAyB;AAC1C,EAAA,OAAO;AAAA,IACH,IAAA,EAAM,KAAK,QAAA,CAAS,IAAA;AAAA,IACpB,IAAA,EAAM,KAAK,QAAA,CAAS,IAAA;AAAA,IACpB,KAAA,EAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAAA,IACzB,MAAA,EAAQ;AAAA,MACJ,SAAA,EAAW,CAAC,IAAA,CAAK,OAAA,IAAW,CAAC,IAAA,CAAK,cAAA;AAAA,MAClC,MAAA,EAAQ,CAAC,IAAA,CAAK;AAAA,KAClB;AAAA,IACA,aAAA,EAAe;AAAA,MACX,OAAO,IAAA,CAAK,OAAA,GAAU,OAAA,GAAU,IAAA,CAAK,iBAAiB,cAAA,GAAiB,SAAA;AAAA,MACvE,iBAAiB,IAAA,CAAK,eAAA;AAAA,MACtB,aAAa,IAAA,CAAK,SAAA,GAAY,OAAO,IAAA,CAAK,SAAS,IAAI,GAAA,GAAO;AAAA,KAClE;AAAA,IACA,OAAA,EAAS,KAAK,OAAA,IAAW,EAAA;AAAA,IACzB,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,SAAS,IAAA,CAAK,OAAA;AAAA,IACd,WAAW,IAAI,IAAA,CAAK,OAAO,IAAA,CAAK,SAAS,IAAI,GAAI,CAAA;AAAA,IACjD,YAAY,IAAA,CAAK,UAAA;AAAA,IACjB,SAAS,IAAA,CAAK,OAAA;AAAA,IACd,QAAQ,IAAA,CAAK,MAAA;AAAA,IACb,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,MAC7B,SAAS,CAAA,CAAE,OAAA;AAAA,MACX,MAAA,EAAQ,MAAA,CAAO,CAAA,CAAE,MAAM;AAAA,KAC3B,CAAE;AAAA,GACN;AACJ;AAeO,IAAM,mBAAA,GAAN,cAAkC,mBAAA,CAAoB;AAAA,EACzD,WAAA,CAAY,YAAoB,yBAAA,EAA2B;AACvD,IAAA,KAAA,CAAM,SAAS,CAAA;AAAA,EACnB;AAAA,EAEA,OAAgB,eAAA,CACZ,cAAA,EACA,WAAA,EAC2C;AAE3C,IAAA,MAAM,aAAA,GACF,OAAO,SAAA,KAAc,WAAA,IAAe,UAAU,OAAA,KAAY,aAAA;AAE9D,IAAA,MAAM,YAAY,MAAM,YAAA,EAAa,CAAE,KAAA,CAAM,CAAC,KAAA,KAAU;AAEpD,MAAA,IAAI,aAAA,EAAe;AACf,QAAA,MAAM,IAAI,KAAA;AAAA,UACN;AAAA,SAGJ;AAAA,MACJ;AACA,MAAA,MAAM,KAAA;AAAA,IACV,CAAC,CAAA;AAED,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,SAAS,mCAAmC,cAAc,CAAA,CAAA;AAE9E,IAAA,OAAO,CAAC,YAAY,OAAA,EAAS;AACzB,MAAA,IAAI;AACA,QAAA,OAAO,iBAAA;AAAA,UACH,GAAA;AAAA,UACA,WAAA;AAAA,UACA,SAAA;AAAA,UACA,EAAE,gBAAgB,kBAAA,EAAmB;AAAA,UACrC,CAAC,IAAA,KAAsC;AAEnC,YAAA,IAAI,IAAA,CAAK,cAAc,KAAA,CAAA,EAAW;AAE9B,cAAA,OAAO,IAAA;AAAA,YACX;AAEA,YAAA,IAAI,KAAK,KAAA,EAAO;AACZ,cAAA,OAAO;AAAA,gBACH,IAAA,EAAM,KAAK,KAAA,CAAM,IAAA;AAAA,gBACjB,OAAA,EAAS,IAAA,CAAK,KAAA,CAAM,OAAA,IAAW,EAAC;AAAA,gBAChC,WAAW,IAAA,CAAK,KAAA,CAAM,YAAY,EAAC,EAAG,IAAI,WAAW,CAAA;AAAA,gBACrD,aAAa,IAAA,CAAK,KAAA,CAAM,cAAc,EAAC,EAAG,IAAI,WAAW,CAAA;AAAA,gBACzD,aAAa,IAAA,CAAK,KAAA,CAAM,cAAc,EAAC,EAAG,IAAI,WAAW,CAAA;AAAA,gBACzD,EAAA,EAAI,KAAK,KAAA,CAAM,EAAA;AAAA,gBACf,aAAA,EAAe,KAAK,KAAA,CAAM;AAAA,eAC9B;AAAA,YACJ;AACA,YAAA,OAAO,IAAA;AAAA,UACX;AAAA,SACJ;AAAA,MACJ,SAAS,KAAA,EAAO;AACZ,QAAA,IAAI,KAAA,YAAiB,KAAA,IAAS,KAAA,CAAM,IAAA,KAAS,YAAA,EAAc;AACvD,UAAA;AAAA,QACJ;AAIA,QAAA,IAAI,mBAAA,CAAoB,KAAK,CAAA,EAAG;AAC5B,UAAA,OAAA,CAAQ,MAAM,uBAAuB,CAAA;AACrC,UAAA;AAAA,QACJ;AAEA,QAAA,OAAA,CAAQ,KAAA,CAAM,uBAAuB,KAAK,CAAA;AAC1C,QAAA,MAAM,KAAA;AAAA,MACV;AAAA,IACJ;AAAA,EACJ;AACJ","file":"chunk-5WDBHWX3.js","sourcesContent":["/**\n * Dynamically imports expo/fetch with fallback to standard fetch.\n * @returns A fetch function suitable for SSE streaming\n */\nexport async function getExpoFetch(options?: { requireExpo?: boolean }): Promise<typeof fetch> {\n const requireExpo = options?.requireExpo ?? false;\n\n try {\n const expoFetchModule = await import(\"expo/fetch\");\n console.debug(\"Using expo/fetch for streaming\");\n return expoFetchModule.fetch as unknown as typeof fetch;\n } catch (error) {\n if (requireExpo) {\n throw new Error(\n \"expo/fetch is unavailable in this environment. \" +\n \"Please ensure expo/fetch is installed and properly configured.\",\n );\n }\n\n console.warn(\n \"Using standard fetch instead of expo/fetch. \" +\n \"Streaming may not be fully supported in some environments.\",\n error,\n );\n return fetch;\n }\n}\n\n/**\n * Generic SSE stream processor using fetch API with ReadableStream.\n * Handles SSE format parsing, buffer management, and abort signals.\n *\n * @param url - The SSE endpoint URL\n * @param abortSignal - Signal to abort the stream\n * @param fetchFn - Fetch function to use (defaults to standard fetch)\n * @param headers - Additional headers to send\n * @param parseData - Function to parse and yield data from SSE events\n */\nexport async function* sseStreamIterator<T>(\n url: string,\n abortSignal: AbortSignal,\n fetchFn: typeof fetch,\n headers: Record<string, string>,\n parseData: (data: any) => T | null,\n): AsyncGenerator<T, void, unknown> {\n const fetchController = new AbortController();\n const cleanup = () => fetchController.abort();\n abortSignal?.addEventListener(\"abort\", cleanup, { once: true });\n\n try {\n const response = await fetchFn(url, {\n headers: {\n Accept: \"text/event-stream\",\n ...headers,\n },\n signal: fetchController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Unexpected status ${response.status} when fetching SSE stream`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (!abortSignal?.aborted) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n\n for (let i = 0; i < lines.length - 1; i++) {\n const line = lines[i].trim();\n if (!line) continue;\n\n if (line.startsWith(\"data:\")) {\n const jsonStr = line.substring(5).trim();\n if (!jsonStr) continue;\n\n try {\n const data = JSON.parse(jsonStr);\n const parsed = parseData(data);\n if (parsed !== null) {\n yield parsed;\n }\n } catch (parseError) {\n console.error(\"Failed to parse SSE data:\", parseError);\n throw parseError;\n }\n }\n }\n\n buffer = lines[lines.length - 1];\n }\n } finally {\n abortSignal?.removeEventListener(\"abort\", cleanup);\n }\n}\n","import { DEFAULT_ARKADE_SERVER_URL } from \"../networks\";\nimport { RestArkProvider, SettlementEvent, TxNotification, isFetchTimeoutError } from \"./ark\";\nimport { getExpoFetch, sseStreamIterator } from \"./expoUtils\";\n\n/**\n * Expo-compatible Arkade provider implementation using expo/fetch for SSE support.\n * This provider works specifically in React Native/Expo environments where\n * standard EventSource is not available but expo/fetch provides SSE capabilities.\n *\n * @example\n * ```typescript\n * import { ExpoArkProvider } from '@arkade-os/sdk/providers/expo';\n *\n * const provider = new ExpoArkProvider('https://arkade.computer');\n * const info = await provider.getInfo();\n * ```\n */\nexport class ExpoArkProvider extends RestArkProvider {\n constructor(serverUrl: string = DEFAULT_ARKADE_SERVER_URL) {\n super(serverUrl);\n }\n\n override async *getEventStream(\n signal: AbortSignal,\n topics: string[],\n ): AsyncIterableIterator<SettlementEvent> {\n const expoFetch = await getExpoFetch();\n const url = `${this.serverUrl}/v1/batch/events`;\n const queryParams =\n topics.length > 0\n ? `?${topics.map((topic) => `topics=${encodeURIComponent(topic)}`).join(\"&\")}`\n : \"\";\n\n while (!signal?.aborted) {\n try {\n yield* sseStreamIterator(url + queryParams, signal, expoFetch, {}, (data) => {\n // Handle different response structures\n // v8 mesh API might wrap in {result: ...} or send directly\n const eventData = data.result || data;\n\n // Skip heartbeat messages\n if (eventData.heartbeat !== undefined) {\n return null;\n }\n\n return this.parseSettlementEvent(eventData);\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n break;\n }\n\n // ignore timeout errors, they're expected when the server is not sending anything for 5 min\n // these timeouts are set by expo/fetch function\n if (isFetchTimeoutError(error)) {\n console.debug(\"Timeout error ignored\");\n continue;\n }\n\n console.error(\"Event stream error:\", error);\n throw error;\n }\n }\n }\n\n override async *getTransactionsStream(signal: AbortSignal): AsyncIterableIterator<{\n commitmentTx?: TxNotification;\n arkTx?: TxNotification;\n }> {\n const expoFetch = await getExpoFetch();\n const url = `${this.serverUrl}/v1/txs`;\n\n while (!signal?.aborted) {\n try {\n yield* sseStreamIterator(url, signal, expoFetch, {}, (data) => {\n return this.parseTransactionNotification(data.result);\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n break;\n }\n\n // ignore timeout errors, they're expected when the server is not sending anything for 5 min\n // these timeouts are set by expo/fetch function\n if (isFetchTimeoutError(error)) {\n console.debug(\"Timeout error ignored\");\n continue;\n }\n\n console.error(\"Transaction stream error:\", error);\n throw error;\n }\n }\n }\n}\n","import { RestIndexerProvider, SubscriptionResponse, Vtxo } from \"./indexer\";\nimport { isFetchTimeoutError } from \"./ark\";\nimport { VirtualCoin } from \"../wallet\";\nimport { getExpoFetch, sseStreamIterator } from \"./expoUtils\";\nimport { DEFAULT_ARKADE_SERVER_URL } from \"../networks\";\n\n// Helper function to convert Vtxo to VirtualCoin (same as in indexer.ts)\nfunction convertVtxo(vtxo: Vtxo): VirtualCoin {\n return {\n txid: vtxo.outpoint.txid,\n vout: vtxo.outpoint.vout,\n value: Number(vtxo.amount),\n status: {\n confirmed: !vtxo.isSwept && !vtxo.isPreconfirmed,\n isLeaf: !vtxo.isPreconfirmed,\n },\n virtualStatus: {\n state: vtxo.isSwept ? \"swept\" : vtxo.isPreconfirmed ? \"preconfirmed\" : \"settled\",\n commitmentTxIds: vtxo.commitmentTxids,\n batchExpiry: vtxo.expiresAt ? Number(vtxo.expiresAt) * 1000 : undefined,\n },\n spentBy: vtxo.spentBy ?? \"\",\n settledBy: vtxo.settledBy,\n arkTxId: vtxo.arkTxid,\n createdAt: new Date(Number(vtxo.createdAt) * 1000),\n isUnrolled: vtxo.isUnrolled,\n isSpent: vtxo.isSpent,\n script: vtxo.script,\n assets: vtxo.assets?.map((a) => ({\n assetId: a.assetId,\n amount: BigInt(a.amount),\n })),\n };\n}\n\n/**\n * Expo-compatible Indexer provider implementation using expo/fetch for streaming support.\n * This provider works specifically in React Native/Expo environments where\n * standard fetch streaming may not work properly but expo/fetch provides streaming capabilities.\n *\n * @example\n * ```typescript\n * import { ExpoIndexerProvider } from '@arkade-os/sdk/adapters/expo';\n *\n * const provider = new ExpoIndexerProvider('https://indexer.example.com');\n * const vtxos = await provider.getVtxos({ scripts: ['script1'] });\n * ```\n */\nexport class ExpoIndexerProvider extends RestIndexerProvider {\n constructor(serverUrl: string = DEFAULT_ARKADE_SERVER_URL) {\n super(serverUrl);\n }\n\n override async *getSubscription(\n subscriptionId: string,\n abortSignal: AbortSignal,\n ): AsyncIterableIterator<SubscriptionResponse> {\n // Detect if we're running in React Native/Expo environment\n const isReactNative =\n typeof navigator !== \"undefined\" && navigator.product === \"ReactNative\";\n\n const expoFetch = await getExpoFetch().catch((error) => {\n // In React Native/Expo, expo/fetch is required for proper streaming support\n if (isReactNative) {\n throw new Error(\n \"expo/fetch is unavailable in React Native environment. \" +\n \"Please ensure expo/fetch is installed and properly configured. \" +\n \"Streaming support may not work with standard fetch in React Native.\",\n );\n }\n throw error;\n });\n\n const url = `${this.serverUrl}/v1/indexer/script/subscription/${subscriptionId}`;\n\n while (!abortSignal.aborted) {\n try {\n yield* sseStreamIterator(\n url,\n abortSignal,\n expoFetch,\n { \"Content-Type\": \"application/json\" },\n (data): SubscriptionResponse | null => {\n // Handle new v8 proto format with heartbeat or event\n if (data.heartbeat !== undefined) {\n // Skip heartbeat messages\n return null;\n }\n // Process event messages\n if (data.event) {\n return {\n txid: data.event.txid,\n scripts: data.event.scripts || [],\n newVtxos: (data.event.newVtxos || []).map(convertVtxo),\n spentVtxos: (data.event.spentVtxos || []).map(convertVtxo),\n sweptVtxos: (data.event.sweptVtxos || []).map(convertVtxo),\n tx: data.event.tx,\n checkpointTxs: data.event.checkpointTxs,\n };\n }\n return null;\n },\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n break;\n }\n\n // ignore timeout errors, they're expected when the server is not sending anything for 5 min\n // these timeouts are set by expo/fetch function\n if (isFetchTimeoutError(error)) {\n console.debug(\"Timeout error ignored\");\n continue;\n }\n\n console.error(\"Subscription error:\", error);\n throw error;\n }\n }\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/providers/expoUtils.ts","../src/providers/expoArk.ts","../src/providers/expoIndexer.ts"],"names":["RestArkProvider","DEFAULT_ARKADE_SERVER_URL","isFetchTimeoutError","RestIndexerProvider"],"mappings":"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","file":"chunk-CCLNFHJ5.cjs","sourcesContent":["/**\n * Dynamically imports expo/fetch with fallback to standard fetch.\n * @returns A fetch function suitable for SSE streaming\n */\nexport async function getExpoFetch(options?: { requireExpo?: boolean }): Promise<typeof fetch> {\n const requireExpo = options?.requireExpo ?? false;\n\n try {\n const expoFetchModule = await import(\"expo/fetch\");\n console.debug(\"Using expo/fetch for streaming\");\n return expoFetchModule.fetch as unknown as typeof fetch;\n } catch (error) {\n if (requireExpo) {\n throw new Error(\n \"expo/fetch is unavailable in this environment. \" +\n \"Please ensure expo/fetch is installed and properly configured.\",\n );\n }\n\n console.warn(\n \"Using standard fetch instead of expo/fetch. \" +\n \"Streaming may not be fully supported in some environments.\",\n error,\n );\n return fetch;\n }\n}\n\n/**\n * Generic SSE stream processor using fetch API with ReadableStream.\n * Handles SSE format parsing, buffer management, and abort signals.\n *\n * @param url - The SSE endpoint URL\n * @param abortSignal - Signal to abort the stream\n * @param fetchFn - Fetch function to use (defaults to standard fetch)\n * @param headers - Additional headers to send\n * @param parseData - Function to parse and yield data from SSE events\n */\nexport async function* sseStreamIterator<T>(\n url: string,\n abortSignal: AbortSignal,\n fetchFn: typeof fetch,\n headers: Record<string, string>,\n parseData: (data: any) => T | null,\n): AsyncGenerator<T, void, unknown> {\n const fetchController = new AbortController();\n const cleanup = () => fetchController.abort();\n abortSignal?.addEventListener(\"abort\", cleanup, { once: true });\n\n try {\n const response = await fetchFn(url, {\n headers: {\n Accept: \"text/event-stream\",\n ...headers,\n },\n signal: fetchController.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Unexpected status ${response.status} when fetching SSE stream`);\n }\n\n if (!response.body) {\n throw new Error(\"Response body is null\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (!abortSignal?.aborted) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n\n for (let i = 0; i < lines.length - 1; i++) {\n const line = lines[i].trim();\n if (!line) continue;\n\n if (line.startsWith(\"data:\")) {\n const jsonStr = line.substring(5).trim();\n if (!jsonStr) continue;\n\n try {\n const data = JSON.parse(jsonStr);\n const parsed = parseData(data);\n if (parsed !== null) {\n yield parsed;\n }\n } catch (parseError) {\n console.error(\"Failed to parse SSE data:\", parseError);\n throw parseError;\n }\n }\n }\n\n buffer = lines[lines.length - 1];\n }\n } finally {\n abortSignal?.removeEventListener(\"abort\", cleanup);\n }\n}\n","import { DEFAULT_ARKADE_SERVER_URL } from \"../networks\";\nimport { RestArkProvider, SettlementEvent, TxNotification, isFetchTimeoutError } from \"./ark\";\nimport { getExpoFetch, sseStreamIterator } from \"./expoUtils\";\n\n/**\n * Expo-compatible Arkade provider implementation using expo/fetch for SSE support.\n * This provider works specifically in React Native/Expo environments where\n * standard EventSource is not available but expo/fetch provides SSE capabilities.\n *\n * @example\n * ```typescript\n * import { ExpoArkProvider } from '@arkade-os/sdk/providers/expo';\n *\n * const provider = new ExpoArkProvider('https://arkade.computer');\n * const info = await provider.getInfo();\n * ```\n */\nexport class ExpoArkProvider extends RestArkProvider {\n constructor(serverUrl: string = DEFAULT_ARKADE_SERVER_URL) {\n super(serverUrl);\n }\n\n override async *getEventStream(\n signal: AbortSignal,\n topics: string[],\n ): AsyncIterableIterator<SettlementEvent> {\n const expoFetch = await getExpoFetch();\n const url = `${this.serverUrl}/v1/batch/events`;\n const queryParams =\n topics.length > 0\n ? `?${topics.map((topic) => `topics=${encodeURIComponent(topic)}`).join(\"&\")}`\n : \"\";\n\n while (!signal?.aborted) {\n try {\n yield* sseStreamIterator(url + queryParams, signal, expoFetch, {}, (data) => {\n // Handle different response structures\n // v8 mesh API might wrap in {result: ...} or send directly\n const eventData = data.result || data;\n\n // Skip heartbeat messages\n if (eventData.heartbeat !== undefined) {\n return null;\n }\n\n return this.parseSettlementEvent(eventData);\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n break;\n }\n\n // ignore timeout errors, they're expected when the server is not sending anything for 5 min\n // these timeouts are set by expo/fetch function\n if (isFetchTimeoutError(error)) {\n console.debug(\"Timeout error ignored\");\n continue;\n }\n\n console.error(\"Event stream error:\", error);\n throw error;\n }\n }\n }\n\n override async *getTransactionsStream(signal: AbortSignal): AsyncIterableIterator<{\n commitmentTx?: TxNotification;\n arkTx?: TxNotification;\n }> {\n const expoFetch = await getExpoFetch();\n const url = `${this.serverUrl}/v1/txs`;\n\n while (!signal?.aborted) {\n try {\n yield* sseStreamIterator(url, signal, expoFetch, {}, (data) => {\n return this.parseTransactionNotification(data.result);\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n break;\n }\n\n // ignore timeout errors, they're expected when the server is not sending anything for 5 min\n // these timeouts are set by expo/fetch function\n if (isFetchTimeoutError(error)) {\n console.debug(\"Timeout error ignored\");\n continue;\n }\n\n console.error(\"Transaction stream error:\", error);\n throw error;\n }\n }\n }\n}\n","import { RestIndexerProvider, SubscriptionResponse, Vtxo } from \"./indexer\";\nimport { isFetchTimeoutError } from \"./ark\";\nimport { VirtualCoin } from \"../wallet\";\nimport { getExpoFetch, sseStreamIterator } from \"./expoUtils\";\nimport { DEFAULT_ARKADE_SERVER_URL } from \"../networks\";\n\n// Helper function to convert Vtxo to VirtualCoin (same as in indexer.ts)\nfunction convertVtxo(vtxo: Vtxo): VirtualCoin {\n return {\n txid: vtxo.outpoint.txid,\n vout: vtxo.outpoint.vout,\n value: Number(vtxo.amount),\n status: {\n confirmed: !vtxo.isSwept && !vtxo.isPreconfirmed,\n isLeaf: !vtxo.isPreconfirmed,\n },\n virtualStatus: {\n state: vtxo.isSwept ? \"swept\" : vtxo.isPreconfirmed ? \"preconfirmed\" : \"settled\",\n commitmentTxIds: vtxo.commitmentTxids,\n batchExpiry: vtxo.expiresAt ? Number(vtxo.expiresAt) * 1000 : undefined,\n },\n spentBy: vtxo.spentBy ?? \"\",\n settledBy: vtxo.settledBy,\n arkTxId: vtxo.arkTxid,\n createdAt: new Date(Number(vtxo.createdAt) * 1000),\n isUnrolled: vtxo.isUnrolled,\n isSpent: vtxo.isSpent,\n script: vtxo.script,\n assets: vtxo.assets?.map((a) => ({\n assetId: a.assetId,\n amount: BigInt(a.amount),\n })),\n };\n}\n\n/**\n * Expo-compatible Indexer provider implementation using expo/fetch for streaming support.\n * This provider works specifically in React Native/Expo environments where\n * standard fetch streaming may not work properly but expo/fetch provides streaming capabilities.\n *\n * @example\n * ```typescript\n * import { ExpoIndexerProvider } from '@arkade-os/sdk/adapters/expo';\n *\n * const provider = new ExpoIndexerProvider('https://indexer.example.com');\n * const vtxos = await provider.getVtxos({ scripts: ['script1'] });\n * ```\n */\nexport class ExpoIndexerProvider extends RestIndexerProvider {\n constructor(serverUrl: string = DEFAULT_ARKADE_SERVER_URL) {\n super(serverUrl);\n }\n\n override async *getSubscription(\n subscriptionId: string,\n abortSignal: AbortSignal,\n ): AsyncIterableIterator<SubscriptionResponse> {\n // Detect if we're running in React Native/Expo environment\n const isReactNative =\n typeof navigator !== \"undefined\" && navigator.product === \"ReactNative\";\n\n const expoFetch = await getExpoFetch().catch((error) => {\n // In React Native/Expo, expo/fetch is required for proper streaming support\n if (isReactNative) {\n throw new Error(\n \"expo/fetch is unavailable in React Native environment. \" +\n \"Please ensure expo/fetch is installed and properly configured. \" +\n \"Streaming support may not work with standard fetch in React Native.\",\n );\n }\n throw error;\n });\n\n const url = `${this.serverUrl}/v1/indexer/script/subscription/${subscriptionId}`;\n\n while (!abortSignal.aborted) {\n try {\n yield* sseStreamIterator(\n url,\n abortSignal,\n expoFetch,\n { \"Content-Type\": \"application/json\" },\n (data): SubscriptionResponse | null => {\n // Handle new v8 proto format with heartbeat or event\n if (data.heartbeat !== undefined) {\n // Skip heartbeat messages\n return null;\n }\n // Process event messages\n if (data.event) {\n return {\n txid: data.event.txid,\n scripts: data.event.scripts || [],\n newVtxos: (data.event.newVtxos || []).map(convertVtxo),\n spentVtxos: (data.event.spentVtxos || []).map(convertVtxo),\n sweptVtxos: (data.event.sweptVtxos || []).map(convertVtxo),\n tx: data.event.tx,\n checkpointTxs: data.event.checkpointTxs,\n };\n }\n return null;\n },\n );\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n break;\n }\n\n // ignore timeout errors, they're expected when the server is not sending anything for 5 min\n // these timeouts are set by expo/fetch function\n if (isFetchTimeoutError(error)) {\n console.debug(\"Timeout error ignored\");\n continue;\n }\n\n console.error(\"Subscription error:\", error);\n throw error;\n }\n }\n }\n}\n"]}