@@ -2,10 +2,15 @@ use serde::{Deserialize, Serialize};
2
2
3
3
use bitcoin_waila:: PaymentParams ;
4
4
use lightning_invoice:: Bolt11Invoice ;
5
+ use lnurl:: lightning_address:: LightningAddress ;
6
+ use lnurl:: lnurl:: LnUrl ;
5
7
use lnurl:: LnUrlResponse ;
8
+ use nostr:: prelude:: ZapRequestData ;
9
+ use nostr:: { EventBuilder , Filter , JsonUtil , Kind , Metadata , UncheckedUrl } ;
6
10
use std:: str:: FromStr ;
7
11
use tonic_openssl_lnd:: lnrpc;
8
12
13
+ use crate :: nostr_dms:: RELAYS ;
9
14
use crate :: { AppState , MAX_SEND_AMOUNT } ;
10
15
11
16
#[ derive( Clone , Deserialize ) ]
@@ -44,6 +49,48 @@ pub async fn pay_lightning(state: AppState, bolt11: &str) -> anyhow::Result<Stri
44
49
}
45
50
_ => anyhow:: bail!( "invalid lnurl" ) ,
46
51
}
52
+ } else if let Some ( npub) = params. nostr_pubkey ( ) {
53
+ let client = nostr_sdk:: Client :: default ( ) ;
54
+ client. add_relays ( RELAYS ) . await ?;
55
+ client. connect ( ) . await ;
56
+
57
+ let filter = Filter :: new ( )
58
+ . author ( npub. into ( ) )
59
+ . kind ( Kind :: Metadata )
60
+ . limit ( 1 ) ;
61
+ let events = client. get_events_of ( vec ! [ filter] , None ) . await ?;
62
+ let event = events
63
+ . into_iter ( )
64
+ . max_by_key ( |e| e. created_at )
65
+ . ok_or ( anyhow:: anyhow!( "no event" ) ) ?;
66
+
67
+ let metadata = Metadata :: from_json ( & event. content ) ?;
68
+ let lnurl = metadata
69
+ . lud16
70
+ . and_then ( |l| LightningAddress :: from_str ( & l) . ok ( ) . map ( |l| l. lnurl ( ) ) )
71
+ . or ( metadata. lud06 . and_then ( |l| LnUrl :: decode ( l) . ok ( ) ) )
72
+ . ok_or ( anyhow:: anyhow!( "no lnurl" ) ) ?;
73
+
74
+ match state. lnurl . make_request ( & lnurl. url ) . await ? {
75
+ LnUrlResponse :: LnUrlPayResponse ( pay) => {
76
+ if pay. min_sendable > MAX_SEND_AMOUNT {
77
+ anyhow:: bail!( "max amount is 10,000,000" ) ;
78
+ }
79
+
80
+ let relays = RELAYS . iter ( ) . map ( |r| UncheckedUrl :: new ( * r) ) ;
81
+ let zap_data = ZapRequestData :: new ( npub. into ( ) , relays)
82
+ . lnurl ( lnurl. encode ( ) )
83
+ . amount ( pay. min_sendable ) ;
84
+ let zap = EventBuilder :: public_zap_request ( zap_data) . to_event ( & state. keys ) ?;
85
+
86
+ let inv = state
87
+ . lnurl
88
+ . get_invoice ( & pay, pay. min_sendable , Some ( zap. as_json ( ) ) , None )
89
+ . await ?;
90
+ Bolt11Invoice :: from_str ( inv. invoice ( ) ) ?
91
+ }
92
+ _ => anyhow:: bail!( "invalid lnurl" ) ,
93
+ }
47
94
} else {
48
95
anyhow:: bail!( "invalid bolt11" )
49
96
} ;
0 commit comments