mirror of
https://github.com/getAlby/hub.git
synced 2026-08-13 12:33:39 +02:00
feat: add notifications for CLN backend (#2287)
* fix: protoc command for cln bindings documentation * feat: update cln proto bindings to v26.04 * feat: add notifications for CLN backend starting with nwc_lnclient_payment_sent, nwc_lnclient_payment_failed, nwc_lnclient_payment_received, nwc_payment_forwarded, nwc_channel_ready, nwc_channel_closed
This commit is contained in:
parent
099ad146df
commit
12c454f3ae
5 changed files with 9632 additions and 3028 deletions
|
|
@ -57,6 +57,8 @@ protoc \
|
|||
--go_opt=Mnode.proto=github.com/getAlby/hub/lnclient/cln/clngrpc \
|
||||
--go-grpc_out=./lnclient/cln/clngrpc \
|
||||
--go-grpc_opt=paths=source_relative \
|
||||
--go-grpc_opt=Mprimitives.proto=github.com/getAlby/hub/lnclient/cln/clngrpc \
|
||||
--go-grpc_opt=Mnode.proto=github.com/getAlby/hub/lnclient/cln/clngrpc \
|
||||
../lightning/cln-grpc/proto/node.proto \
|
||||
../lightning/cln-grpc/proto/primitives.proto
|
||||
```
|
||||
|
|
@ -71,5 +73,6 @@ protoc \
|
|||
--go_opt=Mhold.proto=github.com/getAlby/hub/lnclient/cln/clngrpc_hold \
|
||||
--go-grpc_out=./lnclient/cln/clngrpc_hold \
|
||||
--go-grpc_opt=paths=source_relative \
|
||||
--go-grpc_opt=Mhold.proto=github.com/getAlby/hub/lnclient/cln/clngrpc_hold \
|
||||
../hold/protos/hold.proto
|
||||
```
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/getAlby/hub/config"
|
||||
"github.com/getAlby/hub/events"
|
||||
"github.com/getAlby/hub/lnclient"
|
||||
clngrpc "github.com/getAlby/hub/lnclient/cln/clngrpc"
|
||||
|
|
@ -33,15 +35,16 @@ import (
|
|||
)
|
||||
|
||||
type CLNService struct {
|
||||
ctx context.Context
|
||||
client clngrpc.NodeClient
|
||||
clientHold clngrpcHold.HoldClient
|
||||
holdEnabled bool
|
||||
conn *grpc.ClientConn
|
||||
connHold *grpc.ClientConn
|
||||
eventPublisher events.EventPublisher
|
||||
pubkey string
|
||||
cancel context.CancelFunc
|
||||
ctx context.Context
|
||||
client clngrpc.NodeClient
|
||||
clientHold clngrpcHold.HoldClient
|
||||
holdEnabled bool
|
||||
conn *grpc.ClientConn
|
||||
connHold *grpc.ClientConn
|
||||
eventPublisher events.EventPublisher
|
||||
pubkey string
|
||||
enableNotifications bool
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
func NewCLNService(ctx context.Context, eventPublisher events.EventPublisher, address, lightningDir, addressHold string) (lnclient lnclient.LNClient, err error) {
|
||||
|
|
@ -146,6 +149,25 @@ func NewCLNService(ctx context.Context, eventPublisher events.EventPublisher, ad
|
|||
|
||||
svc.pubkey = resp.Pubkey
|
||||
|
||||
getinfo, err := svc.client.Getinfo(ctx, &clngrpc.GetinfoRequest{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getinfo failed: %w", err)
|
||||
}
|
||||
|
||||
svc.enableNotifications, err = atOrAboveVersion(getinfo.Version, "26.04")
|
||||
if err != nil {
|
||||
logger.Logger.Errorf("Failed to check CLN version %s: %v", getinfo.Version, err)
|
||||
}
|
||||
|
||||
if svc.enableNotifications {
|
||||
logger.Logger.Info("Enabling notifications")
|
||||
go svc.subscribeSuccessfulPayments(ctx)
|
||||
go svc.subscribeFailedPayments(ctx)
|
||||
go svc.subscribeInvoices(ctx)
|
||||
go svc.trackForwardedPayments(ctx)
|
||||
go svc.subscribeChannelEvents(ctx)
|
||||
}
|
||||
|
||||
logger.Logger.Info("Successfully connected to CLN via gRPC")
|
||||
return svc, nil
|
||||
}
|
||||
|
|
@ -180,6 +202,445 @@ func loadTLSCredentials(lightningDir string, serverName string) (*tls.Config, er
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (svc *CLNService) subscribeSuccessfulPayments(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
paymentStream, err := svc.client.SubscribeSendPaySuccess(ctx, &clngrpc.StreamSendPaySuccessRequest{})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Error subscribing to successful payments")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Second):
|
||||
continue
|
||||
}
|
||||
}
|
||||
paymentsLoop:
|
||||
for {
|
||||
payment, err := paymentStream.Recv()
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to receive sendpay_success notification")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(2 * time.Second):
|
||||
break paymentsLoop
|
||||
}
|
||||
}
|
||||
|
||||
transaction, err := svc.clnSendpaySuccessToTransaction(ctx, payment)
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to convert notification to transaction")
|
||||
continue
|
||||
}
|
||||
svc.eventPublisher.Publish(&events.Event{
|
||||
Event: "nwc_lnclient_payment_sent",
|
||||
Properties: transaction,
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *CLNService) clnSendpaySuccessToTransaction(ctx context.Context, payment *clngrpc.SendPaySuccessNotification) (*lnclient.Transaction, error) {
|
||||
var invstring string
|
||||
if payment.Bolt11 != nil {
|
||||
invstring = *payment.Bolt11
|
||||
} else if payment.Bolt12 != nil {
|
||||
invstring = *payment.Bolt12
|
||||
}
|
||||
|
||||
var amountMsat int64
|
||||
if payment.AmountMsat != nil {
|
||||
amountMsat = int64(payment.AmountMsat.Msat)
|
||||
}
|
||||
|
||||
var feesPaidMsat int64
|
||||
if payment.AmountSentMsat != nil {
|
||||
feesPaidMsat = int64(payment.AmountSentMsat.Msat) - amountMsat
|
||||
}
|
||||
|
||||
var settledAt *int64
|
||||
if payment.CompletedAt != nil {
|
||||
SettledAtUint64 := int64(*payment.CompletedAt)
|
||||
settledAt = &SettledAtUint64
|
||||
}
|
||||
|
||||
var descriptionHash string
|
||||
var expiresAt *int64
|
||||
|
||||
if invstring != "" {
|
||||
decodedInvoice, err := svc.client.Decode(ctx, &clngrpc.DecodeRequest{String_: invstring})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode failed: %w", err)
|
||||
}
|
||||
|
||||
switch decodedInvoice.ItemType {
|
||||
case clngrpc.DecodeResponse_BOLT12_INVOICE:
|
||||
if decodedInvoice.OfferAbsoluteExpiry != nil {
|
||||
expiresAtint64 := int64(*decodedInvoice.OfferAbsoluteExpiry)
|
||||
expiresAt = &expiresAtint64
|
||||
}
|
||||
case clngrpc.DecodeResponse_BOLT11_INVOICE:
|
||||
if decodedInvoice.CreatedAt != nil && decodedInvoice.Expiry != nil {
|
||||
expiresAtint64 := int64(*decodedInvoice.CreatedAt) + int64(*decodedInvoice.Expiry)
|
||||
expiresAt = &expiresAtint64
|
||||
}
|
||||
if decodedInvoice.DescriptionHash != nil {
|
||||
descriptionHash = hex.EncodeToString(decodedInvoice.DescriptionHash)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invstring `%s` is not a bolt11 or bolt12 invoice", invstring)
|
||||
}
|
||||
}
|
||||
|
||||
return &lnclient.Transaction{
|
||||
Type: "outgoing",
|
||||
Invoice: invstring,
|
||||
Description: payment.GetDescription(),
|
||||
DescriptionHash: descriptionHash,
|
||||
Preimage: hex.EncodeToString(payment.GetPaymentPreimage()),
|
||||
PaymentHash: hex.EncodeToString(payment.GetPaymentHash()),
|
||||
AmountMsat: amountMsat,
|
||||
FeesPaidMsat: feesPaidMsat,
|
||||
CreatedAt: int64(payment.CreatedAt),
|
||||
ExpiresAt: expiresAt,
|
||||
SettledAt: settledAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *CLNService) subscribeFailedPayments(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
paymentStream, err := svc.client.SubscribeSendPayFailure(ctx, &clngrpc.StreamSendPayFailureRequest{})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Error subscribing to failed payments")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Second):
|
||||
continue
|
||||
}
|
||||
}
|
||||
paymentsLoop:
|
||||
for {
|
||||
payment, err := paymentStream.Recv()
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to receive sendpay_failure notification")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(2 * time.Second):
|
||||
break paymentsLoop
|
||||
}
|
||||
}
|
||||
|
||||
transaction, err := svc.clnSendpayFailureToTransaction(ctx, payment)
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to convert notification to transaction")
|
||||
continue
|
||||
}
|
||||
svc.eventPublisher.Publish(&events.Event{
|
||||
Event: "nwc_lnclient_payment_failed",
|
||||
Properties: transaction,
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *CLNService) clnSendpayFailureToTransaction(ctx context.Context, payment *clngrpc.SendPayFailureNotification) (*lnclient.Transaction, error) {
|
||||
if payment.Data == nil {
|
||||
return nil, fmt.Errorf("sendpay_failure data is nil")
|
||||
}
|
||||
var invstring string
|
||||
if payment.Data.Bolt11 != nil {
|
||||
invstring = *payment.Data.Bolt11
|
||||
} else if payment.Data.Bolt12 != nil {
|
||||
invstring = *payment.Data.Bolt12
|
||||
}
|
||||
|
||||
var amountMsat int64
|
||||
if payment.Data.AmountMsat != nil {
|
||||
amountMsat = int64(payment.Data.AmountMsat.Msat)
|
||||
}
|
||||
|
||||
var feesPaidMsat int64
|
||||
if payment.Data.AmountSentMsat != nil {
|
||||
feesPaidMsat = int64(payment.Data.AmountSentMsat.Msat) - amountMsat
|
||||
}
|
||||
|
||||
var settledAt int64
|
||||
if payment.Data.CompletedAt != nil {
|
||||
SettledAtUint64 := *payment.Data.CompletedAt
|
||||
settledAt = int64(SettledAtUint64)
|
||||
}
|
||||
|
||||
var descriptionHash string
|
||||
var expiresAt int64
|
||||
|
||||
if invstring != "" {
|
||||
decodedInvoice, err := svc.client.Decode(ctx, &clngrpc.DecodeRequest{String_: invstring})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode failed: %w", err)
|
||||
}
|
||||
|
||||
switch decodedInvoice.ItemType {
|
||||
case clngrpc.DecodeResponse_BOLT12_INVOICE:
|
||||
if decodedInvoice.OfferAbsoluteExpiry != nil {
|
||||
expiresAt = int64(*decodedInvoice.OfferAbsoluteExpiry)
|
||||
}
|
||||
case clngrpc.DecodeResponse_BOLT11_INVOICE:
|
||||
if decodedInvoice.CreatedAt != nil && decodedInvoice.Expiry != nil {
|
||||
expiresAt = int64(*decodedInvoice.CreatedAt) + int64(*decodedInvoice.Expiry)
|
||||
}
|
||||
if decodedInvoice.DescriptionHash != nil {
|
||||
descriptionHash = hex.EncodeToString(decodedInvoice.DescriptionHash)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("invstring `%s` is not a bolt11 or bolt12 invoice", invstring)
|
||||
}
|
||||
}
|
||||
|
||||
return &lnclient.Transaction{
|
||||
Type: "outgoing",
|
||||
Invoice: invstring,
|
||||
Description: payment.Data.GetDescription(),
|
||||
DescriptionHash: descriptionHash,
|
||||
Preimage: hex.EncodeToString(payment.Data.GetPaymentPreimage()),
|
||||
PaymentHash: hex.EncodeToString(payment.Data.GetPaymentHash()),
|
||||
AmountMsat: amountMsat,
|
||||
FeesPaidMsat: feesPaidMsat,
|
||||
CreatedAt: int64(payment.Data.GetCreatedAt()),
|
||||
ExpiresAt: &expiresAt,
|
||||
SettledAt: &settledAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *CLNService) subscribeInvoices(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
invoiceStream, err := svc.client.SubscribeInvoicePayment(ctx, &clngrpc.StreamInvoicePaymentRequest{})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Error subscribing to invoices")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Second):
|
||||
continue
|
||||
}
|
||||
}
|
||||
invoicesLoop:
|
||||
for {
|
||||
invoice_notif, err := invoiceStream.Recv()
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to receive invoice")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(2 * time.Second):
|
||||
break invoicesLoop
|
||||
}
|
||||
}
|
||||
|
||||
listinvoice, err := svc.client.ListInvoices(ctx, &clngrpc.ListinvoicesRequest{
|
||||
Label: &invoice_notif.Label,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Logger.WithFields(logrus.Fields{
|
||||
"label": invoice_notif.Label,
|
||||
}).WithError(err).Error("Failed to list invoice")
|
||||
continue
|
||||
}
|
||||
if len(listinvoice.Invoices) != 1 {
|
||||
logger.Logger.WithFields(logrus.Fields{
|
||||
"label": invoice_notif.Label,
|
||||
"count": len(listinvoice.Invoices),
|
||||
}).Error("Failed to list invoice")
|
||||
continue
|
||||
}
|
||||
|
||||
invoice := listinvoice.Invoices[0]
|
||||
|
||||
transaction, err := svc.clnInvoiceToTransaction(ctx, invoice)
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to convert invoice to transaction")
|
||||
continue
|
||||
}
|
||||
|
||||
svc.eventPublisher.Publish(&events.Event{
|
||||
Event: "nwc_lnclient_payment_received",
|
||||
Properties: transaction,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *CLNService) trackForwardedPayments(ctx context.Context) {
|
||||
// NOTE: this only tracks payments when hub is online and attached
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
forwardsStream, err := svc.client.SubscribeForwardEvent(ctx, &clngrpc.StreamForwardEventRequest{})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("failed to read forwarding history")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Second):
|
||||
continue
|
||||
}
|
||||
}
|
||||
forwardsLoop:
|
||||
for {
|
||||
forwardNotif, err := forwardsStream.Recv()
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to receive invoice")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(2 * time.Second):
|
||||
break forwardsLoop
|
||||
}
|
||||
}
|
||||
|
||||
if forwardNotif.Status != clngrpc.ForwardEventNotification_SETTLED {
|
||||
continue
|
||||
}
|
||||
|
||||
if forwardNotif.FeeMsat == nil || forwardNotif.OutMsat == nil {
|
||||
logger.Logger.WithFields(logrus.Fields{
|
||||
"earned_msat": forwardNotif.FeeMsat,
|
||||
"outbound_amount_forwarded_msat": forwardNotif.OutMsat,
|
||||
}).Error("forwarded payment has missing required fields")
|
||||
continue
|
||||
}
|
||||
|
||||
svc.eventPublisher.Publish(&events.Event{
|
||||
Event: "nwc_payment_forwarded",
|
||||
Properties: &lnclient.PaymentForwardedEventProperties{
|
||||
TotalFeeEarnedMsat: forwardNotif.FeeMsat.Msat,
|
||||
OutboundAmountForwardedMsat: forwardNotif.OutMsat.Msat,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (svc *CLNService) subscribeChannelEvents(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
channelEvents, err := svc.client.SubscribeChannelStateChanged(ctx, &clngrpc.StreamChannelStateChangedRequest{})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Error subscribing to channel events")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(10 * time.Second):
|
||||
continue
|
||||
}
|
||||
}
|
||||
channelEventsLoop:
|
||||
for {
|
||||
event, err := channelEvents.Recv()
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to receive channel event")
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-time.After(2 * time.Second):
|
||||
break channelEventsLoop
|
||||
}
|
||||
}
|
||||
|
||||
if event.NewState != clngrpc.ChannelState_ChanneldNormal && event.NewState != clngrpc.ChannelState_Onchain {
|
||||
continue
|
||||
}
|
||||
|
||||
if event.ShortChannelId == nil {
|
||||
logger.Logger.Warn("Received CHANNELD_NORMAL channel event with no short channel id")
|
||||
continue
|
||||
}
|
||||
|
||||
channels, err := svc.client.ListPeerChannels(ctx, &clngrpc.ListpeerchannelsRequest{ShortChannelId: event.ShortChannelId})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("Failed to ListPeerChannels")
|
||||
continue
|
||||
}
|
||||
if len(channels.Channels) != 1 {
|
||||
logger.Logger.WithFields(logrus.Fields{
|
||||
"short_channel_id": event.ShortChannelId,
|
||||
"count": len(channels.Channels),
|
||||
}).Error("Expected one channel in ListPeerChannels response")
|
||||
continue
|
||||
}
|
||||
channel := channels.Channels[0]
|
||||
peerId := hex.EncodeToString(event.PeerId)
|
||||
var capacity uint64
|
||||
if channel.TotalMsat != nil {
|
||||
capacity = channel.TotalMsat.Msat / 1000
|
||||
}
|
||||
isOutbound := channel.Opener == clngrpc.ChannelSide_LOCAL
|
||||
public := !channel.GetPrivate()
|
||||
|
||||
switch event.NewState {
|
||||
case clngrpc.ChannelState_ChanneldNormal:
|
||||
logger.Logger.WithFields(logrus.Fields{
|
||||
"counterparty_node_id": peerId,
|
||||
"public": public,
|
||||
"capacity": capacity,
|
||||
"is_outbound": isOutbound,
|
||||
}).Info("Channel opened")
|
||||
|
||||
svc.eventPublisher.Publish(&events.Event{
|
||||
Event: "nwc_channel_ready",
|
||||
Properties: map[string]interface{}{
|
||||
"counterparty_node_id": peerId,
|
||||
"node_type": config.CLNBackendType,
|
||||
"public": public,
|
||||
"capacity": capacity,
|
||||
"is_outbound": isOutbound,
|
||||
},
|
||||
})
|
||||
case clngrpc.ChannelState_Onchain:
|
||||
logger.Logger.WithFields(logrus.Fields{
|
||||
"counterparty_node_id": peerId,
|
||||
"reason": channel.Status,
|
||||
}).Info("Channel closed")
|
||||
|
||||
svc.eventPublisher.Publish(&events.Event{
|
||||
Event: "nwc_channel_closed",
|
||||
Properties: map[string]interface{}{
|
||||
"counterparty_node_id": peerId,
|
||||
"counterparty_node_url": "https://amboss.space/node/" + peerId,
|
||||
"reason": channel.Status,
|
||||
"node_type": config.CLNBackendType,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CLNService) subscribeOpenHoldInvoices(ctx context.Context) {
|
||||
holdinvoices := make([]*clngrpcHold.Invoice, 0)
|
||||
|
||||
|
|
@ -1016,6 +1477,11 @@ func (c *CLNService) GetSupportedNIP47NotificationTypes() []string {
|
|||
result = append(result,
|
||||
notifications.HOLD_INVOICE_ACCEPTED_NOTIFICATION)
|
||||
}
|
||||
if c.enableNotifications {
|
||||
result = append(result,
|
||||
notifications.PAYMENT_RECEIVED_NOTIFICATION,
|
||||
notifications.PAYMENT_SENT_NOTIFICATION)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
@ -1321,13 +1787,15 @@ func (c *CLNService) LookupInvoice(ctx context.Context, paymentHash string) (tra
|
|||
}
|
||||
|
||||
func (c *CLNService) clnInvoiceToTransaction(ctx context.Context, invoice *clngrpc.ListinvoicesInvoices) (*lnclient.Transaction, error) {
|
||||
var invoiceStr string
|
||||
var invstring string
|
||||
var bolt11Invoice string
|
||||
if invoice.Bolt11 != nil {
|
||||
invoiceStr = *invoice.Bolt11
|
||||
invstring = *invoice.Bolt11
|
||||
bolt11Invoice = *invoice.Bolt11
|
||||
} else if invoice.Bolt12 != nil {
|
||||
invoiceStr = *invoice.Bolt12
|
||||
invstring = *invoice.Bolt12
|
||||
} else {
|
||||
invoiceStr = ""
|
||||
return nil, fmt.Errorf("bolt11 and bolt12 missing from invoice")
|
||||
}
|
||||
|
||||
var amountMsat int64
|
||||
|
|
@ -1350,27 +1818,39 @@ func (c *CLNService) clnInvoiceToTransaction(ctx context.Context, invoice *clngr
|
|||
paid_at = &paid_at_int64
|
||||
}
|
||||
|
||||
decoded_invoice, err := c.client.Decode(ctx, &clngrpc.DecodeRequest{String_: invoiceStr})
|
||||
decoded_invoice, err := c.client.Decode(ctx, &clngrpc.DecodeRequest{String_: invstring})
|
||||
if err != nil {
|
||||
logger.Logger.WithError(err).Error("decode failed")
|
||||
return nil, fmt.Errorf("decode failed: %w", err)
|
||||
}
|
||||
|
||||
var created_at int64
|
||||
metadata := map[string]interface{}{}
|
||||
var description_hash string
|
||||
switch decoded_invoice.ItemType {
|
||||
case clngrpc.DecodeResponse_BOLT12_INVOICE:
|
||||
if decoded_invoice.InvoiceCreatedAt == nil {
|
||||
return nil, fmt.Errorf("invoice_created_at missing from bolt12 invoice")
|
||||
}
|
||||
created_at = int64(*decoded_invoice.InvoiceCreatedAt)
|
||||
|
||||
offer := map[string]interface{}{}
|
||||
offer["id"] = hex.EncodeToString(decoded_invoice.OfferId)
|
||||
if invoice.InvreqPayerNote != nil {
|
||||
offer["payer_note"] = *invoice.InvreqPayerNote
|
||||
}
|
||||
metadata["offer"] = offer
|
||||
case clngrpc.DecodeResponse_BOLT11_INVOICE:
|
||||
if decoded_invoice.CreatedAt == nil {
|
||||
return nil, fmt.Errorf("created_at missing from bolt11 invoice")
|
||||
}
|
||||
created_at = int64(*decoded_invoice.CreatedAt)
|
||||
|
||||
if decoded_invoice.DescriptionHash != nil {
|
||||
description_hash = hex.EncodeToString(decoded_invoice.DescriptionHash)
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("created_at missing from invoice")
|
||||
return nil, fmt.Errorf("invoice is not a bolt11 or bolt12 invoice")
|
||||
}
|
||||
|
||||
var description string
|
||||
|
|
@ -1382,9 +1862,9 @@ func (c *CLNService) clnInvoiceToTransaction(ctx context.Context, invoice *clngr
|
|||
|
||||
transaction := &lnclient.Transaction{
|
||||
Type: "incoming",
|
||||
Invoice: invoiceStr,
|
||||
Invoice: bolt11Invoice,
|
||||
Description: description,
|
||||
DescriptionHash: "",
|
||||
DescriptionHash: description_hash,
|
||||
Preimage: hex.EncodeToString(invoice.PaymentPreimage),
|
||||
PaymentHash: hex.EncodeToString(invoice.PaymentHash),
|
||||
AmountMsat: amountMsat,
|
||||
|
|
@ -1392,8 +1872,7 @@ func (c *CLNService) clnInvoiceToTransaction(ctx context.Context, invoice *clngr
|
|||
CreatedAt: created_at,
|
||||
ExpiresAt: &expires_at,
|
||||
SettledAt: paid_at,
|
||||
Metadata: lnclient.Metadata{},
|
||||
SettleDeadline: nil,
|
||||
Metadata: metadata,
|
||||
}
|
||||
return transaction, nil
|
||||
}
|
||||
|
|
@ -1937,3 +2416,45 @@ func (c *CLNService) UpdateChannel(ctx context.Context, updateChannelRequest *ln
|
|||
|
||||
func (c *CLNService) UpdateLastWalletSyncRequest() {
|
||||
}
|
||||
|
||||
func atOrAboveVersion(myVersion string, minVersion string) (bool, error) {
|
||||
idx := strings.IndexRune(myVersion, 'v')
|
||||
if idx == -1 {
|
||||
return false, fmt.Errorf("could not find v in version string")
|
||||
}
|
||||
cleanStartMyVersion := myVersion[idx+1:]
|
||||
|
||||
var builder strings.Builder
|
||||
for _, r := range cleanStartMyVersion {
|
||||
if unicode.IsDigit(r) || r == '.' {
|
||||
builder.WriteRune(r)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
fullCleanMyVersion := builder.String()
|
||||
|
||||
myVersionParts := strings.Split(fullCleanMyVersion, ".")
|
||||
minVersionParts := strings.Split(minVersion, ".")
|
||||
|
||||
if len(myVersionParts) <= 1 || len(myVersionParts) > 3 {
|
||||
return false, fmt.Errorf("version string parse error: %s", myVersion)
|
||||
}
|
||||
|
||||
for i := 0; i < len(myVersionParts) && i < len(minVersionParts); i++ {
|
||||
myNum, err := strconv.ParseUint(myVersionParts[i], 10, 32)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
minNum, err := strconv.ParseUint(minVersionParts[i], 10, 32)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if myNum != minNum {
|
||||
return myNum > minNum, nil
|
||||
}
|
||||
}
|
||||
|
||||
return len(myVersionParts) >= len(minVersionParts), nil
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -84,6 +84,7 @@ const (
|
|||
ChannelState_ChanneldAwaitingSplice ChannelState = 11
|
||||
ChannelState_DualopendOpenCommitted ChannelState = 12
|
||||
ChannelState_DualopendOpenCommittReady ChannelState = 13
|
||||
ChannelState_Closed ChannelState = 14
|
||||
)
|
||||
|
||||
// Enum value maps for ChannelState.
|
||||
|
|
@ -103,6 +104,7 @@ var (
|
|||
11: "ChanneldAwaitingSplice",
|
||||
12: "DualopendOpenCommitted",
|
||||
13: "DualopendOpenCommittReady",
|
||||
14: "Closed",
|
||||
}
|
||||
ChannelState_value = map[string]int32{
|
||||
"Openingd": 0,
|
||||
|
|
@ -119,6 +121,7 @@ var (
|
|||
"ChanneldAwaitingSplice": 11,
|
||||
"DualopendOpenCommitted": 12,
|
||||
"DualopendOpenCommittReady": 13,
|
||||
"Closed": 14,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -1286,6 +1289,468 @@ func (x *TlvStream) GetEntries() []*TlvEntry {
|
|||
return nil
|
||||
}
|
||||
|
||||
type JsonObjectOrArray struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Types that are valid to be assigned to Structure:
|
||||
//
|
||||
// *JsonObjectOrArray_Object
|
||||
// *JsonObjectOrArray_Array
|
||||
Structure isJsonObjectOrArray_Structure `protobuf_oneof:"structure"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JsonObjectOrArray) Reset() {
|
||||
*x = JsonObjectOrArray{}
|
||||
mi := &file_primitives_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *JsonObjectOrArray) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*JsonObjectOrArray) ProtoMessage() {}
|
||||
|
||||
func (x *JsonObjectOrArray) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_primitives_proto_msgTypes[14]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use JsonObjectOrArray.ProtoReflect.Descriptor instead.
|
||||
func (*JsonObjectOrArray) Descriptor() ([]byte, []int) {
|
||||
return file_primitives_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *JsonObjectOrArray) GetStructure() isJsonObjectOrArray_Structure {
|
||||
if x != nil {
|
||||
return x.Structure
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JsonObjectOrArray) GetObject() *JsonObject {
|
||||
if x != nil {
|
||||
if x, ok := x.Structure.(*JsonObjectOrArray_Object); ok {
|
||||
return x.Object
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JsonObjectOrArray) GetArray() *JsonArray {
|
||||
if x != nil {
|
||||
if x, ok := x.Structure.(*JsonObjectOrArray_Array); ok {
|
||||
return x.Array
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isJsonObjectOrArray_Structure interface {
|
||||
isJsonObjectOrArray_Structure()
|
||||
}
|
||||
|
||||
type JsonObjectOrArray_Object struct {
|
||||
Object *JsonObject `protobuf:"bytes,1,opt,name=object,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonObjectOrArray_Array struct {
|
||||
Array *JsonArray `protobuf:"bytes,2,opt,name=array,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*JsonObjectOrArray_Object) isJsonObjectOrArray_Structure() {}
|
||||
|
||||
func (*JsonObjectOrArray_Array) isJsonObjectOrArray_Structure() {}
|
||||
|
||||
type JsonObject struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Fields map[string]*JsonValue `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JsonObject) Reset() {
|
||||
*x = JsonObject{}
|
||||
mi := &file_primitives_proto_msgTypes[15]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *JsonObject) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*JsonObject) ProtoMessage() {}
|
||||
|
||||
func (x *JsonObject) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_primitives_proto_msgTypes[15]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use JsonObject.ProtoReflect.Descriptor instead.
|
||||
func (*JsonObject) Descriptor() ([]byte, []int) {
|
||||
return file_primitives_proto_rawDescGZIP(), []int{15}
|
||||
}
|
||||
|
||||
func (x *JsonObject) GetFields() map[string]*JsonValue {
|
||||
if x != nil {
|
||||
return x.Fields
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type JsonArray struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Values []*JsonValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JsonArray) Reset() {
|
||||
*x = JsonArray{}
|
||||
mi := &file_primitives_proto_msgTypes[16]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *JsonArray) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*JsonArray) ProtoMessage() {}
|
||||
|
||||
func (x *JsonArray) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_primitives_proto_msgTypes[16]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use JsonArray.ProtoReflect.Descriptor instead.
|
||||
func (*JsonArray) Descriptor() ([]byte, []int) {
|
||||
return file_primitives_proto_rawDescGZIP(), []int{16}
|
||||
}
|
||||
|
||||
func (x *JsonArray) GetValues() []*JsonValue {
|
||||
if x != nil {
|
||||
return x.Values
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type JsonValue struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Types that are valid to be assigned to Kind:
|
||||
//
|
||||
// *JsonValue_BoolValue
|
||||
// *JsonValue_IntValue
|
||||
// *JsonValue_UintValue
|
||||
// *JsonValue_DoubleValue
|
||||
// *JsonValue_StringValue
|
||||
// *JsonValue_Array
|
||||
// *JsonValue_Object
|
||||
Kind isJsonValue_Kind `protobuf_oneof:"kind"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JsonValue) Reset() {
|
||||
*x = JsonValue{}
|
||||
mi := &file_primitives_proto_msgTypes[17]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *JsonValue) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*JsonValue) ProtoMessage() {}
|
||||
|
||||
func (x *JsonValue) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_primitives_proto_msgTypes[17]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use JsonValue.ProtoReflect.Descriptor instead.
|
||||
func (*JsonValue) Descriptor() ([]byte, []int) {
|
||||
return file_primitives_proto_rawDescGZIP(), []int{17}
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetKind() isJsonValue_Kind {
|
||||
if x != nil {
|
||||
return x.Kind
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetBoolValue() bool {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_BoolValue); ok {
|
||||
return x.BoolValue
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetIntValue() int64 {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_IntValue); ok {
|
||||
return x.IntValue
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetUintValue() uint64 {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_UintValue); ok {
|
||||
return x.UintValue
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetDoubleValue() float64 {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_DoubleValue); ok {
|
||||
return x.DoubleValue
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetStringValue() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_StringValue); ok {
|
||||
return x.StringValue
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetArray() *JsonArray {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_Array); ok {
|
||||
return x.Array
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JsonValue) GetObject() *JsonObject {
|
||||
if x != nil {
|
||||
if x, ok := x.Kind.(*JsonValue_Object); ok {
|
||||
return x.Object
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isJsonValue_Kind interface {
|
||||
isJsonValue_Kind()
|
||||
}
|
||||
|
||||
type JsonValue_BoolValue struct {
|
||||
BoolValue bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonValue_IntValue struct {
|
||||
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonValue_UintValue struct {
|
||||
UintValue uint64 `protobuf:"varint,3,opt,name=uint_value,json=uintValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonValue_DoubleValue struct {
|
||||
DoubleValue float64 `protobuf:"fixed64,4,opt,name=double_value,json=doubleValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonValue_StringValue struct {
|
||||
StringValue string `protobuf:"bytes,5,opt,name=string_value,json=stringValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonValue_Array struct {
|
||||
Array *JsonArray `protobuf:"bytes,6,opt,name=array,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonValue_Object struct {
|
||||
Object *JsonObject `protobuf:"bytes,7,opt,name=object,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*JsonValue_BoolValue) isJsonValue_Kind() {}
|
||||
|
||||
func (*JsonValue_IntValue) isJsonValue_Kind() {}
|
||||
|
||||
func (*JsonValue_UintValue) isJsonValue_Kind() {}
|
||||
|
||||
func (*JsonValue_DoubleValue) isJsonValue_Kind() {}
|
||||
|
||||
func (*JsonValue_StringValue) isJsonValue_Kind() {}
|
||||
|
||||
func (*JsonValue_Array) isJsonValue_Kind() {}
|
||||
|
||||
func (*JsonValue_Object) isJsonValue_Kind() {}
|
||||
|
||||
type JsonScalar struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Types that are valid to be assigned to Scalar:
|
||||
//
|
||||
// *JsonScalar_BoolValue
|
||||
// *JsonScalar_IntValue
|
||||
// *JsonScalar_UintValue
|
||||
// *JsonScalar_DoubleValue
|
||||
// *JsonScalar_StringValue
|
||||
Scalar isJsonScalar_Scalar `protobuf_oneof:"scalar"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *JsonScalar) Reset() {
|
||||
*x = JsonScalar{}
|
||||
mi := &file_primitives_proto_msgTypes[18]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *JsonScalar) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*JsonScalar) ProtoMessage() {}
|
||||
|
||||
func (x *JsonScalar) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_primitives_proto_msgTypes[18]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use JsonScalar.ProtoReflect.Descriptor instead.
|
||||
func (*JsonScalar) Descriptor() ([]byte, []int) {
|
||||
return file_primitives_proto_rawDescGZIP(), []int{18}
|
||||
}
|
||||
|
||||
func (x *JsonScalar) GetScalar() isJsonScalar_Scalar {
|
||||
if x != nil {
|
||||
return x.Scalar
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *JsonScalar) GetBoolValue() bool {
|
||||
if x != nil {
|
||||
if x, ok := x.Scalar.(*JsonScalar_BoolValue); ok {
|
||||
return x.BoolValue
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *JsonScalar) GetIntValue() int64 {
|
||||
if x != nil {
|
||||
if x, ok := x.Scalar.(*JsonScalar_IntValue); ok {
|
||||
return x.IntValue
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonScalar) GetUintValue() uint64 {
|
||||
if x != nil {
|
||||
if x, ok := x.Scalar.(*JsonScalar_UintValue); ok {
|
||||
return x.UintValue
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonScalar) GetDoubleValue() float64 {
|
||||
if x != nil {
|
||||
if x, ok := x.Scalar.(*JsonScalar_DoubleValue); ok {
|
||||
return x.DoubleValue
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *JsonScalar) GetStringValue() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Scalar.(*JsonScalar_StringValue); ok {
|
||||
return x.StringValue
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type isJsonScalar_Scalar interface {
|
||||
isJsonScalar_Scalar()
|
||||
}
|
||||
|
||||
type JsonScalar_BoolValue struct {
|
||||
BoolValue bool `protobuf:"varint,1,opt,name=bool_value,json=boolValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonScalar_IntValue struct {
|
||||
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonScalar_UintValue struct {
|
||||
UintValue uint64 `protobuf:"varint,3,opt,name=uint_value,json=uintValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonScalar_DoubleValue struct {
|
||||
DoubleValue float64 `protobuf:"fixed64,4,opt,name=double_value,json=doubleValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
type JsonScalar_StringValue struct {
|
||||
StringValue string `protobuf:"bytes,5,opt,name=string_value,json=stringValue,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*JsonScalar_BoolValue) isJsonScalar_Scalar() {}
|
||||
|
||||
func (*JsonScalar_IntValue) isJsonScalar_Scalar() {}
|
||||
|
||||
func (*JsonScalar_UintValue) isJsonScalar_Scalar() {}
|
||||
|
||||
func (*JsonScalar_DoubleValue) isJsonScalar_Scalar() {}
|
||||
|
||||
func (*JsonScalar_StringValue) isJsonScalar_Scalar() {}
|
||||
|
||||
var File_primitives_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_primitives_proto_rawDesc = "" +
|
||||
|
|
@ -1339,11 +1804,44 @@ const file_primitives_proto_rawDesc = "" +
|
|||
"\x04type\x18\x01 \x01(\x04R\x04type\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\fR\x05value\"4\n" +
|
||||
"\tTlvStream\x12'\n" +
|
||||
"\aentries\x18\x01 \x03(\v2\r.cln.TlvEntryR\aentries*$\n" +
|
||||
"\aentries\x18\x01 \x03(\v2\r.cln.TlvEntryR\aentries\"s\n" +
|
||||
"\x11JsonObjectOrArray\x12)\n" +
|
||||
"\x06object\x18\x01 \x01(\v2\x0f.cln.JsonObjectH\x00R\x06object\x12&\n" +
|
||||
"\x05array\x18\x02 \x01(\v2\x0e.cln.JsonArrayH\x00R\x05arrayB\v\n" +
|
||||
"\tstructure\"\x8c\x01\n" +
|
||||
"\n" +
|
||||
"JsonObject\x123\n" +
|
||||
"\x06fields\x18\x01 \x03(\v2\x1b.cln.JsonObject.FieldsEntryR\x06fields\x1aI\n" +
|
||||
"\vFieldsEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12$\n" +
|
||||
"\x05value\x18\x02 \x01(\v2\x0e.cln.JsonValueR\x05value:\x028\x01\"3\n" +
|
||||
"\tJsonArray\x12&\n" +
|
||||
"\x06values\x18\x01 \x03(\v2\x0e.cln.JsonValueR\x06values\"\x91\x02\n" +
|
||||
"\tJsonValue\x12\x1f\n" +
|
||||
"\n" +
|
||||
"bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x12\x1d\n" +
|
||||
"\tint_value\x18\x02 \x01(\x03H\x00R\bintValue\x12\x1f\n" +
|
||||
"\n" +
|
||||
"uint_value\x18\x03 \x01(\x04H\x00R\tuintValue\x12#\n" +
|
||||
"\fdouble_value\x18\x04 \x01(\x01H\x00R\vdoubleValue\x12#\n" +
|
||||
"\fstring_value\x18\x05 \x01(\tH\x00R\vstringValue\x12&\n" +
|
||||
"\x05array\x18\x06 \x01(\v2\x0e.cln.JsonArrayH\x00R\x05array\x12)\n" +
|
||||
"\x06object\x18\a \x01(\v2\x0f.cln.JsonObjectH\x00R\x06objectB\x06\n" +
|
||||
"\x04kind\"\xc1\x01\n" +
|
||||
"\n" +
|
||||
"JsonScalar\x12\x1f\n" +
|
||||
"\n" +
|
||||
"bool_value\x18\x01 \x01(\bH\x00R\tboolValue\x12\x1d\n" +
|
||||
"\tint_value\x18\x02 \x01(\x03H\x00R\bintValue\x12\x1f\n" +
|
||||
"\n" +
|
||||
"uint_value\x18\x03 \x01(\x04H\x00R\tuintValue\x12#\n" +
|
||||
"\fdouble_value\x18\x04 \x01(\x01H\x00R\vdoubleValue\x12#\n" +
|
||||
"\fstring_value\x18\x05 \x01(\tH\x00R\vstringValueB\b\n" +
|
||||
"\x06scalar*$\n" +
|
||||
"\vChannelSide\x12\t\n" +
|
||||
"\x05LOCAL\x10\x00\x12\n" +
|
||||
"\n" +
|
||||
"\x06REMOTE\x10\x01*\xdb\x02\n" +
|
||||
"\x06REMOTE\x10\x01*\xe7\x02\n" +
|
||||
"\fChannelState\x12\f\n" +
|
||||
"\bOpeningd\x10\x00\x12\x1a\n" +
|
||||
"\x16ChanneldAwaitingLockin\x10\x01\x12\x12\n" +
|
||||
|
|
@ -1359,7 +1857,9 @@ const file_primitives_proto_rawDesc = "" +
|
|||
"\x12\x1a\n" +
|
||||
"\x16ChanneldAwaitingSplice\x10\v\x12\x1a\n" +
|
||||
"\x16DualopendOpenCommitted\x10\f\x12\x1d\n" +
|
||||
"\x19DualopendOpenCommittReady\x10\r*\xd5\x03\n" +
|
||||
"\x19DualopendOpenCommittReady\x10\r\x12\n" +
|
||||
"\n" +
|
||||
"\x06Closed\x10\x0e*\xd5\x03\n" +
|
||||
"\tHtlcState\x12\x0f\n" +
|
||||
"\vSentAddHtlc\x10\x00\x12\x11\n" +
|
||||
"\rSentAddCommit\x10\x01\x12\x15\n" +
|
||||
|
|
@ -1418,7 +1918,7 @@ func file_primitives_proto_rawDescGZIP() []byte {
|
|||
}
|
||||
|
||||
var file_primitives_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
|
||||
var file_primitives_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_primitives_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
|
||||
var file_primitives_proto_goTypes = []any{
|
||||
(ChannelSide)(0), // 0: cln.ChannelSide
|
||||
(ChannelState)(0), // 1: cln.ChannelState
|
||||
|
|
@ -1440,6 +1940,12 @@ var file_primitives_proto_goTypes = []any{
|
|||
(*DecodeRoutehintList)(nil), // 17: cln.DecodeRoutehintList
|
||||
(*TlvEntry)(nil), // 18: cln.TlvEntry
|
||||
(*TlvStream)(nil), // 19: cln.TlvStream
|
||||
(*JsonObjectOrArray)(nil), // 20: cln.JsonObjectOrArray
|
||||
(*JsonObject)(nil), // 21: cln.JsonObject
|
||||
(*JsonArray)(nil), // 22: cln.JsonArray
|
||||
(*JsonValue)(nil), // 23: cln.JsonValue
|
||||
(*JsonScalar)(nil), // 24: cln.JsonScalar
|
||||
nil, // 25: cln.JsonObject.FieldsEntry
|
||||
}
|
||||
var file_primitives_proto_depIdxs = []int32{
|
||||
6, // 0: cln.AmountOrAll.amount:type_name -> cln.Amount
|
||||
|
|
@ -1452,11 +1958,18 @@ var file_primitives_proto_depIdxs = []int32{
|
|||
15, // 7: cln.DecodeRoutehint.hops:type_name -> cln.DecodeRouteHop
|
||||
16, // 8: cln.DecodeRoutehintList.hints:type_name -> cln.DecodeRoutehint
|
||||
18, // 9: cln.TlvStream.entries:type_name -> cln.TlvEntry
|
||||
10, // [10:10] is the sub-list for method output_type
|
||||
10, // [10:10] is the sub-list for method input_type
|
||||
10, // [10:10] is the sub-list for extension type_name
|
||||
10, // [10:10] is the sub-list for extension extendee
|
||||
0, // [0:10] is the sub-list for field type_name
|
||||
21, // 10: cln.JsonObjectOrArray.object:type_name -> cln.JsonObject
|
||||
22, // 11: cln.JsonObjectOrArray.array:type_name -> cln.JsonArray
|
||||
25, // 12: cln.JsonObject.fields:type_name -> cln.JsonObject.FieldsEntry
|
||||
23, // 13: cln.JsonArray.values:type_name -> cln.JsonValue
|
||||
22, // 14: cln.JsonValue.array:type_name -> cln.JsonArray
|
||||
21, // 15: cln.JsonValue.object:type_name -> cln.JsonObject
|
||||
23, // 16: cln.JsonObject.FieldsEntry.value:type_name -> cln.JsonValue
|
||||
17, // [17:17] is the sub-list for method output_type
|
||||
17, // [17:17] is the sub-list for method input_type
|
||||
17, // [17:17] is the sub-list for extension type_name
|
||||
17, // [17:17] is the sub-list for extension extendee
|
||||
0, // [0:17] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_primitives_proto_init() }
|
||||
|
|
@ -1479,13 +1992,33 @@ func file_primitives_proto_init() {
|
|||
(*Feerate_Perkb)(nil),
|
||||
(*Feerate_Perkw)(nil),
|
||||
}
|
||||
file_primitives_proto_msgTypes[14].OneofWrappers = []any{
|
||||
(*JsonObjectOrArray_Object)(nil),
|
||||
(*JsonObjectOrArray_Array)(nil),
|
||||
}
|
||||
file_primitives_proto_msgTypes[17].OneofWrappers = []any{
|
||||
(*JsonValue_BoolValue)(nil),
|
||||
(*JsonValue_IntValue)(nil),
|
||||
(*JsonValue_UintValue)(nil),
|
||||
(*JsonValue_DoubleValue)(nil),
|
||||
(*JsonValue_StringValue)(nil),
|
||||
(*JsonValue_Array)(nil),
|
||||
(*JsonValue_Object)(nil),
|
||||
}
|
||||
file_primitives_proto_msgTypes[18].OneofWrappers = []any{
|
||||
(*JsonScalar_BoolValue)(nil),
|
||||
(*JsonScalar_IntValue)(nil),
|
||||
(*JsonScalar_UintValue)(nil),
|
||||
(*JsonScalar_DoubleValue)(nil),
|
||||
(*JsonScalar_StringValue)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_primitives_proto_rawDesc), len(file_primitives_proto_rawDesc)),
|
||||
NumEnums: 6,
|
||||
NumMessages: 14,
|
||||
NumMessages: 20,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue