@@ -50,15 +50,6 @@ const parseAmount = (amountStr) => {
50
50
// Function to format amounts with sats unit
51
51
const formatAmount = ( amount ) => `${ amount . toLocaleString ( ) } sats`
52
52
53
- // Function to prompt user for confirmation
54
- const confirm = ( question ) => {
55
- return new Promise ( ( resolve ) => {
56
- rl . question ( question , ( answer ) => {
57
- resolve ( answer . toLowerCase ( ) === 'y' || answer . toLowerCase ( ) === 'yes' )
58
- } )
59
- } )
60
- }
61
-
62
53
// Function to get invoice from Lightning address
63
54
async function getInvoiceFromLnAddress ( lnAddress , amount , comment ) {
64
55
try {
@@ -237,33 +228,277 @@ async function main () {
237
228
238
229
// Process each recipient group
239
230
for ( const [ recipient , group ] of recipientGroups . entries ( ) ) {
240
- console . log ( '\nPending awards for recipient:' )
241
- console . log ( `Recipient : ${ recipient } ` )
231
+ console . log ( '\n' + '=' . repeat ( 60 ) )
232
+ console . log ( `RECIPIENT : ${ recipient } ` )
242
233
console . log ( `Total amount: ${ formatAmount ( group . totalAmount ) } ` )
243
234
console . log ( `Number of awards: ${ group . awards . length } ` )
235
+ console . log ( '=' . repeat ( 60 ) )
244
236
245
237
console . log ( '\nAwards breakdown:' )
246
238
for ( const award of group . awards ) {
247
239
console . log ( `- ${ award . name } : ${ award . type } | ${ formatAmount ( parseAmount ( award . amount ) ) } (${ award . amount } )` )
248
240
}
249
241
250
- const shouldPay = await confirm ( 'Pay this consolidated award? (y/n): ' )
242
+ // Ask for payment mode for this specific recipient
243
+ console . log ( '\nPayment options for this recipient:' )
244
+ console . log ( '1. Consolidated: Pay all awards in one payment' )
245
+ console . log ( '2. Individual: Pay each award separately' )
246
+ console . log ( '3. Skip: Skip this recipient entirely' )
247
+
248
+ const paymentChoice = await promptInput ( 'Choose option (1, 2, or 3): ' )
249
+
250
+ if ( paymentChoice === '3' ) {
251
+ console . log ( 'Skipping this recipient.' )
252
+ continue
253
+ }
254
+
255
+ const payIndividually = paymentChoice === '2'
256
+
257
+ if ( payIndividually ) {
258
+ console . log ( '\n--- INDIVIDUAL PAYMENT MODE ---' )
259
+
260
+ // Process each award individually for this recipient
261
+ for ( let i = 0 ; i < group . awards . length ; i ++ ) {
262
+ const award = group . awards [ i ]
263
+ const amount = parseAmount ( award . amount )
264
+
265
+ console . log ( `\n--- Award ${ i + 1 } of ${ group . awards . length } for ${ recipient } ---` )
266
+ console . log ( `Name: ${ award . name } ` )
267
+ console . log ( `Type: ${ award . type } ` )
268
+ console . log ( `Amount: ${ formatAmount ( amount ) } (${ award . amount } )` )
269
+ console . log ( `Original recipient: ${ recipient } ` )
270
+
271
+ console . log ( '\nPayment options for this award:' )
272
+ console . log ( '1. Pay to original address' )
273
+ console . log ( '2. Pay to alternative address' )
274
+ console . log ( '3. Skip this award' )
275
+
276
+ const paymentOption = await promptInput ( 'Choose option (1, 2, or 3): ' )
277
+
278
+ if ( paymentOption === '3' ) {
279
+ console . log ( 'Award skipped.' )
280
+ continue
281
+ }
282
+
283
+ let actualRecipient = recipient
284
+ if ( paymentOption === '2' ) {
285
+ actualRecipient = await promptInput ( 'Enter alternative lightning address or receive method: ' )
286
+ if ( ! actualRecipient || actualRecipient . trim ( ) === '' ) {
287
+ console . log ( 'No alternative address provided. Award skipped.' )
288
+ continue
289
+ }
290
+ console . log ( `Using alternative recipient: ${ actualRecipient } ` )
291
+ }
292
+
293
+ try {
294
+ console . log ( `Sending ${ formatAmount ( amount ) } to ${ actualRecipient } ...` )
295
+
296
+ // Get today's date (YYYY-MM-DD) for updating records
297
+ const today = new Date ( )
298
+ const formattedDate = today . toISOString ( ) . split ( 'T' ) [ 0 ]
299
+ let paymentSuccessful = false
300
+
301
+ // Check if recipient is a Lightning address or a BOLT11 invoice
302
+ if ( actualRecipient . includes ( '@' ) ) {
303
+ // Handle Lightning address
304
+ const comment = `Award: ${ award . name } (${ award . type } ) - see https://github.com/stackernews/stacker.news/blob/master/awards.csv`
305
+ console . log ( 'Getting invoice from Lightning address...' )
306
+ const invoice = await getInvoiceFromLnAddress ( actualRecipient , amount , comment )
307
+ console . log ( 'Invoice received, making payment...' )
308
+
309
+ // Use @getalby /sdk to pay the invoice
310
+ const payResult = await payInvoice ( nwcClient , invoice )
311
+
312
+ if ( payResult && payResult . preimage ) {
313
+ console . log ( 'Payment successful!' )
314
+ console . log ( `Preimage: ${ payResult . preimage } ` )
315
+ paymentSuccessful = true
316
+ } else {
317
+ console . error ( 'Payment failed:' , payResult )
318
+ }
319
+ } else {
320
+ // Not a Lightning address, prompt for BOLT11 invoice
321
+ console . log ( `For award: ${ award . name } (${ award . type } )` )
322
+ console . log ( `Recipient: ${ actualRecipient } ` )
323
+ const invoice = await promptInput ( `Enter BOLT11 invoice for ${ formatAmount ( amount ) } : ` )
324
+
325
+ if ( ! invoice || invoice . trim ( ) === '' ) {
326
+ console . log ( 'No invoice provided. Payment skipped.' )
327
+ continue
328
+ }
329
+
330
+ // Handle BOLT11 invoice
331
+ console . log ( 'Making payment to BOLT11 invoice...' )
332
+ const payResult = await payInvoice ( nwcClient , invoice )
333
+
334
+ if ( payResult && payResult . preimage ) {
335
+ console . log ( 'Payment successful!' )
336
+ console . log ( `Preimage: ${ payResult . preimage } ` )
337
+ paymentSuccessful = true
338
+ } else {
339
+ console . error ( 'Payment failed:' , payResult )
340
+ }
341
+ }
342
+
343
+ // Update this specific award with the payment date if successful
344
+ if ( paymentSuccessful ) {
345
+ award [ 'date paid' ] = formattedDate
346
+ // Update the receive method if an alternative was used
347
+ if ( paymentOption === '2' ) {
348
+ award [ 'receive method' ] = actualRecipient
349
+ console . log ( `Award for ${ award . name } marked as paid with updated recipient: ${ actualRecipient } ` )
350
+ } else {
351
+ console . log ( `Award for ${ award . name } marked as paid.` )
352
+ }
353
+ }
354
+ } catch ( error ) {
355
+ console . error ( 'Error making payment:' , error )
356
+ }
357
+ }
358
+ } else {
359
+ console . log ( '\n--- CONSOLIDATED PAYMENT MODE ---' )
360
+
361
+ console . log ( '\nConsolidated payment options:' )
362
+ console . log ( '1. Pay to original address (consolidated)' )
363
+ console . log ( '2. Pay to alternative address (consolidated)' )
364
+ console . log ( '3. Switch to individual mode for this recipient' )
365
+ console . log ( '4. Skip this recipient' )
366
+
367
+ const consolidatedOption = await promptInput ( 'Choose option (1, 2, 3, or 4): ' )
368
+
369
+ if ( consolidatedOption === '4' ) {
370
+ console . log ( 'Recipient skipped.' )
371
+ continue
372
+ }
373
+
374
+ if ( consolidatedOption === '3' ) {
375
+ console . log ( '\n--- SWITCHING TO INDIVIDUAL PAYMENT MODE ---' )
376
+
377
+ // Process each award individually for this recipient
378
+ for ( let i = 0 ; i < group . awards . length ; i ++ ) {
379
+ const award = group . awards [ i ]
380
+ const amount = parseAmount ( award . amount )
381
+
382
+ console . log ( `\n--- Award ${ i + 1 } of ${ group . awards . length } for ${ recipient } ---` )
383
+ console . log ( `Name: ${ award . name } ` )
384
+ console . log ( `Type: ${ award . type } ` )
385
+ console . log ( `Amount: ${ formatAmount ( amount ) } (${ award . amount } )` )
386
+ console . log ( `Original recipient: ${ recipient } ` )
387
+
388
+ console . log ( '\nPayment options for this award:' )
389
+ console . log ( '1. Pay to original address' )
390
+ console . log ( '2. Pay to alternative address' )
391
+ console . log ( '3. Skip this award' )
392
+
393
+ const paymentOption = await promptInput ( 'Choose option (1, 2, or 3): ' )
394
+
395
+ if ( paymentOption === '3' ) {
396
+ console . log ( 'Award skipped.' )
397
+ continue
398
+ }
399
+
400
+ let actualRecipient = recipient
401
+ if ( paymentOption === '2' ) {
402
+ actualRecipient = await promptInput ( 'Enter alternative lightning address or receive method: ' )
403
+ if ( ! actualRecipient || actualRecipient . trim ( ) === '' ) {
404
+ console . log ( 'No alternative address provided. Award skipped.' )
405
+ continue
406
+ }
407
+ console . log ( `Using alternative recipient: ${ actualRecipient } ` )
408
+ }
409
+
410
+ try {
411
+ console . log ( `Sending ${ formatAmount ( amount ) } to ${ actualRecipient } ...` )
412
+
413
+ // Get today's date (YYYY-MM-DD) for updating records
414
+ const today = new Date ( )
415
+ const formattedDate = today . toISOString ( ) . split ( 'T' ) [ 0 ]
416
+ let paymentSuccessful = false
417
+
418
+ // Check if recipient is a Lightning address or a BOLT11 invoice
419
+ if ( actualRecipient . includes ( '@' ) ) {
420
+ // Handle Lightning address
421
+ const comment = `Award: ${ award . name } (${ award . type } ) - see https://github.com/stackernews/stacker.news/blob/master/awards.csv`
422
+ console . log ( 'Getting invoice from Lightning address...' )
423
+ const invoice = await getInvoiceFromLnAddress ( actualRecipient , amount , comment )
424
+ console . log ( 'Invoice received, making payment...' )
425
+
426
+ // Use @getalby /sdk to pay the invoice
427
+ const payResult = await payInvoice ( nwcClient , invoice )
428
+
429
+ if ( payResult && payResult . preimage ) {
430
+ console . log ( 'Payment successful!' )
431
+ console . log ( `Preimage: ${ payResult . preimage } ` )
432
+ paymentSuccessful = true
433
+ } else {
434
+ console . error ( 'Payment failed:' , payResult )
435
+ }
436
+ } else {
437
+ // Not a Lightning address, prompt for BOLT11 invoice
438
+ console . log ( `For award: ${ award . name } (${ award . type } )` )
439
+ console . log ( `Recipient: ${ actualRecipient } ` )
440
+ const invoice = await promptInput ( `Enter BOLT11 invoice for ${ formatAmount ( amount ) } : ` )
441
+
442
+ if ( ! invoice || invoice . trim ( ) === '' ) {
443
+ console . log ( 'No invoice provided. Payment skipped.' )
444
+ continue
445
+ }
446
+
447
+ // Handle BOLT11 invoice
448
+ console . log ( 'Making payment to BOLT11 invoice...' )
449
+ const payResult = await payInvoice ( nwcClient , invoice )
450
+
451
+ if ( payResult && payResult . preimage ) {
452
+ console . log ( 'Payment successful!' )
453
+ console . log ( `Preimage: ${ payResult . preimage } ` )
454
+ paymentSuccessful = true
455
+ } else {
456
+ console . error ( 'Payment failed:' , payResult )
457
+ }
458
+ }
459
+
460
+ // Update this specific award with the payment date if successful
461
+ if ( paymentSuccessful ) {
462
+ award [ 'date paid' ] = formattedDate
463
+ // Update the receive method if an alternative was used
464
+ if ( paymentOption === '2' ) {
465
+ award [ 'receive method' ] = actualRecipient
466
+ console . log ( `Award for ${ award . name } marked as paid with updated recipient: ${ actualRecipient } ` )
467
+ } else {
468
+ console . log ( `Award for ${ award . name } marked as paid.` )
469
+ }
470
+ }
471
+ } catch ( error ) {
472
+ console . error ( 'Error making payment:' , error )
473
+ }
474
+ }
475
+ continue
476
+ }
477
+
478
+ let actualRecipient = recipient
479
+ if ( consolidatedOption === '2' ) {
480
+ actualRecipient = await promptInput ( 'Enter alternative lightning address or receive method for all awards: ' )
481
+ if ( ! actualRecipient || actualRecipient . trim ( ) === '' ) {
482
+ console . log ( 'No alternative address provided. Recipient skipped.' )
483
+ continue
484
+ }
485
+ console . log ( `Using alternative recipient: ${ actualRecipient } ` )
486
+ }
251
487
252
- if ( shouldPay ) {
253
488
try {
254
- console . log ( `Sending ${ formatAmount ( group . totalAmount ) } to ${ recipient } ...` )
489
+ console . log ( `Sending ${ formatAmount ( group . totalAmount ) } to ${ actualRecipient } ...` )
255
490
256
491
// Get today's date (YYYY-MM-DD) for updating records
257
492
const today = new Date ( )
258
493
const formattedDate = today . toISOString ( ) . split ( 'T' ) [ 0 ]
259
494
let paymentSuccessful = false
260
495
261
496
// Check if recipient is a Lightning address or a BOLT11 invoice
262
- if ( recipient . includes ( '@' ) ) {
497
+ if ( actualRecipient . includes ( '@' ) ) {
263
498
// Handle Lightning address
264
499
const comment = 'see https://github.com/stackernews/stacker.news/blob/master/awards.csv'
265
500
console . log ( 'Getting invoice from Lightning address...' )
266
- const invoice = await getInvoiceFromLnAddress ( recipient , group . totalAmount , comment )
501
+ const invoice = await getInvoiceFromLnAddress ( actualRecipient , group . totalAmount , comment )
267
502
console . log ( 'Invoice received, making payment...' )
268
503
269
504
// Use @getalby /sdk to pay the invoice
@@ -278,7 +513,7 @@ async function main () {
278
513
}
279
514
} else {
280
515
// Not a Lightning address, prompt for BOLT11 invoice
281
- console . log ( `For recipient: ${ recipient } ` )
516
+ console . log ( `For recipient: ${ actualRecipient } ` )
282
517
const invoice = await promptInput ( `Enter BOLT11 invoice for ${ formatAmount ( group . totalAmount ) } : ` )
283
518
284
519
if ( ! invoice || invoice . trim ( ) === '' ) {
@@ -303,13 +538,20 @@ async function main () {
303
538
if ( paymentSuccessful ) {
304
539
for ( const award of group . awards ) {
305
540
award [ 'date paid' ] = formattedDate
541
+ // Update the receive method if an alternative was used
542
+ if ( consolidatedOption === '2' ) {
543
+ award [ 'receive method' ] = actualRecipient
544
+ }
545
+ }
546
+ if ( consolidatedOption === '2' ) {
547
+ console . log ( `All awards marked as paid with updated recipient: ${ actualRecipient } ` )
548
+ } else {
549
+ console . log ( 'All awards marked as paid.' )
306
550
}
307
551
}
308
552
} catch ( error ) {
309
553
console . error ( 'Error making payment:' , error )
310
554
}
311
- } else {
312
- console . log ( 'Payment skipped.' )
313
555
}
314
556
}
315
557
0 commit comments