multi: add relevant queries for QueryPayments implemenation

This commit is contained in:
ziggie committed 2026-02-25 08:02:04 +01:00
1 parent e7a3096621
commit 18e7768837
4 files changed
+776

No files matched your search

+18
View File
@@ -1,14 +1,32 @@
package paymentsdb
import (
"context"
"fmt"
"github.com/lightningnetwork/lnd/sqldb"
"github.com/lightningnetwork/lnd/sqldb/sqlc"
)
// SQLQueries is a subset of the sqlc.Querier interface that can be used to
// execute queries against the SQL payments tables.
type SQLQueries interface {
/*
Payment DB read operations.
*/
FilterPayments(ctx context.Context, query sqlc.FilterPaymentsParams) ([]sqlc.FilterPaymentsRow, error)
FetchPayment(ctx context.Context, paymentIdentifier []byte) (sqlc.FetchPaymentRow, error)
FetchPaymentsByIDs(ctx context.Context, paymentIDs []int64) ([]sqlc.FetchPaymentsByIDsRow, error)
CountPayments(ctx context.Context) (int64, error)
FetchHtlcAttemptsForPayments(ctx context.Context, paymentIDs []int64) ([]sqlc.FetchHtlcAttemptsForPaymentsRow, error)
FetchAllInflightAttempts(ctx context.Context) ([]sqlc.PaymentHtlcAttempt, error)
FetchHopsForAttempts(ctx context.Context, htlcAttemptIndices []int64) ([]sqlc.FetchHopsForAttemptsRow, error)
FetchPaymentLevelFirstHopCustomRecords(ctx context.Context, paymentIDs []int64) ([]sqlc.PaymentFirstHopCustomRecord, error)
FetchRouteLevelFirstHopCustomRecords(ctx context.Context, htlcAttemptIndices []int64) ([]sqlc.PaymentAttemptFirstHopCustomRecord, error)
FetchHopLevelCustomRecords(ctx context.Context, hopIDs []int64) ([]sqlc.PaymentHopCustomRecord, error)
}
// BatchedSQLQueries is a version of the SQLQueries that's capable
+594
View File
@@ -0,0 +1,594 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.29.0
// source: payments.sql
package sqlc
import (
"context"
"database/sql"
"strings"
"time"
)
const countPayments = `-- name: CountPayments :one
SELECT COUNT(*) FROM payments
`
func (q *Queries) CountPayments(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countPayments)
var count int64
err := row.Scan(&count)
return count, err
}
const fetchAllInflightAttempts = `-- name: FetchAllInflightAttempts :many
SELECT
ha.id,
ha.attempt_index,
ha.payment_id,
ha.session_key,
ha.attempt_time,
ha.payment_hash,
ha.first_hop_amount_msat,
ha.route_total_time_lock,
ha.route_total_amount,
ha.route_source_key
FROM payment_htlc_attempts ha
WHERE NOT EXISTS (
SELECT 1 FROM payment_htlc_attempt_resolutions hr
WHERE hr.attempt_index = ha.attempt_index
)
ORDER BY ha.attempt_index ASC
`
// Fetch all inflight attempts across all payments
func (q *Queries) FetchAllInflightAttempts(ctx context.Context) ([]PaymentHtlcAttempt, error) {
rows, err := q.db.QueryContext(ctx, fetchAllInflightAttempts)
if err != nil {
return nil, err
}
defer rows.Close()
var items []PaymentHtlcAttempt
for rows.Next() {
var i PaymentHtlcAttempt
if err := rows.Scan(
&i.ID,
&i.AttemptIndex,
&i.PaymentID,
&i.SessionKey,
&i.AttemptTime,
&i.PaymentHash,
&i.FirstHopAmountMsat,
&i.RouteTotalTimeLock,
&i.RouteTotalAmount,
&i.RouteSourceKey,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const fetchHopLevelCustomRecords = `-- name: FetchHopLevelCustomRecords :many
SELECT
l.id,
l.hop_id,
l.key,
l.value
FROM payment_hop_custom_records l
WHERE l.hop_id IN (/*SLICE:hop_ids*/?)
ORDER BY l.hop_id ASC, l.key ASC
`
func (q *Queries) FetchHopLevelCustomRecords(ctx context.Context, hopIds []int64) ([]PaymentHopCustomRecord, error) {
query := fetchHopLevelCustomRecords
var queryParams []interface{}
if len(hopIds) > 0 {
for _, v := range hopIds {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:hop_ids*/?", makeQueryParams(len(queryParams), len(hopIds)), 1)
} else {
query = strings.Replace(query, "/*SLICE:hop_ids*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []PaymentHopCustomRecord
for rows.Next() {
var i PaymentHopCustomRecord
if err := rows.Scan(
&i.ID,
&i.HopID,
&i.Key,
&i.Value,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const fetchHopsForAttempts = `-- name: FetchHopsForAttempts :many
SELECT
h.id,
h.htlc_attempt_index,
h.hop_index,
h.pub_key,
h.scid,
h.outgoing_time_lock,
h.amt_to_forward,
h.meta_data,
m.payment_addr AS mpp_payment_addr,
m.total_msat AS mpp_total_msat,
a.root_share AS amp_root_share,
a.set_id AS amp_set_id,
a.child_index AS amp_child_index,
b.encrypted_data,
b.blinding_point,
b.blinded_path_total_amt
FROM payment_route_hops h
LEFT JOIN payment_route_hop_mpp m ON m.hop_id = h.id
LEFT JOIN payment_route_hop_amp a ON a.hop_id = h.id
LEFT JOIN payment_route_hop_blinded b ON b.hop_id = h.id
WHERE h.htlc_attempt_index IN (/*SLICE:htlc_attempt_indices*/?)
ORDER BY h.htlc_attempt_index ASC, h.hop_index ASC
`
type FetchHopsForAttemptsRow struct {
ID int64
HtlcAttemptIndex int64
HopIndex int32
PubKey []byte
Scid string
OutgoingTimeLock int32
AmtToForward int64
MetaData []byte
MppPaymentAddr []byte
MppTotalMsat sql.NullInt64
AmpRootShare []byte
AmpSetID []byte
AmpChildIndex sql.NullInt32
EncryptedData []byte
BlindingPoint []byte
BlindedPathTotalAmt sql.NullInt64
}
func (q *Queries) FetchHopsForAttempts(ctx context.Context, htlcAttemptIndices []int64) ([]FetchHopsForAttemptsRow, error) {
query := fetchHopsForAttempts
var queryParams []interface{}
if len(htlcAttemptIndices) > 0 {
for _, v := range htlcAttemptIndices {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", makeQueryParams(len(queryParams), len(htlcAttemptIndices)), 1)
} else {
query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []FetchHopsForAttemptsRow
for rows.Next() {
var i FetchHopsForAttemptsRow
if err := rows.Scan(
&i.ID,
&i.HtlcAttemptIndex,
&i.HopIndex,
&i.PubKey,
&i.Scid,
&i.OutgoingTimeLock,
&i.AmtToForward,
&i.MetaData,
&i.MppPaymentAddr,
&i.MppTotalMsat,
&i.AmpRootShare,
&i.AmpSetID,
&i.AmpChildIndex,
&i.EncryptedData,
&i.BlindingPoint,
&i.BlindedPathTotalAmt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const fetchHtlcAttemptsForPayments = `-- name: FetchHtlcAttemptsForPayments :many
SELECT
ha.id,
ha.attempt_index,
ha.payment_id,
ha.session_key,
ha.attempt_time,
ha.payment_hash,
ha.first_hop_amount_msat,
ha.route_total_time_lock,
ha.route_total_amount,
ha.route_source_key,
hr.resolution_type,
hr.resolution_time,
hr.failure_source_index,
hr.htlc_fail_reason,
hr.failure_msg,
hr.settle_preimage
FROM payment_htlc_attempts ha
LEFT JOIN payment_htlc_attempt_resolutions hr ON hr.attempt_index = ha.attempt_index
WHERE ha.payment_id IN (/*SLICE:payment_ids*/?)
ORDER BY ha.payment_id ASC, ha.attempt_time ASC
`
type FetchHtlcAttemptsForPaymentsRow struct {
ID int64
AttemptIndex int64
PaymentID int64
SessionKey []byte
AttemptTime time.Time
PaymentHash []byte
FirstHopAmountMsat int64
RouteTotalTimeLock int32
RouteTotalAmount int64
RouteSourceKey []byte
ResolutionType sql.NullInt32
ResolutionTime sql.NullTime
FailureSourceIndex sql.NullInt32
HtlcFailReason sql.NullInt32
FailureMsg []byte
SettlePreimage []byte
}
func (q *Queries) FetchHtlcAttemptsForPayments(ctx context.Context, paymentIds []int64) ([]FetchHtlcAttemptsForPaymentsRow, error) {
query := fetchHtlcAttemptsForPayments
var queryParams []interface{}
if len(paymentIds) > 0 {
for _, v := range paymentIds {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:payment_ids*/?", makeQueryParams(len(queryParams), len(paymentIds)), 1)
} else {
query = strings.Replace(query, "/*SLICE:payment_ids*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []FetchHtlcAttemptsForPaymentsRow
for rows.Next() {
var i FetchHtlcAttemptsForPaymentsRow
if err := rows.Scan(
&i.ID,
&i.AttemptIndex,
&i.PaymentID,
&i.SessionKey,
&i.AttemptTime,
&i.PaymentHash,
&i.FirstHopAmountMsat,
&i.RouteTotalTimeLock,
&i.RouteTotalAmount,
&i.RouteSourceKey,
&i.ResolutionType,
&i.ResolutionTime,
&i.FailureSourceIndex,
&i.HtlcFailReason,
&i.FailureMsg,
&i.SettlePreimage,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const fetchPayment = `-- name: FetchPayment :one
SELECT
p.id, p.intent_id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason,
i.intent_type AS "intent_type",
i.intent_payload AS "intent_payload"
FROM payments p
LEFT JOIN payment_intents i ON i.id = p.intent_id
WHERE p.payment_identifier = $1
`
type FetchPaymentRow struct {
Payment Payment
IntentType sql.NullInt16
IntentPayload []byte
}
func (q *Queries) FetchPayment(ctx context.Context, paymentIdentifier []byte) (FetchPaymentRow, error) {
row := q.db.QueryRowContext(ctx, fetchPayment, paymentIdentifier)
var i FetchPaymentRow
err := row.Scan(
&i.Payment.ID,
&i.Payment.IntentID,
&i.Payment.AmountMsat,
&i.Payment.CreatedAt,
&i.Payment.PaymentIdentifier,
&i.Payment.FailReason,
&i.IntentType,
&i.IntentPayload,
)
return i, err
}
const fetchPaymentLevelFirstHopCustomRecords = `-- name: FetchPaymentLevelFirstHopCustomRecords :many
SELECT
l.id,
l.payment_id,
l.key,
l.value
FROM payment_first_hop_custom_records l
WHERE l.payment_id IN (/*SLICE:payment_ids*/?)
ORDER BY l.payment_id ASC, l.key ASC
`
func (q *Queries) FetchPaymentLevelFirstHopCustomRecords(ctx context.Context, paymentIds []int64) ([]PaymentFirstHopCustomRecord, error) {
query := fetchPaymentLevelFirstHopCustomRecords
var queryParams []interface{}
if len(paymentIds) > 0 {
for _, v := range paymentIds {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:payment_ids*/?", makeQueryParams(len(queryParams), len(paymentIds)), 1)
} else {
query = strings.Replace(query, "/*SLICE:payment_ids*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []PaymentFirstHopCustomRecord
for rows.Next() {
var i PaymentFirstHopCustomRecord
if err := rows.Scan(
&i.ID,
&i.PaymentID,
&i.Key,
&i.Value,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const fetchPaymentsByIDs = `-- name: FetchPaymentsByIDs :many
SELECT
p.id, p.intent_id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason,
i.intent_type AS "intent_type",
i.intent_payload AS "intent_payload"
FROM payments p
LEFT JOIN payment_intents i ON i.id = p.intent_id
WHERE p.id IN (/*SLICE:payment_ids*/?)
`
type FetchPaymentsByIDsRow struct {
Payment Payment
IntentType sql.NullInt16
IntentPayload []byte
}
func (q *Queries) FetchPaymentsByIDs(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsRow, error) {
query := fetchPaymentsByIDs
var queryParams []interface{}
if len(paymentIds) > 0 {
for _, v := range paymentIds {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:payment_ids*/?", makeQueryParams(len(queryParams), len(paymentIds)), 1)
} else {
query = strings.Replace(query, "/*SLICE:payment_ids*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []FetchPaymentsByIDsRow
for rows.Next() {
var i FetchPaymentsByIDsRow
if err := rows.Scan(
&i.Payment.ID,
&i.Payment.IntentID,
&i.Payment.AmountMsat,
&i.Payment.CreatedAt,
&i.Payment.PaymentIdentifier,
&i.Payment.FailReason,
&i.IntentType,
&i.IntentPayload,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const fetchRouteLevelFirstHopCustomRecords = `-- name: FetchRouteLevelFirstHopCustomRecords :many
SELECT
l.id,
l.htlc_attempt_index,
l.key,
l.value
FROM payment_attempt_first_hop_custom_records l
WHERE l.htlc_attempt_index IN (/*SLICE:htlc_attempt_indices*/?)
ORDER BY l.htlc_attempt_index ASC, l.key ASC
`
func (q *Queries) FetchRouteLevelFirstHopCustomRecords(ctx context.Context, htlcAttemptIndices []int64) ([]PaymentAttemptFirstHopCustomRecord, error) {
query := fetchRouteLevelFirstHopCustomRecords
var queryParams []interface{}
if len(htlcAttemptIndices) > 0 {
for _, v := range htlcAttemptIndices {
queryParams = append(queryParams, v)
}
query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", makeQueryParams(len(queryParams), len(htlcAttemptIndices)), 1)
} else {
query = strings.Replace(query, "/*SLICE:htlc_attempt_indices*/?", "NULL", 1)
}
rows, err := q.db.QueryContext(ctx, query, queryParams...)
if err != nil {
return nil, err
}
defer rows.Close()
var items []PaymentAttemptFirstHopCustomRecord
for rows.Next() {
var i PaymentAttemptFirstHopCustomRecord
if err := rows.Scan(
&i.ID,
&i.HtlcAttemptIndex,
&i.Key,
&i.Value,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const filterPayments = `-- name: FilterPayments :many
/* ─────────────────────────────────────────────
fetch queries
─────────────────────────────────────────────
*/
SELECT
p.id, p.intent_id, p.amount_msat, p.created_at, p.payment_identifier, p.fail_reason,
i.intent_type AS "intent_type",
i.intent_payload AS "intent_payload"
FROM payments p
LEFT JOIN payment_intents i ON i.id = p.intent_id
WHERE (
p.id > $1 OR
$1 IS NULL
) AND (
p.id < $2 OR
$2 IS NULL
) AND (
p.created_at >= $3 OR
$3 IS NULL
) AND (
p.created_at <= $4 OR
$4 IS NULL
) AND (
i.intent_type = $5 OR
$5 IS NULL OR i.intent_type IS NULL
)
ORDER BY
CASE WHEN $6 = false OR $6 IS NULL THEN p.id END ASC,
CASE WHEN $6 = true THEN p.id END DESC
LIMIT $7
`
type FilterPaymentsParams struct {
IndexOffsetGet sql.NullInt64
IndexOffsetLet sql.NullInt64
CreatedAfter sql.NullTime
CreatedBefore sql.NullTime
IntentType sql.NullInt16
Reverse interface{}
NumLimit int32
}
type FilterPaymentsRow struct {
Payment Payment
IntentType sql.NullInt16
IntentPayload []byte
}
func (q *Queries) FilterPayments(ctx context.Context, arg FilterPaymentsParams) ([]FilterPaymentsRow, error) {
rows, err := q.db.QueryContext(ctx, filterPayments,
arg.IndexOffsetGet,
arg.IndexOffsetLet,
arg.CreatedAfter,
arg.CreatedBefore,
arg.IntentType,
arg.Reverse,
arg.NumLimit,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []FilterPaymentsRow
for rows.Next() {
var i FilterPaymentsRow
if err := rows.Scan(
&i.Payment.ID,
&i.Payment.IntentID,
&i.Payment.AmountMsat,
&i.Payment.CreatedAt,
&i.Payment.PaymentIdentifier,
&i.Payment.FailReason,
&i.IntentType,
&i.IntentPayload,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
+11
View File
@@ -15,6 +15,7 @@ type Querier interface {
AddV1ChannelProof(ctx context.Context, arg AddV1ChannelProofParams) (sql.Result, error)
AddV2ChannelProof(ctx context.Context, arg AddV2ChannelProofParams) (sql.Result, error)
ClearKVInvoiceHashIndex(ctx context.Context) error
CountPayments(ctx context.Context) (int64, error)
CountZombieChannels(ctx context.Context, version int16) (int64, error)
CreateChannel(ctx context.Context, arg CreateChannelParams) (int64, error)
DeleteCanceledInvoices(ctx context.Context) (sql.Result, error)
@@ -31,10 +32,19 @@ type Querier interface {
DeleteZombieChannel(ctx context.Context, arg DeleteZombieChannelParams) (sql.Result, error)
FetchAMPSubInvoiceHTLCs(ctx context.Context, arg FetchAMPSubInvoiceHTLCsParams) ([]FetchAMPSubInvoiceHTLCsRow, error)
FetchAMPSubInvoices(ctx context.Context, arg FetchAMPSubInvoicesParams) ([]AmpSubInvoice, error)
// Fetch all inflight attempts across all payments
FetchAllInflightAttempts(ctx context.Context) ([]PaymentHtlcAttempt, error)
FetchHopLevelCustomRecords(ctx context.Context, hopIds []int64) ([]PaymentHopCustomRecord, error)
FetchHopsForAttempts(ctx context.Context, htlcAttemptIndices []int64) ([]FetchHopsForAttemptsRow, error)
FetchHtlcAttemptsForPayments(ctx context.Context, paymentIds []int64) ([]FetchHtlcAttemptsForPaymentsRow, error)
FetchPayment(ctx context.Context, paymentIdentifier []byte) (FetchPaymentRow, error)
FetchPaymentLevelFirstHopCustomRecords(ctx context.Context, paymentIds []int64) ([]PaymentFirstHopCustomRecord, error)
FetchPaymentsByIDs(ctx context.Context, paymentIds []int64) ([]FetchPaymentsByIDsRow, error)
// FetchPendingInvoices returns all invoices in a pending state (open or
// accepted). The invoices_state_idx index on the state column makes this a
// fast index scan rather than a full table scan.
FetchPendingInvoices(ctx context.Context, arg FetchPendingInvoicesParams) ([]Invoice, error)
FetchRouteLevelFirstHopCustomRecords(ctx context.Context, htlcAttemptIndices []int64) ([]PaymentAttemptFirstHopCustomRecord, error)
FetchSettledAMPSubInvoices(ctx context.Context, arg FetchSettledAMPSubInvoicesParams) ([]FetchSettledAMPSubInvoicesRow, error)
// FilterInvoicesByAddIndex returns invoices whose add_index (primary key id)
// is greater than or equal to the given value, ordered by id. Because id is
@@ -58,6 +68,7 @@ type Querier interface {
// It returns invoices in descending id order up to and including add_index_let.
// See FilterInvoicesForward for the expected Go-side defaults.
FilterInvoicesReverse(ctx context.Context, arg FilterInvoicesReverseParams) ([]Invoice, error)
FilterPayments(ctx context.Context, arg FilterPaymentsParams) ([]FilterPaymentsRow, error)
GetAMPInvoiceID(ctx context.Context, setID []byte) (int64, error)
GetChannelAndNodesBySCID(ctx context.Context, arg GetChannelAndNodesBySCIDParams) (GetChannelAndNodesBySCIDRow, error)
GetChannelByOutpointWithPolicies(ctx context.Context, arg GetChannelByOutpointWithPoliciesParams) (GetChannelByOutpointWithPoliciesRow, error)
+153
View File
@@ -0,0 +1,153 @@
/* ─────────────────────────────────────────────
fetch queries
─────────────────────────────────────────────
*/
-- name: FilterPayments :many
SELECT
sqlc.embed(p),
i.intent_type AS "intent_type",
i.intent_payload AS "intent_payload"
FROM payments p
LEFT JOIN payment_intents i ON i.id = p.intent_id
WHERE (
p.id > sqlc.narg('index_offset_get') OR
sqlc.narg('index_offset_get') IS NULL
) AND (
p.id < sqlc.narg('index_offset_let') OR
sqlc.narg('index_offset_let') IS NULL
) AND (
p.created_at >= sqlc.narg('created_after') OR
sqlc.narg('created_after') IS NULL
) AND (
p.created_at <= sqlc.narg('created_before') OR
sqlc.narg('created_before') IS NULL
) AND (
i.intent_type = sqlc.narg('intent_type') OR
sqlc.narg('intent_type') IS NULL OR i.intent_type IS NULL
)
ORDER BY
CASE WHEN sqlc.narg('reverse') = false OR sqlc.narg('reverse') IS NULL THEN p.id END ASC,
CASE WHEN sqlc.narg('reverse') = true THEN p.id END DESC
LIMIT @num_limit;
-- name: FetchPayment :one
SELECT
sqlc.embed(p),
i.intent_type AS "intent_type",
i.intent_payload AS "intent_payload"
FROM payments p
LEFT JOIN payment_intents i ON i.id = p.intent_id
WHERE p.payment_identifier = $1;
-- name: FetchPaymentsByIDs :many
SELECT
sqlc.embed(p),
i.intent_type AS "intent_type",
i.intent_payload AS "intent_payload"
FROM payments p
LEFT JOIN payment_intents i ON i.id = p.intent_id
WHERE p.id IN (sqlc.slice('payment_ids')/*SLICE:payment_ids*/);
-- name: CountPayments :one
SELECT COUNT(*) FROM payments;
-- name: FetchHtlcAttemptsForPayments :many
SELECT
ha.id,
ha.attempt_index,
ha.payment_id,
ha.session_key,
ha.attempt_time,
ha.payment_hash,
ha.first_hop_amount_msat,
ha.route_total_time_lock,
ha.route_total_amount,
ha.route_source_key,
hr.resolution_type,
hr.resolution_time,
hr.failure_source_index,
hr.htlc_fail_reason,
hr.failure_msg,
hr.settle_preimage
FROM payment_htlc_attempts ha
LEFT JOIN payment_htlc_attempt_resolutions hr ON hr.attempt_index = ha.attempt_index
WHERE ha.payment_id IN (sqlc.slice('payment_ids')/*SLICE:payment_ids*/)
ORDER BY ha.payment_id ASC, ha.attempt_time ASC;
-- name: FetchAllInflightAttempts :many
-- Fetch all inflight attempts across all payments
SELECT
ha.id,
ha.attempt_index,
ha.payment_id,
ha.session_key,
ha.attempt_time,
ha.payment_hash,
ha.first_hop_amount_msat,
ha.route_total_time_lock,
ha.route_total_amount,
ha.route_source_key
FROM payment_htlc_attempts ha
WHERE NOT EXISTS (
SELECT 1 FROM payment_htlc_attempt_resolutions hr
WHERE hr.attempt_index = ha.attempt_index
)
ORDER BY ha.attempt_index ASC;
-- name: FetchHopsForAttempts :many
SELECT
h.id,
h.htlc_attempt_index,
h.hop_index,
h.pub_key,
h.scid,
h.outgoing_time_lock,
h.amt_to_forward,
h.meta_data,
m.payment_addr AS mpp_payment_addr,
m.total_msat AS mpp_total_msat,
a.root_share AS amp_root_share,
a.set_id AS amp_set_id,
a.child_index AS amp_child_index,
b.encrypted_data,
b.blinding_point,
b.blinded_path_total_amt
FROM payment_route_hops h
LEFT JOIN payment_route_hop_mpp m ON m.hop_id = h.id
LEFT JOIN payment_route_hop_amp a ON a.hop_id = h.id
LEFT JOIN payment_route_hop_blinded b ON b.hop_id = h.id
WHERE h.htlc_attempt_index IN (sqlc.slice('htlc_attempt_indices')/*SLICE:htlc_attempt_indices*/)
ORDER BY h.htlc_attempt_index ASC, h.hop_index ASC;
-- name: FetchPaymentLevelFirstHopCustomRecords :many
SELECT
l.id,
l.payment_id,
l.key,
l.value
FROM payment_first_hop_custom_records l
WHERE l.payment_id IN (sqlc.slice('payment_ids')/*SLICE:payment_ids*/)
ORDER BY l.payment_id ASC, l.key ASC;
-- name: FetchRouteLevelFirstHopCustomRecords :many
SELECT
l.id,
l.htlc_attempt_index,
l.key,
l.value
FROM payment_attempt_first_hop_custom_records l
WHERE l.htlc_attempt_index IN (sqlc.slice('htlc_attempt_indices')/*SLICE:htlc_attempt_indices*/)
ORDER BY l.htlc_attempt_index ASC, l.key ASC;
-- name: FetchHopLevelCustomRecords :many
SELECT
l.id,
l.hop_id,
l.key,
l.value
FROM payment_hop_custom_records l
WHERE l.hop_id IN (sqlc.slice('hop_ids')/*SLICE:hop_ids*/)
ORDER BY l.hop_id ASC, l.key ASC;