@@ -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