Skip to content

Commit 4034755

Browse files
committed
vibe in award payment enhancements: option to consolidate + use alt receive method
1 parent 04daf87 commit 4034755

File tree

1 file changed

+261
-19
lines changed

1 file changed

+261
-19
lines changed

scripts/pay-awards.js

Lines changed: 261 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,6 @@ const parseAmount = (amountStr) => {
5050
// Function to format amounts with sats unit
5151
const formatAmount = (amount) => `${amount.toLocaleString()} sats`
5252

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-
6253
// Function to get invoice from Lightning address
6354
async function getInvoiceFromLnAddress (lnAddress, amount, comment) {
6455
try {
@@ -237,33 +228,277 @@ async function main () {
237228

238229
// Process each recipient group
239230
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}`)
242233
console.log(`Total amount: ${formatAmount(group.totalAmount)}`)
243234
console.log(`Number of awards: ${group.awards.length}`)
235+
console.log('='.repeat(60))
244236

245237
console.log('\nAwards breakdown:')
246238
for (const award of group.awards) {
247239
console.log(`- ${award.name}: ${award.type} | ${formatAmount(parseAmount(award.amount))} (${award.amount})`)
248240
}
249241

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+
}
251487

252-
if (shouldPay) {
253488
try {
254-
console.log(`Sending ${formatAmount(group.totalAmount)} to ${recipient}...`)
489+
console.log(`Sending ${formatAmount(group.totalAmount)} to ${actualRecipient}...`)
255490

256491
// Get today's date (YYYY-MM-DD) for updating records
257492
const today = new Date()
258493
const formattedDate = today.toISOString().split('T')[0]
259494
let paymentSuccessful = false
260495

261496
// Check if recipient is a Lightning address or a BOLT11 invoice
262-
if (recipient.includes('@')) {
497+
if (actualRecipient.includes('@')) {
263498
// Handle Lightning address
264499
const comment = 'see https://github.com/stackernews/stacker.news/blob/master/awards.csv'
265500
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)
267502
console.log('Invoice received, making payment...')
268503

269504
// Use @getalby/sdk to pay the invoice
@@ -278,7 +513,7 @@ async function main () {
278513
}
279514
} else {
280515
// Not a Lightning address, prompt for BOLT11 invoice
281-
console.log(`For recipient: ${recipient}`)
516+
console.log(`For recipient: ${actualRecipient}`)
282517
const invoice = await promptInput(`Enter BOLT11 invoice for ${formatAmount(group.totalAmount)}: `)
283518

284519
if (!invoice || invoice.trim() === '') {
@@ -303,13 +538,20 @@ async function main () {
303538
if (paymentSuccessful) {
304539
for (const award of group.awards) {
305540
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.')
306550
}
307551
}
308552
} catch (error) {
309553
console.error('Error making payment:', error)
310554
}
311-
} else {
312-
console.log('Payment skipped.')
313555
}
314556
}
315557

0 commit comments

Comments
 (0)