@arkade-os/sdk 0.3.7 → 0.3.9

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 (41) hide show
  1. package/README.md +78 -1
  2. package/dist/cjs/identity/singleKey.js +33 -1
  3. package/dist/cjs/index.js +17 -2
  4. package/dist/cjs/intent/index.js +31 -2
  5. package/dist/cjs/providers/ark.js +9 -3
  6. package/dist/cjs/providers/indexer.js +2 -2
  7. package/dist/cjs/wallet/batch.js +183 -0
  8. package/dist/cjs/wallet/index.js +15 -0
  9. package/dist/cjs/wallet/serviceWorker/request.js +0 -2
  10. package/dist/cjs/wallet/serviceWorker/wallet.js +98 -34
  11. package/dist/cjs/wallet/serviceWorker/worker.js +169 -69
  12. package/dist/cjs/wallet/utils.js +2 -2
  13. package/dist/cjs/wallet/vtxo-manager.js +5 -0
  14. package/dist/cjs/wallet/wallet.js +399 -356
  15. package/dist/esm/identity/singleKey.js +31 -0
  16. package/dist/esm/index.js +12 -7
  17. package/dist/esm/intent/index.js +31 -2
  18. package/dist/esm/providers/ark.js +9 -3
  19. package/dist/esm/providers/indexer.js +2 -2
  20. package/dist/esm/wallet/batch.js +180 -0
  21. package/dist/esm/wallet/index.js +14 -0
  22. package/dist/esm/wallet/serviceWorker/request.js +0 -2
  23. package/dist/esm/wallet/serviceWorker/wallet.js +96 -33
  24. package/dist/esm/wallet/serviceWorker/worker.js +171 -71
  25. package/dist/esm/wallet/utils.js +2 -2
  26. package/dist/esm/wallet/vtxo-manager.js +6 -1
  27. package/dist/esm/wallet/wallet.js +400 -359
  28. package/dist/types/identity/index.d.ts +5 -3
  29. package/dist/types/identity/singleKey.d.ts +20 -1
  30. package/dist/types/index.d.ts +11 -8
  31. package/dist/types/intent/index.d.ts +19 -2
  32. package/dist/types/providers/ark.d.ts +9 -8
  33. package/dist/types/providers/indexer.d.ts +2 -2
  34. package/dist/types/wallet/batch.d.ts +87 -0
  35. package/dist/types/wallet/index.d.ts +75 -16
  36. package/dist/types/wallet/serviceWorker/request.d.ts +5 -1
  37. package/dist/types/wallet/serviceWorker/wallet.d.ts +46 -15
  38. package/dist/types/wallet/serviceWorker/worker.d.ts +6 -3
  39. package/dist/types/wallet/utils.d.ts +8 -3
  40. package/dist/types/wallet/wallet.d.ts +96 -35
  41. package/package.json +123 -113
@@ -1,10 +1,12 @@
1
1
  import { Transaction } from "../utils/transaction";
2
2
  import { SignerSession } from "../tree/signingSession";
3
- export interface Identity {
3
+ export interface Identity extends ReadonlyIdentity {
4
4
  signerSession(): SignerSession;
5
- xOnlyPublicKey(): Promise<Uint8Array>;
6
- compressedPublicKey(): Promise<Uint8Array>;
7
5
  signMessage(message: Uint8Array, signatureType: "schnorr" | "ecdsa"): Promise<Uint8Array>;
8
6
  sign(tx: Transaction, inputIndexes?: number[]): Promise<Transaction>;
9
7
  }
8
+ export interface ReadonlyIdentity {
9
+ xOnlyPublicKey(): Promise<Uint8Array>;
10
+ compressedPublicKey(): Promise<Uint8Array>;
11
+ }
10
12
  export * from "./singleKey";
@@ -1,4 +1,4 @@
1
- import { Identity } from ".";
1
+ import { Identity, ReadonlyIdentity } from ".";
2
2
  import { Transaction } from "../utils/transaction";
3
3
  import { SignerSession } from "../tree/signingSession";
4
4
  /**
@@ -36,4 +36,23 @@ export declare class SingleKey implements Identity {
36
36
  xOnlyPublicKey(): Promise<Uint8Array>;
37
37
  signerSession(): SignerSession;
38
38
  signMessage(message: Uint8Array, signatureType?: "schnorr" | "ecdsa"): Promise<Uint8Array>;
39
+ toReadonly(): Promise<ReadonlySingleKey>;
40
+ }
41
+ export declare class ReadonlySingleKey implements ReadonlyIdentity {
42
+ private readonly publicKey;
43
+ constructor(publicKey: Uint8Array);
44
+ /**
45
+ * Create a ReadonlySingleKey from a compressed public key.
46
+ *
47
+ * @param publicKey - 33-byte compressed public key (02/03 prefix + 32-byte x coordinate)
48
+ * @returns A new ReadonlySingleKey instance
49
+ * @example
50
+ * ```typescript
51
+ * const pubkey = new Uint8Array(33); // your compressed public key
52
+ * const readonlyKey = ReadonlySingleKey.fromPublicKey(pubkey);
53
+ * ```
54
+ */
55
+ static fromPublicKey(publicKey: Uint8Array): ReadonlySingleKey;
56
+ xOnlyPublicKey(): Promise<Uint8Array>;
57
+ compressedPublicKey(): Promise<Uint8Array>;
39
58
  }
