@arkade-os/sdk 0.3.0-alpha.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +48 -14
  2. package/dist/cjs/arknote/index.js +3 -3
  3. package/dist/cjs/forfeit.js +2 -2
  4. package/dist/cjs/identity/singleKey.js +8 -8
  5. package/dist/cjs/index.js +13 -5
  6. package/dist/cjs/{bip322 → intent}/index.js +38 -61
  7. package/dist/cjs/musig2/index.js +2 -1
  8. package/dist/cjs/musig2/nonces.js +4 -0
  9. package/dist/cjs/providers/ark.js +76 -45
  10. package/dist/cjs/providers/errors.js +59 -0
  11. package/dist/cjs/providers/expoArk.js +15 -170
  12. package/dist/cjs/providers/expoIndexer.js +22 -111
  13. package/dist/cjs/providers/expoUtils.js +124 -0
  14. package/dist/cjs/providers/onchain.js +19 -20
  15. package/dist/cjs/repositories/walletRepository.js +64 -28
  16. package/dist/cjs/script/base.js +15 -7
  17. package/dist/cjs/script/tapscript.js +20 -21
  18. package/dist/cjs/script/vhtlc.js +2 -2
  19. package/dist/cjs/tree/signingSession.js +44 -11
  20. package/dist/cjs/tree/txTree.js +3 -4
  21. package/dist/cjs/tree/validation.js +2 -3
  22. package/dist/cjs/utils/arkTransaction.js +105 -15
  23. package/dist/cjs/utils/transaction.js +28 -0
  24. package/dist/cjs/utils/unknownFields.js +7 -7
  25. package/dist/cjs/wallet/onchain.js +6 -7
  26. package/dist/cjs/wallet/serviceWorker/response.js +32 -0
  27. package/dist/cjs/wallet/serviceWorker/utils.js +2 -0
  28. package/dist/cjs/wallet/serviceWorker/wallet.js +7 -8
  29. package/dist/cjs/wallet/serviceWorker/worker.js +46 -27
  30. package/dist/cjs/wallet/unroll.js +7 -9
  31. package/dist/cjs/wallet/utils.js +9 -0
  32. package/dist/cjs/wallet/vtxo-manager.js +323 -0
  33. package/dist/cjs/wallet/wallet.js +98 -125
  34. package/dist/esm/arknote/index.js +2 -2
  35. package/dist/esm/forfeit.js +1 -1
  36. package/dist/esm/identity/singleKey.js +9 -9
  37. package/dist/esm/index.js +14 -10
  38. package/dist/esm/{bip322 → intent}/index.js +32 -54
  39. package/dist/esm/musig2/index.js +1 -1
  40. package/dist/esm/musig2/nonces.js +3 -0
  41. package/dist/esm/providers/ark.js +76 -45
  42. package/dist/esm/providers/errors.js +54 -0
  43. package/dist/esm/providers/expoArk.js +15 -137
  44. package/dist/esm/providers/expoIndexer.js +22 -78
  45. package/dist/esm/providers/expoUtils.js +87 -0
  46. package/dist/esm/providers/onchain.js +19 -20
  47. package/dist/esm/repositories/walletRepository.js +64 -28
  48. package/dist/esm/script/base.js +12 -4
  49. package/dist/esm/script/tapscript.js +1 -2
  50. package/dist/esm/script/vhtlc.js +1 -1
  51. package/dist/esm/tree/signingSession.js +45 -12
  52. package/dist/esm/tree/txTree.js +3 -4
  53. package/dist/esm/tree/validation.js +2 -3
  54. package/dist/esm/utils/arkTransaction.js +97 -8
  55. package/dist/esm/utils/transaction.js +24 -0
  56. package/dist/esm/utils/unknownFields.js +3 -3
  57. package/dist/esm/wallet/onchain.js +3 -4
  58. package/dist/esm/wallet/serviceWorker/response.js +32 -0
  59. package/dist/esm/wallet/serviceWorker/utils.js +1 -0
  60. package/dist/esm/wallet/serviceWorker/wallet.js +8 -9
  61. package/dist/esm/wallet/serviceWorker/worker.js +48 -29
  62. package/dist/esm/wallet/unroll.js +5 -7
  63. package/dist/esm/wallet/utils.js +8 -0
  64. package/dist/esm/wallet/vtxo-manager.js +317 -0
  65. package/dist/esm/wallet/wallet.js +92 -119
  66. package/dist/types/arknote/index.d.ts +1 -1
  67. package/dist/types/forfeit.d.ts +2 -2
  68. package/dist/types/identity/index.d.ts +2 -2
  69. package/dist/types/identity/singleKey.d.ts +2 -2
  70. package/dist/types/index.d.ts +9 -7
  71. package/dist/types/intent/index.d.ts +41 -0
  72. package/dist/types/musig2/index.d.ts +1 -1
  73. package/dist/types/musig2/nonces.d.ts +1 -0
  74. package/dist/types/providers/ark.d.ts +62 -26
  75. package/dist/types/providers/errors.d.ts +13 -0
  76. package/dist/types/providers/expoIndexer.d.ts +2 -10
  77. package/dist/types/providers/expoUtils.d.ts +18 -0
  78. package/dist/types/providers/indexer.d.ts +1 -9
  79. package/dist/types/providers/onchain.d.ts +6 -2
  80. package/dist/types/repositories/walletRepository.d.ts +9 -5
  81. package/dist/types/script/base.d.ts +5 -2
  82. package/dist/types/tree/signingSession.d.ts +16 -11
  83. package/dist/types/utils/anchor.d.ts +2 -2
  84. package/dist/types/utils/arkTransaction.d.ts +12 -4
  85. package/dist/types/utils/transaction.d.ts +13 -0
  86. package/dist/types/utils/unknownFields.d.ts +4 -4
  87. package/dist/types/wallet/index.d.ts +6 -4
  88. package/dist/types/wallet/onchain.d.ts +1 -1
  89. package/dist/types/wallet/serviceWorker/response.d.ts +16 -2
  90. package/dist/types/wallet/serviceWorker/utils.d.ts +1 -0
  91. package/dist/types/wallet/serviceWorker/wallet.d.ts +2 -2
  92. package/dist/types/wallet/serviceWorker/worker.d.ts +7 -1
  93. package/dist/types/wallet/unroll.d.ts +1 -1
  94. package/dist/types/wallet/utils.d.ts +2 -1
  95. package/dist/types/wallet/vtxo-manager.d.ts +179 -0
  96. package/dist/types/wallet/wallet.d.ts +8 -4
  97. package/package.json +1 -2
  98. package/dist/cjs/bip322/errors.js +0 -13
  99. package/dist/esm/bip322/errors.js +0 -9
  100. package/dist/types/bip322/errors.d.ts +0 -6
  101. package/dist/types/bip322/index.d.ts +0 -57
