@@ -34,6 +34,8 @@ function NWCTab() {
3434 const [ nwcUri , setNwcUri ] = useState ( '' )
3535 const [ name , setName ] = useState ( '' )
3636 const [ invoice , setInvoice ] = useState ( '' )
37+ const [ sendAmount , setSendAmount ] = useState ( '' )
38+ const [ sendComment , setSendComment ] = useState ( '' )
3739 const [ amount , setAmount ] = useState ( '' )
3840 const [ desc , setDesc ] = useState ( '' )
3941 const [ genInv , setGenInv ] = useState ( '' )
@@ -55,10 +57,42 @@ function NWCTab() {
5557 catch ( e :any ) { show ( String ( e ) , 'err' ) }
5658 setLoading ( false )
5759 }
60+ const isLightningAddress = ( v :string ) => / ^ [ ^ @ \s ] + @ [ ^ @ \s ] + \. [ ^ @ \s ] + $ / . test ( v . trim ( ) )
61+
5862 const pay = async ( ) => {
63+ const target = invoice . trim ( )
5964 setLoading ( true ) ; setMsg ( '' )
60- try { await zap ( ) ?. nwcPayInvoice ( { invoice} ) ; show ( 'Pagato! ⚡' ) ; setInvoice ( '' ) ; setAction ( null ) }
61- catch ( e :any ) { show ( String ( e ) , 'err' ) }
65+
66+ try {
67+ if ( isLightningAddress ( target ) ) {
68+ const sats = parseInt ( sendAmount )
69+ if ( ! Number . isFinite ( sats ) || sats <= 0 ) throw new Error ( 'Inserisci un importo valido in sats' )
70+
71+ const params = await zap ( ) ?. lnurlFetchPayParams ( { address :target } )
72+ const amountMsat = sats * 1000
73+
74+ if ( amountMsat < params . minSendable || amountMsat > params . maxSendable ) {
75+ throw new Error ( `Importo fuori range. Min ${ Math . ceil ( params . minSendable / 1000 ) } sats, max ${ Math . floor ( params . maxSendable / 1000 ) } sats` )
76+ }
77+
78+ const inv = await zap ( ) ?. lnurlRequestInvoice ( {
79+ callback :params . callback ,
80+ amountMsat,
81+ comment :sendComment . trim ( ) || undefined
82+ } )
83+
84+ await zap ( ) ?. nwcPayInvoice ( { invoice :inv . invoice } )
85+ } else {
86+ await zap ( ) ?. nwcPayInvoice ( { invoice :target } )
87+ }
88+
89+ show ( 'Pagato! ⚡' )
90+ setInvoice ( '' )
91+ setSendAmount ( '' )
92+ setSendComment ( '' )
93+ setAction ( null )
94+ }
95+ catch ( e :any ) { show ( String ( e ?. message || e ) , 'err' ) }
6296 setLoading ( false )
6397 }
6498 const mkInv = async ( ) => {
@@ -112,11 +146,19 @@ function NWCTab() {
112146 < button className = "act-btn" onClick = { ( ) => setAction ( 'receive' ) } > ↓ Invoice</ button >
113147 </ div >
114148 { action === 'send' && < >
115- < div className = "field" > < label > Invoice Lightning</ label >
116- < textarea className = "inp inp-mono" rows = { 4 } placeholder = "lnbc..." value = { invoice } onChange = { e => setInvoice ( e . target . value ) } /> </ div >
149+ < div className = "field" > < label > Invoice Lightning o Lightning Address</ label >
150+ < textarea className = "inp inp-mono" rows = { 3 } placeholder = "lnbc... oppure name@domain.com" value = { invoice } onChange = { e => setInvoice ( e . target . value ) } /> </ div >
151+
152+ { isLightningAddress ( invoice ) && < >
153+ < div className = "field" > < label > Importo (sats)</ label >
154+ < input className = "inp" type = "number" min = "1" placeholder = "21" value = { sendAmount } onChange = { e => setSendAmount ( e . target . value ) } /> </ div >
155+ < div className = "field" > < label > Commento opzionale</ label >
156+ < input className = "inp" placeholder = "Zap from Zap Browser" value = { sendComment } onChange = { e => setSendComment ( e . target . value ) } /> </ div >
157+ </ > }
158+
117159 { msg && < div className = { `msg ${ msgK } ` } > { msg } </ div > }
118160 < div className = "act-row" >
119- < button className = "act-btn primary" disabled = { loading || ! invoice } onClick = { pay } > { loading ?'Pagando...' :'Paga ⚡' } </ button >
161+ < button className = "act-btn primary" disabled = { loading || ! invoice || isLightningAddress ( invoice ) && ! sendAmount } onClick = { pay } > { loading ?'Pagando...' :'Paga ⚡' } </ button >
120162 < button className = "act-btn" onClick = { ( ) => setAction ( null ) } > Annulla</ button >
121163 </ div >
122164 </ > }
0 commit comments