fedimint_wallet_client/
client_db.rs

1use core::fmt;
2use std::ops;
3use std::time::SystemTime;
4
5use fedimint_client::module::init::recovery::RecoveryFromHistoryCommon;
6use fedimint_core::core::OperationId;
7use fedimint_core::encoding::{Decodable, Encodable};
8use fedimint_core::{impl_db_lookup, impl_db_record, TransactionId};
9use serde::{Deserialize, Serialize};
10use strum_macros::EnumIter;
11
12use crate::backup::WalletRecoveryState;
13
14#[derive(Clone, EnumIter, Debug)]
15pub enum DbKeyPrefix {
16    NextPegInTweakIndex = 0x2c,
17    PegInTweakIndex = 0x2d,
18    ClaimedPegIn = 0x2e,
19    RecoveryFinalized = 0x2f,
20    RecoveryState = 0x30,
21}
22
23impl std::fmt::Display for DbKeyPrefix {
24    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
25        write!(f, "{self:?}")
26    }
27}
28
29/// An index of a deposit address
30///
31/// Under the hood it's similar to `ChildId`, but in a wallet module
32/// it's used often enough to deserve own newtype.
33#[derive(
34    Copy,
35    Clone,
36    Debug,
37    Encodable,
38    Decodable,
39    Serialize,
40    Deserialize,
41    Default,
42    PartialEq,
43    Eq,
44    PartialOrd,
45    Ord,
46)]
47pub struct TweakIdx(pub u64);
48
49impl fmt::Display for TweakIdx {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        f.write_fmt(format_args!("TweakIdx({})", self.0))
52    }
53}
54
55impl TweakIdx {
56    #[must_use]
57    pub fn next(self) -> Self {
58        Self(self.0 + 1)
59    }
60
61    #[must_use]
62    pub fn prev(self) -> Option<Self> {
63        self.0.checked_sub(1).map(Self)
64    }
65
66    #[must_use]
67    pub fn advance(self, i: u64) -> Self {
68        Self(self.0 + i)
69    }
70
71    pub fn saturating_sub(&self, rhs: TweakIdx) -> u64 {
72        self.0.saturating_sub(rhs.0)
73    }
74}
75
76impl ops::Sub for TweakIdx {
77    type Output = u64;
78
79    fn sub(self, rhs: Self) -> Self::Output {
80        self.0 - rhs.0
81    }
82}
83
84/// A counter tracking next index to use to derive a peg-in address
85#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
86pub struct NextPegInTweakIndexKey;
87
88impl_db_record!(
89    key = NextPegInTweakIndexKey,
90    value = TweakIdx,
91    db_prefix = DbKeyPrefix::NextPegInTweakIndex,
92);
93
94/// Peg in index that was already allocated and is being tracked for deposits to
95/// claim
96#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
97pub struct PegInTweakIndexKey(pub TweakIdx);
98
99#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
100pub struct PegInTweakIndexPrefix;
101
102#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
103pub struct PegInTweakIndexData {
104    pub operation_id: OperationId,
105    pub creation_time: SystemTime,
106    pub last_check_time: Option<SystemTime>,
107    pub next_check_time: Option<SystemTime>,
108    pub claimed: Vec<bitcoin::OutPoint>,
109}
110
111impl_db_record!(
112    key = PegInTweakIndexKey,
113    value = PegInTweakIndexData,
114    db_prefix = DbKeyPrefix::PegInTweakIndex,
115);
116
117impl_db_lookup!(
118    key = PegInTweakIndexKey,
119    query_prefix = PegInTweakIndexPrefix
120);
121
122#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
123pub struct ClaimedPegInKey {
124    pub peg_in_index: TweakIdx,
125    pub btc_out_point: bitcoin::OutPoint,
126}
127
128#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
129pub struct ClaimedPegInPrefix;
130
131#[derive(Clone, Debug, Encodable, Decodable, Serialize)]
132pub struct ClaimedPegInData {
133    pub claim_txid: TransactionId,
134    pub change: Vec<fedimint_core::OutPoint>,
135}
136
137impl_db_record!(
138    key = ClaimedPegInKey,
139    value = ClaimedPegInData,
140    db_prefix = DbKeyPrefix::ClaimedPegIn,
141    notify_on_modify = true,
142);
143impl_db_lookup!(key = ClaimedPegInKey, query_prefix = ClaimedPegInPrefix);
144
145#[derive(Debug, Clone, Encodable, Decodable, Serialize)]
146pub struct RecoveryFinalizedKey;
147
148#[derive(Debug, Clone, Encodable, Decodable)]
149pub struct RecoveryFinalizedKeyPrefix;
150
151impl_db_record!(
152    key = RecoveryFinalizedKey,
153    value = bool,
154    db_prefix = DbKeyPrefix::RecoveryFinalized,
155);
156
157#[derive(Debug, Clone, Encodable, Decodable, Serialize)]
158pub struct RecoveryStateKey;
159
160#[derive(Debug, Clone, Encodable, Decodable)]
161pub struct RestoreStateKeyPrefix;
162
163impl_db_record!(
164    key = RecoveryStateKey,
165    value = (WalletRecoveryState, RecoveryFromHistoryCommon),
166    db_prefix = DbKeyPrefix::RecoveryState,
167);