breez_sdk_liquid/swapper/
mod.rs

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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use anyhow::Result;
use boltz_client::{
    boltz::{
        ChainPair, CreateChainRequest, CreateChainResponse, CreateReverseRequest,
        CreateReverseResponse, CreateSubmarineRequest, CreateSubmarineResponse, ReversePair,
        SubmarineClaimTxResponse, SubmarinePair,
    },
    network::Chain,
    Amount,
};
use maybe_sync::{MaybeSend, MaybeSync};
use mockall::automock;
use sdk_common::utils::Arc;
use tokio::sync::{broadcast, watch};

use crate::{
    error::{PaymentError, SdkError},
    prelude::{Direction, SendSwap, Swap, Utxo},
};
pub(crate) use subscription_handler::*;
pub(crate) mod boltz;
pub(crate) mod subscription_handler;

#[automock]
#[sdk_macros::async_trait]
pub trait Swapper: MaybeSend + MaybeSync {
    /// Create a new chain swap
    async fn create_chain_swap(
        &self,
        req: CreateChainRequest,
    ) -> Result<CreateChainResponse, PaymentError>;

    /// Create a new send swap
    async fn create_send_swap(
        &self,
        req: CreateSubmarineRequest,
    ) -> Result<CreateSubmarineResponse, PaymentError>;

    /// Get the current rate, limits and fees for a given swap direction
    async fn get_chain_pair(&self, direction: Direction)
        -> Result<Option<ChainPair>, PaymentError>;

    /// Get the current rate, limits and fees for both swap directions
    async fn get_chain_pairs(&self)
        -> Result<(Option<ChainPair>, Option<ChainPair>), PaymentError>;

    /// Get the quote for a Zero-Amount Receive Chain Swap.
    ///
    /// If the user locked-up funds in the valid range this will return that amount. In all other
    /// cases, this will return an error.
    async fn get_zero_amount_chain_swap_quote(&self, swap_id: &str) -> Result<Amount, SdkError>;

    /// Accept a specific quote for a Zero-Amount Receive Chain Swap
    async fn accept_zero_amount_chain_swap_quote(
        &self,
        swap_id: &str,
        server_lockup_sat: u64,
    ) -> Result<(), PaymentError>;

    /// Get a submarine pair information
    async fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError>;

    /// Get a submarine swap's preimage    
    async fn get_submarine_preimage(&self, swap_id: &str) -> Result<String, PaymentError>;

    /// Get send swap claim tx details which includes the preimage as a proof of payment.
    /// It is used to validate the preimage before claiming which is the reason why we need to separate
    /// the claim into two steps.
    async fn get_send_claim_tx_details(
        &self,
        swap: &SendSwap,
    ) -> Result<SubmarineClaimTxResponse, PaymentError>;

    /// Claim send swap cooperatively. Here the remote swapper is the one that claims.
    /// We are helping to use key spend path for cheaper fees.
    async fn claim_send_swap_cooperative(
        &self,
        swap: &SendSwap,
        claim_tx_response: SubmarineClaimTxResponse,
        refund_address: &str,
    ) -> Result<(), PaymentError>;

    /// Create a new receive swap
    async fn create_receive_swap(
        &self,
        req: CreateReverseRequest,
    ) -> Result<CreateReverseResponse, PaymentError>;

    /// Get a reverse pair information
    async fn get_reverse_swap_pairs(&self) -> Result<Option<ReversePair>, PaymentError>;

    /// Create a claim transaction for a receive or chain swap
    async fn create_claim_tx(
        &self,
        swap: Swap,
        claim_address: Option<String>,
    ) -> Result<crate::prelude::Transaction, PaymentError>;

    /// Estimate the refund broadcast transaction size and fees in sats for a send or chain swap
    async fn estimate_refund_broadcast(
        &self,
        swap: Swap,
        refund_address: &str,
        fee_rate_sat_per_vb: Option<f64>,
        is_cooperative: bool,
    ) -> Result<(u32, u64), SdkError>;

    /// Create a refund transaction for a send or chain swap
    async fn create_refund_tx(
        &self,
        swap: Swap,
        refund_address: &str,
        utxos: Vec<Utxo>,
        broadcast_fee_rate_sat_per_vb: Option<f64>,
        is_cooperative: bool,
    ) -> Result<crate::prelude::Transaction, PaymentError>;

    /// Broadcasts a transaction and returns its id
    async fn broadcast_tx(&self, chain: Chain, tx_hex: &str) -> Result<String, PaymentError>;

    /// Look for a valid Magic Routing Hint. If found, validate it and extract the BIP21 info (amount, address).
    async fn check_for_mrh(
        &self,
        invoice: &str,
    ) -> Result<Option<(String, boltz_client::bitcoin::Amount)>, PaymentError>;

    async fn get_bolt12_invoice(
        &self,
        offer: &str,
        amount_sat: u64,
    ) -> Result<String, PaymentError>;
}

pub trait SwapperStatusStream: MaybeSend + MaybeSync {
    fn start(
        self: Arc<Self>,
        callback: Box<dyn SubscriptionHandler>,
        shutdown: watch::Receiver<()>,
    );
    fn track_swap_id(&self, swap_id: &str) -> Result<()>;
    fn subscribe_swap_updates(&self) -> broadcast::Receiver<boltz_client::boltz::SwapStatus>;
}

#[sdk_macros::async_trait]
pub(crate) trait ProxyUrlFetcher: MaybeSend + MaybeSync + 'static {
    async fn fetch(&self) -> Result<&Option<String>>;
}