diff --git a/.msggen.json b/.msggen.json index 7344c15eb..9e553c569 100644 --- a/.msggen.json +++ b/.msggen.json @@ -48,6 +48,9 @@ "torv2": 3, "torv3": 4 }, + "KeysendStatus": { + "complete": 0 + }, "ListfundsOutputsStatus": { "confirmed": 1, "spent": 2, @@ -58,6 +61,14 @@ "paid": 1, "unpaid": 0 }, + "ListnodesNodesAddressesType": { + "dns": 0, + "ipv4": 1, + "ipv6": 2, + "torv2": 3, + "torv3": 4, + "websocket": 5 + }, "ListpeersPeersChannelsHtlcsDirection": { "in": 0, "out": 1 @@ -95,6 +106,70 @@ "IO_OUT": 6, "SKIPPED": 0, "UNUSUAL": 2 + }, + "ListsendpaysPaymentsStatus": { + "complete": 2, + "failed": 1, + "pending": 0 + }, + "ListsendpaysStatus": { + "complete": 1, + "failed": 2, + "pending": 0 + }, + "ListtransactionsTransactionsInputsType": { + "channel_funding": 3, + "channel_htlc_success": 7, + "channel_htlc_timeout": 8, + "channel_mutual_close": 4, + "channel_penalty": 9, + "channel_sweep": 6, + "channel_unilateral_cheat": 10, + "channel_unilateral_close": 5, + "deposit": 1, + "theirs": 0, + "withdraw": 2 + }, + "ListtransactionsTransactionsOutputsType": { + "channel_funding": 3, + "channel_htlc_success": 7, + "channel_htlc_timeout": 8, + "channel_mutual_close": 4, + "channel_penalty": 9, + "channel_sweep": 6, + "channel_unilateral_cheat": 10, + "channel_unilateral_close": 5, + "deposit": 1, + "theirs": 0, + "withdraw": 2 + }, + "NewaddrAddresstype": { + "bech32": 0, + "p2sh-segwit": 1 + }, + "PayStatus": { + "complete": 0, + "failed": 2, + "pending": 1 + }, + "SendonionStatus": { + "complete": 1, + "pending": 0 + }, + "SendpayStatus": { + "complete": 1, + "pending": 0 + }, + "WaitanyinvoiceStatus": { + "expired": 1, + "paid": 0 + }, + "WaitinvoiceStatus": { + "expired": 1, + "paid": 0 + }, + "WaitsendpayStatus": { + "complete": 0 } }, "grpc-field-map": { @@ -170,6 +245,20 @@ "CreateInvoice.payment_preimage": 12, "CreateInvoice.status": 6 }, + "CreateonionHops": { + "CreateOnion.hops[].payload": 2, + "CreateOnion.hops[].pubkey": 1 + }, + "CreateonionRequest": { + "CreateOnion.assocdata": 2, + "CreateOnion.hops[]": 1, + "CreateOnion.onion_size": 4, + "CreateOnion.session_key": 3 + }, + "CreateonionResponse": { + "CreateOnion.onion": 1, + "CreateOnion.shared_secrets[]": 2 + }, "DatastoreRequest": { "Datastore.generation": 4, "Datastore.hex": 2, @@ -266,6 +355,26 @@ "Invoice.warning_offline": 6, "Invoice.warning_private_unused": 8 }, + "KeysendRequest": { + "KeySend.destination": 1, + "KeySend.exemptfee": 7, + "KeySend.label": 3, + "KeySend.maxdelay": 6, + "KeySend.maxfeepercent": 4, + "KeySend.msatoshi": 2, + "KeySend.retry_for": 5 + }, + "KeysendResponse": { + "KeySend.amount_msat": 6, + "KeySend.amount_sent_msat": 7, + "KeySend.created_at": 4, + "KeySend.destination": 2, + "KeySend.parts": 5, + "KeySend.payment_hash": 3, + "KeySend.payment_preimage": 1, + "KeySend.status": 9, + "KeySend.warning_partial_completion": 8 + }, "ListchannelsChannels": { "ListChannels.channels[].active": 8, "ListChannels.channels[].amount_msat": 5, @@ -355,6 +464,25 @@ "ListinvoicesResponse": { "ListInvoices.invoices[]": 1 }, + "ListnodesNodes": { + "ListNodes.nodes[].addresses[]": 6, + "ListNodes.nodes[].alias": 3, + "ListNodes.nodes[].color": 4, + "ListNodes.nodes[].features": 5, + "ListNodes.nodes[].last_timestamp": 2, + "ListNodes.nodes[].nodeid": 1 + }, + "ListnodesNodesAddresses": { + "ListNodes.nodes[].addresses[].address": 3, + "ListNodes.nodes[].addresses[].port": 2, + "ListNodes.nodes[].addresses[].type": 1 + }, + "ListnodesRequest": { + "ListNodes.id": 1 + }, + "ListnodesResponse": { + "ListNodes.nodes[]": 1 + }, "ListpeersPeers": { "ListPeers.peers[].channels[]": 4, "ListPeers.peers[].connected": 2, @@ -454,6 +582,206 @@ }, "ListpeersResponse": { "ListPeers.peers[]": 1 + }, + "ListsendpaysPayments": { + "ListSendPays.payments[].amount_msat": 5, + "ListSendPays.payments[].amount_sent_msat": 8, + "ListSendPays.payments[].bolt11": 10, + "ListSendPays.payments[].bolt12": 11, + "ListSendPays.payments[].created_at": 7, + "ListSendPays.payments[].destination": 6, + "ListSendPays.payments[].erroronion": 13, + "ListSendPays.payments[].groupid": 2, + "ListSendPays.payments[].id": 1, + "ListSendPays.payments[].label": 9, + "ListSendPays.payments[].payment_hash": 3, + "ListSendPays.payments[].payment_preimage": 12, + "ListSendPays.payments[].status": 4 + }, + "ListsendpaysRequest": { + "ListSendPays.bolt11": 1, + "ListSendPays.payment_hash": 2, + "ListSendPays.status": 3 + }, + "ListsendpaysResponse": { + "ListSendPays.payments[]": 1 + }, + "ListtransactionsResponse": { + "ListTransactions.transactions[]": 1 + }, + "ListtransactionsTransactions": { + "ListTransactions.transactions[].blockheight": 3, + "ListTransactions.transactions[].channel": 6, + "ListTransactions.transactions[].hash": 1, + "ListTransactions.transactions[].inputs[]": 9, + "ListTransactions.transactions[].locktime": 7, + "ListTransactions.transactions[].outputs[]": 10, + "ListTransactions.transactions[].rawtx": 2, + "ListTransactions.transactions[].txindex": 4, + "ListTransactions.transactions[].type[]": 5, + "ListTransactions.transactions[].version": 8 + }, + "ListtransactionsTransactionsInputs": { + "ListTransactions.transactions[].inputs[].channel": 5, + "ListTransactions.transactions[].inputs[].index": 2, + "ListTransactions.transactions[].inputs[].sequence": 3, + "ListTransactions.transactions[].inputs[].txid": 1, + "ListTransactions.transactions[].inputs[].type": 4 + }, + "ListtransactionsTransactionsOutputs": { + "ListTransactions.transactions[].outputs[].channel": 5, + "ListTransactions.transactions[].outputs[].index": 1, + "ListTransactions.transactions[].outputs[].msat": 2, + "ListTransactions.transactions[].outputs[].scriptPubKey": 3, + "ListTransactions.transactions[].outputs[].type": 4 + }, + "NewaddrRequest": { + "NewAddr.addresstype": 1 + }, + "NewaddrResponse": { + "NewAddr.bech32": 1, + "NewAddr.p2sh-segwit": 2 + }, + "PayRequest": { + "Pay.bolt11": 1, + "Pay.exemptfee": 7, + "Pay.label": 3, + "Pay.maxdelay": 6, + "Pay.maxfeepercent": 4, + "Pay.msatoshi": 2, + "Pay.retry_for": 5, + "Pay.riskfactor": 8 + }, + "PayResponse": { + "Pay.amount_msat": 6, + "Pay.amount_sent_msat": 7, + "Pay.created_at": 4, + "Pay.destination": 2, + "Pay.parts": 5, + "Pay.payment_hash": 3, + "Pay.payment_preimage": 1, + "Pay.status": 9, + "Pay.warning_partial_completion": 8 + }, + "SendonionFirst_hop": { + "SendOnion.first_hop.amount_msat": 2, + "SendOnion.first_hop.delay": 3, + "SendOnion.first_hop.id": 1 + }, + "SendonionRequest": { + "SendOnion.first_hop": 2, + "SendOnion.onion": 1 + }, + "SendonionResponse": { + "SendOnion.amount_msat": 4, + "SendOnion.amount_sent_msat": 7, + "SendOnion.bolt11": 9, + "SendOnion.bolt12": 10, + "SendOnion.created_at": 6, + "SendOnion.destination": 5, + "SendOnion.id": 1, + "SendOnion.label": 8, + "SendOnion.message": 12, + "SendOnion.payment_hash": 2, + "SendOnion.payment_preimage": 11, + "SendOnion.status": 3 + }, + "SendpayRequest": { + "SendPay.bolt11": 5, + "SendPay.label": 3, + "SendPay.msatoshi": 4, + "SendPay.partid": 7, + "SendPay.payment_hash": 2, + "SendPay.payment_secret": 6, + "SendPay.route[]": 1 + }, + "SendpayResponse": { + "SendPay.amount_msat": 5, + "SendPay.amount_sent_msat": 8, + "SendPay.bolt11": 11, + "SendPay.bolt12": 12, + "SendPay.created_at": 7, + "SendPay.destination": 6, + "SendPay.groupid": 2, + "SendPay.id": 1, + "SendPay.label": 9, + "SendPay.message": 14, + "SendPay.partid": 10, + "SendPay.payment_hash": 3, + "SendPay.payment_preimage": 13, + "SendPay.status": 4 + }, + "SendpayRoute": { + "SendPay.route[].channel": 4, + "SendPay.route[].delay": 3, + "SendPay.route[].id": 2, + "SendPay.route[].msatoshi": 1 + }, + "WaitanyinvoiceRequest": { + "WaitAnyInvoice.lastpay_index": 1, + "WaitAnyInvoice.timeout": 2 + }, + "WaitanyinvoiceResponse": { + "WaitAnyInvoice.amount_msat": 6, + "WaitAnyInvoice.amount_received_msat": 10, + "WaitAnyInvoice.bolt11": 7, + "WaitAnyInvoice.bolt12": 8, + "WaitAnyInvoice.description": 2, + "WaitAnyInvoice.expires_at": 5, + "WaitAnyInvoice.label": 1, + "WaitAnyInvoice.paid_at": 11, + "WaitAnyInvoice.pay_index": 9, + "WaitAnyInvoice.payment_hash": 3, + "WaitAnyInvoice.payment_preimage": 12, + "WaitAnyInvoice.status": 4 + }, + "WaitinvoiceRequest": { + "WaitInvoice.label": 1 + }, + "WaitinvoiceResponse": { + "WaitInvoice.amount_msat": 6, + "WaitInvoice.amount_received_msat": 10, + "WaitInvoice.bolt11": 7, + "WaitInvoice.bolt12": 8, + "WaitInvoice.description": 2, + "WaitInvoice.expires_at": 5, + "WaitInvoice.label": 1, + "WaitInvoice.paid_at": 11, + "WaitInvoice.pay_index": 9, + "WaitInvoice.payment_hash": 3, + "WaitInvoice.payment_preimage": 12, + "WaitInvoice.status": 4 + }, + "WaitsendpayRequest": { + "WaitSendPay.partid": 2, + "WaitSendPay.payment_hash": 1, + "WaitSendPay.timeout": 3 + }, + "WaitsendpayResponse": { + "WaitSendPay.amount_msat": 5, + "WaitSendPay.amount_sent_msat": 8, + "WaitSendPay.bolt11": 11, + "WaitSendPay.bolt12": 12, + "WaitSendPay.created_at": 7, + "WaitSendPay.destination": 6, + "WaitSendPay.groupid": 2, + "WaitSendPay.id": 1, + "WaitSendPay.label": 9, + "WaitSendPay.partid": 10, + "WaitSendPay.payment_hash": 3, + "WaitSendPay.payment_preimage": 13, + "WaitSendPay.status": 4 + }, + "WithdrawRequest": { + "Withdraw.destination": 1, + "Withdraw.minconf": 3, + "Withdraw.satoshi": 2, + "Withdraw.utxos[]": 4 + }, + "WithdrawResponse": { + "Withdraw.psbt": 3, + "Withdraw.tx": 1, + "Withdraw.txid": 2 } } } \ No newline at end of file diff --git a/cln-grpc/proto/node.proto b/cln-grpc/proto/node.proto index 241e628f3..fc26237dd 100644 --- a/cln-grpc/proto/node.proto +++ b/cln-grpc/proto/node.proto @@ -11,6 +11,7 @@ service Node { rpc Getinfo(GetinfoRequest) returns (GetinfoResponse) {} rpc ListPeers(ListpeersRequest) returns (ListpeersResponse) {} rpc ListFunds(ListfundsRequest) returns (ListfundsResponse) {} + rpc SendPay(SendpayRequest) returns (SendpayResponse) {} rpc ListChannels(ListchannelsRequest) returns (ListchannelsResponse) {} rpc AddGossip(AddgossipRequest) returns (AddgossipResponse) {} rpc AutoCleanInvoice(AutocleaninvoiceRequest) returns (AutocleaninvoiceResponse) {} @@ -19,12 +20,24 @@ service Node { rpc ConnectPeer(ConnectRequest) returns (ConnectResponse) {} rpc CreateInvoice(CreateinvoiceRequest) returns (CreateinvoiceResponse) {} rpc Datastore(DatastoreRequest) returns (DatastoreResponse) {} + rpc CreateOnion(CreateonionRequest) returns (CreateonionResponse) {} rpc DelDatastore(DeldatastoreRequest) returns (DeldatastoreResponse) {} rpc DelExpiredInvoice(DelexpiredinvoiceRequest) returns (DelexpiredinvoiceResponse) {} rpc DelInvoice(DelinvoiceRequest) returns (DelinvoiceResponse) {} rpc Invoice(InvoiceRequest) returns (InvoiceResponse) {} rpc ListDatastore(ListdatastoreRequest) returns (ListdatastoreResponse) {} rpc ListInvoices(ListinvoicesRequest) returns (ListinvoicesResponse) {} + rpc SendOnion(SendonionRequest) returns (SendonionResponse) {} + rpc ListSendPays(ListsendpaysRequest) returns (ListsendpaysResponse) {} + rpc ListTransactions(ListtransactionsRequest) returns (ListtransactionsResponse) {} + rpc Pay(PayRequest) returns (PayResponse) {} + rpc ListNodes(ListnodesRequest) returns (ListnodesResponse) {} + rpc WaitAnyInvoice(WaitanyinvoiceRequest) returns (WaitanyinvoiceResponse) {} + rpc WaitInvoice(WaitinvoiceRequest) returns (WaitinvoiceResponse) {} + rpc WaitSendPay(WaitsendpayRequest) returns (WaitsendpayResponse) {} + rpc NewAddr(NewaddrRequest) returns (NewaddrResponse) {} + rpc Withdraw(WithdrawRequest) returns (WithdrawResponse) {} + rpc KeySend(KeysendRequest) returns (KeysendResponse) {} } message GetinfoRequest { @@ -271,6 +284,45 @@ message ListfundsChannels { optional string short_channel_id = 8; } +message SendpayRequest { + repeated SendpayRoute route = 1; + bytes payment_hash = 2; + optional string label = 3; + optional Amount msatoshi = 4; + optional string bolt11 = 5; + optional bytes payment_secret = 6; + optional uint32 partid = 7; +} + +message SendpayResponse { + // SendPay.status + enum SendpayStatus { + PENDING = 0; + COMPLETE = 1; + } + uint64 id = 1; + optional uint64 groupid = 2; + bytes payment_hash = 3; + SendpayStatus status = 4; + optional Amount amount_msat = 5; + optional bytes destination = 6; + uint64 created_at = 7; + Amount amount_sent_msat = 8; + optional string label = 9; + optional uint64 partid = 10; + optional string bolt11 = 11; + optional string bolt12 = 12; + optional bytes payment_preimage = 13; + optional string message = 14; +} + +message SendpayRoute { + Amount msatoshi = 1; + bytes id = 2; + uint32 delay = 3; + string channel = 4; +} + message ListchannelsRequest { optional string short_channel_id = 1; optional bytes source = 2; @@ -432,6 +484,23 @@ message DatastoreResponse { optional string string = 4; } +message CreateonionRequest { + repeated CreateonionHops hops = 1; + bytes assocdata = 2; + optional bytes session_key = 3; + optional uint32 onion_size = 4; +} + +message CreateonionResponse { + bytes onion = 1; + repeated bytes shared_secrets = 2; +} + +message CreateonionHops { + bytes pubkey = 1; + bytes payload = 2; +} + message DeldatastoreRequest { repeated string key = 1; optional uint64 generation = 2; @@ -550,3 +619,323 @@ message ListinvoicesInvoices { optional uint64 paid_at = 13; optional bytes payment_preimage = 14; } + +message SendonionRequest { + bytes onion = 1; +} + +message SendonionResponse { + // SendOnion.status + enum SendonionStatus { + PENDING = 0; + COMPLETE = 1; + } + uint64 id = 1; + bytes payment_hash = 2; + SendonionStatus status = 3; + optional Amount amount_msat = 4; + optional bytes destination = 5; + uint64 created_at = 6; + Amount amount_sent_msat = 7; + optional string label = 8; + optional string bolt11 = 9; + optional string bolt12 = 10; + optional bytes payment_preimage = 11; + optional string message = 12; +} + +message SendonionFirst_hop { + bytes id = 1; + Amount amount_msat = 2; + uint32 delay = 3; +} + +message ListsendpaysRequest { + // ListSendPays.status + enum ListsendpaysStatus { + PENDING = 0; + COMPLETE = 1; + FAILED = 2; + } + optional string bolt11 = 1; + optional bytes payment_hash = 2; + optional ListsendpaysStatus status = 3; +} + +message ListsendpaysResponse { + repeated ListsendpaysPayments payments = 1; +} + +message ListsendpaysPayments { + // ListSendPays.payments[].status + enum ListsendpaysPaymentsStatus { + PENDING = 0; + FAILED = 1; + COMPLETE = 2; + } + uint64 id = 1; + optional uint64 groupid = 2; + bytes payment_hash = 3; + ListsendpaysPaymentsStatus status = 4; + optional Amount amount_msat = 5; + optional bytes destination = 6; + uint64 created_at = 7; + Amount amount_sent_msat = 8; + optional string label = 9; + optional string bolt11 = 10; + optional string bolt12 = 11; + optional bytes payment_preimage = 12; + optional bytes erroronion = 13; +} + +message ListtransactionsRequest { +} + +message ListtransactionsResponse { + repeated ListtransactionsTransactions transactions = 1; +} + +message ListtransactionsTransactions { + bytes hash = 1; + bytes rawtx = 2; + uint32 blockheight = 3; + uint32 txindex = 4; + optional string channel = 6; + uint32 locktime = 7; + uint32 version = 8; + repeated ListtransactionsTransactionsInputs inputs = 9; + repeated ListtransactionsTransactionsOutputs outputs = 10; +} + +message ListtransactionsTransactionsInputs { + // ListTransactions.transactions[].inputs[].type + enum ListtransactionsTransactionsInputsType { + THEIRS = 0; + DEPOSIT = 1; + WITHDRAW = 2; + CHANNEL_FUNDING = 3; + CHANNEL_MUTUAL_CLOSE = 4; + CHANNEL_UNILATERAL_CLOSE = 5; + CHANNEL_SWEEP = 6; + CHANNEL_HTLC_SUCCESS = 7; + CHANNEL_HTLC_TIMEOUT = 8; + CHANNEL_PENALTY = 9; + CHANNEL_UNILATERAL_CHEAT = 10; + } + bytes txid = 1; + uint32 index = 2; + uint32 sequence = 3; + optional ListtransactionsTransactionsInputsType item_type = 4; + optional string channel = 5; +} + +message ListtransactionsTransactionsOutputs { + // ListTransactions.transactions[].outputs[].type + enum ListtransactionsTransactionsOutputsType { + THEIRS = 0; + DEPOSIT = 1; + WITHDRAW = 2; + CHANNEL_FUNDING = 3; + CHANNEL_MUTUAL_CLOSE = 4; + CHANNEL_UNILATERAL_CLOSE = 5; + CHANNEL_SWEEP = 6; + CHANNEL_HTLC_SUCCESS = 7; + CHANNEL_HTLC_TIMEOUT = 8; + CHANNEL_PENALTY = 9; + CHANNEL_UNILATERAL_CHEAT = 10; + } + uint32 index = 1; + Amount msat = 2; + bytes scriptPubKey = 3; + optional ListtransactionsTransactionsOutputsType item_type = 4; + optional string channel = 5; +} + +message PayRequest { + string bolt11 = 1; + optional Amount msatoshi = 2; + optional string label = 3; + optional float riskfactor = 8; + optional float maxfeepercent = 4; + optional uint32 retry_for = 5; + optional uint32 maxdelay = 6; + optional float exemptfee = 7; +} + +message PayResponse { + // Pay.status + enum PayStatus { + COMPLETE = 0; + PENDING = 1; + FAILED = 2; + } + bytes payment_preimage = 1; + optional bytes destination = 2; + bytes payment_hash = 3; + sint64 created_at = 4; + uint32 parts = 5; + Amount amount_msat = 6; + Amount amount_sent_msat = 7; + optional string warning_partial_completion = 8; + PayStatus status = 9; +} + +message ListnodesRequest { + optional bytes id = 1; +} + +message ListnodesResponse { + repeated ListnodesNodes nodes = 1; +} + +message ListnodesNodes { + bytes nodeid = 1; + optional uint32 last_timestamp = 2; + optional string alias = 3; + optional bytes color = 4; + optional bytes features = 5; + repeated ListnodesNodesAddresses addresses = 6; +} + +message ListnodesNodesAddresses { + // ListNodes.nodes[].addresses[].type + enum ListnodesNodesAddressesType { + DNS = 0; + IPV4 = 1; + IPV6 = 2; + TORV2 = 3; + TORV3 = 4; + WEBSOCKET = 5; + } + ListnodesNodesAddressesType item_type = 1; + uint32 port = 2; + optional string address = 3; +} + +message WaitanyinvoiceRequest { + optional sint64 lastpay_index = 1; + optional sint64 timeout = 2; +} + +message WaitanyinvoiceResponse { + // WaitAnyInvoice.status + enum WaitanyinvoiceStatus { + PAID = 0; + EXPIRED = 1; + } + string label = 1; + string description = 2; + bytes payment_hash = 3; + WaitanyinvoiceStatus status = 4; + uint64 expires_at = 5; + optional Amount amount_msat = 6; + optional string bolt11 = 7; + optional string bolt12 = 8; + optional uint64 pay_index = 9; + optional Amount amount_received_msat = 10; + optional uint64 paid_at = 11; + optional bytes payment_preimage = 12; +} + +message WaitinvoiceRequest { + string label = 1; +} + +message WaitinvoiceResponse { + // WaitInvoice.status + enum WaitinvoiceStatus { + PAID = 0; + EXPIRED = 1; + } + string label = 1; + string description = 2; + bytes payment_hash = 3; + WaitinvoiceStatus status = 4; + uint64 expires_at = 5; + optional Amount amount_msat = 6; + optional string bolt11 = 7; + optional string bolt12 = 8; + optional uint64 pay_index = 9; + optional Amount amount_received_msat = 10; + optional uint64 paid_at = 11; + optional bytes payment_preimage = 12; +} + +message WaitsendpayRequest { + bytes payment_hash = 1; + optional uint32 partid = 2; + optional uint32 timeout = 3; +} + +message WaitsendpayResponse { + // WaitSendPay.status + enum WaitsendpayStatus { + COMPLETE = 0; + } + uint64 id = 1; + optional uint64 groupid = 2; + bytes payment_hash = 3; + WaitsendpayStatus status = 4; + optional Amount amount_msat = 5; + optional bytes destination = 6; + uint64 created_at = 7; + Amount amount_sent_msat = 8; + optional string label = 9; + optional uint64 partid = 10; + optional string bolt11 = 11; + optional string bolt12 = 12; + optional bytes payment_preimage = 13; +} + +message NewaddrRequest { + // NewAddr.addresstype + enum NewaddrAddresstype { + BECH32 = 0; + P2SH_SEGWIT = 1; + } + optional NewaddrAddresstype addresstype = 1; +} + +message NewaddrResponse { + optional string bech32 = 1; + optional string p2sh_segwit = 2; +} + +message WithdrawRequest { + bytes destination = 1; + optional Amount satoshi = 2; + optional uint32 minconf = 3; + repeated Utxo utxos = 4; +} + +message WithdrawResponse { + bytes tx = 1; + bytes txid = 2; + string psbt = 3; +} + +message KeysendRequest { + bytes destination = 1; + Amount msatoshi = 2; + optional string label = 3; + optional float maxfeepercent = 4; + optional sint64 retry_for = 5; + optional sint64 maxdelay = 6; + optional Amount exemptfee = 7; +} + +message KeysendResponse { + // KeySend.status + enum KeysendStatus { + COMPLETE = 0; + } + bytes payment_preimage = 1; + optional bytes destination = 2; + bytes payment_hash = 3; + sint64 created_at = 4; + uint32 parts = 5; + Amount amount_msat = 6; + Amount amount_sent_msat = 7; + optional string warning_partial_completion = 8; + KeysendStatus status = 9; +} diff --git a/cln-grpc/proto/primitives.proto b/cln-grpc/proto/primitives.proto index 0b1064c55..bbcde1c7d 100644 --- a/cln-grpc/proto/primitives.proto +++ b/cln-grpc/proto/primitives.proto @@ -24,4 +24,9 @@ enum ChannelState { DualopendAwaitingLockin = 10; } -message ChannelStateChangeCause {} \ No newline at end of file +message ChannelStateChangeCause {} + +message Utxo { + bytes txid = 1; + uint32 outnum = 2; +} \ No newline at end of file diff --git a/cln-grpc/src/convert.rs b/cln-grpc/src/convert.rs index 797b5bb4c..58b78b3f9 100644 --- a/cln-grpc/src/convert.rs +++ b/cln-grpc/src/convert.rs @@ -13,8 +13,8 @@ impl From<&responses::GetinfoAddress> for pb::GetinfoAddress { fn from(c: &responses::GetinfoAddress) -> Self { Self { item_type: c.item_type as i32, - port: c.port.into(), - address: c.address.clone(), + port: c.port.into(), // Rule #2 for type u16 + address: c.address.clone(), // Rule #2 for type string? } } } @@ -24,9 +24,9 @@ impl From<&responses::GetinfoBinding> for pb::GetinfoBinding { fn from(c: &responses::GetinfoBinding) -> Self { Self { item_type: c.item_type as i32, - address: c.address.clone(), - port: c.port.map(|v| v.into()), - socket: c.socket.clone(), + address: c.address.clone(), // Rule #2 for type string? + port: c.port.map(|v| v.into()), // Rule #2 for type u16? + socket: c.socket.clone(), // Rule #2 for type string? } } } @@ -35,22 +35,22 @@ impl From<&responses::GetinfoBinding> for pb::GetinfoBinding { impl From<&responses::GetinfoResponse> for pb::GetinfoResponse { fn from(c: &responses::GetinfoResponse) -> Self { Self { - id: hex::decode(&c.id).unwrap(), - alias: c.alias.clone(), - color: hex::decode(&c.color).unwrap(), - num_peers: c.num_peers.clone(), - num_pending_channels: c.num_pending_channels.clone(), - num_active_channels: c.num_active_channels.clone(), - num_inactive_channels: c.num_inactive_channels.clone(), - version: c.version.clone(), - lightning_dir: c.lightning_dir.clone(), - blockheight: c.blockheight.clone(), - network: c.network.clone(), - fees_collected_msat: Some(c.fees_collected_msat.into()), + id: hex::decode(&c.id).unwrap(), // Rule #2 for type pubkey + alias: c.alias.clone(), // Rule #2 for type string + color: hex::decode(&c.color).unwrap(), // Rule #2 for type hex + num_peers: c.num_peers.clone(), // Rule #2 for type u32 + num_pending_channels: c.num_pending_channels.clone(), // Rule #2 for type u32 + num_active_channels: c.num_active_channels.clone(), // Rule #2 for type u32 + num_inactive_channels: c.num_inactive_channels.clone(), // Rule #2 for type u32 + version: c.version.clone(), // Rule #2 for type string + lightning_dir: c.lightning_dir.clone(), // Rule #2 for type string + blockheight: c.blockheight.clone(), // Rule #2 for type u32 + network: c.network.clone(), // Rule #2 for type string + fees_collected_msat: Some(c.fees_collected_msat.into()), // Rule #2 for type msat address: c.address.iter().map(|i| i.into()).collect(), binding: c.binding.iter().map(|i| i.into()).collect(), - warning_bitcoind_sync: c.warning_bitcoind_sync.clone(), - warning_lightningd_sync: c.warning_lightningd_sync.clone(), + warning_bitcoind_sync: c.warning_bitcoind_sync.clone(), // Rule #2 for type string? + warning_lightningd_sync: c.warning_lightningd_sync.clone(), // Rule #2 for type string? } } } @@ -60,12 +60,12 @@ impl From<&responses::ListpeersPeersLog> for pb::ListpeersPeersLog { fn from(c: &responses::ListpeersPeersLog) -> Self { Self { item_type: c.item_type as i32, - num_skipped: c.num_skipped.clone(), - time: c.time.clone(), - source: c.source.clone(), - log: c.log.clone(), - node_id: c.node_id.as_ref().map(|v| hex::decode(&v).unwrap()), - data: c.data.as_ref().map(|v| hex::decode(&v).unwrap()), + num_skipped: c.num_skipped.clone(), // Rule #2 for type u32? + time: c.time.clone(), // Rule #2 for type string? + source: c.source.clone(), // Rule #2 for type string? + log: c.log.clone(), // Rule #2 for type string? + node_id: c.node_id.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + data: c.data.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? } } } @@ -74,12 +74,12 @@ impl From<&responses::ListpeersPeersLog> for pb::ListpeersPeersLog { impl From<&responses::ListpeersPeersChannelsInflight> for pb::ListpeersPeersChannelsInflight { fn from(c: &responses::ListpeersPeersChannelsInflight) -> Self { Self { - funding_txid: hex::decode(&c.funding_txid).unwrap(), - funding_outnum: c.funding_outnum.clone(), - feerate: c.feerate.clone(), - total_funding_msat: Some(c.total_funding_msat.into()), - our_funding_msat: Some(c.our_funding_msat.into()), - scratch_txid: hex::decode(&c.scratch_txid).unwrap(), + funding_txid: hex::decode(&c.funding_txid).unwrap(), // Rule #2 for type txid + funding_outnum: c.funding_outnum.clone(), // Rule #2 for type u32 + feerate: c.feerate.clone(), // Rule #2 for type string + total_funding_msat: Some(c.total_funding_msat.into()), // Rule #2 for type msat + our_funding_msat: Some(c.our_funding_msat.into()), // Rule #2 for type msat + scratch_txid: hex::decode(&c.scratch_txid).unwrap(), // Rule #2 for type txid } } } @@ -89,12 +89,12 @@ impl From<&responses::ListpeersPeersChannelsHtlcs> for pb::ListpeersPeersChannel fn from(c: &responses::ListpeersPeersChannelsHtlcs) -> Self { Self { direction: c.direction as i32, - id: c.id.clone(), - amount_msat: Some(c.amount_msat.into()), - expiry: c.expiry.clone(), - payment_hash: hex::decode(&c.payment_hash).unwrap(), - local_trimmed: c.local_trimmed.clone(), - status: c.status.clone(), + id: c.id.clone(), // Rule #2 for type u64 + amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat + expiry: c.expiry.clone(), // Rule #2 for type u32 + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + local_trimmed: c.local_trimmed.clone(), // Rule #2 for type boolean? + status: c.status.clone(), // Rule #2 for type string? state: c.state as i32, } } @@ -105,49 +105,49 @@ impl From<&responses::ListpeersPeersChannels> for pb::ListpeersPeersChannels { fn from(c: &responses::ListpeersPeersChannels) -> Self { Self { state: c.state as i32, - scratch_txid: c.scratch_txid.as_ref().map(|v| hex::decode(&v).unwrap()), - owner: c.owner.clone(), - short_channel_id: c.short_channel_id.clone(), - channel_id: c.channel_id.as_ref().map(|v| hex::decode(&v).unwrap()), - funding_txid: c.funding_txid.as_ref().map(|v| hex::decode(&v).unwrap()), - funding_outnum: c.funding_outnum.clone(), - initial_feerate: c.initial_feerate.clone(), - last_feerate: c.last_feerate.clone(), - next_feerate: c.next_feerate.clone(), - next_fee_step: c.next_fee_step.clone(), + scratch_txid: c.scratch_txid.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type txid? + owner: c.owner.clone(), // Rule #2 for type string? + short_channel_id: c.short_channel_id.clone(), // Rule #2 for type short_channel_id? + channel_id: c.channel_id.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + funding_txid: c.funding_txid.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type txid? + funding_outnum: c.funding_outnum.clone(), // Rule #2 for type u32? + initial_feerate: c.initial_feerate.clone(), // Rule #2 for type string? + last_feerate: c.last_feerate.clone(), // Rule #2 for type string? + next_feerate: c.next_feerate.clone(), // Rule #2 for type string? + next_fee_step: c.next_fee_step.clone(), // Rule #2 for type u32? inflight: c.inflight.iter().map(|i| i.into()).collect(), - close_to: c.close_to.as_ref().map(|v| hex::decode(&v).unwrap()), - private: c.private.clone(), + close_to: c.close_to.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + private: c.private.clone(), // Rule #2 for type boolean? opener: c.opener as i32, closer: c.closer.map(|v| v as i32), features: c.features.iter().map(|i| i.into()).collect(), - to_us_msat: c.to_us_msat.map(|f| f.into()), - min_to_us_msat: c.min_to_us_msat.map(|f| f.into()), - max_to_us_msat: c.max_to_us_msat.map(|f| f.into()), - total_msat: c.total_msat.map(|f| f.into()), - fee_base_msat: c.fee_base_msat.map(|f| f.into()), - fee_proportional_millionths: c.fee_proportional_millionths.clone(), - dust_limit_msat: c.dust_limit_msat.map(|f| f.into()), - max_total_htlc_in_msat: c.max_total_htlc_in_msat.map(|f| f.into()), - their_reserve_msat: c.their_reserve_msat.map(|f| f.into()), - our_reserve_msat: c.our_reserve_msat.map(|f| f.into()), - spendable_msat: c.spendable_msat.map(|f| f.into()), - receivable_msat: c.receivable_msat.map(|f| f.into()), - minimum_htlc_in_msat: c.minimum_htlc_in_msat.map(|f| f.into()), - their_to_self_delay: c.their_to_self_delay.clone(), - our_to_self_delay: c.our_to_self_delay.clone(), - max_accepted_htlcs: c.max_accepted_htlcs.clone(), + to_us_msat: c.to_us_msat.map(|f| f.into()), // Rule #2 for type msat? + min_to_us_msat: c.min_to_us_msat.map(|f| f.into()), // Rule #2 for type msat? + max_to_us_msat: c.max_to_us_msat.map(|f| f.into()), // Rule #2 for type msat? + total_msat: c.total_msat.map(|f| f.into()), // Rule #2 for type msat? + fee_base_msat: c.fee_base_msat.map(|f| f.into()), // Rule #2 for type msat? + fee_proportional_millionths: c.fee_proportional_millionths.clone(), // Rule #2 for type u32? + dust_limit_msat: c.dust_limit_msat.map(|f| f.into()), // Rule #2 for type msat? + max_total_htlc_in_msat: c.max_total_htlc_in_msat.map(|f| f.into()), // Rule #2 for type msat? + their_reserve_msat: c.their_reserve_msat.map(|f| f.into()), // Rule #2 for type msat? + our_reserve_msat: c.our_reserve_msat.map(|f| f.into()), // Rule #2 for type msat? + spendable_msat: c.spendable_msat.map(|f| f.into()), // Rule #2 for type msat? + receivable_msat: c.receivable_msat.map(|f| f.into()), // Rule #2 for type msat? + minimum_htlc_in_msat: c.minimum_htlc_in_msat.map(|f| f.into()), // Rule #2 for type msat? + their_to_self_delay: c.their_to_self_delay.clone(), // Rule #2 for type u32? + our_to_self_delay: c.our_to_self_delay.clone(), // Rule #2 for type u32? + max_accepted_htlcs: c.max_accepted_htlcs.clone(), // Rule #2 for type u32? status: c.status.iter().map(|i| i.into()).collect(), - in_payments_offered: c.in_payments_offered.clone(), - in_offered_msat: c.in_offered_msat.map(|f| f.into()), - in_payments_fulfilled: c.in_payments_fulfilled.clone(), - in_fulfilled_msat: c.in_fulfilled_msat.map(|f| f.into()), - out_payments_offered: c.out_payments_offered.clone(), - out_offered_msat: c.out_offered_msat.map(|f| f.into()), - out_payments_fulfilled: c.out_payments_fulfilled.clone(), - out_fulfilled_msat: c.out_fulfilled_msat.map(|f| f.into()), + in_payments_offered: c.in_payments_offered.clone(), // Rule #2 for type u64? + in_offered_msat: c.in_offered_msat.map(|f| f.into()), // Rule #2 for type msat? + in_payments_fulfilled: c.in_payments_fulfilled.clone(), // Rule #2 for type u64? + in_fulfilled_msat: c.in_fulfilled_msat.map(|f| f.into()), // Rule #2 for type msat? + out_payments_offered: c.out_payments_offered.clone(), // Rule #2 for type u64? + out_offered_msat: c.out_offered_msat.map(|f| f.into()), // Rule #2 for type msat? + out_payments_fulfilled: c.out_payments_fulfilled.clone(), // Rule #2 for type u64? + out_fulfilled_msat: c.out_fulfilled_msat.map(|f| f.into()), // Rule #2 for type msat? htlcs: c.htlcs.iter().map(|i| i.into()).collect(), - close_to_addr: c.close_to_addr.clone(), + close_to_addr: c.close_to_addr.clone(), // Rule #2 for type string? } } } @@ -156,12 +156,12 @@ impl From<&responses::ListpeersPeersChannels> for pb::ListpeersPeersChannels { impl From<&responses::ListpeersPeers> for pb::ListpeersPeers { fn from(c: &responses::ListpeersPeers) -> Self { Self { - id: hex::decode(&c.id).unwrap(), - connected: c.connected.clone(), + id: hex::decode(&c.id).unwrap(), // Rule #2 for type pubkey + connected: c.connected.clone(), // Rule #2 for type boolean log: c.log.iter().map(|i| i.into()).collect(), channels: c.channels.iter().map(|i| i.into()).collect(), netaddr: c.netaddr.iter().map(|i| i.into()).collect(), - features: c.features.as_ref().map(|v| hex::decode(&v).unwrap()), + features: c.features.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? } } } @@ -179,14 +179,14 @@ impl From<&responses::ListpeersResponse> for pb::ListpeersResponse { impl From<&responses::ListfundsOutputs> for pb::ListfundsOutputs { fn from(c: &responses::ListfundsOutputs) -> Self { Self { - txid: hex::decode(&c.txid).unwrap(), - output: c.output.clone(), - amount_msat: Some(c.amount_msat.into()), - scriptpubkey: hex::decode(&c.scriptpubkey).unwrap(), - address: c.address.clone(), - redeemscript: c.redeemscript.as_ref().map(|v| hex::decode(&v).unwrap()), + txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid + output: c.output.clone(), // Rule #2 for type u32 + amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat + scriptpubkey: hex::decode(&c.scriptpubkey).unwrap(), // Rule #2 for type hex + address: c.address.clone(), // Rule #2 for type string? + redeemscript: c.redeemscript.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? status: c.status as i32, - blockheight: c.blockheight.clone(), + blockheight: c.blockheight.clone(), // Rule #2 for type u32? } } } @@ -195,14 +195,14 @@ impl From<&responses::ListfundsOutputs> for pb::ListfundsOutputs { impl From<&responses::ListfundsChannels> for pb::ListfundsChannels { fn from(c: &responses::ListfundsChannels) -> Self { Self { - peer_id: hex::decode(&c.peer_id).unwrap(), - our_amount_msat: Some(c.our_amount_msat.into()), - amount_msat: Some(c.amount_msat.into()), - funding_txid: hex::decode(&c.funding_txid).unwrap(), - funding_output: c.funding_output.clone(), - connected: c.connected.clone(), + peer_id: hex::decode(&c.peer_id).unwrap(), // Rule #2 for type pubkey + our_amount_msat: Some(c.our_amount_msat.into()), // Rule #2 for type msat + amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat + funding_txid: hex::decode(&c.funding_txid).unwrap(), // Rule #2 for type txid + funding_output: c.funding_output.clone(), // Rule #2 for type u32 + connected: c.connected.clone(), // Rule #2 for type boolean state: c.state as i32, - short_channel_id: c.short_channel_id.clone(), + short_channel_id: c.short_channel_id.clone(), // Rule #2 for type short_channel_id? } } } @@ -217,25 +217,47 @@ impl From<&responses::ListfundsResponse> for pb::ListfundsResponse { } } +#[allow(unused_variables)] +impl From<&responses::SendpayResponse> for pb::SendpayResponse { + fn from(c: &responses::SendpayResponse) -> Self { + Self { + id: c.id.clone(), // Rule #2 for type u64 + groupid: c.groupid.clone(), // Rule #2 for type u64? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + status: c.status as i32, + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + destination: c.destination.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + created_at: c.created_at.clone(), // Rule #2 for type u64 + amount_sent_msat: Some(c.amount_sent_msat.into()), // Rule #2 for type msat + label: c.label.clone(), // Rule #2 for type string? + partid: c.partid.clone(), // Rule #2 for type u64? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + message: c.message.clone(), // Rule #2 for type string? + } + } +} + #[allow(unused_variables)] impl From<&responses::ListchannelsChannels> for pb::ListchannelsChannels { fn from(c: &responses::ListchannelsChannels) -> Self { Self { - source: hex::decode(&c.source).unwrap(), - destination: hex::decode(&c.destination).unwrap(), - short_channel_id: c.short_channel_id.clone(), - public: c.public.clone(), - amount_msat: Some(c.amount_msat.into()), - message_flags: c.message_flags.into(), - channel_flags: c.channel_flags.into(), - active: c.active.clone(), - last_update: c.last_update.clone(), - base_fee_millisatoshi: c.base_fee_millisatoshi.clone(), - fee_per_millionth: c.fee_per_millionth.clone(), - delay: c.delay.clone(), - htlc_minimum_msat: Some(c.htlc_minimum_msat.into()), - htlc_maximum_msat: c.htlc_maximum_msat.map(|f| f.into()), - features: hex::decode(&c.features).unwrap(), + source: hex::decode(&c.source).unwrap(), // Rule #2 for type pubkey + destination: hex::decode(&c.destination).unwrap(), // Rule #2 for type pubkey + short_channel_id: c.short_channel_id.clone(), // Rule #2 for type short_channel_id + public: c.public.clone(), // Rule #2 for type boolean + amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat + message_flags: c.message_flags.into(), // Rule #2 for type u8 + channel_flags: c.channel_flags.into(), // Rule #2 for type u8 + active: c.active.clone(), // Rule #2 for type boolean + last_update: c.last_update.clone(), // Rule #2 for type u32 + base_fee_millisatoshi: c.base_fee_millisatoshi.clone(), // Rule #2 for type u32 + fee_per_millionth: c.fee_per_millionth.clone(), // Rule #2 for type u32 + delay: c.delay.clone(), // Rule #2 for type u32 + htlc_minimum_msat: Some(c.htlc_minimum_msat.into()), // Rule #2 for type msat + htlc_maximum_msat: c.htlc_maximum_msat.map(|f| f.into()), // Rule #2 for type msat? + features: hex::decode(&c.features).unwrap(), // Rule #2 for type hex } } } @@ -261,9 +283,9 @@ impl From<&responses::AddgossipResponse> for pb::AddgossipResponse { impl From<&responses::AutocleaninvoiceResponse> for pb::AutocleaninvoiceResponse { fn from(c: &responses::AutocleaninvoiceResponse) -> Self { Self { - enabled: c.enabled.clone(), - expired_by: c.expired_by.clone(), - cycle_seconds: c.cycle_seconds.clone(), + enabled: c.enabled.clone(), // Rule #2 for type boolean + expired_by: c.expired_by.clone(), // Rule #2 for type u64? + cycle_seconds: c.cycle_seconds.clone(), // Rule #2 for type u64? } } } @@ -272,8 +294,8 @@ impl From<&responses::AutocleaninvoiceResponse> for pb::AutocleaninvoiceResponse impl From<&responses::CheckmessageResponse> for pb::CheckmessageResponse { fn from(c: &responses::CheckmessageResponse) -> Self { Self { - verified: c.verified.clone(), - pubkey: c.pubkey.as_ref().map(|v| hex::decode(&v).unwrap()), + verified: c.verified.clone(), // Rule #2 for type boolean + pubkey: c.pubkey.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? } } } @@ -283,8 +305,8 @@ impl From<&responses::CloseResponse> for pb::CloseResponse { fn from(c: &responses::CloseResponse) -> Self { Self { item_type: c.item_type as i32, - tx: c.tx.as_ref().map(|v| hex::decode(&v).unwrap()), - txid: c.txid.as_ref().map(|v| hex::decode(&v).unwrap()), + tx: c.tx.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + txid: c.txid.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type txid? } } } @@ -293,8 +315,8 @@ impl From<&responses::CloseResponse> for pb::CloseResponse { impl From<&responses::ConnectResponse> for pb::ConnectResponse { fn from(c: &responses::ConnectResponse) -> Self { Self { - id: hex::decode(&c.id).unwrap(), - features: hex::decode(&c.features).unwrap(), + id: hex::decode(&c.id).unwrap(), // Rule #2 for type pubkey + features: hex::decode(&c.features).unwrap(), // Rule #2 for type hex direction: c.direction as i32, } } @@ -304,20 +326,20 @@ impl From<&responses::ConnectResponse> for pb::ConnectResponse { impl From<&responses::CreateinvoiceResponse> for pb::CreateinvoiceResponse { fn from(c: &responses::CreateinvoiceResponse) -> Self { Self { - label: c.label.clone(), - bolt11: c.bolt11.clone(), - bolt12: c.bolt12.clone(), - payment_hash: hex::decode(&c.payment_hash).unwrap(), - amount_msat: c.amount_msat.map(|f| f.into()), + label: c.label.clone(), // Rule #2 for type string + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? status: c.status as i32, - description: c.description.clone(), - expires_at: c.expires_at.clone(), - pay_index: c.pay_index.clone(), - amount_received_msat: c.amount_received_msat.map(|f| f.into()), - paid_at: c.paid_at.clone(), - payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), - local_offer_id: c.local_offer_id.as_ref().map(|v| hex::decode(&v).unwrap()), - payer_note: c.payer_note.clone(), + description: c.description.clone(), // Rule #2 for type string + expires_at: c.expires_at.clone(), // Rule #2 for type u64 + pay_index: c.pay_index.clone(), // Rule #2 for type u64? + amount_received_msat: c.amount_received_msat.map(|f| f.into()), // Rule #2 for type msat? + paid_at: c.paid_at.clone(), // Rule #2 for type u64? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + local_offer_id: c.local_offer_id.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + payer_note: c.payer_note.clone(), // Rule #2 for type string? } } } @@ -327,9 +349,19 @@ impl From<&responses::DatastoreResponse> for pb::DatastoreResponse { fn from(c: &responses::DatastoreResponse) -> Self { Self { key: c.key.iter().map(|i| i.into()).collect(), - generation: c.generation.clone(), - hex: c.hex.as_ref().map(|v| hex::decode(&v).unwrap()), - string: c.string.clone(), + generation: c.generation.clone(), // Rule #2 for type u64? + hex: c.hex.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + string: c.string.clone(), // Rule #2 for type string? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::CreateonionResponse> for pb::CreateonionResponse { + fn from(c: &responses::CreateonionResponse) -> Self { + Self { + onion: hex::decode(&c.onion).unwrap(), // Rule #2 for type hex + shared_secrets: c.shared_secrets.iter().map(|i| hex::decode(i).unwrap()).collect(), } } } @@ -339,9 +371,9 @@ impl From<&responses::DeldatastoreResponse> for pb::DeldatastoreResponse { fn from(c: &responses::DeldatastoreResponse) -> Self { Self { key: c.key.iter().map(|i| i.into()).collect(), - generation: c.generation.clone(), - hex: c.hex.as_ref().map(|v| hex::decode(&v).unwrap()), - string: c.string.clone(), + generation: c.generation.clone(), // Rule #2 for type u64? + hex: c.hex.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + string: c.string.clone(), // Rule #2 for type string? } } } @@ -358,16 +390,16 @@ impl From<&responses::DelexpiredinvoiceResponse> for pb::DelexpiredinvoiceRespon impl From<&responses::DelinvoiceResponse> for pb::DelinvoiceResponse { fn from(c: &responses::DelinvoiceResponse) -> Self { Self { - label: c.label.clone(), - bolt11: c.bolt11.clone(), - bolt12: c.bolt12.clone(), - amount_msat: c.amount_msat.map(|f| f.into()), - description: c.description.clone(), - payment_hash: hex::decode(&c.payment_hash).unwrap(), + label: c.label.clone(), // Rule #2 for type string + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + description: c.description.clone(), // Rule #2 for type string? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex status: c.status as i32, - expires_at: c.expires_at.clone(), - local_offer_id: c.local_offer_id.as_ref().map(|v| hex::decode(&v).unwrap()), - payer_note: c.payer_note.clone(), + expires_at: c.expires_at.clone(), // Rule #2 for type u64 + local_offer_id: c.local_offer_id.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + payer_note: c.payer_note.clone(), // Rule #2 for type string? } } } @@ -376,15 +408,15 @@ impl From<&responses::DelinvoiceResponse> for pb::DelinvoiceResponse { impl From<&responses::InvoiceResponse> for pb::InvoiceResponse { fn from(c: &responses::InvoiceResponse) -> Self { Self { - bolt11: c.bolt11.clone(), - payment_hash: hex::decode(&c.payment_hash).unwrap(), - payment_secret: hex::decode(&c.payment_secret).unwrap(), - expires_at: c.expires_at.clone(), - warning_capacity: c.warning_capacity.clone(), - warning_offline: c.warning_offline.clone(), - warning_deadends: c.warning_deadends.clone(), - warning_private_unused: c.warning_private_unused.clone(), - warning_mpp: c.warning_mpp.clone(), + bolt11: c.bolt11.clone(), // Rule #2 for type string + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + payment_secret: hex::decode(&c.payment_secret).unwrap(), // Rule #2 for type hex + expires_at: c.expires_at.clone(), // Rule #2 for type u64 + warning_capacity: c.warning_capacity.clone(), // Rule #2 for type string? + warning_offline: c.warning_offline.clone(), // Rule #2 for type string? + warning_deadends: c.warning_deadends.clone(), // Rule #2 for type string? + warning_private_unused: c.warning_private_unused.clone(), // Rule #2 for type string? + warning_mpp: c.warning_mpp.clone(), // Rule #2 for type string? } } } @@ -394,9 +426,9 @@ impl From<&responses::ListdatastoreDatastore> for pb::ListdatastoreDatastore { fn from(c: &responses::ListdatastoreDatastore) -> Self { Self { key: c.key.iter().map(|i| i.into()).collect(), - generation: c.generation.clone(), - hex: c.hex.as_ref().map(|v| hex::decode(&v).unwrap()), - string: c.string.clone(), + generation: c.generation.clone(), // Rule #2 for type u64? + hex: c.hex.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + string: c.string.clone(), // Rule #2 for type string? } } } @@ -414,20 +446,20 @@ impl From<&responses::ListdatastoreResponse> for pb::ListdatastoreResponse { impl From<&responses::ListinvoicesInvoices> for pb::ListinvoicesInvoices { fn from(c: &responses::ListinvoicesInvoices) -> Self { Self { - label: c.label.clone(), - description: c.description.clone(), - payment_hash: hex::decode(&c.payment_hash).unwrap(), + label: c.label.clone(), // Rule #2 for type string + description: c.description.clone(), // Rule #2 for type string + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex status: c.status as i32, - expires_at: c.expires_at.clone(), - amount_msat: c.amount_msat.map(|f| f.into()), - bolt11: c.bolt11.clone(), - bolt12: c.bolt12.clone(), - local_offer_id: c.local_offer_id.as_ref().map(|v| hex::decode(&v).unwrap()), - payer_note: c.payer_note.clone(), - pay_index: c.pay_index.clone(), - amount_received_msat: c.amount_received_msat.map(|f| f.into()), - paid_at: c.paid_at.clone(), - payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), + expires_at: c.expires_at.clone(), // Rule #2 for type u64 + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + local_offer_id: c.local_offer_id.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + payer_note: c.payer_note.clone(), // Rule #2 for type string? + pay_index: c.pay_index.clone(), // Rule #2 for type u64? + amount_received_msat: c.amount_received_msat.map(|f| f.into()), // Rule #2 for type msat? + paid_at: c.paid_at.clone(), // Rule #2 for type u64? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? } } } @@ -441,6 +473,258 @@ impl From<&responses::ListinvoicesResponse> for pb::ListinvoicesResponse { } } +#[allow(unused_variables)] +impl From<&responses::SendonionResponse> for pb::SendonionResponse { + fn from(c: &responses::SendonionResponse) -> Self { + Self { + id: c.id.clone(), // Rule #2 for type u64 + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + status: c.status as i32, + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + destination: c.destination.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + created_at: c.created_at.clone(), // Rule #2 for type u64 + amount_sent_msat: Some(c.amount_sent_msat.into()), // Rule #2 for type msat + label: c.label.clone(), // Rule #2 for type string? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + message: c.message.clone(), // Rule #2 for type string? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListsendpaysPayments> for pb::ListsendpaysPayments { + fn from(c: &responses::ListsendpaysPayments) -> Self { + Self { + id: c.id.clone(), // Rule #2 for type u64 + groupid: c.groupid.clone(), // Rule #2 for type u64? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + status: c.status as i32, + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + destination: c.destination.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + created_at: c.created_at.clone(), // Rule #2 for type u64 + amount_sent_msat: Some(c.amount_sent_msat.into()), // Rule #2 for type msat + label: c.label.clone(), // Rule #2 for type string? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + erroronion: c.erroronion.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListsendpaysResponse> for pb::ListsendpaysResponse { + fn from(c: &responses::ListsendpaysResponse) -> Self { + Self { + payments: c.payments.iter().map(|i| i.into()).collect(), + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListtransactionsTransactionsInputs> for pb::ListtransactionsTransactionsInputs { + fn from(c: &responses::ListtransactionsTransactionsInputs) -> Self { + Self { + txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid + index: c.index.clone(), // Rule #2 for type u32 + sequence: c.sequence.clone(), // Rule #2 for type u32 + item_type: c.item_type.map(|v| v as i32), + channel: c.channel.clone(), // Rule #2 for type short_channel_id? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListtransactionsTransactionsOutputs> for pb::ListtransactionsTransactionsOutputs { + fn from(c: &responses::ListtransactionsTransactionsOutputs) -> Self { + Self { + index: c.index.clone(), // Rule #2 for type u32 + msat: Some(c.msat.into()), // Rule #2 for type msat + script_pub_key: hex::decode(&c.script_pub_key).unwrap(), // Rule #2 for type hex + item_type: c.item_type.map(|v| v as i32), + channel: c.channel.clone(), // Rule #2 for type short_channel_id? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListtransactionsTransactions> for pb::ListtransactionsTransactions { + fn from(c: &responses::ListtransactionsTransactions) -> Self { + Self { + hash: hex::decode(&c.hash).unwrap(), // Rule #2 for type txid + rawtx: hex::decode(&c.rawtx).unwrap(), // Rule #2 for type hex + blockheight: c.blockheight.clone(), // Rule #2 for type u32 + txindex: c.txindex.clone(), // Rule #2 for type u32 + channel: c.channel.clone(), // Rule #2 for type short_channel_id? + locktime: c.locktime.clone(), // Rule #2 for type u32 + version: c.version.clone(), // Rule #2 for type u32 + inputs: c.inputs.iter().map(|i| i.into()).collect(), + outputs: c.outputs.iter().map(|i| i.into()).collect(), + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListtransactionsResponse> for pb::ListtransactionsResponse { + fn from(c: &responses::ListtransactionsResponse) -> Self { + Self { + transactions: c.transactions.iter().map(|i| i.into()).collect(), + } + } +} + +#[allow(unused_variables)] +impl From<&responses::PayResponse> for pb::PayResponse { + fn from(c: &responses::PayResponse) -> Self { + Self { + payment_preimage: hex::decode(&c.payment_preimage).unwrap(), // Rule #2 for type hex + destination: c.destination.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + created_at: c.created_at.clone(), // Rule #2 for type number + parts: c.parts.clone(), // Rule #2 for type u32 + amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat + amount_sent_msat: Some(c.amount_sent_msat.into()), // Rule #2 for type msat + warning_partial_completion: c.warning_partial_completion.clone(), // Rule #2 for type string? + status: c.status as i32, + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListnodesNodesAddresses> for pb::ListnodesNodesAddresses { + fn from(c: &responses::ListnodesNodesAddresses) -> Self { + Self { + item_type: c.item_type as i32, + port: c.port.into(), // Rule #2 for type u16 + address: c.address.clone(), // Rule #2 for type string? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListnodesNodes> for pb::ListnodesNodes { + fn from(c: &responses::ListnodesNodes) -> Self { + Self { + nodeid: hex::decode(&c.nodeid).unwrap(), // Rule #2 for type pubkey + last_timestamp: c.last_timestamp.clone(), // Rule #2 for type u32? + alias: c.alias.clone(), // Rule #2 for type string? + color: c.color.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + features: c.features.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + addresses: c.addresses.iter().map(|i| i.into()).collect(), + } + } +} + +#[allow(unused_variables)] +impl From<&responses::ListnodesResponse> for pb::ListnodesResponse { + fn from(c: &responses::ListnodesResponse) -> Self { + Self { + nodes: c.nodes.iter().map(|i| i.into()).collect(), + } + } +} + +#[allow(unused_variables)] +impl From<&responses::WaitanyinvoiceResponse> for pb::WaitanyinvoiceResponse { + fn from(c: &responses::WaitanyinvoiceResponse) -> Self { + Self { + label: c.label.clone(), // Rule #2 for type string + description: c.description.clone(), // Rule #2 for type string + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + status: c.status as i32, + expires_at: c.expires_at.clone(), // Rule #2 for type u64 + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + pay_index: c.pay_index.clone(), // Rule #2 for type u64? + amount_received_msat: c.amount_received_msat.map(|f| f.into()), // Rule #2 for type msat? + paid_at: c.paid_at.clone(), // Rule #2 for type u64? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::WaitinvoiceResponse> for pb::WaitinvoiceResponse { + fn from(c: &responses::WaitinvoiceResponse) -> Self { + Self { + label: c.label.clone(), // Rule #2 for type string + description: c.description.clone(), // Rule #2 for type string + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + status: c.status as i32, + expires_at: c.expires_at.clone(), // Rule #2 for type u64 + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + pay_index: c.pay_index.clone(), // Rule #2 for type u64? + amount_received_msat: c.amount_received_msat.map(|f| f.into()), // Rule #2 for type msat? + paid_at: c.paid_at.clone(), // Rule #2 for type u64? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::WaitsendpayResponse> for pb::WaitsendpayResponse { + fn from(c: &responses::WaitsendpayResponse) -> Self { + Self { + id: c.id.clone(), // Rule #2 for type u64 + groupid: c.groupid.clone(), // Rule #2 for type u64? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + status: c.status as i32, + amount_msat: c.amount_msat.map(|f| f.into()), // Rule #2 for type msat? + destination: c.destination.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + created_at: c.created_at.clone(), // Rule #2 for type u64 + amount_sent_msat: Some(c.amount_sent_msat.into()), // Rule #2 for type msat + label: c.label.clone(), // Rule #2 for type string? + partid: c.partid.clone(), // Rule #2 for type u64? + bolt11: c.bolt11.clone(), // Rule #2 for type string? + bolt12: c.bolt12.clone(), // Rule #2 for type string? + payment_preimage: c.payment_preimage.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type hex? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::NewaddrResponse> for pb::NewaddrResponse { + fn from(c: &responses::NewaddrResponse) -> Self { + Self { + bech32: c.bech32.clone(), // Rule #2 for type string? + p2sh_segwit: c.p2sh_segwit.clone(), // Rule #2 for type string? + } + } +} + +#[allow(unused_variables)] +impl From<&responses::WithdrawResponse> for pb::WithdrawResponse { + fn from(c: &responses::WithdrawResponse) -> Self { + Self { + tx: hex::decode(&c.tx).unwrap(), // Rule #2 for type hex + txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid + psbt: c.psbt.clone(), // Rule #2 for type string + } + } +} + +#[allow(unused_variables)] +impl From<&responses::KeysendResponse> for pb::KeysendResponse { + fn from(c: &responses::KeysendResponse) -> Self { + Self { + payment_preimage: hex::decode(&c.payment_preimage).unwrap(), // Rule #2 for type hex + destination: c.destination.as_ref().map(|v| hex::decode(&v).unwrap()), // Rule #2 for type pubkey? + payment_hash: hex::decode(&c.payment_hash).unwrap(), // Rule #2 for type hex + created_at: c.created_at.clone(), // Rule #2 for type number + parts: c.parts.clone(), // Rule #2 for type u32 + amount_msat: Some(c.amount_msat.into()), // Rule #2 for type msat + amount_sent_msat: Some(c.amount_sent_msat.into()), // Rule #2 for type msat + warning_partial_completion: c.warning_partial_completion.clone(), // Rule #2 for type string? + status: c.status as i32, + } + } +} + #[allow(unused_variables)] impl From<&pb::GetinfoRequest> for requests::GetinfoRequest { fn from(c: &pb::GetinfoRequest) -> Self { @@ -453,8 +737,8 @@ impl From<&pb::GetinfoRequest> for requests::GetinfoRequest { impl From<&pb::ListpeersRequest> for requests::ListpeersRequest { fn from(c: &pb::ListpeersRequest) -> Self { Self { - id: c.id.clone().map(|v| hex::encode(v)), - level: c.level.clone(), + id: c.id.clone().map(|v| hex::encode(v)), // Rule #1 for type pubkey? + level: c.level.clone(), // Rule #1 for type string? } } } @@ -463,7 +747,34 @@ impl From<&pb::ListpeersRequest> for requests::ListpeersRequest { impl From<&pb::ListfundsRequest> for requests::ListfundsRequest { fn from(c: &pb::ListfundsRequest) -> Self { Self { - spent: c.spent.clone(), + spent: c.spent.clone(), // Rule #1 for type boolean? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::SendpayRoute> for requests::SendpayRoute { + fn from(c: &pb::SendpayRoute) -> Self { + Self { + msatoshi: c.msatoshi.as_ref().unwrap().into(), // Rule #1 for type msat + id: hex::encode(&c.id), // Rule #1 for type pubkey + delay: c.delay as u16, // Rule #1 for type u16 + channel: c.channel.clone(), // Rule #1 for type short_channel_id + } + } +} + +#[allow(unused_variables)] +impl From<&pb::SendpayRequest> for requests::SendpayRequest { + fn from(c: &pb::SendpayRequest) -> Self { + Self { + route: c.route.iter().map(|s| s.into()).collect(), + payment_hash: hex::encode(&c.payment_hash), // Rule #1 for type hex + label: c.label.clone(), // Rule #1 for type string? + msatoshi: c.msatoshi.as_ref().map(|a| a.into()), // Rule #1 for type msat? + bolt11: c.bolt11.clone(), // Rule #1 for type string? + payment_secret: c.payment_secret.clone().map(|v| hex::encode(v)), // Rule #1 for type hex? + partid: c.partid.map(|v| v as u16), // Rule #1 for type u16? } } } @@ -472,9 +783,9 @@ impl From<&pb::ListfundsRequest> for requests::ListfundsRequest { impl From<&pb::ListchannelsRequest> for requests::ListchannelsRequest { fn from(c: &pb::ListchannelsRequest) -> Self { Self { - short_channel_id: c.short_channel_id.clone(), - source: c.source.clone().map(|v| hex::encode(v)), - destination: c.destination.clone().map(|v| hex::encode(v)), + short_channel_id: c.short_channel_id.clone(), // Rule #1 for type short_channel_id? + source: c.source.clone().map(|v| hex::encode(v)), // Rule #1 for type pubkey? + destination: c.destination.clone().map(|v| hex::encode(v)), // Rule #1 for type pubkey? } } } @@ -483,7 +794,7 @@ impl From<&pb::ListchannelsRequest> for requests::ListchannelsRequest { impl From<&pb::AddgossipRequest> for requests::AddgossipRequest { fn from(c: &pb::AddgossipRequest) -> Self { Self { - message: hex::encode(&c.message), + message: hex::encode(&c.message), // Rule #1 for type hex } } } @@ -492,8 +803,8 @@ impl From<&pb::AddgossipRequest> for requests::AddgossipRequest { impl From<&pb::AutocleaninvoiceRequest> for requests::AutocleaninvoiceRequest { fn from(c: &pb::AutocleaninvoiceRequest) -> Self { Self { - expired_by: c.expired_by.clone(), - cycle_seconds: c.cycle_seconds.clone(), + expired_by: c.expired_by.clone(), // Rule #1 for type u64? + cycle_seconds: c.cycle_seconds.clone(), // Rule #1 for type u64? } } } @@ -502,9 +813,9 @@ impl From<&pb::AutocleaninvoiceRequest> for requests::AutocleaninvoiceRequest { impl From<&pb::CheckmessageRequest> for requests::CheckmessageRequest { fn from(c: &pb::CheckmessageRequest) -> Self { Self { - message: c.message.clone(), - zbase: c.zbase.clone(), - pubkey: c.pubkey.clone().map(|v| hex::encode(v)), + message: c.message.clone(), // Rule #1 for type string + zbase: c.zbase.clone(), // Rule #1 for type string + pubkey: c.pubkey.clone().map(|v| hex::encode(v)), // Rule #1 for type pubkey? } } } @@ -513,12 +824,12 @@ impl From<&pb::CheckmessageRequest> for requests::CheckmessageRequest { impl From<&pb::CloseRequest> for requests::CloseRequest { fn from(c: &pb::CloseRequest) -> Self { Self { - id: hex::encode(&c.id), - unilateraltimeout: c.unilateraltimeout.clone(), - destination: c.destination.clone(), - fee_negotiation_step: c.fee_negotiation_step.clone(), - wrong_funding: c.wrong_funding.clone().map(|v| hex::encode(v)), - force_lease_closed: c.force_lease_closed.clone(), + id: hex::encode(&c.id), // Rule #1 for type pubkey + unilateraltimeout: c.unilateraltimeout.clone(), // Rule #1 for type u32? + destination: c.destination.clone(), // Rule #1 for type string? + fee_negotiation_step: c.fee_negotiation_step.clone(), // Rule #1 for type string? + wrong_funding: c.wrong_funding.clone().map(|v| hex::encode(v)), // Rule #1 for type txid? + force_lease_closed: c.force_lease_closed.clone(), // Rule #1 for type boolean? } } } @@ -527,9 +838,9 @@ impl From<&pb::CloseRequest> for requests::CloseRequest { impl From<&pb::ConnectRequest> for requests::ConnectRequest { fn from(c: &pb::ConnectRequest) -> Self { Self { - id: hex::encode(&c.id), - host: c.host.clone(), - port: c.port.map(|v| v as u16), + id: hex::encode(&c.id), // Rule #1 for type pubkey + host: c.host.clone(), // Rule #1 for type string? + port: c.port.map(|v| v as u16), // Rule #1 for type u16? } } } @@ -538,9 +849,9 @@ impl From<&pb::ConnectRequest> for requests::ConnectRequest { impl From<&pb::CreateinvoiceRequest> for requests::CreateinvoiceRequest { fn from(c: &pb::CreateinvoiceRequest) -> Self { Self { - invstring: c.invstring.clone(), - label: c.label.clone(), - preimage: hex::encode(&c.preimage), + invstring: c.invstring.clone(), // Rule #1 for type string + label: c.label.clone(), // Rule #1 for type string + preimage: hex::encode(&c.preimage), // Rule #1 for type hex } } } @@ -550,9 +861,31 @@ impl From<&pb::DatastoreRequest> for requests::DatastoreRequest { fn from(c: &pb::DatastoreRequest) -> Self { Self { key: c.key.iter().map(|s| s.into()).collect(), - hex: c.hex.clone().map(|v| hex::encode(v)), + hex: c.hex.clone().map(|v| hex::encode(v)), // Rule #1 for type hex? mode: c.mode.map(|v| v.try_into().unwrap()), - generation: c.generation.clone(), + generation: c.generation.clone(), // Rule #1 for type u64? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::CreateonionHops> for requests::CreateonionHops { + fn from(c: &pb::CreateonionHops) -> Self { + Self { + pubkey: hex::encode(&c.pubkey), // Rule #1 for type pubkey + payload: hex::encode(&c.payload), // Rule #1 for type hex + } + } +} + +#[allow(unused_variables)] +impl From<&pb::CreateonionRequest> for requests::CreateonionRequest { + fn from(c: &pb::CreateonionRequest) -> Self { + Self { + hops: c.hops.iter().map(|s| s.into()).collect(), + assocdata: hex::encode(&c.assocdata), // Rule #1 for type hex + session_key: c.session_key.clone().map(|v| hex::encode(v)), // Rule #1 for type hex? + onion_size: c.onion_size.map(|v| v as u16), // Rule #1 for type u16? } } } @@ -562,7 +895,7 @@ impl From<&pb::DeldatastoreRequest> for requests::DeldatastoreRequest { fn from(c: &pb::DeldatastoreRequest) -> Self { Self { key: c.key.iter().map(|s| s.into()).collect(), - generation: c.generation.clone(), + generation: c.generation.clone(), // Rule #1 for type u64? } } } @@ -571,7 +904,7 @@ impl From<&pb::DeldatastoreRequest> for requests::DeldatastoreRequest { impl From<&pb::DelexpiredinvoiceRequest> for requests::DelexpiredinvoiceRequest { fn from(c: &pb::DelexpiredinvoiceRequest) -> Self { Self { - maxexpirytime: c.maxexpirytime.clone(), + maxexpirytime: c.maxexpirytime.clone(), // Rule #1 for type u32 } } } @@ -580,7 +913,7 @@ impl From<&pb::DelexpiredinvoiceRequest> for requests::DelexpiredinvoiceRequest impl From<&pb::DelinvoiceRequest> for requests::DelinvoiceRequest { fn from(c: &pb::DelinvoiceRequest) -> Self { Self { - label: c.label.clone(), + label: c.label.clone(), // Rule #1 for type string status: c.status.try_into().unwrap(), } } @@ -590,12 +923,12 @@ impl From<&pb::DelinvoiceRequest> for requests::DelinvoiceRequest { impl From<&pb::InvoiceRequest> for requests::InvoiceRequest { fn from(c: &pb::InvoiceRequest) -> Self { Self { - msatoshi: c.msatoshi.as_ref().unwrap().into(), - description: c.description.clone(), - label: c.label.clone(), + msatoshi: c.msatoshi.as_ref().unwrap().into(), // Rule #1 for type msat + description: c.description.clone(), // Rule #1 for type string + label: c.label.clone(), // Rule #1 for type string fallbacks: c.fallbacks.iter().map(|s| s.into()).collect(), - preimage: c.preimage.clone().map(|v| hex::encode(v)), - cltv: c.cltv.clone(), + preimage: c.preimage.clone().map(|v| hex::encode(v)), // Rule #1 for type hex? + cltv: c.cltv.clone(), // Rule #1 for type u32? } } } @@ -613,10 +946,129 @@ impl From<&pb::ListdatastoreRequest> for requests::ListdatastoreRequest { impl From<&pb::ListinvoicesRequest> for requests::ListinvoicesRequest { fn from(c: &pb::ListinvoicesRequest) -> Self { Self { - label: c.label.clone(), - invstring: c.invstring.clone(), - payment_hash: c.payment_hash.clone().map(|v| hex::encode(v)), - offer_id: c.offer_id.clone(), + label: c.label.clone(), // Rule #1 for type string? + invstring: c.invstring.clone(), // Rule #1 for type string? + payment_hash: c.payment_hash.clone().map(|v| hex::encode(v)), // Rule #1 for type hex? + offer_id: c.offer_id.clone(), // Rule #1 for type string? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::SendonionRequest> for requests::SendonionRequest { + fn from(c: &pb::SendonionRequest) -> Self { + Self { + onion: hex::encode(&c.onion), // Rule #1 for type hex + } + } +} + +#[allow(unused_variables)] +impl From<&pb::ListsendpaysRequest> for requests::ListsendpaysRequest { + fn from(c: &pb::ListsendpaysRequest) -> Self { + Self { + bolt11: c.bolt11.clone(), // Rule #1 for type string? + payment_hash: c.payment_hash.clone().map(|v| hex::encode(v)), // Rule #1 for type hex? + status: c.status.map(|v| v.try_into().unwrap()), + } + } +} + +#[allow(unused_variables)] +impl From<&pb::ListtransactionsRequest> for requests::ListtransactionsRequest { + fn from(c: &pb::ListtransactionsRequest) -> Self { + Self { + } + } +} + +#[allow(unused_variables)] +impl From<&pb::PayRequest> for requests::PayRequest { + fn from(c: &pb::PayRequest) -> Self { + Self { + bolt11: c.bolt11.clone(), // Rule #1 for type string + msatoshi: c.msatoshi.as_ref().map(|a| a.into()), // Rule #1 for type msat? + label: c.label.clone(), // Rule #1 for type string? + riskfactor: c.riskfactor.clone(), // Rule #1 for type float? + maxfeepercent: c.maxfeepercent.clone(), // Rule #1 for type f32? + retry_for: c.retry_for.map(|v| v as u16), // Rule #1 for type u16? + maxdelay: c.maxdelay.map(|v| v as u16), // Rule #1 for type u16? + exemptfee: c.exemptfee.clone(), // Rule #1 for type f32? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::ListnodesRequest> for requests::ListnodesRequest { + fn from(c: &pb::ListnodesRequest) -> Self { + Self { + id: c.id.clone().map(|v| hex::encode(v)), // Rule #1 for type pubkey? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::WaitanyinvoiceRequest> for requests::WaitanyinvoiceRequest { + fn from(c: &pb::WaitanyinvoiceRequest) -> Self { + Self { + lastpay_index: c.lastpay_index.clone(), // Rule #1 for type number? + timeout: c.timeout.clone(), // Rule #1 for type number? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::WaitinvoiceRequest> for requests::WaitinvoiceRequest { + fn from(c: &pb::WaitinvoiceRequest) -> Self { + Self { + label: c.label.clone(), // Rule #1 for type string + } + } +} + +#[allow(unused_variables)] +impl From<&pb::WaitsendpayRequest> for requests::WaitsendpayRequest { + fn from(c: &pb::WaitsendpayRequest) -> Self { + Self { + payment_hash: hex::encode(&c.payment_hash), // Rule #1 for type hex + partid: c.partid.map(|v| v as u16), // Rule #1 for type u16? + timeout: c.timeout.clone(), // Rule #1 for type u32? + } + } +} + +#[allow(unused_variables)] +impl From<&pb::NewaddrRequest> for requests::NewaddrRequest { + fn from(c: &pb::NewaddrRequest) -> Self { + Self { + addresstype: c.addresstype.map(|v| v.try_into().unwrap()), + } + } +} + +#[allow(unused_variables)] +impl From<&pb::WithdrawRequest> for requests::WithdrawRequest { + fn from(c: &pb::WithdrawRequest) -> Self { + Self { + destination: hex::encode(&c.destination), // Rule #1 for type pubkey + satoshi: c.satoshi.as_ref().map(|a| a.into()), // Rule #1 for type msat? + minconf: c.minconf.map(|v| v as u16), // Rule #1 for type u16? + utxos: c.utxos.iter().map(|s| s.into()).collect(), + } + } +} + +#[allow(unused_variables)] +impl From<&pb::KeysendRequest> for requests::KeysendRequest { + fn from(c: &pb::KeysendRequest) -> Self { + Self { + destination: hex::encode(&c.destination), // Rule #1 for type pubkey + msatoshi: c.msatoshi.as_ref().unwrap().into(), // Rule #1 for type msat + label: c.label.clone(), // Rule #1 for type string? + maxfeepercent: c.maxfeepercent.clone(), // Rule #1 for type float? + retry_for: c.retry_for.clone(), // Rule #1 for type number? + maxdelay: c.maxdelay.clone(), // Rule #1 for type number? + exemptfee: c.exemptfee.as_ref().map(|a| a.into()), // Rule #1 for type msat? } } } diff --git a/cln-grpc/src/pb.rs b/cln-grpc/src/pb.rs index 0e5ba33ef..ae8e8bc4b 100644 --- a/cln-grpc/src/pb.rs +++ b/cln-grpc/src/pb.rs @@ -1,6 +1,6 @@ tonic::include_proto!("cln"); -use cln_rpc::primitives::Amount as JAmount; +use cln_rpc::primitives::{Amount as JAmount, Utxo as JUtxo}; impl From for Amount { fn from(a: JAmount) -> Self { @@ -10,6 +10,24 @@ impl From for Amount { impl From<&Amount> for JAmount { fn from(a: &Amount) -> Self { - JAmount::from_msat(a.msat) + JAmount::from_msat(a.msat) + } +} + +impl From for Utxo { + fn from(a: JUtxo) -> Self { + Utxo { + txid: a.txid, + outnum: a.outnum, + } + } +} + +impl From<&Utxo> for JUtxo { + fn from(a: &Utxo) -> Self { + JUtxo { + txid: a.txid.clone(), + outnum: a.outnum, + } } } diff --git a/cln-grpc/src/server.rs b/cln-grpc/src/server.rs index fb5380460..c0039c677 100644 --- a/cln-grpc/src/server.rs +++ b/cln-grpc/src/server.rs @@ -116,6 +116,36 @@ async fn list_funds( } +async fn send_pay( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::SendpayRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::SendPay(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method SendPay: {:?}", e)))?; + match result { + Response::SendPay(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call SendPay", + r + ) + )), + } + +} + async fn list_channels( &self, request: tonic::Request, @@ -356,6 +386,36 @@ async fn datastore( } +async fn create_onion( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::CreateonionRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::CreateOnion(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method CreateOnion: {:?}", e)))?; + match result { + Response::CreateOnion(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call CreateOnion", + r + ) + )), + } + +} + async fn del_datastore( &self, request: tonic::Request, @@ -536,4 +596,334 @@ async fn list_invoices( } +async fn send_onion( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::SendonionRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::SendOnion(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method SendOnion: {:?}", e)))?; + match result { + Response::SendOnion(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call SendOnion", + r + ) + )), + } + +} + +async fn list_send_pays( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::ListsendpaysRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::ListSendPays(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method ListSendPays: {:?}", e)))?; + match result { + Response::ListSendPays(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call ListSendPays", + r + ) + )), + } + +} + +async fn list_transactions( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::ListtransactionsRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::ListTransactions(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method ListTransactions: {:?}", e)))?; + match result { + Response::ListTransactions(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call ListTransactions", + r + ) + )), + } + +} + +async fn pay( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::PayRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::Pay(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method Pay: {:?}", e)))?; + match result { + Response::Pay(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call Pay", + r + ) + )), + } + +} + +async fn list_nodes( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::ListnodesRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::ListNodes(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method ListNodes: {:?}", e)))?; + match result { + Response::ListNodes(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call ListNodes", + r + ) + )), + } + +} + +async fn wait_any_invoice( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::WaitanyinvoiceRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::WaitAnyInvoice(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method WaitAnyInvoice: {:?}", e)))?; + match result { + Response::WaitAnyInvoice(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call WaitAnyInvoice", + r + ) + )), + } + +} + +async fn wait_invoice( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::WaitinvoiceRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::WaitInvoice(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method WaitInvoice: {:?}", e)))?; + match result { + Response::WaitInvoice(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call WaitInvoice", + r + ) + )), + } + +} + +async fn wait_send_pay( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::WaitsendpayRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::WaitSendPay(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method WaitSendPay: {:?}", e)))?; + match result { + Response::WaitSendPay(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call WaitSendPay", + r + ) + )), + } + +} + +async fn new_addr( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::NewaddrRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::NewAddr(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method NewAddr: {:?}", e)))?; + match result { + Response::NewAddr(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call NewAddr", + r + ) + )), + } + +} + +async fn withdraw( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::WithdrawRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::Withdraw(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method Withdraw: {:?}", e)))?; + match result { + Response::Withdraw(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call Withdraw", + r + ) + )), + } + +} + +async fn key_send( + &self, + request: tonic::Request, +) -> Result, tonic::Status> { + let req = request.into_inner(); + let req: requests::KeysendRequest = (&req).into(); + debug!("Client asked for getinfo"); + let mut rpc = ClnRpc::new(&self.rpc_path) + .await + .map_err(|e| Status::new(Code::Internal, e.to_string()))?; + let result = rpc.call(Request::KeySend(req)) + .await + .map_err(|e| Status::new( + Code::Unknown, + format!("Error calling method KeySend: {:?}", e)))?; + match result { + Response::KeySend(r) => Ok( + tonic::Response::new((&r).into()) + ), + r => Err(Status::new( + Code::Internal, + format!( + "Unexpected result {:?} to method call KeySend", + r + ) + )), + } + +} + } diff --git a/cln-rpc/Cargo.toml b/cln-rpc/Cargo.toml index 3c8f7f6e4..6c6b789be 100644 --- a/cln-rpc/Cargo.toml +++ b/cln-rpc/Cargo.toml @@ -17,6 +17,7 @@ tokio-util = { version = "0.6.9", features = ["codec"] } tokio = { version = "1", features = ["net"]} native-tls = { version = "*", features = ["vendored"] } futures-util = { version = "*", features = [ "sink" ] } +hex = "0.4.3" [dev-dependencies] tokio = { version = "1", features = ["net", "macros", "rt-multi-thread"]} diff --git a/cln-rpc/src/model.rs b/cln-rpc/src/model.rs index 78e80f032..ac81bc0da 100644 --- a/cln-rpc/src/model.rs +++ b/cln-rpc/src/model.rs @@ -19,6 +19,7 @@ pub enum Request { Getinfo(requests::GetinfoRequest), ListPeers(requests::ListpeersRequest), ListFunds(requests::ListfundsRequest), + SendPay(requests::SendpayRequest), ListChannels(requests::ListchannelsRequest), AddGossip(requests::AddgossipRequest), AutoCleanInvoice(requests::AutocleaninvoiceRequest), @@ -27,12 +28,24 @@ pub enum Request { ConnectPeer(requests::ConnectRequest), CreateInvoice(requests::CreateinvoiceRequest), Datastore(requests::DatastoreRequest), + CreateOnion(requests::CreateonionRequest), DelDatastore(requests::DeldatastoreRequest), DelExpiredInvoice(requests::DelexpiredinvoiceRequest), DelInvoice(requests::DelinvoiceRequest), Invoice(requests::InvoiceRequest), ListDatastore(requests::ListdatastoreRequest), ListInvoices(requests::ListinvoicesRequest), + SendOnion(requests::SendonionRequest), + ListSendPays(requests::ListsendpaysRequest), + ListTransactions(requests::ListtransactionsRequest), + Pay(requests::PayRequest), + ListNodes(requests::ListnodesRequest), + WaitAnyInvoice(requests::WaitanyinvoiceRequest), + WaitInvoice(requests::WaitinvoiceRequest), + WaitSendPay(requests::WaitsendpayRequest), + NewAddr(requests::NewaddrRequest), + Withdraw(requests::WithdrawRequest), + KeySend(requests::KeysendRequest), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -42,6 +55,7 @@ pub enum Response { Getinfo(responses::GetinfoResponse), ListPeers(responses::ListpeersResponse), ListFunds(responses::ListfundsResponse), + SendPay(responses::SendpayResponse), ListChannels(responses::ListchannelsResponse), AddGossip(responses::AddgossipResponse), AutoCleanInvoice(responses::AutocleaninvoiceResponse), @@ -50,12 +64,24 @@ pub enum Response { ConnectPeer(responses::ConnectResponse), CreateInvoice(responses::CreateinvoiceResponse), Datastore(responses::DatastoreResponse), + CreateOnion(responses::CreateonionResponse), DelDatastore(responses::DeldatastoreResponse), DelExpiredInvoice(responses::DelexpiredinvoiceResponse), DelInvoice(responses::DelinvoiceResponse), Invoice(responses::InvoiceResponse), ListDatastore(responses::ListdatastoreResponse), ListInvoices(responses::ListinvoicesResponse), + SendOnion(responses::SendonionResponse), + ListSendPays(responses::ListsendpaysResponse), + ListTransactions(responses::ListtransactionsResponse), + Pay(responses::PayResponse), + ListNodes(responses::ListnodesResponse), + WaitAnyInvoice(responses::WaitanyinvoiceResponse), + WaitInvoice(responses::WaitinvoiceResponse), + WaitSendPay(responses::WaitsendpayResponse), + NewAddr(responses::NewaddrResponse), + Withdraw(responses::WithdrawResponse), + KeySend(responses::KeysendResponse), } pub mod requests { @@ -82,6 +108,36 @@ pub mod requests { pub spent: Option, } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct SendpayRoute { + #[serde(alias = "msatoshi")] + pub msatoshi: Amount, + #[serde(alias = "id")] + pub id: String, + #[serde(alias = "delay")] + pub delay: u16, + #[serde(alias = "channel")] + pub channel: String, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct SendpayRequest { + #[serde(alias = "route")] + pub route: Vec, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "msatoshi", skip_serializing_if = "Option::is_none")] + pub msatoshi: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "payment_secret", skip_serializing_if = "Option::is_none")] + pub payment_secret: Option, + #[serde(alias = "partid", skip_serializing_if = "Option::is_none")] + pub partid: Option, + } + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ListchannelsRequest { #[serde(alias = "short_channel_id", skip_serializing_if = "Option::is_none")] @@ -186,6 +242,26 @@ pub mod requests { pub generation: Option, } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct CreateonionHops { + #[serde(alias = "pubkey")] + pub pubkey: String, + #[serde(alias = "payload")] + pub payload: String, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct CreateonionRequest { + #[serde(alias = "hops")] + pub hops: Vec, + #[serde(alias = "assocdata")] + pub assocdata: String, + #[serde(alias = "session_key", skip_serializing_if = "Option::is_none")] + pub session_key: Option, + #[serde(alias = "onion_size", skip_serializing_if = "Option::is_none")] + pub onion_size: Option, + } + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DeldatastoreRequest { #[serde(alias = "key")] @@ -262,6 +338,156 @@ pub mod requests { pub offer_id: Option, } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct SendonionFirst_hop { + #[serde(alias = "id")] + pub id: String, + #[serde(alias = "amount_msat")] + pub amount_msat: Amount, + #[serde(alias = "delay")] + pub delay: u16, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct SendonionRequest { + #[serde(alias = "onion")] + pub onion: String, + } + + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ListsendpaysStatus { + PENDING, + COMPLETE, + FAILED, + } + + impl TryFrom for ListsendpaysStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(ListsendpaysStatus::PENDING), + 1 => Ok(ListsendpaysStatus::COMPLETE), + 2 => Ok(ListsendpaysStatus::FAILED), + o => Err(anyhow::anyhow!("Unknown variant {} for enum ListsendpaysStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListsendpaysRequest { + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "payment_hash", skip_serializing_if = "Option::is_none")] + pub payment_hash: Option, + pub status: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListtransactionsRequest { + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct PayRequest { + #[serde(alias = "bolt11")] + pub bolt11: String, + #[serde(alias = "msatoshi", skip_serializing_if = "Option::is_none")] + pub msatoshi: Option, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "riskfactor", skip_serializing_if = "Option::is_none")] + pub riskfactor: Option, + #[serde(alias = "maxfeepercent", skip_serializing_if = "Option::is_none")] + pub maxfeepercent: Option, + #[serde(alias = "retry_for", skip_serializing_if = "Option::is_none")] + pub retry_for: Option, + #[serde(alias = "maxdelay", skip_serializing_if = "Option::is_none")] + pub maxdelay: Option, + #[serde(alias = "exemptfee", skip_serializing_if = "Option::is_none")] + pub exemptfee: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListnodesRequest { + #[serde(alias = "id", skip_serializing_if = "Option::is_none")] + pub id: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WaitanyinvoiceRequest { + #[serde(alias = "lastpay_index", skip_serializing_if = "Option::is_none")] + pub lastpay_index: Option, + #[serde(alias = "timeout", skip_serializing_if = "Option::is_none")] + pub timeout: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WaitinvoiceRequest { + #[serde(alias = "label")] + pub label: String, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WaitsendpayRequest { + #[serde(alias = "payment_hash")] + pub payment_hash: String, + #[serde(alias = "partid", skip_serializing_if = "Option::is_none")] + pub partid: Option, + #[serde(alias = "timeout", skip_serializing_if = "Option::is_none")] + pub timeout: Option, + } + + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum NewaddrAddresstype { + BECH32, + P2SH_SEGWIT, + } + + impl TryFrom for NewaddrAddresstype { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(NewaddrAddresstype::BECH32), + 1 => Ok(NewaddrAddresstype::P2SH_SEGWIT), + o => Err(anyhow::anyhow!("Unknown variant {} for enum NewaddrAddresstype", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct NewaddrRequest { + pub addresstype: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WithdrawRequest { + #[serde(alias = "destination")] + pub destination: String, + #[serde(alias = "satoshi", skip_serializing_if = "Option::is_none")] + pub satoshi: Option, + #[serde(alias = "minconf", skip_serializing_if = "Option::is_none")] + pub minconf: Option, + #[serde(alias = "utxos")] + pub utxos: Vec, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct KeysendRequest { + #[serde(alias = "destination")] + pub destination: String, + #[serde(alias = "msatoshi")] + pub msatoshi: Amount, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "maxfeepercent", skip_serializing_if = "Option::is_none")] + pub maxfeepercent: Option, + #[serde(alias = "retry_for", skip_serializing_if = "Option::is_none")] + pub retry_for: Option, + #[serde(alias = "maxdelay", skip_serializing_if = "Option::is_none")] + pub maxdelay: Option, + #[serde(alias = "exemptfee", skip_serializing_if = "Option::is_none")] + pub exemptfee: Option, + } + } @@ -786,6 +1012,57 @@ pub mod responses { pub channels: Vec, } + /// status of the payment (could be complete if already sent previously) + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum SendpayStatus { + PENDING, + COMPLETE, + } + + impl TryFrom for SendpayStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(SendpayStatus::PENDING), + 1 => Ok(SendpayStatus::COMPLETE), + o => Err(anyhow::anyhow!("Unknown variant {} for enum SendpayStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct SendpayResponse { + #[serde(alias = "id")] + pub id: u64, + #[serde(alias = "groupid", skip_serializing_if = "Option::is_none")] + pub groupid: Option, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + // Path `SendPay.status` + #[serde(rename = "status")] + pub status: SendpayStatus, + #[serde(alias = "amount_msat", skip_serializing_if = "Option::is_none")] + pub amount_msat: Option, + #[serde(alias = "destination", skip_serializing_if = "Option::is_none")] + pub destination: Option, + #[serde(alias = "created_at")] + pub created_at: u64, + #[serde(alias = "amount_sent_msat")] + pub amount_sent_msat: Amount, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "partid", skip_serializing_if = "Option::is_none")] + pub partid: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "bolt12", skip_serializing_if = "Option::is_none")] + pub bolt12: Option, + #[serde(alias = "payment_preimage", skip_serializing_if = "Option::is_none")] + pub payment_preimage: Option, + #[serde(alias = "message", skip_serializing_if = "Option::is_none")] + pub message: Option, + } + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ListchannelsChannels { #[serde(alias = "source")] @@ -1010,6 +1287,14 @@ pub mod responses { pub string: Option, } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct CreateonionResponse { + #[serde(alias = "onion")] + pub onion: String, + #[serde(alias = "shared_secrets")] + pub shared_secrets: Vec, + } + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DeldatastoreResponse { #[serde(alias = "key")] @@ -1170,5 +1455,535 @@ pub mod responses { pub invoices: Vec, } + /// status of the payment (could be complete if already sent previously) + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum SendonionStatus { + PENDING, + COMPLETE, + } + + impl TryFrom for SendonionStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(SendonionStatus::PENDING), + 1 => Ok(SendonionStatus::COMPLETE), + o => Err(anyhow::anyhow!("Unknown variant {} for enum SendonionStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct SendonionResponse { + #[serde(alias = "id")] + pub id: u64, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + // Path `SendOnion.status` + #[serde(rename = "status")] + pub status: SendonionStatus, + #[serde(alias = "amount_msat", skip_serializing_if = "Option::is_none")] + pub amount_msat: Option, + #[serde(alias = "destination", skip_serializing_if = "Option::is_none")] + pub destination: Option, + #[serde(alias = "created_at")] + pub created_at: u64, + #[serde(alias = "amount_sent_msat")] + pub amount_sent_msat: Amount, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "bolt12", skip_serializing_if = "Option::is_none")] + pub bolt12: Option, + #[serde(alias = "payment_preimage", skip_serializing_if = "Option::is_none")] + pub payment_preimage: Option, + #[serde(alias = "message", skip_serializing_if = "Option::is_none")] + pub message: Option, + } + + /// status of the payment + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ListsendpaysPaymentsStatus { + PENDING, + FAILED, + COMPLETE, + } + + impl TryFrom for ListsendpaysPaymentsStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(ListsendpaysPaymentsStatus::PENDING), + 1 => Ok(ListsendpaysPaymentsStatus::FAILED), + 2 => Ok(ListsendpaysPaymentsStatus::COMPLETE), + o => Err(anyhow::anyhow!("Unknown variant {} for enum ListsendpaysPaymentsStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListsendpaysPayments { + #[serde(alias = "id")] + pub id: u64, + #[serde(alias = "groupid", skip_serializing_if = "Option::is_none")] + pub groupid: Option, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + // Path `ListSendPays.payments[].status` + #[serde(rename = "status")] + pub status: ListsendpaysPaymentsStatus, + #[serde(alias = "amount_msat", skip_serializing_if = "Option::is_none")] + pub amount_msat: Option, + #[serde(alias = "destination", skip_serializing_if = "Option::is_none")] + pub destination: Option, + #[serde(alias = "created_at")] + pub created_at: u64, + #[serde(alias = "amount_sent_msat")] + pub amount_sent_msat: Amount, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "bolt12", skip_serializing_if = "Option::is_none")] + pub bolt12: Option, + #[serde(alias = "payment_preimage", skip_serializing_if = "Option::is_none")] + pub payment_preimage: Option, + #[serde(alias = "erroronion", skip_serializing_if = "Option::is_none")] + pub erroronion: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListsendpaysResponse { + #[serde(alias = "payments")] + pub payments: Vec, + } + + /// the purpose of this input (*EXPERIMENTAL_FEATURES* only) + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ListtransactionsTransactionsInputsType { + THEIRS, + DEPOSIT, + WITHDRAW, + CHANNEL_FUNDING, + CHANNEL_MUTUAL_CLOSE, + CHANNEL_UNILATERAL_CLOSE, + CHANNEL_SWEEP, + CHANNEL_HTLC_SUCCESS, + CHANNEL_HTLC_TIMEOUT, + CHANNEL_PENALTY, + CHANNEL_UNILATERAL_CHEAT, + } + + impl TryFrom for ListtransactionsTransactionsInputsType { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(ListtransactionsTransactionsInputsType::THEIRS), + 1 => Ok(ListtransactionsTransactionsInputsType::DEPOSIT), + 2 => Ok(ListtransactionsTransactionsInputsType::WITHDRAW), + 3 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_FUNDING), + 4 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_MUTUAL_CLOSE), + 5 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_UNILATERAL_CLOSE), + 6 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_SWEEP), + 7 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_HTLC_SUCCESS), + 8 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_HTLC_TIMEOUT), + 9 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_PENALTY), + 10 => Ok(ListtransactionsTransactionsInputsType::CHANNEL_UNILATERAL_CHEAT), + o => Err(anyhow::anyhow!("Unknown variant {} for enum ListtransactionsTransactionsInputsType", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListtransactionsTransactionsInputs { + #[serde(alias = "txid")] + pub txid: String, + #[serde(alias = "index")] + pub index: u32, + #[serde(alias = "sequence")] + pub sequence: u32, + pub item_type: Option, + #[serde(alias = "channel", skip_serializing_if = "Option::is_none")] + pub channel: Option, + } + + /// the purpose of this output (*EXPERIMENTAL_FEATURES* only) + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ListtransactionsTransactionsOutputsType { + THEIRS, + DEPOSIT, + WITHDRAW, + CHANNEL_FUNDING, + CHANNEL_MUTUAL_CLOSE, + CHANNEL_UNILATERAL_CLOSE, + CHANNEL_SWEEP, + CHANNEL_HTLC_SUCCESS, + CHANNEL_HTLC_TIMEOUT, + CHANNEL_PENALTY, + CHANNEL_UNILATERAL_CHEAT, + } + + impl TryFrom for ListtransactionsTransactionsOutputsType { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(ListtransactionsTransactionsOutputsType::THEIRS), + 1 => Ok(ListtransactionsTransactionsOutputsType::DEPOSIT), + 2 => Ok(ListtransactionsTransactionsOutputsType::WITHDRAW), + 3 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_FUNDING), + 4 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_MUTUAL_CLOSE), + 5 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_UNILATERAL_CLOSE), + 6 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_SWEEP), + 7 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_HTLC_SUCCESS), + 8 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_HTLC_TIMEOUT), + 9 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_PENALTY), + 10 => Ok(ListtransactionsTransactionsOutputsType::CHANNEL_UNILATERAL_CHEAT), + o => Err(anyhow::anyhow!("Unknown variant {} for enum ListtransactionsTransactionsOutputsType", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListtransactionsTransactionsOutputs { + #[serde(alias = "index")] + pub index: u32, + #[serde(alias = "msat")] + pub msat: Amount, + #[serde(alias = "scriptPubKey")] + pub script_pub_key: String, + pub item_type: Option, + #[serde(alias = "channel", skip_serializing_if = "Option::is_none")] + pub channel: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListtransactionsTransactions { + #[serde(alias = "hash")] + pub hash: String, + #[serde(alias = "rawtx")] + pub rawtx: String, + #[serde(alias = "blockheight")] + pub blockheight: u32, + #[serde(alias = "txindex")] + pub txindex: u32, + #[serde(alias = "channel", skip_serializing_if = "Option::is_none")] + pub channel: Option, + #[serde(alias = "locktime")] + pub locktime: u32, + #[serde(alias = "version")] + pub version: u32, + #[serde(alias = "inputs")] + pub inputs: Vec, + #[serde(alias = "outputs")] + pub outputs: Vec, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListtransactionsResponse { + #[serde(alias = "transactions")] + pub transactions: Vec, + } + + /// status of payment + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum PayStatus { + COMPLETE, + PENDING, + FAILED, + } + + impl TryFrom for PayStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(PayStatus::COMPLETE), + 1 => Ok(PayStatus::PENDING), + 2 => Ok(PayStatus::FAILED), + o => Err(anyhow::anyhow!("Unknown variant {} for enum PayStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct PayResponse { + #[serde(alias = "payment_preimage")] + pub payment_preimage: String, + #[serde(alias = "destination", skip_serializing_if = "Option::is_none")] + pub destination: Option, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + #[serde(alias = "created_at")] + pub created_at: i64, + #[serde(alias = "parts")] + pub parts: u32, + #[serde(alias = "amount_msat")] + pub amount_msat: Amount, + #[serde(alias = "amount_sent_msat")] + pub amount_sent_msat: Amount, + #[serde(alias = "warning_partial_completion", skip_serializing_if = "Option::is_none")] + pub warning_partial_completion: Option, + // Path `Pay.status` + #[serde(rename = "status")] + pub status: PayStatus, + } + + /// Type of connection + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum ListnodesNodesAddressesType { + DNS, + IPV4, + IPV6, + TORV2, + TORV3, + WEBSOCKET, + } + + impl TryFrom for ListnodesNodesAddressesType { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(ListnodesNodesAddressesType::DNS), + 1 => Ok(ListnodesNodesAddressesType::IPV4), + 2 => Ok(ListnodesNodesAddressesType::IPV6), + 3 => Ok(ListnodesNodesAddressesType::TORV2), + 4 => Ok(ListnodesNodesAddressesType::TORV3), + 5 => Ok(ListnodesNodesAddressesType::WEBSOCKET), + o => Err(anyhow::anyhow!("Unknown variant {} for enum ListnodesNodesAddressesType", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListnodesNodesAddresses { + // Path `ListNodes.nodes[].addresses[].type` + #[serde(rename = "type")] + pub item_type: ListnodesNodesAddressesType, + #[serde(alias = "port")] + pub port: u16, + #[serde(alias = "address", skip_serializing_if = "Option::is_none")] + pub address: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListnodesNodes { + #[serde(alias = "nodeid")] + pub nodeid: String, + #[serde(alias = "last_timestamp", skip_serializing_if = "Option::is_none")] + pub last_timestamp: Option, + #[serde(alias = "alias", skip_serializing_if = "Option::is_none")] + pub alias: Option, + #[serde(alias = "color", skip_serializing_if = "Option::is_none")] + pub color: Option, + #[serde(alias = "features", skip_serializing_if = "Option::is_none")] + pub features: Option, + #[serde(alias = "addresses")] + pub addresses: Vec, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct ListnodesResponse { + #[serde(alias = "nodes")] + pub nodes: Vec, + } + + /// Whether it's paid or expired + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum WaitanyinvoiceStatus { + PAID, + EXPIRED, + } + + impl TryFrom for WaitanyinvoiceStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(WaitanyinvoiceStatus::PAID), + 1 => Ok(WaitanyinvoiceStatus::EXPIRED), + o => Err(anyhow::anyhow!("Unknown variant {} for enum WaitanyinvoiceStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WaitanyinvoiceResponse { + #[serde(alias = "label")] + pub label: String, + #[serde(alias = "description")] + pub description: String, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + // Path `WaitAnyInvoice.status` + #[serde(rename = "status")] + pub status: WaitanyinvoiceStatus, + #[serde(alias = "expires_at")] + pub expires_at: u64, + #[serde(alias = "amount_msat", skip_serializing_if = "Option::is_none")] + pub amount_msat: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "bolt12", skip_serializing_if = "Option::is_none")] + pub bolt12: Option, + #[serde(alias = "pay_index", skip_serializing_if = "Option::is_none")] + pub pay_index: Option, + #[serde(alias = "amount_received_msat", skip_serializing_if = "Option::is_none")] + pub amount_received_msat: Option, + #[serde(alias = "paid_at", skip_serializing_if = "Option::is_none")] + pub paid_at: Option, + #[serde(alias = "payment_preimage", skip_serializing_if = "Option::is_none")] + pub payment_preimage: Option, + } + + /// Whether it's paid or expired + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum WaitinvoiceStatus { + PAID, + EXPIRED, + } + + impl TryFrom for WaitinvoiceStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(WaitinvoiceStatus::PAID), + 1 => Ok(WaitinvoiceStatus::EXPIRED), + o => Err(anyhow::anyhow!("Unknown variant {} for enum WaitinvoiceStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WaitinvoiceResponse { + #[serde(alias = "label")] + pub label: String, + #[serde(alias = "description")] + pub description: String, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + // Path `WaitInvoice.status` + #[serde(rename = "status")] + pub status: WaitinvoiceStatus, + #[serde(alias = "expires_at")] + pub expires_at: u64, + #[serde(alias = "amount_msat", skip_serializing_if = "Option::is_none")] + pub amount_msat: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "bolt12", skip_serializing_if = "Option::is_none")] + pub bolt12: Option, + #[serde(alias = "pay_index", skip_serializing_if = "Option::is_none")] + pub pay_index: Option, + #[serde(alias = "amount_received_msat", skip_serializing_if = "Option::is_none")] + pub amount_received_msat: Option, + #[serde(alias = "paid_at", skip_serializing_if = "Option::is_none")] + pub paid_at: Option, + #[serde(alias = "payment_preimage", skip_serializing_if = "Option::is_none")] + pub payment_preimage: Option, + } + + /// status of the payment + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum WaitsendpayStatus { + COMPLETE, + } + + impl TryFrom for WaitsendpayStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(WaitsendpayStatus::COMPLETE), + o => Err(anyhow::anyhow!("Unknown variant {} for enum WaitsendpayStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WaitsendpayResponse { + #[serde(alias = "id")] + pub id: u64, + #[serde(alias = "groupid", skip_serializing_if = "Option::is_none")] + pub groupid: Option, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + // Path `WaitSendPay.status` + #[serde(rename = "status")] + pub status: WaitsendpayStatus, + #[serde(alias = "amount_msat", skip_serializing_if = "Option::is_none")] + pub amount_msat: Option, + #[serde(alias = "destination", skip_serializing_if = "Option::is_none")] + pub destination: Option, + #[serde(alias = "created_at")] + pub created_at: u64, + #[serde(alias = "amount_sent_msat")] + pub amount_sent_msat: Amount, + #[serde(alias = "label", skip_serializing_if = "Option::is_none")] + pub label: Option, + #[serde(alias = "partid", skip_serializing_if = "Option::is_none")] + pub partid: Option, + #[serde(alias = "bolt11", skip_serializing_if = "Option::is_none")] + pub bolt11: Option, + #[serde(alias = "bolt12", skip_serializing_if = "Option::is_none")] + pub bolt12: Option, + #[serde(alias = "payment_preimage", skip_serializing_if = "Option::is_none")] + pub payment_preimage: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct NewaddrResponse { + #[serde(alias = "bech32", skip_serializing_if = "Option::is_none")] + pub bech32: Option, + #[serde(alias = "p2sh-segwit", skip_serializing_if = "Option::is_none")] + pub p2sh_segwit: Option, + } + + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct WithdrawResponse { + #[serde(alias = "tx")] + pub tx: String, + #[serde(alias = "txid")] + pub txid: String, + #[serde(alias = "psbt")] + pub psbt: String, + } + + /// status of payment + #[derive(Copy, Clone, Debug, Deserialize, Serialize)] + #[serde(rename_all = "lowercase")] + pub enum KeysendStatus { + COMPLETE, + } + + impl TryFrom for KeysendStatus { + type Error = anyhow::Error; + fn try_from(c: i32) -> Result { + match c { + 0 => Ok(KeysendStatus::COMPLETE), + o => Err(anyhow::anyhow!("Unknown variant {} for enum KeysendStatus", o)), + } + } + } + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct KeysendResponse { + #[serde(alias = "payment_preimage")] + pub payment_preimage: String, + #[serde(alias = "destination", skip_serializing_if = "Option::is_none")] + pub destination: Option, + #[serde(alias = "payment_hash")] + pub payment_hash: String, + #[serde(alias = "created_at")] + pub created_at: i64, + #[serde(alias = "parts")] + pub parts: u32, + #[serde(alias = "amount_msat")] + pub amount_msat: Amount, + #[serde(alias = "amount_sent_msat")] + pub amount_sent_msat: Amount, + #[serde(alias = "warning_partial_completion", skip_serializing_if = "Option::is_none")] + pub warning_partial_completion: Option, + // Path `KeySend.status` + #[serde(rename = "status")] + pub status: KeysendStatus, + } + } diff --git a/cln-rpc/src/primitives.rs b/cln-rpc/src/primitives.rs index a3317d415..8f7daacf7 100644 --- a/cln-rpc/src/primitives.rs +++ b/cln-rpc/src/primitives.rs @@ -68,6 +68,44 @@ impl Amount { } } +#[derive(Clone, Debug, PartialEq)] +pub struct Utxo { + pub txid: Vec, + pub outnum: u32, +} + +impl Serialize for Utxo { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&format!("{}:{}", hex::encode(&self.txid), self.outnum)) + } +} + +impl<'de> Deserialize<'de> for Utxo { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + use serde::de::Error; + let s: String = Deserialize::deserialize(deserializer)?; + + let splits: Vec<&str> = s.split(':').collect(); + if splits.len() != 2 { + return Err(Error::custom("not a valid txid:output tuple")); + } + + let txid = + hex::decode(splits[0]).map_err(|_| Error::custom("not a valid hex encoded txid"))?; + let outnum: u32 = splits[1] + .parse() + .map_err(|e| Error::custom(format!("{} is not a valid number: {}", s, e)))?; + + Ok(Utxo { txid, outnum }) + } +} + #[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)] pub enum ChannelSide { LOCAL, diff --git a/contrib/msggen/msggen/__main__.py b/contrib/msggen/msggen/__main__.py index da2865d3a..766aa3680 100644 --- a/contrib/msggen/msggen/__main__.py +++ b/contrib/msggen/msggen/__main__.py @@ -43,22 +43,35 @@ def load_jsonrpc_service(): "Getinfo", "ListPeers", "ListFunds", - # "ListConfigs", + "SendPay", "ListChannels", "AddGossip", "AutoCleanInvoice", "CheckMessage", - # "check", # No point in mapping this one "Close", "Connect", "CreateInvoice", - # "createonion", "Datastore", - # "decodepay", - # "decode", + "CreateOnion", "DelDatastore", "DelExpiredInvoice", "DelInvoice", + "Invoice", + "ListDatastore", + "ListInvoices", + "SendOnion", + "ListSendPays", + "ListTransactions", + "Pay", + "ListNodes", + "WaitAnyInvoice", + "WaitInvoice", + "WaitSendPay", + "NewAddr", + "Withdraw", + "KeySend", + # "decodepay", + # "decode", # "delpay", # "disableoffer", # "disconnect", @@ -70,28 +83,15 @@ def load_jsonrpc_service(): # "fundchannel_start", # "funderupdate", # "fundpsbt", - # "getinfo", # "getlog", # "getroute", # "getsharedsecret", - # "help", - "Invoice", - # "keysend", - # "listchannels", # "listconfigs", - "ListDatastore", # "listforwards", - # "listfunds", - "ListInvoices", - # "listnodes", # "listoffers", # "listpays", - # "listsendpays", - # "listtransactions", # "multifundchannel", # "multiwithdraw", - # "newaddr", - # "notifications", # "offerout", # "offer", # "openchannel_abort", @@ -100,30 +100,27 @@ def load_jsonrpc_service(): # "openchannel_signed", # "openchannel_update", # "parsefeerate", - # "pay", # "ping", # "plugin", # "reserveinputs", # "sendcustommsg", # "sendinvoice", # "sendonionmessage", - # "sendonion", - # "sendpay", # "sendpsbt", # "setchannelfee", # "signmessage", # "signpsbt", - # "stop", # "txdiscard", # "txprepare", # "txsend", # "unreserveinputs", - # "utxopsbt", - # "waitanyinvoice", # "waitblockheight", - # "waitinvoice", - # "waitsendpay", - # "withdraw", + # "ListConfigs", + # "check", # No point in mapping this one + # "Stop", # Breaks a core assumption (root is an object) can't map unless we change this + # "UtxoPsbt", # Breaks since the utxos array has dynamic keys which we can't map as is + # "notifications", # No point in mapping this + # "help", ] methods = [load_jsonrpc_method(name) for name in method_names] service = Service(name="Node", methods=methods) diff --git a/contrib/msggen/msggen/grpc.py b/contrib/msggen/msggen/grpc.py index ea37250a3..ad1f28181 100644 --- a/contrib/msggen/msggen/grpc.py +++ b/contrib/msggen/msggen/grpc.py @@ -20,7 +20,9 @@ typemap = { 'u32': 'uint32', 'u64': 'uint64', 'u16': 'uint32', # Yeah, I know... + 'f32': 'float', 'integer': 'sint64', + "utxo": "Utxo", } @@ -33,6 +35,7 @@ overrides = { 'ListPeers.peers[].channels[].closer': "ChannelSide", 'ListPeers.peers[].channels[].features[]': "string", 'ListFunds.channels[].state': 'ChannelState', + 'ListTransactions.transactions[].type[]': None, } method_name_overrides = { @@ -258,6 +261,7 @@ class GrpcConverterGenerator: continue name = f.normalized() + name = re.sub(r'(? {name} ({a.path})") - _, decl = gen_field(a.itemtype) if isinstance(a.itemtype, PrimitiveField): @@ -152,6 +156,9 @@ def gen_array(a): decl = "" # No declaration if we have an override itemtype = overrides[a.path] + if itemtype is None: + return ("", "") # Override said not to include + itemtype = typemap.get(itemtype, itemtype) alias = a.name.normalized()[:-2] # Strip the `[]` suffix for arrays. defi = f" #[serde(alias = \"{alias}\")]\n pub {name}: {'Vec<'*a.dims}{itemtype}{'>'*a.dims},\n" diff --git a/doc/lightning-pay.7.md b/doc/lightning-pay.7.md index ed8156015..e8dc09d08 100644 --- a/doc/lightning-pay.7.md +++ b/doc/lightning-pay.7.md @@ -84,7 +84,7 @@ On success, an object is returned, containing: - **parts** (u32): how many attempts this took - **amount_msat** (msat): Amount the recipient received - **amount_sent_msat** (msat): Total amount we sent (including fees) -- **status** (string): status of payment (always "complete") +- **status** (string): status of payment (one of "complete", "pending", "failed") - **destination** (pubkey, optional): the final destination of the payment The following warnings may also be returned: @@ -149,4 +149,4 @@ RESOURCES Main web site: -[comment]: # ( SHA256STAMP:bf507985544575c4ef2fe194fda6a693378cb8ab3bfb30ca7a7c066be271be29) +[comment]: # ( SHA256STAMP:e537b9c74918559db99e673fac63cfa43a347ab80c32f33012ab3655b9edc45e) diff --git a/doc/schemas/createonion.request.json b/doc/schemas/createonion.request.json new file mode 100644 index 000000000..656023f4e --- /dev/null +++ b/doc/schemas/createonion.request.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "hops", + "assocdata" + ], + "properties": { + "hops": { + "type": "array", + "description": "", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "pubkey", + "payload" + ], + "properties": { + "pubkey": { + "type": "pubkey" + }, + "payload": { + "type": "hex" + } + } + } + }, + "assocdata": { + "type": "hex", + "description": "" + }, + "session_key": { + "type": "hex" + }, + "onion_size": { + "type": "u16" + } + } +} diff --git a/doc/schemas/keysend.request.json b/doc/schemas/keysend.request.json new file mode 100644 index 000000000..b8e6f3242 --- /dev/null +++ b/doc/schemas/keysend.request.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "destination", + "msatoshi" + ], + "properties": { + "destination": { + "type": "pubkey" + }, + "msatoshi": { + "type": "msat" + }, + "label": { + "type": "string" + }, + "maxfeepercent": { + "type": "float" + }, + "retry_for": { + "type": "number" + }, + "maxdelay": { + "type": "number" + }, + "exemptfee": { + "type": "msat" + } + } +} diff --git a/doc/schemas/listnodes.request.json b/doc/schemas/listnodes.request.json new file mode 100644 index 000000000..75e30b4b3 --- /dev/null +++ b/doc/schemas/listnodes.request.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [], + "properties": { + "id": { + "type": "pubkey" + } + } +} diff --git a/doc/schemas/listsendpays.request.json b/doc/schemas/listsendpays.request.json new file mode 100644 index 000000000..0ed227e81 --- /dev/null +++ b/doc/schemas/listsendpays.request.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [], + "properties": { + "bolt11": { + "type": "string" + }, + "payment_hash": { + "type": "hex" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "complete", + "failed" + ] + } + } +} diff --git a/doc/schemas/listtransactions.request.json b/doc/schemas/listtransactions.request.json new file mode 100644 index 000000000..f99496c5a --- /dev/null +++ b/doc/schemas/listtransactions.request.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [], + "additionalProperties": false, + "properties": {} +} diff --git a/doc/schemas/newaddr.request.json b/doc/schemas/newaddr.request.json new file mode 100644 index 000000000..94eebe44f --- /dev/null +++ b/doc/schemas/newaddr.request.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [], + "properties": { + "addresstype": { + "type": "string", + "enum": [ + "bech32", + "p2sh-segwit" + ] + } + } +} diff --git a/doc/schemas/pay.request.json b/doc/schemas/pay.request.json new file mode 100644 index 000000000..e2c939b1b --- /dev/null +++ b/doc/schemas/pay.request.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "bolt11" + ], + "properties": { + "bolt11": { + "type": "string" + }, + "msatoshi": { + "type": "msat" + }, + "label": { + "type": "string" + }, + "riskfactor": { + "type": "float" + }, + "maxfeepercent": { + "type": "f32" + }, + "retry_for": { + "type": "u16" + }, + "maxdelay": { + "type": "u16" + }, + "exemptfee": { + "type": "f32" + } + } +} diff --git a/doc/schemas/pay.schema.json b/doc/schemas/pay.schema.json index 1a4f395f9..6c80bb316 100644 --- a/doc/schemas/pay.schema.json +++ b/doc/schemas/pay.schema.json @@ -57,7 +57,9 @@ "status": { "type": "string", "enum": [ - "complete" + "complete", + "pending", + "failed" ], "description": "status of payment" } diff --git a/doc/schemas/sendonion.request.json b/doc/schemas/sendonion.request.json new file mode 100644 index 000000000..884ce85c4 --- /dev/null +++ b/doc/schemas/sendonion.request.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "onion", + "first_hop", + "payment_hash" + ], + "properties": { + "onion": { + "type": "hex" + }, + "first_hop": { + "type": "object", + "required": [ + "id", + "amount_msat", + "delay" + ], + "properties": { + "id": { + "type": "pubkey" + }, + "amount_msat": { + "type": "msat" + }, + "delay": { + "type": "u16" + } + }, + "payment_hash": { + "type": "hex" + }, + "label": { + "type": "string" + }, + "shared_secrets": { + "type": "array", + "itemtype": { + "type": "hex" + } + }, + "partid": { + "type": "u16" + }, + "bolt11": { + "type": "string" + }, + "msatoshi": { + "type": "msat" + }, + "destination": { + "type": "pubkey" + } + } + } +} diff --git a/doc/schemas/sendpay.request.json b/doc/schemas/sendpay.request.json new file mode 100644 index 000000000..541ac2666 --- /dev/null +++ b/doc/schemas/sendpay.request.json @@ -0,0 +1,54 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "route", + "payment_hash" + ], + "properties": { + "route": { + "type": "array", + "items": { + "type": "object", + "required": [ + "msatoshi", + "id", + "delay", + "channel" + ], + "properties": { + "msatoshi": { + "type": "msat" + }, + "id": { + "type": "pubkey" + }, + "delay": { + "type": "u16" + }, + "channel": { + "type": "short_channel_id" + } + } + } + }, + "payment_hash": { + "type": "hex" + }, + "label": { + "type": "string" + }, + "msatoshi": { + "type": "msat" + }, + "bolt11": { + "type": "string" + }, + "payment_secret": { + "type": "hex" + }, + "partid": { + "type": "u16" + } + } +} diff --git a/doc/schemas/waitanyinvoice.request.json b/doc/schemas/waitanyinvoice.request.json new file mode 100644 index 000000000..ed73b9db1 --- /dev/null +++ b/doc/schemas/waitanyinvoice.request.json @@ -0,0 +1,13 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [], + "properties": { + "lastpay_index": { + "type": "number" + }, + "timeout": { + "type": "number" + } + } +} diff --git a/doc/schemas/waitinvoice.request.json b/doc/schemas/waitinvoice.request.json new file mode 100644 index 000000000..b3ceab08d --- /dev/null +++ b/doc/schemas/waitinvoice.request.json @@ -0,0 +1,12 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "label" + ], + "properties": { + "label": { + "type": "string" + } + } +} diff --git a/doc/schemas/waitsendpay.request.json b/doc/schemas/waitsendpay.request.json new file mode 100644 index 000000000..833a929dd --- /dev/null +++ b/doc/schemas/waitsendpay.request.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "payment_hash" + ], + "properties": { + "payment_hash": { + "type": "hex" + }, + "partid": { + "type": "u16" + }, + "timeout": { + "type": "u32" + } + } +} diff --git a/doc/schemas/withdraw.request.json b/doc/schemas/withdraw.request.json new file mode 100644 index 000000000..d098171c8 --- /dev/null +++ b/doc/schemas/withdraw.request.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "required": [ + "destination" + ], + "properties": { + "destination": { + "type": "pubkey" + }, + "satoshi": { + "type": "msat" + }, + "feerate": { + "type": "feerate" + }, + "minconf": { + "type": "u16" + }, + "utxos": { + "type": "array", + "items": { + "type": "utxo" + } + } + } +}