@@ -3,7 +3,19 @@ import wrap from './lib/promise-wrap'
3
3
4
4
const debug = require ( 'debug' ) ( 'lightning-charge' )
5
5
6
- module . exports = ( app , payListen , model , auth ) => {
6
+ module . exports = ( app , payListen , model , auth , ln ) => async {
7
+ // check if method invoicewithdescriptionhash exists
8
+ let help = await ln . help ( )
9
+ let foundCommand
10
+ for ( let i = 0 ; i < help . help . length ; i ++ ) {
11
+ let command = help . help [ i ] . command
12
+ if ( command . slice ( 0 , 26 ) !== 'invoicewithdescriptionhash' ) continue
13
+ foundCommand = true
14
+ break
15
+ }
16
+ if ( ! foundCommand ) return
17
+
18
+ // define routes
7
19
const {
8
20
newInvoice, listInvoicesByLnurlPayEndpoint
9
21
, getLnurlPayEndpoint, listLnurlPayEndpoints
@@ -26,47 +38,65 @@ module.exports = (app, payListen, model, auth) => {
26
38
addBech32Lnurl ( req , await setLnurlPayEndpoint ( req . params . id , req . body ) )
27
39
) ) )
28
40
29
- app . delete ( '/endpoint/:id' , auth , wrap ( async ( req , res ) =>
30
- res . status ( 200 ) . send ( await delLnurlPayEndpoint ( req . params . id ) ) ) )
41
+ app . delete ( '/endpoint/:id' , auth , wrap ( async ( req , res ) => {
42
+ const deletedRows = await delLnurlPayEndpoint ( req . params . id )
43
+ if ( deletedRows ) res . status ( 204 )
44
+ else res . status ( 404 )
45
+ } ) )
31
46
32
- app . get ( '/endpoint/:id' , auth , wrap ( async ( req , res ) =>
33
- res . status ( 200 ) . send (
34
- addBech32Lnurl ( req , await getLnurlPayEndpoint ( req . params . id ) )
35
- ) ) )
47
+ app . get ( '/endpoint/:id' , auth , wrap ( async ( req , res ) => {
48
+ const endpoint = await getLnurlPayEndpoint ( req . params . id )
49
+ if ( endpoint ) res . status ( 200 ) . send ( addBech32Lnurl ( req , endpoint ) )
50
+ else res . status ( 404 )
51
+ } ) )
36
52
37
53
app . get ( '/endpoint/:id/invoices' , auth , wrap ( async ( req , res ) =>
38
54
res . send ( await listInvoicesByLnurlPayEndpoint ( req . params . id ) ) ) )
39
55
40
56
// this is the actual endpoint users will hit
41
57
app . get ( '/lnurl/:id' , wrap ( async ( req , res ) => {
42
- const lnurlpay = await getLnurlPayEndpoint ( req . params . id )
58
+ const endpoint = await getLnurlPayEndpoint ( req . params . id )
59
+
60
+ if ( ! endpoint ) {
61
+ res . status ( 404 )
62
+ return
63
+ }
43
64
44
65
res . status ( 200 ) . send ( {
45
66
tag : 'payRequest'
46
- , minSendable : lnurlpay . min
47
- , maxSendable : lnurlpay . max
48
- , metadata : makeMetadata ( lnurlpay )
49
- , commentAllowed : lnurlpay . comment
67
+ , minSendable : endpoint . min
68
+ , maxSendable : endpoint . max
69
+ , metadata : makeMetadata ( endpoint )
70
+ , commentAllowed : endpoint . comment_length
50
71
, callback : `https://${ req . hostname } /lnurl/${ lnurlpay . id } /callback`
51
72
} )
52
73
} ) )
53
74
54
75
app . get ( '/lnurl/:id/callback' , wrap ( async ( req , res ) => {
55
- const lnurlpay = await getLnurlPayEndpoint ( req . params . id )
76
+ const endpoint = await getLnurlPayEndpoint ( req . params . id )
77
+ const amount = + req . query . amount
56
78
57
- if ( req . query . amount > lnurlpay . max )
58
- return res . send ( { status : 'ERROR' , reason : 'amount too large' } )
59
- if ( req . query . amount < lnurlpay . min )
60
- return res . send ( { status : 'ERROR' , reason : 'amount too small' } )
79
+ if ( ! amount )
80
+ return res . send ( { status : 'ERROR' , reason : `invalid amount '${ req . query . amount } '` } )
81
+ if ( amount > endpoint . max )
82
+ return res . send ( { status : 'ERROR' , reason : `amount must be smaller than ${ Math . floor ( endpoint . max / 1000 ) } sat` } )
83
+ if ( amount < endpoint . min )
84
+ return res . send ( { status : 'ERROR' , reason : `amount must be greater than ${ Math . ceil ( endpoint . min / 1000 ) } sat` } )
61
85
62
86
let invoiceMetadata = { ...req . query }
63
87
delete invoiceMetadata . amount
64
88
delete invoiceMetadata . fromnodes
65
89
delete invoiceMetadata . nonce
66
- invoiceMetadata = { ...lnurlpay . metadata , ...invoiceMetadata }
90
+ invoiceMetadata = { ...endpoint . metadata , ...invoiceMetadata }
91
+
92
+ // enforce comment length
93
+ invoiceMetadata . comment =
94
+ ( lnurlpay . comment && req . query . comment )
95
+ ? ( '' + req . query . comment ) . substr ( 0 , lnurlpay . comment )
96
+ : undefined
67
97
68
98
const invoice = await newInvoice ( {
69
- descriptionHash : require ( 'crypto' )
99
+ description_hash : require ( 'crypto' )
70
100
. createHash ( 'sha256' )
71
101
. update ( makeMetadata ( lnurlpay ) )
72
102
. digest ( 'hex' )
@@ -83,7 +113,7 @@ module.exports = (app, payListen, model, auth) => {
83
113
, url : lnurlpay . success_url
84
114
, description : lnurlpay . success_text || ''
85
115
}
86
- } else if ( lnurlpay . success_value ) {
116
+ } else if ( lnurlpay . success_secret ) {
87
117
// not implemented yet
88
118
} else if ( lnurlpay . success_text ) {
89
119
successAction = { tag : 'message' , message : lnurlpay . success_text }
@@ -98,18 +128,18 @@ module.exports = (app, payListen, model, auth) => {
98
128
} ) )
99
129
}
100
130
101
- function makeMetadata ( lnurlpay ) {
102
- const text = lnurlpay . text
103
-
104
- const meta = [ [ 'text/plain' , text ] ]
105
- . concat ( lnurlpay . image ? [ 'image/png;base64' , lnurlpay . image ] : [ ] )
106
-
107
- return JSON . stringify ( meta )
131
+ function makeMetadata ( endpoint ) {
132
+ return JSON . stringify (
133
+ [ [ 'text/plain' , endpoint . text ] ]
134
+ . concat ( endpoint . image ? [ 'image/png;base64' , endpoint . image ] : [ ] )
135
+ . concat ( JSON . parse ( endpoint . other_metadata || [ ] ) )
136
+ )
108
137
}
109
138
110
139
function addBech32Lnurl ( req , lnurlpay ) {
111
- const hostname = req . hostname || req . params . hostname
112
- const url = `https://${ hostname } /lnurl/${ lnurlpay . id } `
140
+ let base = process . env . URL || `https://${ req . hostname } `
141
+ base = base [ base . length - 1 ] === '/' ? base . slice ( 0 , - 1 ) : base
142
+ const url = `${ base } /lnurl/${ lnurlpay . id } `
113
143
const words = bech32 . toWords ( Buffer . from ( url ) )
114
144
lnurlpay . bech32 = bech32 . encode ( 'lnurl' , words , 2500 ) . toUpperCase ( )
115
145
return lnurlpay
0 commit comments