@@ -41,6 +41,23 @@ const timestampToDate = (unixSeconds?: number): Date | null => {
4141 return null
4242}
4343
44+ const toSafeNumber = ( value : bigint , fieldName : string ) : number => {
45+ if ( value < 0n ) {
46+ throw new Error ( `${ fieldName } must be a non-negative bigint.` )
47+ }
48+
49+ if ( value > BigInt ( Number . MAX_SAFE_INTEGER ) ) {
50+ throw new Error ( `${ fieldName } exceeds Number.MAX_SAFE_INTEGER.` )
51+ }
52+
53+ const asNumber = Number ( value )
54+ if ( ! Number . isSafeInteger ( asNumber ) ) {
55+ throw new Error ( `${ fieldName } is not a safe integer.` )
56+ }
57+
58+ return asNumber
59+ }
60+
4461export class AlbyNwcInvoice implements Invoice {
4562 id : string
4663 pubkey : string
@@ -117,24 +134,42 @@ export class AlbyNwcPaymentsProcessor implements IPaymentsProcessor {
117134 ) ) as NwcTransaction
118135 const status = mapNwcStateToInvoiceStatus ( transaction . state )
119136
120- const invoice = new AlbyNwcInvoice ( )
121- invoice . id = transaction . payment_hash || invoiceId
122- invoice . pubkey = typeof invoiceOrId === 'string' ? '' : invoiceOrId . pubkey
123- invoice . bolt11 = transaction . invoice || ( typeof invoiceOrId === 'string' ? '' : invoiceOrId . bolt11 )
124- invoice . amountRequested =
125- typeof transaction . amount === 'number' && Number . isFinite ( transaction . amount )
126- ? BigInt ( Math . trunc ( transaction . amount ) )
127- : typeof invoiceOrId === 'string'
128- ? 0n
137+ const invoice : GetInvoiceResponse = {
138+ id : transaction . payment_hash || invoiceId ,
139+ status,
140+ confirmedAt : status === InvoiceStatus . COMPLETED ? ( timestampToDate ( transaction . settled_at ) ?? new Date ( ) ) : null ,
141+ expiresAt : timestampToDate ( transaction . expires_at ) ,
142+ updatedAt : new Date ( ) ,
143+ }
144+
145+ if ( typeof invoiceOrId !== 'string' ) {
146+ invoice . pubkey = invoiceOrId . pubkey
147+ invoice . bolt11 = transaction . invoice || invoiceOrId . bolt11
148+ invoice . amountRequested =
149+ typeof transaction . amount === 'number' && Number . isFinite ( transaction . amount )
150+ ? BigInt ( Math . trunc ( transaction . amount ) )
129151 : invoiceOrId . amountRequested
130- invoice . amountPaid = status === InvoiceStatus . COMPLETED ? invoice . amountRequested : undefined
131- invoice . unit = InvoiceUnit . MSATS
132- invoice . status = status
133- invoice . description = transaction . description || ( typeof invoiceOrId === 'string' ? '' : invoiceOrId . description )
134- invoice . confirmedAt = status === InvoiceStatus . COMPLETED ? ( timestampToDate ( transaction . settled_at ) ?? new Date ( ) ) : null
135- invoice . expiresAt = timestampToDate ( transaction . expires_at )
136- invoice . createdAt = timestampToDate ( transaction . created_at ) ?? new Date ( )
137- invoice . updatedAt = new Date ( )
152+ invoice . amountPaid = status === InvoiceStatus . COMPLETED ? invoice . amountRequested : undefined
153+ invoice . unit = InvoiceUnit . MSATS
154+ invoice . description = transaction . description || invoiceOrId . description
155+ invoice . createdAt = timestampToDate ( transaction . created_at ) ?? invoiceOrId . createdAt
156+ } else {
157+ if ( transaction . invoice ) {
158+ invoice . bolt11 = transaction . invoice
159+ }
160+ if ( typeof transaction . amount === 'number' && Number . isFinite ( transaction . amount ) ) {
161+ invoice . amountRequested = BigInt ( Math . trunc ( transaction . amount ) )
162+ invoice . amountPaid = status === InvoiceStatus . COMPLETED ? invoice . amountRequested : undefined
163+ invoice . unit = InvoiceUnit . MSATS
164+ }
165+ if ( transaction . description ) {
166+ invoice . description = transaction . description
167+ }
168+ const createdAt = timestampToDate ( transaction . created_at )
169+ if ( createdAt ) {
170+ invoice . createdAt = createdAt
171+ }
172+ }
138173
139174 return invoice
140175 } )
@@ -155,9 +190,10 @@ export class AlbyNwcPaymentsProcessor implements IPaymentsProcessor {
155190 try {
156191 return await this . withClient ( async ( client ) => {
157192 const expirySeconds = this . settings ( ) . paymentsProcessors ?. alby ?. invoiceExpirySeconds
193+ const amount = toSafeNumber ( amountMsats , 'CreateInvoiceRequest.amount' )
158194 const transaction = ( await this . withReplyTimeout (
159195 client . makeInvoice ( {
160- amount : Number ( amountMsats ) ,
196+ amount,
161197 description,
162198 expiry : expirySeconds ,
163199 } ) ,
0 commit comments