@arkade-os/sdk 0.4.19 → 0.4.21

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 (61) hide show
  1. package/dist/cjs/contracts/contractWatcher.js +33 -3
  2. package/dist/cjs/contracts/handlers/default.js +10 -3
  3. package/dist/cjs/contracts/handlers/helpers.js +47 -5
  4. package/dist/cjs/contracts/handlers/vhtlc.js +4 -2
  5. package/dist/cjs/identity/descriptor.js +98 -0
  6. package/dist/cjs/identity/descriptorProvider.js +2 -0
  7. package/dist/cjs/identity/index.js +15 -1
  8. package/dist/cjs/identity/seedIdentity.js +91 -6
  9. package/dist/cjs/identity/serialize.js +166 -0
  10. package/dist/cjs/identity/staticDescriptorProvider.js +65 -0
  11. package/dist/cjs/index.js +6 -3
  12. package/dist/cjs/providers/ark.js +71 -46
  13. package/dist/cjs/providers/electrum.js +663 -0
  14. package/dist/cjs/providers/indexer.js +60 -43
  15. package/dist/cjs/providers/utils.js +62 -12
  16. package/dist/cjs/wallet/ramps.js +1 -1
  17. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +10 -0
  18. package/dist/cjs/wallet/serviceWorker/wallet.js +137 -91
  19. package/dist/cjs/wallet/vtxo-manager.js +56 -8
  20. package/dist/cjs/wallet/wallet.js +130 -156
  21. package/dist/cjs/worker/messageBus.js +200 -56
  22. package/dist/esm/contracts/contractWatcher.js +33 -3
  23. package/dist/esm/contracts/handlers/default.js +10 -3
  24. package/dist/esm/contracts/handlers/helpers.js +47 -5
  25. package/dist/esm/contracts/handlers/vhtlc.js +4 -2
  26. package/dist/esm/identity/descriptor.js +92 -0
  27. package/dist/esm/identity/descriptorProvider.js +1 -0
  28. package/dist/esm/identity/index.js +6 -1
  29. package/dist/esm/identity/seedIdentity.js +89 -6
  30. package/dist/esm/identity/serialize.js +159 -0
  31. package/dist/esm/identity/staticDescriptorProvider.js +61 -0
  32. package/dist/esm/index.js +2 -1
  33. package/dist/esm/providers/ark.js +72 -47
  34. package/dist/esm/providers/electrum.js +658 -0
  35. package/dist/esm/providers/indexer.js +61 -44
  36. package/dist/esm/providers/utils.js +61 -12
  37. package/dist/esm/wallet/ramps.js +1 -1
  38. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +10 -0
  39. package/dist/esm/wallet/serviceWorker/wallet.js +137 -91
  40. package/dist/esm/wallet/vtxo-manager.js +56 -8
  41. package/dist/esm/wallet/wallet.js +130 -156
  42. package/dist/esm/worker/messageBus.js +201 -57
  43. package/dist/types/contracts/contractWatcher.d.ts +3 -0
  44. package/dist/types/contracts/handlers/default.d.ts +1 -1
  45. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  46. package/dist/types/contracts/types.d.ts +11 -3
  47. package/dist/types/identity/descriptor.d.ts +35 -0
  48. package/dist/types/identity/descriptorProvider.d.ts +28 -0
  49. package/dist/types/identity/index.d.ts +7 -1
  50. package/dist/types/identity/seedIdentity.d.ts +41 -4
  51. package/dist/types/identity/serialize.d.ts +84 -0
  52. package/dist/types/identity/staticDescriptorProvider.d.ts +18 -0
  53. package/dist/types/index.d.ts +4 -2
  54. package/dist/types/providers/electrum.d.ts +212 -0
  55. package/dist/types/providers/utils.d.ts +10 -5
  56. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +11 -2
  57. package/dist/types/wallet/serviceWorker/wallet.d.ts +27 -10
  58. package/dist/types/wallet/vtxo-manager.d.ts +2 -0
  59. package/dist/types/wallet/wallet.d.ts +7 -6
  60. package/dist/types/worker/messageBus.d.ts +68 -8
  61. package/package.json +3 -2
