Skip to main content

bsv_wallet_toolbox/wallet/
types.rs

1//! Core wallet types used by the Wallet struct and its methods.
2//!
3//! Defines WalletArgs (construction arguments), AuthId (caller identity),
4//! KeyPair, StorageIdentity, PendingSignAction re-export, and specOp
5//! label/basket constants used for internal wallet operations.
6
7use std::sync::Arc;
8
9use bsv::services::overlay_tools::LookupResolver;
10use bsv::wallet::cached_key_deriver::CachedKeyDeriver;
11use serde::{Deserialize, Serialize};
12
13use crate::tables::ProvenTx;
14
15use crate::services::traits::WalletServices;
16use crate::storage::manager::WalletStorageManager;
17use crate::types::Chain;
18
19use super::privileged::PrivilegedKeyManager;
20use super::settings::WalletSettingsManager;
21
22// Re-export PendingSignAction from the signer module.
23pub use crate::signer::types::PendingSignAction;
24
25// ---------------------------------------------------------------------------
26// WalletArgs -- construction arguments for the Wallet struct
27// ---------------------------------------------------------------------------
28
29/// Arguments for constructing a new `Wallet` instance.
30///
31/// Matches the TypeScript `WalletArgs` interface from wallet-toolbox.
32pub struct WalletArgs {
33    /// Which chain (main, test, etc.) this wallet operates on.
34    pub chain: Chain,
35    /// Key deriver for deriving child keys from the root private key.
36    pub key_deriver: Arc<CachedKeyDeriver>,
37    /// Storage manager providing active + optional backup persistence.
38    pub storage: WalletStorageManager,
39    /// Optional wallet services (broadcasting, chain lookups, etc.).
40    pub services: Option<Arc<dyn WalletServices>>,
41    /// Chain monitor for background transaction lifecycle management (Phase 6).
42    pub monitor: Option<Arc<crate::monitor::Monitor>>,
43    /// Optional privileged key manager for sensitive crypto operations.
44    pub privileged_key_manager: Option<Arc<dyn PrivilegedKeyManager>>,
45    /// Optional settings manager with cached TTL.
46    pub settings_manager: Option<WalletSettingsManager>,
47    /// Optional overlay lookup resolver for identity certificate discovery.
48    pub lookup_resolver: Option<Arc<LookupResolver>>,
49}
50
51// ---------------------------------------------------------------------------
52// AuthId -- caller identity for authorized operations
53// ---------------------------------------------------------------------------
54
55/// Identifies the caller for authorized wallet operations.
56///
57/// The `identity_key` is a compressed public key hex string representing
58/// the caller's identity. The optional `user_id` and `is_active` fields
59/// match the TypeScript `AuthId` interface for Phase 3 JSON serialization.
60#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
61#[serde(rename_all = "camelCase")]
62pub struct AuthId {
63    /// Compressed public key hex (66 chars) of the caller.
64    pub identity_key: String,
65    /// Database user_id for the caller, if already resolved.
66    /// Maps to TypeScript `AuthId.userId?`.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub user_id: Option<i64>,
69    /// Whether this user has active storage access.
70    /// Maps to TypeScript `AuthId.isActive?`.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub is_active: Option<bool>,
73}
74
75// ---------------------------------------------------------------------------
76// KeyPair -- public/private key pair
77// ---------------------------------------------------------------------------
78
79/// A simple public/private key pair, represented as hex strings.
80#[derive(Debug, Clone)]
81pub struct KeyPair {
82    /// Private key as hex string.
83    pub private_key: String,
84    /// Compressed public key as hex string.
85    pub public_key: String,
86}
87
88// ---------------------------------------------------------------------------
89// StorageIdentity -- identity for storage operations
90// ---------------------------------------------------------------------------
91
92/// Storage identity information for the wallet.
93#[derive(Debug, Clone)]
94pub struct StorageIdentity {
95    /// The identity key used for storage operations.
96    pub storage_identity_key: String,
97    /// The name of the storage instance.
98    pub storage_name: String,
99}
100
101// ---------------------------------------------------------------------------
102// specOp constants -- special operation basket/label identifiers
103// ---------------------------------------------------------------------------
104
105/// Special operation: throw review actions (label).
106/// Used to trigger dummy review actions for testing.
107pub const SPEC_OP_THROW_REVIEW_ACTIONS: &str =
108    "a496e747fc3ad5fabdd4ae8f91184e71f87539bd3d962aa2548942faaaf0047a";
109
110/// Special operation: wallet balance (basket).
111/// Used as the basket name for wallet balance queries.
112pub const SPEC_OP_WALLET_BALANCE: &str =
113    "893b7646de0e1c9f741bd6e9169b76a8847ae34adef7bef1e6a285371206d2e8";
114
115/// Special operation: invalid change (basket).
116/// Used as the basket name for invalid change outputs.
117pub const SPEC_OP_INVALID_CHANGE: &str =
118    "5a76fd430a311f8bc0553859061710a4475c19fed46e2ff95969aa918e612e57";
119
120/// Special operation: set wallet change params (basket).
121/// Used as the basket name for wallet change parameter configuration.
122pub const SPEC_OP_SET_WALLET_CHANGE_PARAMS: &str =
123    "a4979d28ced8581e9c1c92f1001cc7cb3aabf8ea32e10888ad898f0a509a3929";
124
125/// Special operation: no-send actions (label).
126/// Applied as a label to actions that should not be broadcast.
127pub const SPEC_OP_NO_SEND_ACTIONS: &str =
128    "ac6b20a3bb320adafecd637b25c84b792ad828d3aa510d05dc841481f664277d";
129
130/// Special operation: failed actions (label).
131/// Applied as a label to actions that have failed.
132pub const SPEC_OP_FAILED_ACTIONS: &str =
133    "97d4eb1e49215e3374cc2c1939a7c43a55e95c7427bf2d45ed63e3b4e0c88153";
134
135/// Returns `true` if the given basket name is a specOp basket.
136pub fn is_spec_op_basket(basket: &str) -> bool {
137    matches!(
138        basket,
139        SPEC_OP_WALLET_BALANCE | SPEC_OP_INVALID_CHANGE | SPEC_OP_SET_WALLET_CHANGE_PARAMS
140    )
141}
142
143/// Returns `true` if the given label is a specOp label.
144pub fn is_spec_op_label(label: &str) -> bool {
145    matches!(label, SPEC_OP_NO_SEND_ACTIONS | SPEC_OP_FAILED_ACTIONS)
146}
147
148/// Returns `true` if the given label is a specOp throw label.
149pub fn is_spec_op_throw_label(label: &str) -> bool {
150    label == SPEC_OP_THROW_REVIEW_ACTIONS
151}
152
153// ---------------------------------------------------------------------------
154// Convenience method types
155// ---------------------------------------------------------------------------
156
157/// Wallet balance result returned by `balance_and_utxos()`.
158#[derive(Debug, Clone, Default, Serialize)]
159pub struct WalletBalance {
160    /// Total satoshis across all spendable UTXOs.
161    pub total: u64,
162    /// Individual UTXO details.
163    pub utxos: Vec<UtxoInfo>,
164}
165
166/// Individual UTXO information for balance queries.
167#[derive(Debug, Clone, Serialize)]
168pub struct UtxoInfo {
169    /// Satoshi value of this UTXO.
170    pub satoshis: u64,
171    /// Outpoint string in "txid.vout" format.
172    pub outpoint: String,
173}
174
175/// Aggregate deployment statistics returned by `admin_stats()`.
176///
177/// Each metric has `_day`, `_week`, `_month`, and `_total` variants
178/// matching the TypeScript `AdminStats` interface.
179#[derive(Debug, Clone, Default, Serialize)]
180pub struct AdminStatsResult {
181    /// Identity key of the requester.
182    pub requested_by: String,
183    /// Timestamp when stats were generated.
184    pub when: String,
185
186    /// Users created in the last day.
187    pub users_day: u64,
188    /// Users created in the last week.
189    pub users_week: u64,
190    /// Users created in the last month.
191    pub users_month: u64,
192    /// Total users.
193    pub users_total: u64,
194
195    /// Transactions created in the last day.
196    pub transactions_day: u64,
197    /// Transactions created in the last week.
198    pub transactions_week: u64,
199    /// Transactions created in the last month.
200    pub transactions_month: u64,
201    /// Total transactions.
202    pub transactions_total: u64,
203
204    /// Completed transactions in the last day.
205    pub tx_completed_day: u64,
206    /// Completed transactions in the last week.
207    pub tx_completed_week: u64,
208    /// Completed transactions in the last month.
209    pub tx_completed_month: u64,
210    /// Total completed transactions.
211    pub tx_completed_total: u64,
212
213    /// Failed transactions in the last day.
214    pub tx_failed_day: u64,
215    /// Failed transactions in the last week.
216    pub tx_failed_week: u64,
217    /// Failed transactions in the last month.
218    pub tx_failed_month: u64,
219    /// Total failed transactions.
220    pub tx_failed_total: u64,
221
222    /// Unprocessed transactions in the last day.
223    pub tx_unprocessed_day: u64,
224    /// Unprocessed transactions in the last week.
225    pub tx_unprocessed_week: u64,
226    /// Unprocessed transactions in the last month.
227    pub tx_unprocessed_month: u64,
228    /// Total unprocessed transactions.
229    pub tx_unprocessed_total: u64,
230
231    /// Sending transactions in the last day.
232    pub tx_sending_day: u64,
233    /// Sending transactions in the last week.
234    pub tx_sending_week: u64,
235    /// Sending transactions in the last month.
236    pub tx_sending_month: u64,
237    /// Total sending transactions.
238    pub tx_sending_total: u64,
239
240    /// Unproven transactions in the last day.
241    pub tx_unproven_day: u64,
242    /// Unproven transactions in the last week.
243    pub tx_unproven_week: u64,
244    /// Unproven transactions in the last month.
245    pub tx_unproven_month: u64,
246    /// Total unproven transactions.
247    pub tx_unproven_total: u64,
248
249    /// Unsigned transactions in the last day.
250    pub tx_unsigned_day: u64,
251    /// Unsigned transactions in the last week.
252    pub tx_unsigned_week: u64,
253    /// Unsigned transactions in the last month.
254    pub tx_unsigned_month: u64,
255    /// Total unsigned transactions.
256    pub tx_unsigned_total: u64,
257
258    /// No-send transactions in the last day.
259    pub tx_nosend_day: u64,
260    /// No-send transactions in the last week.
261    pub tx_nosend_week: u64,
262    /// No-send transactions in the last month.
263    pub tx_nosend_month: u64,
264    /// Total no-send transactions.
265    pub tx_nosend_total: u64,
266
267    /// Non-final transactions in the last day.
268    pub tx_nonfinal_day: u64,
269    /// Non-final transactions in the last week.
270    pub tx_nonfinal_week: u64,
271    /// Non-final transactions in the last month.
272    pub tx_nonfinal_month: u64,
273    /// Total non-final transactions.
274    pub tx_nonfinal_total: u64,
275
276    /// Unfailed transactions in the last day.
277    pub tx_unfail_day: u64,
278    /// Unfailed transactions in the last week.
279    pub tx_unfail_week: u64,
280    /// Unfailed transactions in the last month.
281    pub tx_unfail_month: u64,
282    /// Total unfailed transactions.
283    pub tx_unfail_total: u64,
284
285    /// Default basket satoshis in the last day.
286    pub satoshis_default_day: u64,
287    /// Default basket satoshis in the last week.
288    pub satoshis_default_week: u64,
289    /// Default basket satoshis in the last month.
290    pub satoshis_default_month: u64,
291    /// Total default basket satoshis.
292    pub satoshis_default_total: u64,
293
294    /// Other basket satoshis in the last day.
295    pub satoshis_other_day: u64,
296    /// Other basket satoshis in the last week.
297    pub satoshis_other_week: u64,
298    /// Other basket satoshis in the last month.
299    pub satoshis_other_month: u64,
300    /// Total other basket satoshis.
301    pub satoshis_other_total: u64,
302
303    /// Output baskets created in the last day.
304    pub baskets_day: u64,
305    /// Output baskets created in the last week.
306    pub baskets_week: u64,
307    /// Output baskets created in the last month.
308    pub baskets_month: u64,
309    /// Total output baskets.
310    pub baskets_total: u64,
311
312    /// Transaction labels created in the last day.
313    pub labels_day: u64,
314    /// Transaction labels created in the last week.
315    pub labels_week: u64,
316    /// Transaction labels created in the last month.
317    pub labels_month: u64,
318    /// Total transaction labels.
319    pub labels_total: u64,
320
321    /// Output tags created in the last day.
322    pub tags_day: u64,
323    /// Output tags created in the last week.
324    pub tags_week: u64,
325    /// Output tags created in the last month.
326    pub tags_month: u64,
327    /// Total output tags.
328    pub tags_total: u64,
329}
330
331// ---------------------------------------------------------------------------
332// Reprove result types
333// ---------------------------------------------------------------------------
334
335/// Details of a successful ProvenTx proof update.
336///
337/// Matches TS `ReproveProvenUpdate` (the inner object inside ReproveProvenResult).
338#[derive(Debug, Clone, Serialize, Deserialize)]
339#[serde(rename_all = "camelCase")]
340pub struct ReproveProvenUpdate {
341    /// The updated ProvenTx record with new proof fields.
342    pub update: ProvenTx,
343    /// Human-readable description of what changed (matches TS logUpdate).
344    pub log_update: String,
345}
346
347/// Result from `reprove_proven`.
348///
349/// Matches TS `ReproveProvenResult`:
350/// - `updated` is Some if the proof was re-validated and fields changed.
351/// - `unchanged` is true if proof was fetched but matched the existing data.
352/// - `unavailable` is true if no merkle proof could be obtained.
353#[derive(Debug, Clone, Serialize, Deserialize)]
354#[serde(rename_all = "camelCase")]
355pub struct ReproveProvenResult {
356    /// The updated record and log if the proof was changed, otherwise None.
357    pub updated: Option<ReproveProvenUpdate>,
358    /// True if proof was obtained but data was already up-to-date.
359    pub unchanged: bool,
360    /// True if no merkle proof was available for this tx.
361    pub unavailable: bool,
362}
363
364/// Aggregate result from `reprove_header`.
365///
366/// Matches TS `ReproveHeaderResult`:
367/// All ProvenTx records for the deactivated block hash are partitioned into
368/// updated (proof changed), unchanged (proof same), and unavailable (no proof).
369#[derive(Debug, Clone, Serialize, Deserialize)]
370#[serde(rename_all = "camelCase")]
371pub struct ReproveHeaderResult {
372    /// ProvenTx records whose proof was successfully updated to a new block.
373    pub updated: Vec<ProvenTx>,
374    /// ProvenTx records that already had correct proof (no change needed).
375    pub unchanged: Vec<ProvenTx>,
376    /// ProvenTx records for which no merkle proof could be obtained.
377    pub unavailable: Vec<ProvenTx>,
378}
379
380// ---------------------------------------------------------------------------
381// WalletStorageInfo -- per-store metadata for get_stores()
382// ---------------------------------------------------------------------------
383
384/// Metadata about a single storage provider registered in WalletStorageManager.
385///
386/// Matches TS `WalletStorageInfo`:
387/// { storageIdentityKey, storageName, userId?, isActive, isEnabled, isBackup, isConflicting, endpointUrl? }
388#[derive(Debug, Clone, Serialize, Deserialize)]
389#[serde(rename_all = "camelCase")]
390pub struct WalletStorageInfo {
391    /// Unique identity key of this storage (from Settings.storage_identity_key).
392    pub storage_identity_key: String,
393    /// Human-readable name of this storage (from Settings.storage_name).
394    pub storage_name: String,
395    /// Database user_id for the wallet owner in this store, if resolved.
396    pub user_id: Option<i64>,
397    /// True if this store is the currently active provider.
398    pub is_active: bool,
399    /// True if this store is both active and not conflicting (i.e. enabled for writes).
400    pub is_enabled: bool,
401    /// True if this store is a backup provider.
402    pub is_backup: bool,
403    /// True if this store has a conflicting active_storage reference.
404    pub is_conflicting: bool,
405    /// Remote endpoint URL for StorageClient providers, None for local SQLite.
406    pub endpoint_url: Option<String>,
407}