@@ -0,0 +1,179 @@
1
+ import { ExtendedVirtualCoin, IWallet } from ".";
2
+ import { SettlementEvent } from "../providers/ark";
3
+ /**
4
+ * Configuration options for automatic VTXO renewal
5
+ */
6
+ export interface RenewalConfig {
7
+ /**
8
+ * Enable automatic renewal monitoring
9
+ * @default false
10
+ */
11
+ enabled?: boolean;
12
+ /**
13
+ * Percentage of expiry time to use as threshold (0-100)
14
+ * E.g., 10 means renew when 10% of time until expiry remains
15
+ * @default 10
16
+ */
17
+ thresholdPercentage?: number;
18
+ }
19
+ /**
20
+ * Default renewal configuration values
21
+ */
22
+ export declare const DEFAULT_RENEWAL_CONFIG: Required<Omit<RenewalConfig, "enabled">>;
23
+ /**
24
+ * Check if a VTXO is expiring soon based on threshold
25
+ *
26
+ * @param vtxo - The virtual coin to check
27
+ * @param thresholdMs - Threshold in milliseconds from now
28
+ * @returns true if VTXO expires within threshold, false otherwise
29
+ */
30
+ export declare function isVtxoExpiringSoon(vtxo: ExtendedVirtualCoin, percentage: number): boolean;
31
+ /**
32
+ * Filter VTXOs that are expiring soon or are recoverable/subdust
33
+ *
34
+ * @param vtxos - Array of virtual coins to check
35
+ * @param thresholdMs - Threshold in milliseconds from now
36
+ * @param dustAmount - Dust threshold amount in satoshis
37
+ * @returns Array of VTXOs expiring within threshold
38
+ */
39
+ export declare function getExpiringAndRecoverableVtxos(vtxos: ExtendedVirtualCoin[], percentage: number, dustAmount: bigint): ExtendedVirtualCoin[];
40
+ /**
41
+ * VtxoManager is a unified class for managing VTXO lifecycle operations including
42
+ * recovery of swept/expired VTXOs and renewal to prevent expiration.
43
+ *
44
+ * Key Features:
45
+ * - **Recovery**: Reclaim swept or expired VTXOs back to the wallet
46
+ * - **Renewal**: Refresh VTXO expiration time before they expire
47
+ * - **Smart subdust handling**: Automatically includes subdust VTXOs when economically viable
48
+ * - **Expiry monitoring**: Check for VTXOs that are expiring soon
49
+ *
50
+ * VTXOs become recoverable when:
51
+ * - The Ark server sweeps them (virtualStatus.state === "swept") and they remain spendable
52
+ * - They are preconfirmed subdust (to consolidate small amounts without locking liquidity on settled VTXOs)
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * // Initialize with renewal config
57
+ * const manager = new VtxoManager(wallet, {
58
+ * enabled: true,
59
+ * thresholdPercentage: 10
60
+ * });
61
+ *
62
+ * // Check recoverable balance
63
+ * const balance = await manager.getRecoverableBalance();
64
+ * if (balance.recoverable > 0n) {
65
+ * console.log(`Can recover ${balance.recoverable} sats`);
66
+ * const txid = await manager.recoverVtxos();
67
+ * }
68
+ *
69
+ * // Check for expiring VTXOs
70
+ * const expiring = await manager.getExpiringVtxos();
71
+ * if (expiring.length > 0) {
72
+ * console.log(`${expiring.length} VTXOs expiring soon`);
73
+ * const txid = await manager.renewVtxos();
74
+ * }
75
+ * ```
76
+ */
77
+ export declare class VtxoManager {
78
+ readonly wallet: IWallet;
79
+ readonly renewalConfig?: RenewalConfig | undefined;
80
+ constructor(wallet: IWallet, renewalConfig?: RenewalConfig | undefined);
81
+ /**
82
+ * Recover swept/expired VTXOs by settling them back to the wallet's Ark address.
83
+ *
84
+ * This method:
85
+ * 1. Fetches all VTXOs (including recoverable ones)
86
+ * 2. Filters for swept but still spendable VTXOs and preconfirmed subdust
87
+ * 3. Includes subdust VTXOs if the total value >= dust threshold
88
+ * 4. Settles everything back to the wallet's Ark address
89
+ *
90
+ * Note: Settled VTXOs with long expiry are NOT recovered to avoid locking liquidity unnecessarily.
91
+ * Only preconfirmed subdust is recovered to consolidate small amounts.
92
+ *
93
+ * @param eventCallback - Optional callback to receive settlement events
94
+ * @returns Settlement transaction ID
95
+ * @throws Error if no recoverable VTXOs found
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const manager = new VtxoManager(wallet);
100
+ *
101
+ * // Simple recovery
102
+ * const txid = await manager.recoverVtxos();
103
+ *
104
+ * // With event callback
105
+ * const txid = await manager.recoverVtxos((event) => {
106
+ * console.log('Settlement event:', event.type);
107
+ * });
108
+ * ```
109
+ */
110
+ recoverVtxos(eventCallback?: (event: SettlementEvent) => void): Promise<string>;
111
+ /**
112
+ * Get information about recoverable balance without executing recovery.
113
+ *
114
+ * Useful for displaying to users before they decide to recover funds.
115
+ *
116
+ * @returns Object containing recoverable amounts and subdust information
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * const manager = new VtxoManager(wallet);
121
+ * const balance = await manager.getRecoverableBalance();
122
+ *
123
+ * if (balance.recoverable > 0n) {
124
+ * console.log(`You can recover ${balance.recoverable} sats`);
125
+ * if (balance.includesSubdust) {
126
+ * console.log(`This includes ${balance.subdust} sats from subdust VTXOs`);
127
+ * }
128
+ * }
129
+ * ```
130
+ */
131
+ getRecoverableBalance(): Promise<{
132
+ recoverable: bigint;
133
+ subdust: bigint;
134
+ includesSubdust: boolean;
135
+ vtxoCount: number;
136
+ }>;
137
+ /**
138
+ * Get VTXOs that are expiring soon based on renewal configuration
139
+ *
140
+ * @param thresholdPercentage - Optional override for threshold percentage (0-100)
141
+ * @returns Array of expiring VTXOs, empty array if renewal is disabled or no VTXOs expiring
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const manager = new VtxoManager(wallet, { enabled: true, thresholdPercentage: 10 });
146
+ * const expiringVtxos = await manager.getExpiringVtxos();
147
+ * if (expiringVtxos.length > 0) {
148
+ * console.log(`${expiringVtxos.length} VTXOs expiring soon`);
149
+ * }
150
+ * ```
151
+ */
152
+ getExpiringVtxos(thresholdPercentage?: number): Promise<ExtendedVirtualCoin[]>;
153
+ /**
154
+ * Renew expiring VTXOs by settling them back to the wallet's address
155
+ *
156
+ * This method collects all expiring spendable VTXOs (including recoverable ones) and settles
157
+ * them back to the wallet, effectively refreshing their expiration time. This is the
158
+ * primary way to prevent VTXOs from expiring.
159
+ *
160
+ * @param eventCallback - Optional callback for settlement events
161
+ * @returns Settlement transaction ID
162
+ * @throws Error if no VTXOs available to renew
163
+ * @throws Error if total amount is below dust threshold
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * const manager = new VtxoManager(wallet);
168
+ *
169
+ * // Simple renewal
170
+ * const txid = await manager.renewVtxos();
171
+ *
172
+ * // With event callback
173
+ * const txid = await manager.renewVtxos((event) => {
174
+ * console.log('Settlement event:', event.type);
175
+ * });
176
+ * ```
177
+ */
178
+ renewVtxos(eventCallback?: (event: SettlementEvent) => void): Promise<string>;
179
+ }
@@ -1,3 +1,4 @@
1
+ import { Bytes } from "@scure/btc-signer/utils.js";
1
2
  import { ArkAddress } from "../script/address";
