Skip to content

Commit 2813f97

Browse files
committed
paymentsdb: implement InitPayment for sql backend
1 parent 8802e4d commit 2813f97

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

payments/db/sql_store.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,3 +627,106 @@ func (s *SQLStore) DeleteFailedAttempts(paymentHash lntypes.Hash) error {
627627

628628
return nil
629629
}
630+
631+
// InitPayment initializes a payment.
632+
//
633+
// This is part of the DB interface.
634+
func (s *SQLStore) InitPayment(paymentHash lntypes.Hash,
635+
paymentCreationInfo *PaymentCreationInfo) error {
636+
637+
ctx := context.TODO()
638+
639+
// Create the payment in the database.
640+
err := s.db.ExecTx(ctx, sqldb.WriteTxOpt(), func(db SQLQueries) error {
641+
existingPayment, err := s.db.FetchPayment(ctx, paymentHash[:])
642+
if err == nil {
643+
completePayment, err := s.fetchPaymentWithCompleteData(
644+
ctx, s.db, existingPayment,
645+
)
646+
if err != nil {
647+
return fmt.Errorf("failed to fetch payment "+
648+
"with complete data: %w", err)
649+
}
650+
651+
// Check if the payment is initializable otherwise
652+
// we'll return early.
653+
err = completePayment.Status.initializable()
654+
if err != nil {
655+
return err
656+
}
657+
} else if !errors.Is(err, sql.ErrNoRows) {
658+
// Some other error occurred
659+
return fmt.Errorf("failed to check existing "+
660+
"payment: %w", err)
661+
}
662+
663+
// If payment exists and is failed, delete it first.
664+
if existingPayment.Payment.ID != 0 {
665+
err := db.DeletePayment(ctx, existingPayment.Payment.ID)
666+
if err != nil {
667+
return fmt.Errorf("failed to delete "+
668+
"payment: %w", err)
669+
}
670+
}
671+
672+
var intentID *int64
673+
if len(paymentCreationInfo.PaymentRequest) > 0 {
674+
//nolint:ll
675+
intentIDValue, err := db.InsertPaymentIntent(ctx,
676+
sqlc.InsertPaymentIntentParams{
677+
IntentType: int16(PaymentIntentTypeBolt11),
678+
IntentPayload: paymentCreationInfo.PaymentRequest,
679+
})
680+
if err != nil {
681+
return fmt.Errorf("failed to initialize "+
682+
"payment intent: %w", err)
683+
}
684+
intentID = &intentIDValue
685+
}
686+
687+
// Only set the intent ID if it's not nil.
688+
var intentIDParam sql.NullInt64
689+
if intentID != nil {
690+
intentIDParam = sqldb.SQLInt64(*intentID)
691+
}
692+
693+
err = db.InsertPayment(ctx, sqlc.InsertPaymentParams{
694+
IntentID: intentIDParam,
695+
AmountMsat: int64(paymentCreationInfo.Value),
696+
CreatedAt: paymentCreationInfo.CreationTime.UTC(),
697+
PaymentIdentifier: paymentHash[:],
698+
})
699+
if err != nil {
700+
return fmt.Errorf("failed to insert payment: %w", err)
701+
}
702+
703+
// Get the payment ID from the inserted payment
704+
// We need to fetch the payment we just inserted to get its ID
705+
insertedPayment, err := db.FetchPayment(ctx, paymentHash[:])
706+
if err != nil {
707+
return fmt.Errorf("failed to fetch inserted payment: %w", err)
708+
}
709+
710+
for key, value := range paymentCreationInfo.FirstHopCustomRecords {
711+
err = db.InsertPaymentFirstHopCustomRecord(ctx,
712+
sqlc.InsertPaymentFirstHopCustomRecordParams{
713+
PaymentID: insertedPayment.Payment.ID,
714+
Key: int64(key),
715+
Value: value,
716+
})
717+
if err != nil {
718+
return fmt.Errorf("failed to insert "+
719+
"payment first hop custom "+
720+
"record: %w", err)
721+
}
722+
}
723+
724+
return nil
725+
}, func() {
726+
})
727+
if err != nil {
728+
return fmt.Errorf("failed to initialize payment: %w", err)
729+
}
730+
731+
return nil
732+
}

0 commit comments

Comments
 (0)