@@ -1,17 +1,18 @@
1
1
  import { Transaction } from "./utils/transaction";
2
- import { SingleKey } from "./identity/singleKey";
3
- import { Identity } from "./identity";
2
+ import { SingleKey, ReadonlySingleKey } from "./identity/singleKey";
3
+ import { Identity, ReadonlyIdentity } from "./identity";
4
4
  import { ArkAddress } from "./script/address";
5
5
  import { VHTLC } from "./script/vhtlc";
6
6
  import { DefaultVtxo } from "./script/default";
7
7
  import { VtxoScript, EncodedVtxoScript, TapLeafScript, TapTreeCoder } from "./script/base";
8
- import { TxType, IWallet, WalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, Recipient, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, GetVtxosFilter, TapLeaves } from "./wallet";
9
- import { Wallet, waitForIncomingFunds, IncomingFunds } from "./wallet/wallet";
8
+ import { TxType, IWallet, IReadonlyWallet, BaseWalletConfig, WalletConfig, ReadonlyWalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, Recipient, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, GetVtxosFilter, TapLeaves, isSpendable, isSubdust, isRecoverable, isExpired } from "./wallet";
9
+ import { Batch } from "./wallet/batch";
10
+ import { Wallet, ReadonlyWallet, waitForIncomingFunds, IncomingFunds, getSequence } from "./wallet/wallet";
10
11
  import { TxTree, TxTreeNode } from "./tree/txTree";
11
12
  import { SignerSession, TreeNonces, TreePartialSigs } from "./tree/signingSession";
12
13
  import { Ramps } from "./wallet/ramps";
13
14
  import { isVtxoExpiringSoon, VtxoManager } from "./wallet/vtxo-manager";
14
- import { ServiceWorkerWallet } from "./wallet/serviceWorker/wallet";
15
+ import { ServiceWorkerWallet, ServiceWorkerReadonlyWallet } from "./wallet/serviceWorker/wallet";
15
16
  import { OnchainWallet } from "./wallet/onchain";
16
17
  import { setupServiceWorker } from "./wallet/serviceWorker/utils";
17
18
  import { Worker } from "./wallet/serviceWorker/worker";