2
3
  import { DefaultVtxo } from "../script/default";
3
4
  import { Network, NetworkName } from "../networks";
@@ -5,7 +6,6 @@ import { OnchainProvider } from "../providers/onchain";
5
6
  import { SettlementEvent, ArkProvider } from "../providers/ark";
6
7
  import { Identity } from "../identity";
7
8
  import { ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, GetVtxosFilter, IWallet, SendBitcoinParams, SettleParams, WalletBalance, WalletConfig } from ".";
8
- import { Bytes } from "@scure/btc-signer/utils.js";
9
9
  import { CSVMultisigTapscript } from "../script/tapscript";
10
10
  import { IndexerProvider } from "../providers/indexer";
11
11
  import { WalletRepository } from "../repositories/walletRepository";
@@ -63,10 +63,15 @@ export declare class Wallet implements IWallet {
63
63
  readonly boardingTapscript: DefaultVtxo.Script;
64
64
  readonly serverUnrollScript: CSVMultisigTapscript.Type;
65
65
  readonly forfeitOutputScript: Bytes;
66
+ readonly forfeitPubkey: Bytes;
66
67
  readonly dustAmount: bigint;
67
68
  static MIN_FEE_RATE: number;
68
69
  readonly walletRepository: WalletRepository;
69
70
  readonly contractRepository: ContractRepository;
71
+ readonly renewalConfig: Required<Omit<WalletConfig["renewalConfig"], "enabled">> & {
72
+ enabled: boolean;
73
+ thresholdPercentage: number;
74
+ };
70
75
  private constructor();
71
76
  static create(config: WalletConfig): Promise<Wallet>;
72
77
  get arkAddress(): ArkAddress;
@@ -86,12 +91,11 @@ export declare class Wallet implements IWallet {
86
91
  notifyIncomingFunds(eventCallback: (coins: IncomingFunds) => void): Promise<() => void>;
87
92
  private handleBatchStartedEvent;
88
93
  private handleSettlementSigningEvent;
89
- private handleSettlementSigningNoncesGeneratedEvent;
94
+ private handleSettlementTreeNoncesEvent;
90
95
  private handleSettlementFinalizationEvent;
91
96
  private makeRegisterIntentSignature;
92
97
  private makeDeleteIntentSignature;
93
- private prepareBIP322Inputs;
94
- private makeBIP322Signature;
98
+ private prepareIntentProofInputs;
95
99
  }
96
100
  /**
97
101
  * Wait for incoming funds to the wallet
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/sdk",
3
- "version": "0.3.0-alpha.8",
3
+ "version": "0.3.0",
4
4
  "description": "Bitcoin wallet SDK with Taproot and Ark integration",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -54,7 +54,6 @@
54
54
  },
55
55
  "dependencies": {
56
56
  "@noble/curves": "2.0.0",
57
- "@noble/hashes": "2.0.0",
58
57
  "@noble/secp256k1": "3.0.0",
59
58
  "@scure/base": "2.0.0",
60
59
  "@scure/btc-signer": "2.0.1",
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ErrMissingWitnessUtxo = exports.ErrMissingData = exports.ErrMissingInputs = exports.BIP322Error = void 0;
4
- class BIP322Error extends Error {
5
- constructor(message) {
6
- super(message);
7
- this.name = "BIP322Error";
8
- }
9
- }
10
- exports.BIP322Error = BIP322Error;
11
- exports.ErrMissingInputs = new BIP322Error("missing inputs");
12
- exports.ErrMissingData = new BIP322Error("missing data");
13
- exports.ErrMissingWitnessUtxo = new BIP322Error("missing witness utxo");
@@ -1,9 +0,0 @@
1
- export class BIP322Error extends Error {
2
- constructor(message) {
3
- super(message);
4
- this.name = "BIP322Error";
5
- }
6
- }
7
- export const ErrMissingInputs = new BIP322Error("missing inputs");
8
- export const ErrMissingData = new BIP322Error("missing data");
9
- export const ErrMissingWitnessUtxo = new BIP322Error("missing witness utxo");
@@ -1,6 +0,0 @@
1
- export declare class BIP322Error extends Error {
2
- constructor(message: string);
3
- }
4
- export declare const ErrMissingInputs: BIP322Error;
5
- export declare const ErrMissingData: BIP322Error;
6
- export declare const ErrMissingWitnessUtxo: BIP322Error;
@@ -1,57 +0,0 @@
1
- import { Transaction } from "@scure/btc-signer/transaction.js";
2
- import { TransactionInput, TransactionOutput } from "@scure/btc-signer/psbt.js";
3
- /**
4
- * BIP-322 signature implementation for Bitcoin message signing.
5
- *
6
- * BIP-322 defines a standard for signing Bitcoin messages as well as proving
7
- * ownership of coins. This namespace provides utilities for creating and
8
- * validating BIP-322.
9
- *
10
- * @see https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
11
- *
12
- * @example
13
- * ```typescript
14
- * // Create a BIP-322 proof
15
- * const proof = BIP322.create(
16
- * "Hello Bitcoin!",
17
- * [input],
18
- * [output]
19
- * );
20
- *
21
- * // Sign the proof
22
- * const signedProof = await identity.sign(proof);
23
- *
24
- * // Extract the signature
25
- * const signature = BIP322.signature(signedProof);
26
- * ```
27
- */
28
- export declare namespace BIP322 {
29
- type FullProof = Transaction;
30
- type Signature = string;
31
- /**
32
- * Creates a new BIP-322 "full" proof of funds unsigned transaction.
33
- *
34
- * This function constructs a special transaction that can be signed to prove
35
- * ownership of VTXOs and UTXOs. The proof includes the message to be
36
- * signed and the inputs/outputs that demonstrate ownership.
37
- *
38
- * @param message - The BIP-322 message to be signed
39
- * @param inputs - Array of transaction inputs to prove ownership of
40
- * @param outputs - Optional array of transaction outputs
41
- * @returns An unsigned BIP-322 proof transaction
42
- */
43
- function create(message: string, inputs: TransactionInput[], outputs?: TransactionOutput[]): FullProof;
44
- /**
45
- * Finalizes and extracts the FullProof transaction into a BIP-322 signature.
46
- *
47
- * This function takes a signed proof transaction and converts it into a
48
- * base64-encoded signature string. If the proof's inputs have special
49
- * spending conditions, a custom finalizer can be provided.
50
- *
51
- * @param signedProof - The signed BIP-322 proof transaction
52
- * @param finalizer - Optional custom finalizer function
53
- * @returns Base64-encoded BIP-322 signature
54
- */
55
- function signature(signedProof: FullProof, finalizer?: (tx: FullProof) => void): Signature;
56
- }
57
- export declare function craftToSpendTx(message: string, pkScript: Uint8Array): Transaction;