1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use crate::payment::{IncomingPaymentInfo, OutgoingPaymentInfo, PaymentInfo};
use crate::{Amount, OfferKind, SwapInfo, TzTime};

use crate::reverse_swap::ReverseSwapInfo;
use breez_sdk_core::ReverseSwapStatus;
use std::time::SystemTime;

/// Information about **all** pending and **only** requested completed activities.
pub struct ListActivitiesResponse {
    pub pending_activities: Vec<Activity>,
    pub completed_activities: Vec<Activity>,
}

#[allow(clippy::large_enum_variant)]
#[derive(Debug, PartialEq)]
pub enum Activity {
    IncomingPayment {
        incoming_payment_info: IncomingPaymentInfo,
    },
    OutgoingPayment {
        outgoing_payment_info: OutgoingPaymentInfo,
    },
    // Topup, referrals.
    OfferClaim {
        incoming_payment_info: IncomingPaymentInfo,
        offer_kind: OfferKind,
    },
    /// An On-chain to Lightning swap.
    ///
    /// The optional field `incoming_payment_info` will always be filled in for successful swaps
    /// and missing for pending swaps.
    Swap {
        incoming_payment_info: Option<IncomingPaymentInfo>,
        swap_info: SwapInfo,
    },
    ReverseSwap {
        outgoing_payment_info: OutgoingPaymentInfo,
        reverse_swap_info: ReverseSwapInfo,
    },
    ChannelClose {
        channel_close_info: ChannelCloseInfo,
    },
}

impl Activity {
    pub(crate) fn get_payment_info(&self) -> Option<&PaymentInfo> {
        match self {
            Activity::IncomingPayment {
                incoming_payment_info,
            } => Some(&incoming_payment_info.payment_info),
            Activity::OutgoingPayment {
                outgoing_payment_info,
            } => Some(&outgoing_payment_info.payment_info),
            Activity::OfferClaim {
                incoming_payment_info,
                ..
            } => Some(&incoming_payment_info.payment_info),
            Activity::Swap {
                incoming_payment_info,
                ..
            } => incoming_payment_info.as_ref().map(|i| &i.payment_info),
            Activity::ReverseSwap {
                outgoing_payment_info,
                ..
            } => Some(&outgoing_payment_info.payment_info),
            Activity::ChannelClose { .. } => None,
        }
    }

    pub(crate) fn get_time(&self) -> SystemTime {
        if let Some(payment_info) = self.get_payment_info() {
            return payment_info.created_at.time;
        }
        match self {
            Activity::ChannelClose {
                channel_close_info:
                    ChannelCloseInfo {
                        amount: _,
                        state: _,
                        closed_at: Some(time),
                        ..
                    },
            } => time.time,
            Activity::Swap {
                incoming_payment_info: None,
                swap_info,
            } => swap_info.created_at.time,
            _ => SystemTime::now(),
        }
    }

    pub(crate) fn is_pending(&self) -> bool {
        if let Activity::ReverseSwap {
            reverse_swap_info, ..
        } = self
        {
            return reverse_swap_info.status == ReverseSwapStatus::Initial
                || reverse_swap_info.status == ReverseSwapStatus::InProgress
                || reverse_swap_info.status == ReverseSwapStatus::CompletedSeen;
        }
        if let Some(payment_info) = self.get_payment_info() {
            return payment_info.payment_state.is_pending();
        }
        match self {
            Activity::ChannelClose { channel_close_info } => match channel_close_info.state {
                ChannelCloseState::Pending => true,
                ChannelCloseState::Confirmed => false,
            },
            Activity::Swap {
                incoming_payment_info: None,
                ..
            } => true,
            _ => false,
        }
    }
}

/// Information about a closed channel.
#[derive(Debug, PartialEq)]
pub struct ChannelCloseInfo {
    /// Our balance on the channel that got closed.
    pub amount: Amount,
    pub state: ChannelCloseState,
    /// When the channel closing tx got confirmed. For pending channel closes, this will be empty.
    pub closed_at: Option<TzTime>,
    pub closing_tx_id: String,
}

#[derive(Debug, PartialEq)]
pub enum ChannelCloseState {
    Pending,
    Confirmed,
}