@@ -25,7 +26,7 @@ import { VtxoTaprootTree, ConditionWitness, getArkPsbtFields, setArkPsbtField, A
25
26
  import { Intent } from "./intent";
26
27
  import { ArkNote } from "./arknote";
27
28
  import { networks, Network, NetworkName } from "./networks";
28
- import { RestIndexerProvider, IndexerProvider, IndexerTxType, ChainTxType, PageResponse, Batch, ChainTx, CommitmentTx, TxHistoryRecord, VtxoChain, Tx, Vtxo, PaginationOptions, SubscriptionResponse, SubscriptionHeartbeat, SubscriptionEvent } from "./providers/indexer";
29
+ import { RestIndexerProvider, IndexerProvider, IndexerTxType, ChainTxType, PageResponse, BatchInfo, ChainTx, CommitmentTx, TxHistoryRecord, VtxoChain, Tx, Vtxo, PaginationOptions, SubscriptionResponse, SubscriptionHeartbeat, SubscriptionEvent } from "./providers/indexer";
29
30
  import { Nonces } from "./musig2/nonces";
30
31
  import { PartialSig } from "./musig2/sign";
31
32
  import { AnchorBumper, P2A } from "./utils/anchor";
@@ -33,5 +34,7 @@ import { Unroll } from "./wallet/unroll";
33
34
  import { WalletRepositoryImpl } from "./repositories/walletRepository";
34
35
  import { ContractRepositoryImpl } from "./repositories/contractRepository";
35
36
  import { ArkError, maybeArkError } from "./providers/errors";
36
- export { Wallet, SingleKey, OnchainWallet, Ramps, VtxoManager, ESPLORA_URL, EsploraProvider, RestArkProvider, RestIndexerProvider, ArkAddress, DefaultVtxo, VtxoScript, VHTLC, TxType, IndexerTxType, ChainTxType, SettlementEventType, setupServiceWorker, Worker, ServiceWorkerWallet, Request, Response, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, TapTreeCoder, ArkPsbtFieldKey, ArkPsbtFieldKeyType, setArkPsbtField, getArkPsbtFields, CosignerPublicKey, VtxoTreeExpiry, VtxoTaprootTree, ConditionWitness, buildOffchainTx, verifyTapscriptSignatures, waitForIncomingFunds, hasBoardingTxExpired, combineTapscriptSigs, isVtxoExpiringSoon, ArkNote, networks, WalletRepositoryImpl, ContractRepositoryImpl, Intent, TxTree, P2A, Unroll, Transaction, ArkError, maybeArkError, };
37
- export type { Identity, IWallet, WalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, Recipient, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, ArkTxInput, OffchainTx, TapLeaves, IncomingFunds, IndexerProvider, PageResponse, Batch, 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, Nonces, PartialSig, ArkPsbtFieldCoder, TxTreeNode, AnchorBumper, };
37
+ import { validateVtxoTxGraph, validateConnectorsTxGraph } from "./tree/validation";
38
+ import { buildForfeitTx } from "./forfeit";
39
+ export { Wallet, ReadonlyWallet, SingleKey, ReadonlySingleKey, OnchainWallet, Ramps, VtxoManager, ESPLORA_URL, EsploraProvider, RestArkProvider, RestIndexerProvider, ArkAddress, DefaultVtxo, VtxoScript, VHTLC, TxType, IndexerTxType, ChainTxType, SettlementEventType, setupServiceWorker, Worker, ServiceWorkerWallet, ServiceWorkerReadonlyWallet, Request, Response, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, TapTreeCoder, ArkPsbtFieldKey, ArkPsbtFieldKeyType, setArkPsbtField, getArkPsbtFields, CosignerPublicKey, VtxoTreeExpiry, VtxoTaprootTree, ConditionWitness, buildOffchainTx, verifyTapscriptSignatures, waitForIncomingFunds, hasBoardingTxExpired, combineTapscriptSigs, isVtxoExpiringSoon, ArkNote, networks, WalletRepositoryImpl, ContractRepositoryImpl, Intent, TxTree, P2A, Unroll, Transaction, ArkError, maybeArkError, Batch, validateVtxoTxGraph, validateConnectorsTxGraph, buildForfeitTx, isRecoverable, isSpendable, isSubdust, isExpired, getSequence, };
40
+ export type { Identity, ReadonlyIdentity, IWallet, IReadonlyWallet, BaseWalletConfig, WalletConfig, ReadonlyWalletConfig, ProviderClass, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, Recipient, SettleParams, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, ArkTxInput, OffchainTx, TapLeaves, IncomingFunds, 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, Nonces, PartialSig, ArkPsbtFieldCoder, TxTreeNode, AnchorBumper, };
@@ -32,10 +32,27 @@ export declare namespace Intent {
32
32
  * ownership of VTXOs and UTXOs. The proof includes the message to be
33
33
  * signed and the inputs/outputs that demonstrate ownership.
34
34
  *
35
- * @param message - The Intent message to be signed
35
+ * @param message - The Intent message to be signed, either raw string of Message object
36
36
  * @param inputs - Array of transaction inputs to prove ownership of
37
37
  * @param outputs - Optional array of transaction outputs
38
38
  * @returns An unsigned Intent proof transaction
39
39
  */
40
- function create(message: string, inputs: TransactionInput[], outputs?: TransactionOutput[]): Proof;
40
+ function create(message: string | Message, inputs: TransactionInput[], outputs?: TransactionOutput[]): Proof;
41
+ type RegisterMessage = {
42
+ type: "register";
43
+ onchain_output_indexes: number[];
44
+ valid_at: number;
45
+ expire_at: number;
46
+ cosigners_public_keys: string[];
47
+ };
48
+ type DeleteMessage = {
49
+ type: "delete";
50
+ expire_at: number;
51
+ };
52
+ type GetPendingTxMessage = {
53
+ type: "get-pending-tx";
54
+ expire_at: number;
55
+ };
56
+ type Message = RegisterMessage | DeleteMessage | GetPendingTxMessage;
57
+ function encodeMessage(message: Message): string;
41
58
  }
@@ -1,6 +1,7 @@
1
1
  import { TxTreeNode } from "../tree/txTree";
2
2
  import { TreeNonces, TreePartialSigs } from "../tree/signingSession";
3
3
  import { Vtxo } from "./indexer";
4
+ import { Intent } from "../intent";
4
5
  export type Output = {
5
6
  address: string;
6
7
  amount: bigint;
@@ -113,9 +114,9 @@ export interface ArkInfo {
113
114
  vtxoMaxAmount: bigint;
114
115
  vtxoMinAmount: bigint;
115
116
  }
116
- export interface SignedIntent {
117
+ export interface SignedIntent<T extends Intent.Message> {
117
118
  proof: string;
118
- message: string;
119
+ message: T;
119
120
  }
120
121
  export interface TxNotification {
121
122
  txid: string;
@@ -135,8 +136,8 @@ export interface ArkProvider {
135
136
  signedCheckpointTxs: string[];
136
137
  }>;
137
138
  finalizeTx(arkTxid: string, finalCheckpointTxs: string[]): Promise<void>;
138
- registerIntent(intent: SignedIntent): Promise<string>;
139
- deleteIntent(intent: SignedIntent): Promise<void>;
139
+ registerIntent(intent: SignedIntent<Intent.RegisterMessage>): Promise<string>;
140
+ deleteIntent(intent: SignedIntent<Intent.DeleteMessage>): Promise<void>;
140
141
  confirmRegistration(intentId: string): Promise<void>;
141
142
  submitTreeNonces(batchId: string, pubkey: string, nonces: TreeNonces): Promise<void>;
142
143
  submitTreeSignatures(batchId: string, pubkey: string, signatures: TreePartialSigs): Promise<void>;
@@ -146,7 +147,7 @@ export interface ArkProvider {
146
147
  commitmentTx?: TxNotification;
147
148
  arkTx?: TxNotification;
148
149
  }>;
149
- getPendingTxs(intent: SignedIntent): Promise<PendingTx[]>;
150
+ getPendingTxs(intent: SignedIntent<Intent.GetPendingTxMessage>): Promise<PendingTx[]>;
150
151
  }
151
152
  /**
152
153
  * REST-based Ark provider implementation.
@@ -167,8 +168,8 @@ export declare class RestArkProvider implements ArkProvider {
167
168
  signedCheckpointTxs: string[];
168
169
  }>;
169
170
  finalizeTx(arkTxid: string, finalCheckpointTxs: string[]): Promise<void>;
170
- registerIntent(intent: SignedIntent): Promise<string>;
171
- deleteIntent(intent: SignedIntent): Promise<void>;
171
+ registerIntent(intent: SignedIntent<Intent.RegisterMessage>): Promise<string>;
172
+ deleteIntent(intent: SignedIntent<Intent.DeleteMessage>): Promise<void>;
172
173
  confirmRegistration(intentId: string): Promise<void>;
173
174
  submitTreeNonces(batchId: string, pubkey: string, nonces: TreeNonces): Promise<void>;
174
175
  submitTreeSignatures(batchId: string, pubkey: string, signatures: TreePartialSigs): Promise<void>;
@@ -178,7 +179,7 @@ export declare class RestArkProvider implements ArkProvider {
178
179
  commitmentTx?: TxNotification;
179
180
  arkTx?: TxNotification;
180
181
  }>;
181
- getPendingTxs(intent: SignedIntent): Promise<PendingTx[]>;
182
+ getPendingTxs(intent: SignedIntent<Intent.GetPendingTxMessage>): Promise<PendingTx[]>;
182
183
  protected parseSettlementEvent(data: ProtoTypes.GetEventStreamResponse): SettlementEvent | null;
183
184
  protected parseTransactionNotification(data: ProtoTypes.GetTransactionsStreamResponse): {
184
185
  commitmentTx?: TxNotification;
@@ -20,7 +20,7 @@ export interface PageResponse {
20
20
  next: number;
21
21
  total: number;
22
22
  }
23
- export interface Batch {
23
+ export interface BatchInfo {
24
24
  totalOutputAmount: string;
25
25
  totalOutputVtxos: number;
26
26
  expiresAt: string;
@@ -36,7 +36,7 @@ export interface CommitmentTx {
36
36
  startedAt: string;
37
37
  endedAt: string;
38
38
  batches: {
39
- [key: string]: Batch;
39
+ [key: string]: BatchInfo;
40
40
  };
41
41
  totalInputAmount: string;
42
42
  totalInputVtxos: number;
@@ -0,0 +1,87 @@
1
+ import type { BatchStartedEvent, BatchFinalizedEvent, BatchFailedEvent, TreeTxEvent, TreeSignatureEvent, TreeSigningStartedEvent, TreeNoncesEvent, BatchFinalizationEvent, SettlementEvent } from "../providers/ark";
2
+ import { TxTree } from "../tree/txTree";
3
+ /**
4
+ * Batch namespace provides utilities for joining and processing batch session.
5
+ * The batch settlement process involves multiple events, this namespace provides abstractions and types to handle them.
6
+ * @see https://docs.arkadeos.com/learn/pillars/batch-swaps
7
+ * @example
8
+ * ```typescript
9
+ * // use wallet handler or create a custom one
10
+ * const handler = wallet.createBatchHandler(intentId, inputs, musig2session);
11
+ *
12
+ * const abortController = new AbortController();
13
+ * // Get event stream from Ark provider
14
+ * const eventStream = arkProvider.getEventStream(
15
+ * abortController.signal,
16
+ * ['your-topic-1', 'your-topic-2']
17
+ * );
18
+ *
19
+ * // Join the batch and process events
20
+ * try {
21
+ * const commitmentTxid = await Batch.join(eventStream, handler);
22
+ * console.log('Batch completed with commitment:', commitmentTxid);
23
+ * } catch (error) {
24
+ * console.error('Batch processing failed:', error);
25
+ * } finally {
26
+ * abortController.abort();
27
+ * }
28
+ * ```
29
+ */
30
+ export declare namespace Batch {
31
+ interface Handler {
32
+ /**
33
+ * Called on BatchStarted event.
34
+ * @returns { skip: boolean } indicating whether the batch should be skipped or not.
35
+ */
36
+ onBatchStarted(event: BatchStartedEvent): Promise<{
37
+ skip: boolean;
38
+ }>;
39
+ /**
40
+ * Called when tree signing starts.
41
+ * @param event The tree signing started event.
42
+ * @param vtxoTree The unsigned VTXO tree, reconstructed from the TreeTxEvent events.
43
+ * @returns Promise resolving to a boolean indicating whether to continue processing.
44
+ */
45
+ onTreeSigningStarted(event: TreeSigningStartedEvent, vtxoTree: TxTree): Promise<{
46
+ skip: boolean;
47
+ }>;
48
+ /**
49
+ * Called when tree nonces are received.
50
+ * @param event The tree nonces event.
51
+ * @returns Promise resolving to a boolean indicating whether signing is complete.
52
+ */
53
+ onTreeNonces(event: TreeNoncesEvent): Promise<{
54
+ fullySigned: boolean;
55
+ }>;
56
+ /**
57
+ * Called during batch finalization.
58
+ * @param event The batch finalization event.
59
+ * @param vtxoTree The signed VTXO tree, reconstructed from the TreeTxEvent events.
60
+ * @param connectorTree The connector transaction tree, reconstructed from the TreeTxEvent events.
61
+ */
62
+ onBatchFinalization(event: BatchFinalizationEvent, vtxoTree?: TxTree, connectorTree?: TxTree): Promise<void>;
63
+ onBatchFinalized?(event: BatchFinalizedEvent): Promise<void>;
64
+ onBatchFailed?(event: BatchFailedEvent): Promise<void>;
65
+ onTreeTxEvent?(event: TreeTxEvent): Promise<void>;
66
+ onTreeSignatureEvent?(event: TreeSignatureEvent): Promise<void>;
67
+ }
68
+ /**
69
+ * Options for the join function.
70
+ * @param @optional abortController - The abort controller to use to abort the operation.
71
+ * @param @optional skipVtxoTreeSigning - ignore events related to vtxo tree musig2 signing session.
72
+ * @param @optional eventCallback - A callback to be called for each event.
73
+ * @param eventCallback - A callback to be called for each event.
74
+ */
75
+ type JoinOptions = Partial<{
76
+ abortController: AbortController;
77
+ skipVtxoTreeSigning: boolean;
78
+ eventCallback: (event: SettlementEvent) => Promise<void>;
79
+ }>;
80
+ /**
81
+ * Start the state machine that will process the batch events and join a batch.
82
+ * @param eventIterator - The events stream to process.
83
+ * @param handler - How to react to events.
84
+ * @param options - Options.
85
+ */
86
+ function join(eventIterator: AsyncIterableIterator<SettlementEvent>, handler: Handler, options?: JoinOptions): Promise<string>;
87
+ }
@@ -1,6 +1,6 @@
1
1
  import { Bytes } from "@scure/btc-signer/utils.js";
2
2
  import { ArkProvider, Output, SettlementEvent } from "../providers/ark";
3
- import { Identity } from "../identity";
3
+ import { Identity, ReadonlyIdentity } from "../identity";
4
4
  import { RelativeTimelock } from "../script/tapscript";
5
5
  import { EncodedVtxoScript, TapLeafScript } from "../script/base";
6
6
  import { StorageAdapter } from "../storage";
@@ -8,7 +8,7 @@ import { RenewalConfig } from "./vtxo-manager";
8
8
  import { IndexerProvider } from "../providers/indexer";
9
9
  import { OnchainProvider } from "../providers/onchain";
10
10
  /**
11
- * Configuration options for wallet initialization.
11
+ * Base configuration options shared by all wallet types.
12
12
  *
13
13
  * Supports two configuration modes:
14
14
  * 1. URL-based: Provide arkServerUrl, indexerUrl (optional), and esploraUrl
@@ -20,6 +20,54 @@ import { OnchainProvider } from "../providers/onchain";
20
20
  * The wallet will use provided URLs to create default providers if custom provider
21
21
  * instances are not supplied. If optional parameters are not provided, the wallet
22
22
  * will fetch configuration from the Ark server.
23
+ */
24
+ export interface BaseWalletConfig {
25
+ arkServerUrl?: string;
26
+ indexerUrl?: string;
27
+ esploraUrl?: string;
28
+ arkServerPublicKey?: string;
29
+ boardingTimelock?: RelativeTimelock;
30
+ exitTimelock?: RelativeTimelock;
31
+ storage?: StorageAdapter;
32
+ arkProvider?: ArkProvider;
33
+ indexerProvider?: IndexerProvider;
34
+ onchainProvider?: OnchainProvider;
35
+ }
36
+ /**
37
+ * Configuration options for readonly wallet initialization.
38
+ *
39
+ * Use this config when you only need to query wallet state (balance, addresses, transactions)
40
+ * without the ability to send transactions. This is useful for:
41
+ * - Watch-only wallets
42
+ * - Monitoring addresses
43
+ * - Safe sharing of wallet state without private key exposure
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * // URL-based configuration
48
+ * const wallet = await ReadonlyWallet.create({
49
+ * identity: ReadonlySingleKey.fromPublicKey(pubkey),
50
+ * arkServerUrl: 'https://ark.example.com',
51
+ * esploraUrl: 'https://mempool.space/api'
52
+ * });
53
+ *
54
+ * // Provider-based configuration (e.g., for Expo/React Native)
55
+ * const wallet = await ReadonlyWallet.create({
56
+ * identity: ReadonlySingleKey.fromPublicKey(pubkey),
57
+ * arkProvider: new ExpoArkProvider('https://ark.example.com'),
58
+ * indexerProvider: new ExpoIndexerProvider('https://ark.example.com'),
59
+ * onchainProvider: new EsploraProvider('https://mempool.space/api')
60
+ * });
61
+ * ```
62
+ */
63
+ export interface ReadonlyWalletConfig extends BaseWalletConfig {
64
+ identity: ReadonlyIdentity;
65
+ }
66
+ /**
67
+ * Configuration options for full wallet initialization.
68
+ *
69
+ * This config provides full wallet capabilities including sending transactions,
70
+ * settling VTXOs, and all readonly operations.
23
71
  *
24
72
  * @example
25
73
  * ```typescript
@@ -37,20 +85,20 @@ import { OnchainProvider } from "../providers/onchain";
37
85
  * indexerProvider: new ExpoIndexerProvider('https://ark.example.com'),
38
86
  * onchainProvider: new EsploraProvider('https://mempool.space/api')
39
87
  * });
88
+ *
89
+ * // With renewal configuration
90
+ * const wallet = await Wallet.create({
91
+ * identity: SingleKey.fromHex('...'),
92
+ * arkServerUrl: 'https://ark.example.com',
93
+ * renewalConfig: {
94
+ * enabled: true,
95
+ * thresholdMs: 86400000, // 24 hours
96
+ * }
97
+ * });
40
98
  * ```
41
99
  */
42
- export interface WalletConfig {
100
+ export interface WalletConfig extends ReadonlyWalletConfig {
43
101
  identity: Identity;
44
- arkServerUrl?: string;
45
- indexerUrl?: string;
46
- esploraUrl?: string;
47
- arkServerPublicKey?: string;
48
- boardingTimelock?: RelativeTimelock;
49
- exitTimelock?: RelativeTimelock;
50
- storage?: StorageAdapter;
51
- arkProvider?: ArkProvider;
52
- indexerProvider?: IndexerProvider;
53
- onchainProvider?: OnchainProvider;
54
102
  renewalConfig?: RenewalConfig;
55
103
  }
56
104
  /**
@@ -142,6 +190,7 @@ export type ExtendedVirtualCoin = TapLeaves & EncodedVtxoScript & VirtualCoin &
142
190
  };
143
191
  export declare function isSpendable(vtxo: VirtualCoin): boolean;
144
192
  export declare function isRecoverable(vtxo: VirtualCoin): boolean;
193
+ export declare function isExpired(vtxo: VirtualCoin): boolean;
145
194
  export declare function isSubdust(vtxo: VirtualCoin, dust: bigint): boolean;
146
195
  export type GetVtxosFilter = {
147
196
  withRecoverable?: boolean;
@@ -154,14 +203,24 @@ export type GetVtxosFilter = {
154
203
  * It provides methods for address management, balance checking, virtual UTXO
155
204
  * operations, and transaction management including sending, settling, and unrolling.
156
205
  */
157
- export interface IWallet {
206
+ export interface IWallet extends IReadonlyWallet {
158
207
  identity: Identity;
208
+ sendBitcoin(params: SendBitcoinParams): Promise<string>;
209
+ settle(params?: SettleParams, eventCallback?: (event: SettlementEvent) => void): Promise<string>;
210
+ }
211
+ /**
212
+ * Readonly wallet interface for Bitcoin transactions with Ark protocol support.
213
+ *
214
+ * This interface defines the contract that all wallet implementations must follow.
215
+ * It provides methods for address management, balance checking, virtual UTXO
216
+ * operations, and transaction management including sending, settling, and unrolling.
217
+ */
218
+ export interface IReadonlyWallet {
219
+ identity: ReadonlyIdentity;
159
220
  getAddress(): Promise<string>;
160
221
  getBoardingAddress(): Promise<string>;
161
222
  getBalance(): Promise<WalletBalance>;
162
223
  getVtxos(filter?: GetVtxosFilter): Promise<ExtendedVirtualCoin[]>;
163
224
  getBoardingUtxos(): Promise<ExtendedCoin[]>;
164
225
  getTransactionHistory(): Promise<ArkTransaction[]>;
165
- sendBitcoin(params: SendBitcoinParams): Promise<string>;
166
- settle(params?: SettleParams, eventCallback?: (event: SettlementEvent) => void): Promise<string>;
167
226
  }
@@ -11,7 +11,11 @@ export declare namespace Request {
11
11
  function isBase(message: unknown): message is Base;
12
12
  interface InitWallet extends Base {
13
13
  type: "INIT_WALLET";
14
- privateKey: string;
14
+ key: {
15
+ privateKey: string;
16
+ } | {
17
+ publicKey: string;
18
+ };
15
19
  arkServerUrl: string;
16
20
  arkServerPublicKey?: string;
17
21
  }
@@ -1,10 +1,11 @@
1
- import { IWallet, WalletBalance, SendBitcoinParams, SettleParams, ArkTransaction, ExtendedCoin, ExtendedVirtualCoin, GetVtxosFilter } from "..";
1
+ import { IWallet, WalletBalance, SendBitcoinParams, SettleParams, ArkTransaction, ExtendedCoin, ExtendedVirtualCoin, GetVtxosFilter, IReadonlyWallet } from "..";
2
+ import { Request } from "./request";
2
3
  import { Response } from "./response";
3
4
  import { SettlementEvent } from "../../providers/ark";
4
- import { Identity } from "../../identity";
5
+ import { Identity, ReadonlyIdentity } from "../../identity";
5
6
  import { WalletRepository } from "../../repositories/walletRepository";
6
7
  import { ContractRepository } from "../../repositories/contractRepository";
7
- export type PrivateKeyIdentity = Identity & {
8
+ type PrivateKeyIdentity = Identity & {
8
9
  toHex(): string;
9
10
  };
10
11
  /**
@@ -45,7 +46,7 @@ interface ServiceWorkerWalletOptions {
45
46
  esploraUrl?: string;
46
47
  dbName?: string;
47
48
  dbVersion?: number;
48
- identity: PrivateKeyIdentity;
49
+ identity: ReadonlyIdentity | Identity;
49
50
  }
50
51
  export type ServiceWorkerWalletCreateOptions = ServiceWorkerWalletOptions & {
51
52
  serviceWorker: ServiceWorker;
@@ -53,13 +54,13 @@ export type ServiceWorkerWalletCreateOptions = ServiceWorkerWalletOptions & {
53
54
  export type ServiceWorkerWalletSetupOptions = ServiceWorkerWalletOptions & {
54
55
  serviceWorkerPath: string;
55
56
  };
56
- export declare class ServiceWorkerWallet implements IWallet {
57
+ export declare class ServiceWorkerReadonlyWallet implements IReadonlyWallet {
57
58
  readonly serviceWorker: ServiceWorker;
58
59
  readonly walletRepository: WalletRepository;
59
60
  readonly contractRepository: ContractRepository;
60
- readonly identity: Identity;
61
- private constructor();
62
- static create(options: ServiceWorkerWalletCreateOptions): Promise<ServiceWorkerWallet>;
61
+ readonly identity: ReadonlyIdentity;
62
+ protected constructor(serviceWorker: ServiceWorker, identity: ReadonlyIdentity, walletRepository: WalletRepository, contractRepository: ContractRepository);
63
+ static create(options: ServiceWorkerWalletCreateOptions): Promise<ServiceWorkerReadonlyWallet>;
63
64
  /**
64
65
  * Simplified setup method that handles service worker registration,
65
66
  * identity creation, and wallet initialization automatically.
@@ -67,22 +68,22 @@ export declare class ServiceWorkerWallet implements IWallet {
67
68
  * @example
68
69
  * ```typescript
69
70
  * // One-liner setup - handles everything automatically!
70
- * const wallet = await ServiceWorkerWallet.setup({
71
+ * const wallet = await ServiceWorkerReadonlyWallet.setup({
71
72
  * serviceWorkerPath: '/service-worker.js',
72
73
  * arkServerUrl: 'https://mutinynet.arkade.sh'
73
74
  * });
74
75
  *
75
- * // With custom identity
76
- * const identity = SingleKey.fromHex('your_private_key_hex');
77
- * const wallet = await ServiceWorkerWallet.setup({
76
+ * // With custom readonly identity
77
+ * const identity = ReadonlySingleKey.fromPublicKey('your_public_key_hex');
78
+ * const wallet = await ServiceWorkerReadonlyWallet.setup({
78
79
  * serviceWorkerPath: '/service-worker.js',
79
80
  * arkServerUrl: 'https://mutinynet.arkade.sh',
80
81
  * identity
81
82
  * });
82
83
  * ```
83
84
  */
84
- static setup(options: ServiceWorkerWalletSetupOptions): Promise<ServiceWorkerWallet>;
85
- private sendMessage;
85
+ static setup(options: ServiceWorkerWalletSetupOptions): Promise<ServiceWorkerReadonlyWallet>;
86
+ protected sendMessage<T extends Request.Base>(message: T): Promise<Response.Base>;
86
87
  clear(): Promise<void>;
87
88
  getAddress(): Promise<string>;
88
89
  getBoardingAddress(): Promise<string>;
@@ -91,8 +92,38 @@ export declare class ServiceWorkerWallet implements IWallet {
91
92
  getStatus(): Promise<Response.WalletStatus["status"]>;
92
93
  getTransactionHistory(): Promise<ArkTransaction[]>;
93
94
  getVtxos(filter?: GetVtxosFilter): Promise<ExtendedVirtualCoin[]>;
95
+ reload(): Promise<boolean>;
96
+ }
97
+ export declare class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet implements IWallet {
98
+ readonly serviceWorker: ServiceWorker;
99
+ readonly walletRepository: WalletRepository;
100
+ readonly contractRepository: ContractRepository;
101
+ readonly identity: Identity;
102
+ protected constructor(serviceWorker: ServiceWorker, identity: PrivateKeyIdentity, walletRepository: WalletRepository, contractRepository: ContractRepository);
103
+ static create(options: ServiceWorkerWalletCreateOptions): Promise<ServiceWorkerWallet>;
104
+ /**
105
+ * Simplified setup method that handles service worker registration,
106
+ * identity creation, and wallet initialization automatically.
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // One-liner setup - handles everything automatically!
111
+ * const wallet = await ServiceWorkerWallet.setup({
112
+ * serviceWorkerPath: '/service-worker.js',
113
+ * arkServerUrl: 'https://mutinynet.arkade.sh'
114
+ * });
115
+ *
116
+ * // With custom identity
117
+ * const identity = SingleKey.fromHex('your_private_key_hex');
118
+ * const wallet = await ServiceWorkerWallet.setup({
119
+ * serviceWorkerPath: '/service-worker.js',
120
+ * arkServerUrl: 'https://mutinynet.arkade.sh',
121
+ * identity
122
+ * });
123
+ * ```
124
+ */
125
+ static setup(options: ServiceWorkerWalletSetupOptions): Promise<ServiceWorkerWallet>;
94
126
  sendBitcoin(params: SendBitcoinParams): Promise<string>;
95
127
  settle(params?: SettleParams, callback?: (event: SettlementEvent) => void): Promise<string>;
96
- reload(): Promise<boolean>;
97
128
  }
98
129
  export {};
@@ -1,12 +1,15 @@
1
1
  /**
2
- * Worker is a class letting to interact with ServiceWorkerWallet from the client
3
- * it aims to be run in a service worker context
2
+ * Worker is a class letting to interact with ServiceWorkerWallet and ServiceWorkerReadonlyWallet from
3
+ * the client; it aims to be run in a service worker context.
4
+ *
5
+ * The messages requiring a Wallet rather than a ReadonlyWallet result in no-op
6
+ * without errors.
4
7
  */
5
8
  export declare class Worker {
6
9
  readonly dbName: string;
7
10
  readonly dbVersion: number;
8
11
  private readonly messageCallback;
9
- private wallet;
12
+ private handler;
10
13
  private arkProvider;
11
14
  private indexerProvider;
12
15
  private incomingFundsSubscription;
@@ -1,3 +1,8 @@
1
- import type { Coin, ExtendedCoin, ExtendedVirtualCoin, VirtualCoin, Wallet } from "..";
2
- export declare function extendVirtualCoin(wallet: Wallet, vtxo: VirtualCoin): ExtendedVirtualCoin;
3
- export declare function extendCoin(wallet: Wallet, utxo: Coin): ExtendedCoin;
1
+ import type { Coin, ExtendedCoin, ExtendedVirtualCoin, VirtualCoin } from "..";
2
+ import { ReadonlyWallet } from "./wallet";
3
+ export declare function extendVirtualCoin(wallet: {
4
+ offchainTapscript: ReadonlyWallet["offchainTapscript"];
5
+ }, vtxo: VirtualCoin): ExtendedVirtualCoin;
6
+ export declare function extendCoin(wallet: {
7
+ boardingTapscript: ReadonlyWallet["boardingTapscript"];
8
+ }, utxo: Coin): ExtendedCoin;