@@ -0,0 +1,84 @@
1
+ import type { Identity, ReadonlyIdentity } from ".";
2
+ /**
3
+ * Tagged envelope for a signing identity transported across the
4
+ * service-worker boundary. All variants are structured-clone safe
5
+ * (plain strings only — no functions or prototypes).
6
+ *
7
+ * Adding a new variant is a source change in every worker build; keep
8
+ * old variants around until all deployed workers handle them.
9
+ */
10
+ export type SerializedSigningIdentity = {
11
+ type: "single-key";
12
+ privateKey: string;
13
+ } | {
14
+ type: "seed";
15
+ seed: string;
16
+ descriptor: string;
17
+ } | {
18
+ type: "mnemonic";
19
+ mnemonic: string;
20
+ descriptor: string;
21
+ passphrase?: string;
22
+ };
23
+ /**
24
+ * Tagged envelope for a readonly identity transported across the
25
+ * service-worker boundary. All variants are structured-clone safe.
26
+ */
27
+ export type SerializedReadonlyIdentity = {
28
+ type: "readonly-single-key";
29
+ publicKey: string;
30
+ } | {
31
+ type: "readonly-descriptor";
32
+ descriptor: string;
33
+ };
34
+ export type SerializedIdentity = SerializedSigningIdentity | SerializedReadonlyIdentity;
35
+ /** Type guard — true for signing envelopes, false for readonly envelopes. */
36
+ export declare function isSigningSerialized(s: SerializedIdentity): s is SerializedSigningIdentity;
37
+ /**
38
+ * Serialize a signing identity into a structured-clone safe envelope for
39
+ * transport across the service-worker boundary.
40
+ *
41
+ * Supports SDK-owned signing identities directly. For custom identities, a
42
+ * duck-typed `toHex()` fallback preserves compatibility with existing
43
+ * `SingleKey`-like implementations.
44
+ */
45
+ export declare function serializeSigningIdentity(identity: Identity): SerializedSigningIdentity;
46
+ /**
47
+ * Serialize a readonly identity into a structured-clone safe envelope.
48
+ *
49
+ * Works for any `ReadonlyIdentity` via `compressedPublicKey()`. When called
50
+ * with a signing identity, produces a readonly envelope (never ships signing
51
+ * material) — callers that need to preserve signing capability across the
52
+ * boundary must use {@link serializeSigningIdentity}.
53
+ */
54
+ export declare function serializeReadonlyIdentity(identity: ReadonlyIdentity): Promise<SerializedReadonlyIdentity>;
55
+ /**
56
+ * Rehydrate a serialized identity envelope back into an identity instance.
57
+ * The return type is the union of signing and readonly; use
58
+ * {@link isSigningSerialized} on the envelope before hydration if the caller
59
+ * needs to know which side it ends up on.
60
+ */
61
+ export declare function hydrateIdentity(s: SerializedIdentity): Identity | ReadonlyIdentity;
62
+ /**
63
+ * Legacy untagged shape emitted by page builds prior to the tagged
64
+ * SerializedIdentity envelope. Retained so newer workers can still accept
65
+ * older pages during a rolling upgrade. Slated for removal in the next major.
66
+ *
67
+ * @deprecated Use {@link SerializedIdentity}.
68
+ */
69
+ export type LegacySerializedIdentity = {
70
+ privateKey: string;
71
+ } | {
72
+ publicKey: string;
73
+ };
74
+ /**
75
+ * Accept either a modern {@link SerializedIdentity} envelope or a legacy
76
+ * `{ privateKey }` / `{ publicKey }` shape and normalize to a
77
+ * {@link SerializedIdentity}. Emits a one-time deprecation warning when a
78
+ * legacy shape is seen.
79
+ *
80
+ * Intended for the worker-side boundary; new page builds always emit tagged
81
+ * envelopes via {@link serializeSigningIdentity} /
82
+ * {@link serializeReadonlyIdentity}.
83
+ */
84
+ export declare function normalizeSerializedIdentity(shape: SerializedIdentity | LegacySerializedIdentity): SerializedIdentity;
@@ -0,0 +1,18 @@
1
+ import { Identity } from ".";
2
+ import { DescriptorProvider, DescriptorSigningRequest } from "./descriptorProvider";
3
+ import { Transaction } from "../utils/transaction";
4
+ /**
5
+ * Wraps a legacy Identity (single-key) as a DescriptorProvider.
6
+ * The descriptor is always a simple tr(pubkey) format.
7
+ */
8
+ export declare class StaticDescriptorProvider implements DescriptorProvider {
9
+ private readonly identity;
10
+ private readonly descriptor;
11
+ private readonly pubKeyHex;
12
+ constructor(identity: Identity, pubKeyHex: string);
13
+ static create(identity: Identity): Promise<StaticDescriptorProvider>;
14
+ getSigningDescriptor(): string;
15
+ isOurs(descriptor: string): boolean;
16
+ signWithDescriptor(requests: DescriptorSigningRequest[]): Promise<Transaction[]>;
17
+ signMessageWithDescriptor(descriptor: string, message: Uint8Array, type?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
18
+ }
@@ -22,6 +22,8 @@ import type { MessageTimeouts } from "./wallet/serviceWorker/wallet";
22
22
  import { OnchainWallet } from "./wallet/onchain";
23
23
  import { setupServiceWorker } from "./worker/browser/utils";
24
24
  import { ESPLORA_URL, EsploraProvider, OnchainProvider, ExplorerTransaction } from "./providers/onchain";
25
+ import { ElectrumOnchainProvider, WsElectrumChainSource } from "./providers/electrum";
26
+ import type { TransactionHistory as ElectrumTransactionHistory, BlockHeader as ElectrumBlockHeader, Unspent as ElectrumUnspent } from "./providers/electrum";
25
27
  import { RestArkProvider, ArkProvider, SettlementEvent, SettlementEventType, ArkInfo, SignedIntent, Output, TxNotification, BatchFinalizationEvent, BatchFinalizedEvent, BatchFailedEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchStartedEvent, TreeTxEvent, TreeSignatureEvent, ScheduledSession, FeeInfo } from "./providers/ark";
26
28
  import { DelegatorProvider, DelegateInfo, DelegateOptions, RestDelegatorProvider } from "./providers/delegator";
27
29
  import { CLTVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CSVMultisigTapscript, decodeTapscript, MultisigTapscript, TapscriptType, ArkTapscript, RelativeTimelock } from "./script/tapscript";
@@ -50,5 +52,5 @@ import { IContractManager } from "./contracts/contractManager";
50
52
  import { closeDatabase, openDatabase } from "./repositories/indexedDB/manager";
51
53
  import { WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError } from "./wallet/serviceWorker/wallet-message-handler";
52
54
  import { MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError } from "./worker/errors";
53
- export { Wallet, ReadonlyWallet, SingleKey, ReadonlySingleKey, SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, isBatchSignable, OnchainWallet, Ramps, VtxoManager, DelegatorManagerImpl, RestDelegatorProvider, ESPLORA_URL, EsploraProvider, RestArkProvider, RestIndexerProvider, ArkAddress, DefaultVtxo, DelegateVtxo, VtxoScript, VHTLC, TxType, IndexerTxType, ChainTxType, SettlementEventType, setupServiceWorker, MessageBus, WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError, MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError, ServiceWorkerWallet, ServiceWorkerReadonlyWallet, DEFAULT_MESSAGE_TIMEOUTS, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, TapTreeCoder, ArkPsbtFieldKey, ArkPsbtFieldKeyType, setArkPsbtField, getArkPsbtFields, CosignerPublicKey, VtxoTreeExpiry, VtxoTaprootTree, ConditionWitness, buildOffchainTx, verifyTapscriptSignatures, waitForIncomingFunds, hasBoardingTxExpired, combineTapscriptSigs, isVtxoExpiringSoon, isValidArkAddress, ArkNote, networks, closeDatabase, openDatabase, IndexedDBWalletRepository, IndexedDBContractRepository, InMemoryWalletRepository, InMemoryContractRepository, MIGRATION_KEY, migrateWalletRepository, requiresMigration, getMigrationStatus, rollbackMigration, WalletRepositoryImpl, ContractRepositoryImpl, Intent, BIP322, TxTree, P2A, Unroll, Transaction, ArkError, maybeArkError, Batch, validateVtxoTxGraph, validateConnectorsTxGraph, buildForfeitTx, isRecoverable, isSpendable, isSubdust, isExpired, getSequence, ContractManager, ContractWatcher, contractHandlers, DefaultContractHandler, DelegateContractHandler, VHTLCContractHandler, encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract, };
54
- export type { Identity, ReadonlyIdentity, BatchSignableIdentity, SignRequest, IWallet, IReadonlyWallet, BaseWalletConfig, WalletConfig, ReadonlyWalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, ArkTxInput, OffchainTx, TapLeaves, IncomingFunds, SeedIdentityOptions, MnemonicOptions, NetworkOptions, DescriptorOptions, IndexerProvider, PageResponse, BatchInfo, ChainTx, CommitmentTx, TxHistoryRecord, Vtxo, VtxoChain, Tx, OnchainProvider, ArkProvider, SettlementEvent, FeeInfo, ArkInfo, SignedIntent, Output, TxNotification, ExplorerTransaction, BatchFinalizationEvent, BatchFinalizedEvent, BatchFailedEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchStartedEvent, TreeTxEvent, TreeSignatureEvent, ScheduledSession, PaginationOptions, SubscriptionResponse, SubscriptionHeartbeat, SubscriptionEvent, Network, NetworkName, ArkTapscript, RelativeTimelock, EncodedVtxoScript, TapLeafScript, SignerSession, TreeNonces, TreePartialSigs, GetVtxosFilter, SettlementConfig, IVtxoManager, Asset, Recipient, IssuanceParams, IssuanceResult, ReissuanceParams, BurnParams, AssetDetails, AssetMetadata, KnownMetadata, Nonces, PartialSig, ArkPsbtFieldCoder, TxTreeNode, AnchorBumper, StorageConfig, Contract, ContractVtxo, ContractState, ContractEvent, ContractEventCallback, ContractBalance, ContractWithVtxos, ContractHandler, IContractManager, PathSelection, PathContext, ContractManagerConfig, CreateContractParams, ContractWatcherConfig, ParsedArkContract, DefaultContractParams, DelegateContractParams, VHTLCContractParams, MessageHandler, RequestEnvelope, ResponseEnvelope, MessageTimeouts, IDelegatorManager, DelegatorProvider, DelegateInfo, DelegateOptions, WalletRepository, ContractRepository, MigrationStatus, };
55
+ export { Wallet, ReadonlyWallet, SingleKey, ReadonlySingleKey, SeedIdentity, MnemonicIdentity, ReadonlyDescriptorIdentity, isBatchSignable, OnchainWallet, Ramps, VtxoManager, DelegatorManagerImpl, RestDelegatorProvider, ESPLORA_URL, EsploraProvider, ElectrumOnchainProvider, WsElectrumChainSource, RestArkProvider, RestIndexerProvider, ArkAddress, DefaultVtxo, DelegateVtxo, VtxoScript, VHTLC, TxType, IndexerTxType, ChainTxType, SettlementEventType, setupServiceWorker, MessageBus, WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError, MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError, ServiceWorkerWallet, ServiceWorkerReadonlyWallet, DEFAULT_MESSAGE_TIMEOUTS, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, TapTreeCoder, ArkPsbtFieldKey, ArkPsbtFieldKeyType, setArkPsbtField, getArkPsbtFields, CosignerPublicKey, VtxoTreeExpiry, VtxoTaprootTree, ConditionWitness, buildOffchainTx, verifyTapscriptSignatures, waitForIncomingFunds, hasBoardingTxExpired, combineTapscriptSigs, isVtxoExpiringSoon, isValidArkAddress, ArkNote, networks, closeDatabase, openDatabase, IndexedDBWalletRepository, IndexedDBContractRepository, InMemoryWalletRepository, InMemoryContractRepository, MIGRATION_KEY, migrateWalletRepository, requiresMigration, getMigrationStatus, rollbackMigration, WalletRepositoryImpl, ContractRepositoryImpl, Intent, BIP322, TxTree, P2A, Unroll, Transaction, ArkError, maybeArkError, Batch, validateVtxoTxGraph, validateConnectorsTxGraph, buildForfeitTx, isRecoverable, isSpendable, isSubdust, isExpired, getSequence, ContractManager, ContractWatcher, contractHandlers, DefaultContractHandler, DelegateContractHandler, VHTLCContractHandler, encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract, };
56
+ export type { Identity, ReadonlyIdentity, BatchSignableIdentity, SignRequest, IWallet, IReadonlyWallet, BaseWalletConfig, WalletConfig, ReadonlyWalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, ArkTxInput, OffchainTx, TapLeaves, IncomingFunds, SeedIdentityOptions, MnemonicOptions, NetworkOptions, DescriptorOptions, IndexerProvider, PageResponse, BatchInfo, ChainTx, CommitmentTx, TxHistoryRecord, Vtxo, VtxoChain, Tx, OnchainProvider, ArkProvider, SettlementEvent, FeeInfo, ArkInfo, SignedIntent, Output, TxNotification, ExplorerTransaction, ElectrumTransactionHistory, ElectrumBlockHeader, ElectrumUnspent, BatchFinalizationEvent, BatchFinalizedEvent, BatchFailedEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchStartedEvent, TreeTxEvent, TreeSignatureEvent, ScheduledSession, PaginationOptions, SubscriptionResponse, SubscriptionHeartbeat, SubscriptionEvent, Network, NetworkName, ArkTapscript, RelativeTimelock, EncodedVtxoScript, TapLeafScript, SignerSession, TreeNonces, TreePartialSigs, GetVtxosFilter, SettlementConfig, IVtxoManager, Asset, Recipient, IssuanceParams, IssuanceResult, ReissuanceParams, BurnParams, AssetDetails, AssetMetadata, KnownMetadata, Nonces, PartialSig, ArkPsbtFieldCoder, TxTreeNode, AnchorBumper, StorageConfig, Contract, ContractVtxo, ContractState, ContractEvent, ContractEventCallback, ContractBalance, ContractWithVtxos, ContractHandler, IContractManager, PathSelection, PathContext, ContractManagerConfig, CreateContractParams, ContractWatcherConfig, ParsedArkContract, DefaultContractParams, DelegateContractParams, VHTLCContractParams, MessageHandler, RequestEnvelope, ResponseEnvelope, MessageTimeouts, IDelegatorManager, DelegatorProvider, DelegateInfo, DelegateOptions, WalletRepository, ContractRepository, MigrationStatus, };
@@ -0,0 +1,212 @@
1
+ import type { ElectrumWS } from "ws-electrumx-client";
2
+ import type { Network } from "../networks";
3
+ import type { Coin } from "../wallet";
4
+ import type { ExplorerTransaction, OnchainProvider } from "./onchain";
5
+ export type TransactionHistory = {
6
+ tx_hash: string;
7
+ height: number;
8
+ fee?: number;
9
+ };
10
+ export type BlockHeader = {
11
+ height: number;
12
+ hex: string;
13
+ };
14
+ export type Unspent = {
15
+ txid: string;
16
+ vout: number;
17
+ witnessUtxo: {
18
+ script: Uint8Array;
19
+ value: bigint;
20
+ };
21
+ };
22
+ type VerboseTransaction = {
23
+ txid: string;
24
+ confirmations: number;
25
+ blockhash?: string;
26
+ blocktime?: number;
27
+ time?: number;
28
+ /** Raw transaction hex. Bitcoin Core's getrawtransaction <tx> 1 always
29
+ * includes this; we use it to derive exact satoshi amounts instead of
30
+ * multiplying the floating-point `value` field by 1e8. */
31
+ hex?: string;
32
+ vout: {
33
+ n: number;
34
+ value: number;
35
+ scriptPubKey: {
36
+ addresses?: string[];
37
+ address?: string;
38
+ hex: string;
39
+ };
40
+ }[];
41
+ vin: {
42
+ txid: string;
43
+ vout: number;
44
+ }[];
45
+ };
46
+ type HeaderSubscribeResult = {
47
+ height: number;
48
+ hex: string;
49
+ };
50
+ /**
51
+ * WebSocket-based Electrum chain source using ws-electrumx-client.
52
+ * Provides low-level methods for the Electrum protocol.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * import { ElectrumWS } from "ws-electrumx-client";
57
+ * import { WsElectrumChainSource } from "./providers/electrum";
58
+ * import { networks } from "./networks";
59
+ *
60
+ * const ws = new ElectrumWS("wss://electrum.blockstream.info:50004");
61
+ * const chain = new WsElectrumChainSource(ws, networks.bitcoin);
62
+ *
63
+ * const history = await chain.fetchHistories([script]);
64
+ * await chain.close();
65
+ * ```
66
+ */
67
+ export declare class WsElectrumChainSource {
68
+ private ws;
69
+ private network;
70
+ private cachedTip;
71
+ private headersSubscribePromise;
72
+ constructor(ws: ElectrumWS, network: Network);
73
+ fetchTransactions(txids: string[]): Promise<{
74
+ txID: string;
75
+ hex: string;
76
+ }[]>;
77
+ fetchVerboseTransaction(txid: string): Promise<VerboseTransaction>;
78
+ fetchVerboseTransactions(txids: string[]): Promise<VerboseTransaction[]>;
79
+ unsubscribeScriptStatus(script: Uint8Array): Promise<void>;
80
+ subscribeScriptStatus(script: Uint8Array, callback: (scripthash: string, status: string | null) => void): Promise<void>;
81
+ fetchHistories(scripts: Uint8Array[]): Promise<TransactionHistory[][]>;
82
+ fetchHistory(script: Uint8Array): Promise<TransactionHistory[]>;
83
+ fetchBlockHeaders(heights: number[]): Promise<BlockHeader[]>;
84
+ fetchBlockHeader(height: number): Promise<BlockHeader>;
85
+ /**
86
+ * Returns the current chain tip and keeps it fresh via a single
87
+ * server-side subscription. Subsequent calls return the cached tip
88
+ * (updated by background notifications) without round-tripping to the
89
+ * server. Previously each call issued `blockchain.headers.subscribe` as
90
+ * a regular request, leaving a stale subscription on the server every
91
+ * time — under polling that adds up. ws-electrumx-client deduplicates
92
+ * `subscribe()` by method+params, so registering once is enough.
93
+ */
94
+ subscribeHeaders(): Promise<HeaderSubscribeResult>;
95
+ estimateFees(targetNumberBlocks: number): Promise<number>;
96
+ broadcastTransaction(txHex: string): Promise<string>;
97
+ /**
98
+ * Submit a package of raw transactions atomically via Fulcrum's
99
+ * `blockchain.transaction.broadcast_package` method, the on-the-wire
100
+ * equivalent of bitcoind's `submitpackage` RPC.
101
+ *
102
+ * Required for TRUC (BIP 431) 1P1C relay where the parent has zero
103
+ * (or below-minfee) fee and depends on the child to pay for both via
104
+ * CPFP — sequential broadcast cannot work in that case because the
105
+ * parent would be rejected from the mempool on its own.
106
+ *
107
+ * @param txHexes - Topologically sorted raw transactions; child must
108
+ * be the last element. Currently must be a 1P1C pair
109
+ * (length 2). Parents may not depend on each other.
110
+ * @returns The child transaction id (the last entry in the array),
111
+ * computed locally — `broadcast_package` itself returns
112
+ * `{success, errors}` rather than a txid.
113
+ * @throws If the server does not implement `broadcast_package` (e.g.
114
+ * ElectrumX, or older Fulcrum, or Fulcrum backed by bitcoind
115
+ * < v28.0.0). Callers must surface this clearly to users —
116
+ * this method does NOT silently fall back to sequential
117
+ * broadcasts because doing so would let TRUC packages fail
118
+ * in subtle ways.
119
+ * @throws If the server returns `success=false`, surfacing the
120
+ * underlying mempool rejection in the error message.
121
+ */
122
+ broadcastPackage(txHexes: string[]): Promise<string>;
123
+ getRelayFee(): Promise<number>;
124
+ close(): Promise<void>;
125
+ waitForAddressReceivesTx(addr: string): Promise<void>;
126
+ listUnspents(addr: string): Promise<Unspent[]>;
127
+ /**
128
+ * Get the address string for a script output, if decodable.
129
+ */
130
+ addressForScript(scriptHex: string): string | undefined;
131
+ }
132
+ /**
133
+ * Electrum-based implementation of the OnchainProvider interface.
134
+ * Replaces esplora polling with electrum subscriptions where possible.
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * import { ElectrumWS } from "ws-electrumx-client";
139
+ * import { ElectrumOnchainProvider } from "./providers/electrum";
140
+ * import { networks } from "./networks";
141
+ *
142
+ * const ws = new ElectrumWS("wss://electrum.blockstream.info:50004");
143
+ * const provider = new ElectrumOnchainProvider(ws, networks.bitcoin);
144
+ *
145
+ * const coins = await provider.getCoins("bc1q...");
146
+ * ```
147
+ */
148
+ export declare class ElectrumOnchainProvider implements OnchainProvider {
149
+ private ws;
150
+ private network;
151
+ private chain;
152
+ constructor(ws: ElectrumWS, network: Network);
153
+ getCoins(address: string): Promise<Coin[]>;
154
+ getFeeRate(): Promise<number | undefined>;
155
+ /**
156
+ * Broadcast a single transaction or a TRUC (BIP 431) 1P1C package
157
+ * atomically.
158
+ *
159
+ * **Server requirements for 1P1C packages:** the backing Electrum
160
+ * server must implement `blockchain.transaction.broadcast_package`
161
+ * (Fulcrum ≥ 1.10) and be backed by bitcoind ≥ v28.0.0. ElectrumX
162
+ * does not implement this method. There is **no fallback** to
163
+ * sequential parent-then-child broadcast: TRUC packages typically
164
+ * have a zero-fee parent and would be rejected from the mempool on
165
+ * their own, so a fallback would silently fail in subtle ways.
166
+ * Callers receiving a "method not found" error here should route
167
+ * through a different provider for that submission.
168
+ *
169
+ * @param txs - One transaction (single broadcast) or two
170
+ * topologically-sorted transactions (parent first,
171
+ * child last) for 1P1C package relay.
172
+ * @returns The broadcast txid (or the child txid for 1P1C packages).
173
+ */
174
+ broadcastTransaction(...txs: string[]): Promise<string>;
175
+ getTxOutspends(txid: string): Promise<{
176
+ spent: boolean;
177
+ txid: string;
178
+ }[]>;
179
+ getTransactions(address: string): Promise<ExplorerTransaction[]>;
180
+ /**
181
+ * Map an electrum verbose transaction to the ExplorerTransaction shape.
182
+ *
183
+ * Output values are derived from the raw transaction hex when available,
184
+ * never from the floating-point `value` field returned by the daemon.
185
+ * That field has 8 decimal places and `Math.round(value * 1e8)` is safe
186
+ * in the common case but a footgun for protocol-level money handling —
187
+ * the raw bytes are exact.
188
+ */
189
+ private verboseToExplorer;
190
+ /**
191
+ * Decode `address` into its scriptPubKey, throwing a clear error if the
192
+ * input is malformed. @scure/btc-signer raises a generic decode error
193
+ * which is hard to map back to user input — this wraps it.
194
+ */
195
+ private encodeAddress;
196
+ getTxStatus(txid: string): Promise<{
197
+ confirmed: false;
198
+ } | {
199
+ confirmed: true;
200
+ blockTime: number;
201
+ blockHeight: number;
202
+ }>;
203
+ getChainTip(): Promise<{
204
+ height: number;
205
+ time: number;
206
+ hash: string;
207
+ }>;
208
+ watchAddresses(addresses: string[], eventCallback: (txs: ExplorerTransaction[]) => void): Promise<() => void>;
209
+ /** Close the underlying WebSocket connection. */
210
+ close(): Promise<void>;
211
+ }
212
+ export {};
@@ -1,7 +1,12 @@
1
+ export type ManagedEventSourceIterator = AsyncGenerator<MessageEvent, void, unknown> & {
2
+ close(): void;
3
+ };
1
4
  /**
2
- * Creates an async iterator over EventSource messages that attaches listeners
3
- * eagerly (at call time) rather than lazily (at first .next() call).
4
- * This ensures events are buffered immediately, preventing race conditions
5
- * where events arrive before iteration begins.
5
+ * Creates a close-aware EventSource async iterator.
6
+ *
7
+ * Listeners attach eagerly so events are buffered before the first next() call.
8
+ * close() closes the EventSource, removes listeners, and wakes any pending
9
+ * next() even when the browser does not emit an error from EventSource.close().
6
10
  */
7
- export declare function eventSourceIterator(eventSource: EventSource): AsyncGenerator<MessageEvent, void, unknown>;
11
+ export declare function eventSourceIterator(eventSource: EventSource): ManagedEventSourceIterator;
12
+ export declare function isEventSourceError(error: unknown): error is Error;
@@ -18,11 +18,19 @@ export declare const DEFAULT_MESSAGE_TAG = "WALLET_UPDATER";
18
18
  export type RequestInitWallet = RequestEnvelope & {
19
19
  type: "INIT_WALLET";
20
20
  payload: {
21
- key: {
21
+ /**
22
+ * Legacy per-request key material. Ignored by the current handler —
23
+ * identity hydration happens during INITIALIZE_MESSAGE_BUS. Retained
24
+ * for wire compatibility with older workers that may still read it.
25
+ * Slated for removal in the next major.
26
+ *
27
+ * @deprecated Identity is now carried by INITIALIZE_MESSAGE_BUS.
28
+ */
29
+ key?: {
22
30
  privateKey: string;
23
31
  } | {
24
32
  publicKey: string;
25
- };
33
+ } | {};
26
34
  arkServerUrl: string;
27
35
  arkServerPublicKey?: string;
28
36
  };
@@ -481,6 +489,7 @@ export declare class WalletMessageHandler implements MessageHandler<WalletUpdate
481
489
  private scheduleForNextTick;
482
490
  private requireWallet;
483
491
  private tagged;
492
+ isLongRunning(message: WalletUpdaterRequest): boolean;
484
493
  handleMessage(message: WalletUpdaterRequest): Promise<WalletUpdaterResponse>;
485
494
  private handleInitWallet;
486
495
  private handleGetBalance;
@@ -1,6 +1,6 @@
1
1
  import { IWallet, WalletBalance, SendBitcoinParams, SettleParams, ArkTransaction, ExtendedCoin, ExtendedVirtualCoin, GetVtxosFilter, StorageConfig, IReadonlyWallet, IReadonlyAssetManager, IAssetManager, Recipient } from "..";
2
2
  import { SettlementEvent } from "../../providers/ark";
3
- import { Identity, ReadonlyIdentity } from "../../identity";
3
+ import { Identity, ReadonlyIdentity, type SerializedIdentity, type LegacySerializedIdentity } from "../../identity";
4
4
  import { WalletRepository } from "../../repositories/walletRepository";
5
5
  import { ContractRepository } from "../../repositories/contractRepository";
6
6
  import { RequestInitWallet, ResponseGetStatus, WalletUpdaterRequest, WalletUpdaterResponse } from "./wallet-message-handler";
@@ -11,9 +11,6 @@ import type { ContractWatcherConfig } from "../../contracts/contractWatcher";
11
11
  type RequestType = WalletUpdaterRequest["type"];
12
12
  export type MessageTimeouts = Partial<Record<RequestType, number>>;
13
13
  export declare const DEFAULT_MESSAGE_TIMEOUTS: Readonly<Record<RequestType, number>>;
14
- type PrivateKeyIdentity = Identity & {
15
- toHex(): string;
16
- };
17
14
  /**
18
15
  * Service Worker-based wallet implementation for browser environments.
19
16
  *
@@ -102,11 +99,7 @@ export type ServiceWorkerWalletSetupOptions = ServiceWorkerWalletOptions & {
102
99
  serviceWorkerActivationTimeoutMs?: number;
103
100
  };
104
101
  type MessageBusInitConfig = {
105
- wallet: {
106
- privateKey: string;
107
- } | {
108
- publicKey: string;
109
- };
102
+ wallet: SerializedIdentity | LegacySerializedIdentity;
110
103
  arkServer: {
111
104
  url: string;
112
105
  publicKey?: string;
@@ -117,6 +110,7 @@ type MessageBusInitConfig = {
117
110
  timeoutMs?: number;
118
111
  settlementConfig?: SettlementConfig | false;
119
112
  watcherConfig?: Partial<Omit<ContractWatcherConfig, "indexerProvider">>;
113
+ messageTimeouts?: Record<string, number>;
120
114
  };
121
115
  export declare class ServiceWorkerReadonlyWallet implements IReadonlyWallet {
122
116
  readonly serviceWorker: ServiceWorker;
@@ -129,6 +123,13 @@ export declare class ServiceWorkerReadonlyWallet implements IReadonlyWallet {
129
123
  protected initWalletPayload: RequestInitWallet["payload"] | null;
130
124
  protected messageBusTimeoutMs?: number;
131
125
  protected messageTimeouts: Record<RequestType, number>;
126
+ protected arkServerUrl?: string;
127
+ protected arkServerPublicKey?: string;
128
+ protected delegatorUrl?: string;
129
+ protected indexerUrl?: string;
130
+ protected esploraUrl?: string;
131
+ protected watcherConfig?: Partial<Omit<ContractWatcherConfig, "indexerProvider">>;
132
+ protected settlementConfig?: SettlementConfig | false;
132
133
  private reinitPromise;
133
134
  private pingPromise;
134
135
  private inflightRequests;
@@ -165,6 +166,21 @@ export declare class ServiceWorkerReadonlyWallet implements IReadonlyWallet {
165
166
  private pingServiceWorker;
166
167
  private sendMessageWithRetry;
167
168
  protected sendMessageWithEvents(request: WalletUpdaterRequest, onEvent: (response: WalletUpdaterResponse) => void, isComplete: (response: WalletUpdaterResponse) => boolean): Promise<WalletUpdaterResponse>;
169
+ /**
170
+ * Produce a serialized envelope for the wallet's identity. The base
171
+ * class always emits a readonly envelope; `ServiceWorkerWallet`
172
+ * overrides to emit a signing envelope.
173
+ */
174
+ protected serializeIdentity(): Promise<SerializedIdentity>;
175
+ /**
176
+ * Return the cached init config, or rebuild one from live instance
177
+ * state when the cache was never populated. Recovery path for
178
+ * SDK-factory-created wallets; manual constructor bypasses do not
179
+ * retain enough state here and will hit the "never initialized" throw.
180
+ */
181
+ protected buildInitConfig(): Promise<MessageBusInitConfig>;
182
+ /** Minimal INIT_WALLET payload used on reinitialize when the cache is gone. */
183
+ protected buildInitWalletPayload(): RequestInitWallet["payload"];
168
184
  private reinitialize;
169
185
  /** Clear cached wallet state from both the page and service worker storage. */
170
186
  clear(): Promise<void>;
@@ -195,8 +211,9 @@ export declare class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet imp
195
211
  readonly identity: Identity;
196
212
  private readonly _assetManager;
197
213
  private readonly hasDelegator;
198
- protected constructor(serviceWorker: ServiceWorker, identity: PrivateKeyIdentity, walletRepository: WalletRepository, contractRepository: ContractRepository, messageTag: string, hasDelegator: boolean);
214
+ protected constructor(serviceWorker: ServiceWorker, identity: Identity, walletRepository: WalletRepository, contractRepository: ContractRepository, messageTag: string, hasDelegator: boolean);
199
215
  get assetManager(): IAssetManager;
216
+ protected serializeIdentity(): Promise<SerializedIdentity>;
200
217
  static create(options: ServiceWorkerWalletCreateOptions): Promise<ServiceWorkerWallet>;
201
218
  /**
202
219
  * Simplified setup method that handles service worker registration
@@ -400,6 +400,8 @@ export declare class VtxoManager implements AsyncDisposable, IVtxoManager {
400
400
  private getBoardingOutputScript;
401
401
  /** Returns the onchain provider for fee estimation and broadcasting. */
402
402
  private getOnchainProvider;
403
+ /** Returns the Ark provider for intent fee and server info lookups. */
404
+ private getArkProvider;
403
405
  /** Returns the Bitcoin network configuration from the wallet. */
404
406
  private getNetwork;
405
407
  /** Returns the wallet's identity for transaction signing. */
@@ -8,7 +8,7 @@ import { ArkProvider, SettlementEvent, SignedIntent } from "../providers/ark";
8
8
  import { SignerSession } from "../tree/signingSession";
9
9
  import { Identity, ReadonlyIdentity } from "../identity";
10
10
  import { ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, GetVtxosFilter, IAssetManager, IReadonlyAssetManager, IReadonlyWallet, IWallet, ReadonlyWalletConfig, Recipient, SendBitcoinParams, SettleParams, WalletBalance, WalletConfig } from ".";
11
- import { CSVMultisigTapscript } from "../script/tapscript";
11
+ import { CSVMultisigTapscript, RelativeTimelock } from "../script/tapscript";
12
12
  import { SettlementConfig, VtxoManager } from "./vtxo-manager";
13
13
  import { Intent } from "../intent";
14
14
  import { IndexerProvider } from "../providers/indexer";
@@ -44,9 +44,10 @@ export declare class ReadonlyWallet implements IReadonlyWallet {
44
44
  protected readonly watcherConfig?: ReadonlyWalletConfig["watcherConfig"];
45
45
  private readonly _assetManager;
46
46
  private _syncVtxosInflight?;
47
+ readonly walletContractTimelocks: RelativeTimelock[];
47
48
  protected _pendingSpendOutpoints: Set<string>;
48
49
  get assetManager(): IReadonlyAssetManager;
49
- protected constructor(identity: ReadonlyIdentity, network: Network, onchainProvider: OnchainProvider, indexerProvider: IndexerProvider, arkServerPublicKey: Bytes, offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script, boardingTapscript: DefaultVtxo.Script, dustAmount: bigint, walletRepository: WalletRepository, contractRepository: ContractRepository, delegatorProvider?: DelegatorProvider | undefined, watcherConfig?: ReadonlyWalletConfig["watcherConfig"]);
50
+ protected constructor(identity: ReadonlyIdentity, network: Network, onchainProvider: OnchainProvider, indexerProvider: IndexerProvider, arkServerPublicKey: Bytes, offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script, boardingTapscript: DefaultVtxo.Script, dustAmount: bigint, walletRepository: WalletRepository, contractRepository: ContractRepository, delegatorProvider?: DelegatorProvider | undefined, watcherConfig?: ReadonlyWalletConfig["watcherConfig"], walletContractTimelocks?: RelativeTimelock[]);
50
51
  /**
51
52
  * Protected helper to set up shared wallet configuration.
52
53
  * Extracts common logic used by both ReadonlyWallet.create() and Wallet.create().
@@ -65,6 +66,7 @@ export declare class ReadonlyWallet implements IReadonlyWallet {
65
66
  contractRepository: ContractRepository;
66
67
  info: import("../providers/ark").ArkInfo;
67
68
  delegatorProvider: DelegatorProvider | undefined;
69
+ walletContractTimelocks: RelativeTimelock[];
68
70
  }>;
69
71
  /**
70
72
  * Create a readonly wallet for querying balances, addresses, and history.
@@ -75,8 +77,8 @@ export declare class ReadonlyWallet implements IReadonlyWallet {
75
77
  static create(config: ReadonlyWalletConfig): Promise<ReadonlyWallet>;
76
78
  get arkAddress(): ArkAddress;
77
79
  /**
78
- * Get the contract script for the wallet's default address.
79
- * This is the pkScript hex, used to identify the wallet in ContractManager.
80
+ * Get the pkScript hex for the wallet's primary offchain address.
81
+ * For the full wallet-owned script set registered in ContractManager, use getWalletScripts().
80
82
  */
81
83
  get defaultContractScript(): string;
82
84
  /** Returns the wallet's Arkade address. */
@@ -125,7 +127,6 @@ export declare class ReadonlyWallet implements IReadonlyWallet {
125
127
  /**
126
128
  * Get all pkScript hex strings for the wallet's own addresses
127
129
  * (both delegate and non-delegate, current and historical).
128
- * Falls back to only the current script if ContractManager is not yet initialized.
129
130
  */
130
131
  getWalletScripts(): Promise<string[]>;
131
132
  /**
@@ -229,7 +230,7 @@ export declare class Wallet extends ReadonlyWallet implements IWallet {
229
230
  readonly settlementConfig: SettlementConfig | false;
230
231
  protected constructor(identity: Identity, network: Network, onchainProvider: OnchainProvider, arkProvider: ArkProvider, indexerProvider: IndexerProvider, arkServerPublicKey: Bytes, offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script, boardingTapscript: DefaultVtxo.Script, serverUnrollScript: CSVMultisigTapscript.Type, forfeitOutputScript: Bytes, forfeitPubkey: Bytes, dustAmount: bigint, walletRepository: WalletRepository, contractRepository: ContractRepository,
231
232
  /** @deprecated Use settlementConfig */
232
- renewalConfig?: WalletConfig["renewalConfig"], delegatorProvider?: DelegatorProvider, watcherConfig?: WalletConfig["watcherConfig"], settlementConfig?: WalletConfig["settlementConfig"]);
233
+ renewalConfig?: WalletConfig["renewalConfig"], delegatorProvider?: DelegatorProvider, watcherConfig?: WalletConfig["watcherConfig"], settlementConfig?: WalletConfig["settlementConfig"], walletContractTimelocks?: RelativeTimelock[]);
233
234
  get assetManager(): IAssetManager;
234
235
  getVtxoManager(): Promise<VtxoManager>;
235
236
  dispose(): Promise<void>;