@@ -3,115 +3,58 @@ use bitcoin_payment_instructions::{
33 FixedAmountPaymentInstructions , ParseError , PaymentInstructions , PaymentMethod ,
44 PaymentMethodType , amount, dns_resolver:: DNSHrnResolver ,
55} ;
6- use cli_table:: { Cell , Style , Table , format:: Justify } ;
76use core:: { net:: SocketAddr , str:: FromStr } ;
87
98use crate :: { error:: BDKCliError as Error , utils:: shorten} ;
109
1110#[ derive( Debug ) ]
12- pub struct Payment {
11+ pub struct ResolvedPaymentInfo {
12+ pub hrn : String ,
1313 pub payment_methods : Vec < PaymentMethod > ,
14+ pub description : Option < String > ,
1415 pub min_amount : Option < Amount > ,
1516 pub max_amount : Option < Amount > ,
16- pub description : Option < String > ,
17- pub expected_amount : Option < Amount > ,
18- pub receiving_addr : Option < Address > ,
19- pub hrn : String ,
2017 pub notes : String ,
2118}
2219
23- impl Payment {
24- pub fn display ( & self , pretty : bool ) -> Result < String , Error > {
25- let mut methods: Vec < String > = Vec :: new ( ) ;
26- self . payment_methods . iter ( ) . for_each ( |pm| match pm {
27- bitcoin_payment_instructions:: PaymentMethod :: LightningBolt11 ( bolt11) => {
28- methods. push ( format ! ( "Bolt 11 invoice ({})" , shorten( bolt11, 20 , 15 ) ) )
29- }
30- bitcoin_payment_instructions:: PaymentMethod :: LightningBolt12 ( offer) => {
31- methods. push ( format ! ( "Bolt 12 invoice ({})" , shorten( offer, 20 , 15 ) ) )
32- }
33- bitcoin_payment_instructions:: PaymentMethod :: OnChain ( address) => {
34- methods. push ( format ! ( "On chain ({})" , address) )
35- }
36- bitcoin_payment_instructions:: PaymentMethod :: Cashu ( csh) => {
37- methods. push ( format ! ( "Cashu payment ({})" , shorten( csh, 20 , 15 ) ) )
38- }
39- } ) ;
40-
41- if pretty {
42- let mut table = vec ! [ vec![
43- "HRN" . cell( ) . bold( true ) ,
44- self . hrn. to_string( ) . cell( ) . justify( Justify :: Right ) ,
45- ] ] ;
46-
47- if let Some ( min_amnt) = self . min_amount {
48- table. push ( vec ! [
49- "Min amount" . cell( ) . bold( true ) ,
50- min_amnt. to_string( ) . cell( ) . justify( Justify :: Right ) ,
51- ] ) ;
52- }
53-
54- if let Some ( max_amnt) = self . max_amount {
55- table. push ( vec ! [
56- "Max amount" . cell( ) . bold( true ) ,
57- max_amnt. to_string( ) . cell( ) . justify( Justify :: Right ) ,
58- ] ) ;
59- }
60-
61- if let Some ( send_amnt) = self . expected_amount {
62- table. push ( vec ! [
63- "Expected Amount to send" . cell( ) . bold( true ) ,
64- send_amnt. to_string( ) . cell( ) . justify( Justify :: Right ) ,
65- ] ) ;
66- }
67-
68- if let Some ( descr) = & self . description {
69- table. push ( vec ! [
70- "Description" . cell( ) . bold( true ) ,
71- descr. cell( ) . justify( Justify :: Right ) ,
72- ] ) ;
73- }
74-
75- table. push ( vec ! [
76- "Accepted methods" . cell( ) . bold( true ) ,
77- methods. join( ", " ) . cell( ) . justify( Justify :: Right ) ,
78- ] ) ;
79- table. push ( vec ! [
80- "Notes" . cell( ) . bold( true ) ,
81- self . notes. clone( ) . cell( ) . justify( Justify :: Right ) ,
82- ] ) ;
83-
84- let table = table
85- . table ( )
86- . display ( )
87- . map_err ( |e| Error :: Generic ( e. to_string ( ) ) ) ?;
88-
89- Ok ( format ! ( "{table}" ) )
90- } else {
91- Ok ( serde_json:: to_string_pretty ( & serde_json:: json!( {
92- "hrn" : self . hrn,
93- "payment_methods" : methods,
94- "description" : self . description,
95- "min_amount" : self . min_amount,
96- "max_amount" : self . max_amount,
97- "expected_amount_to_send" : self . expected_amount,
98- "notes" : self . notes
99- } ) ) ?)
100- }
20+ impl ResolvedPaymentInfo {
21+ pub fn display ( & self ) -> Result < String , Error > {
22+ let methods: Vec < String > = self
23+ . payment_methods
24+ . iter ( )
25+ . map ( |pm| match pm {
26+ PaymentMethod :: LightningBolt11 ( bolt11) => {
27+ format ! ( "Bolt 11 invoice ({})" , shorten( bolt11, 20 , 15 ) )
28+ }
29+ PaymentMethod :: LightningBolt12 ( offer) => format ! ( "Bolt 12 invoice ({})" , offer) ,
30+ PaymentMethod :: OnChain ( address) => format ! ( "On chain ({})" , address) ,
31+ PaymentMethod :: Cashu ( csh) => format ! ( "Cashu payment ({})" , csh) ,
32+ } )
33+ . collect ( ) ;
34+
35+ Ok ( serde_json:: to_string_pretty ( & serde_json:: json!( {
36+ "hrn" : self . hrn,
37+ "payment_methods" : methods,
38+ "description" : self . description,
39+ "min_amount" : self . min_amount,
40+ "max_amount" : self . max_amount,
41+ "notes" : self . notes
42+ } ) ) ?)
10143 }
10244}
45+
10346pub ( crate ) async fn parse_dns_instructions (
10447 hrn : & str ,
10548 network : Network ,
106- resolver_ip : String ,
49+ dns_resolver : & str ,
10750) -> Result < ( DNSHrnResolver , PaymentInstructions ) , ParseError > {
108- let ip_address = if resolver_ip . contains ( ':' ) {
109- resolver_ip
51+ let ip_address = if dns_resolver . contains ( ':' ) {
52+ dns_resolver
11053 } else {
111- format ! ( "{resolver_ip }:53" )
54+ & format ! ( "{dns_resolver }:53" )
11255 } ;
11356
114- let sock_addr = SocketAddr :: from_str ( & ip_address) . map_err ( |_| {
57+ let sock_addr = SocketAddr :: from_str ( ip_address) . map_err ( |_| {
11558 ParseError :: HrnResolutionError ( "Unable to create socket from provided address" )
11659 } ) ?;
11760 let resolver = DNSHrnResolver ( sock_addr) ;
@@ -148,7 +91,7 @@ pub async fn process_instructions(
14891 amount_to_send : Amount ,
14992 payment_instructions : & PaymentInstructions ,
15093 resolver : DNSHrnResolver ,
151- ) -> Result < Payment , Error > {
94+ ) -> Result < ( Address , Amount ) , Error > {
15295 match payment_instructions {
15396 PaymentInstructions :: ConfigurableAmount ( instructions) => {
15497 // Look for on chain payment method as it's the only one we can support
@@ -200,44 +143,20 @@ pub async fn process_instructions(
200143
201144 let onchain_details = get_onchain_info ( & fixed_instructions) ?;
202145
203- Ok ( Payment {
204- payment_methods : vec ! [ PaymentMethod :: OnChain ( onchain_details. clone( ) . 0 ) ] ,
205- min_amount,
206- max_amount,
207- description : instructions. recipient_description ( ) . map ( |s| s. to_string ( ) ) ,
208- expected_amount : Some ( onchain_details. 1 ) ,
209- receiving_addr : Some ( onchain_details. 0 . clone ( ) ) ,
210- hrn : instructions. human_readable_name ( ) . unwrap ( ) . to_string ( ) ,
211- notes : "" . to_string ( ) ,
212- } )
146+ Ok ( ( onchain_details. 0 . clone ( ) , onchain_details. 1 ) )
213147 }
214148
215- PaymentInstructions :: FixedAmount ( instructions) => {
216- let onchain_info = get_onchain_info ( instructions) ?;
217-
218- Ok ( Payment {
219- payment_methods : vec ! [ PaymentMethod :: OnChain ( onchain_info. clone( ) . 0 ) ] ,
220- min_amount : None ,
221- max_amount : instructions
222- . max_amount ( )
223- . map ( |amnt| Amount :: from_sat ( amnt. milli_sats ( ) ) ) ,
224- description : instructions. recipient_description ( ) . map ( |s| s. to_string ( ) ) ,
225- expected_amount : Some ( onchain_info. 1 ) ,
226- receiving_addr : Some ( onchain_info. 0 ) ,
227- notes : "" . to_string ( ) ,
228- hrn : instructions. human_readable_name ( ) . unwrap ( ) . to_string ( ) ,
229- } )
230- }
149+ PaymentInstructions :: FixedAmount ( instructions) => Ok ( get_onchain_info ( instructions) ?) ,
231150 }
232151}
233152
234153/// Resolves the dns payment instructions found at the specified Human Readable Name
235154pub async fn resolve_dns_recipient (
236155 hrn : & str ,
237156 network : Network ,
238- ip : String ,
239- ) -> Result < Payment , ParseError > {
240- let ( resolver, instructions) = parse_dns_instructions ( hrn, network, ip ) . await ?;
157+ dns_resolver : & str ,
158+ ) -> Result < ResolvedPaymentInfo , ParseError > {
159+ let ( resolver, instructions) = parse_dns_instructions ( hrn, network, dns_resolver ) . await ?;
241160
242161 match instructions {
243162 PaymentInstructions :: ConfigurableAmount ( ix) => {
@@ -251,15 +170,13 @@ pub async fn resolve_dns_recipient(
251170 . await
252171 . map_err ( ParseError :: InvalidInstructions ) ?;
253172
254- let payment = Payment {
173+ let payment = ResolvedPaymentInfo {
255174 min_amount,
256175 max_amount,
257176 payment_methods : fixed_instructions. methods ( ) . into ( ) ,
258177 description,
259- expected_amount : None ,
260- receiving_addr : None ,
261178 hrn : hrn. to_string ( ) ,
262- notes : "This is configurable payment instructions. You must send an amount between min_amount and max_amount if set." . to_string ( )
179+ notes : "This is configurable payment instructions. You must send an amount between min_amount and max_amount if set." . to_string ( ) ,
263180 } ;
264181
265182 Ok ( payment)
@@ -270,15 +187,13 @@ pub async fn resolve_dns_recipient(
270187 . max_amount ( )
271188 . map ( |amnt| Amount :: from_sat ( amnt. milli_sats ( ) ) ) ;
272189
273- let payment = Payment {
190+ let payment = ResolvedPaymentInfo {
274191 min_amount : None ,
275192 max_amount,
276193 payment_methods : ix. methods ( ) . into ( ) ,
277194 description : ix. recipient_description ( ) . map ( |s| s. to_string ( ) ) ,
278- expected_amount : None ,
279- receiving_addr : None ,
280195 hrn : hrn. to_string ( ) ,
281- notes : "This is a fixed payment instructions. You must send exactly the amount specified in max_amount." . to_string ( )
196+ notes : "This is a fixed payment instructions. You must send exactly the amount specified in max_amount." . to_string ( ) ,
282197 } ;
283198
284199 Ok ( payment)
0 commit comments