cln-rpc: Map PSBT and TX methods

This commit is contained in:
Christian Decker 2022-04-01 14:42:45 +10:30 committed by Rusty Russell
parent 0354a7fdb1
commit 04e7e285d7
14 changed files with 944 additions and 4 deletions

View file

@ -300,6 +300,30 @@
"DelInvoice.payment_hash": 6, "DelInvoice.payment_hash": 6,
"DelInvoice.status": 7 "DelInvoice.status": 7
}, },
"FundpsbtRequest": {
"FundPsbt.feerate": 2,
"FundPsbt.locktime": 6,
"FundPsbt.min_witness_weight": 7,
"FundPsbt.minconf": 4,
"FundPsbt.reserve": 5,
"FundPsbt.satoshi": 1,
"FundPsbt.startweight": 3
},
"FundpsbtReservations": {
"FundPsbt.reservations[].reserved": 4,
"FundPsbt.reservations[].reserved_to_block": 5,
"FundPsbt.reservations[].txid": 1,
"FundPsbt.reservations[].vout": 2,
"FundPsbt.reservations[].was_reserved": 3
},
"FundpsbtResponse": {
"FundPsbt.change_outnum": 5,
"FundPsbt.estimated_final_weight": 3,
"FundPsbt.excess_msat": 4,
"FundPsbt.feerate_per_kw": 2,
"FundPsbt.psbt": 1,
"FundPsbt.reservations[]": 6
},
"GetinfoAddress": { "GetinfoAddress": {
"Getinfo.address[].address": 3, "Getinfo.address[].address": 3,
"Getinfo.address[].port": 2, "Getinfo.address[].port": 2,
@ -717,6 +741,70 @@
"SendPay.route[].id": 2, "SendPay.route[].id": 2,
"SendPay.route[].msatoshi": 1 "SendPay.route[].msatoshi": 1
}, },
"SendpsbtRequest": {
"SendPsbt.psbt": 1
},
"SendpsbtResponse": {
"SendPsbt.tx": 1,
"SendPsbt.txid": 2
},
"SignpsbtRequest": {
"SignPsbt.psbt": 1,
"SignPsbt.signonly[]": 2
},
"SignpsbtResponse": {
"SignPsbt.signed_psbt": 1
},
"TxdiscardRequest": {
"TxDiscard.txid": 1
},
"TxdiscardResponse": {
"TxDiscard.txid": 2,
"TxDiscard.unsigned_tx": 1
},
"TxprepareRequest": {
"TxPrepare.feerate": 2,
"TxPrepare.minconf": 3,
"TxPrepare.outptus[]": 1,
"TxPrepare.utxos[]": 4
},
"TxprepareResponse": {
"TxPrepare.psbt": 1,
"TxPrepare.txid": 3,
"TxPrepare.unsigned_tx": 2
},
"TxsendRequest": {
"TxSend.txid": 1
},
"TxsendResponse": {
"TxSend.psbt": 1,
"TxSend.tx": 2,
"TxSend.txid": 3
},
"UtxopsbtRequest": {
"UtxoPsbt.feerate": 2,
"UtxoPsbt.locktime": 6,
"UtxoPsbt.min_witness_weight": 7,
"UtxoPsbt.reserve": 5,
"UtxoPsbt.satoshi": 1,
"UtxoPsbt.startweight": 3,
"UtxoPsbt.utxos[]": 4
},
"UtxopsbtReservations": {
"UtxoPsbt.reservations[].reserved": 4,
"UtxoPsbt.reservations[].reserved_to_block": 5,
"UtxoPsbt.reservations[].txid": 1,
"UtxoPsbt.reservations[].vout": 2,
"UtxoPsbt.reservations[].was_reserved": 3
},
"UtxopsbtResponse": {
"UtxoPsbt.change_outnum": 5,
"UtxoPsbt.estimated_final_weight": 3,
"UtxoPsbt.excess_msat": 4,
"UtxoPsbt.feerate_per_kw": 2,
"UtxoPsbt.psbt": 1,
"UtxoPsbt.reservations[]": 6
},
"WaitanyinvoiceRequest": { "WaitanyinvoiceRequest": {
"WaitAnyInvoice.lastpay_index": 1, "WaitAnyInvoice.lastpay_index": 1,
"WaitAnyInvoice.timeout": 2 "WaitAnyInvoice.timeout": 2

View file

@ -38,6 +38,13 @@ service Node {
rpc NewAddr(NewaddrRequest) returns (NewaddrResponse) {} rpc NewAddr(NewaddrRequest) returns (NewaddrResponse) {}
rpc Withdraw(WithdrawRequest) returns (WithdrawResponse) {} rpc Withdraw(WithdrawRequest) returns (WithdrawResponse) {}
rpc KeySend(KeysendRequest) returns (KeysendResponse) {} rpc KeySend(KeysendRequest) returns (KeysendResponse) {}
rpc FundPsbt(FundpsbtRequest) returns (FundpsbtResponse) {}
rpc SendPsbt(SendpsbtRequest) returns (SendpsbtResponse) {}
rpc SignPsbt(SignpsbtRequest) returns (SignpsbtResponse) {}
rpc UtxoPsbt(UtxopsbtRequest) returns (UtxopsbtResponse) {}
rpc TxDiscard(TxdiscardRequest) returns (TxdiscardResponse) {}
rpc TxPrepare(TxprepareRequest) returns (TxprepareResponse) {}
rpc TxSend(TxsendRequest) returns (TxsendResponse) {}
} }
message GetinfoRequest { message GetinfoRequest {
@ -940,3 +947,106 @@ message KeysendResponse {
optional string warning_partial_completion = 8; optional string warning_partial_completion = 8;
KeysendStatus status = 9; KeysendStatus status = 9;
} }
message FundpsbtRequest {
Amount satoshi = 1;
Feerate feerate = 2;
sint64 startweight = 3;
optional sint64 minconf = 4;
optional sint64 reserve = 5;
optional sint64 locktime = 6;
optional uint32 min_witness_weight = 7;
}
message FundpsbtResponse {
string psbt = 1;
uint32 feerate_per_kw = 2;
uint32 estimated_final_weight = 3;
Amount excess_msat = 4;
optional uint32 change_outnum = 5;
repeated FundpsbtReservations reservations = 6;
}
message FundpsbtReservations {
bytes txid = 1;
uint32 vout = 2;
bool was_reserved = 3;
bool reserved = 4;
uint32 reserved_to_block = 5;
}
message SendpsbtRequest {
string psbt = 1;
}
message SendpsbtResponse {
bytes tx = 1;
bytes txid = 2;
}
message SignpsbtRequest {
string psbt = 1;
}
message SignpsbtResponse {
string signed_psbt = 1;
}
message UtxopsbtRequest {
Amount satoshi = 1;
Feerate feerate = 2;
sint64 startweight = 3;
repeated Utxo utxos = 4;
optional sint64 reserve = 5;
optional sint64 locktime = 6;
optional uint32 min_witness_weight = 7;
}
message UtxopsbtResponse {
string psbt = 1;
uint32 feerate_per_kw = 2;
uint32 estimated_final_weight = 3;
Amount excess_msat = 4;
optional uint32 change_outnum = 5;
repeated UtxopsbtReservations reservations = 6;
}
message UtxopsbtReservations {
bytes txid = 1;
uint32 vout = 2;
bool was_reserved = 3;
bool reserved = 4;
uint32 reserved_to_block = 5;
}
message TxdiscardRequest {
bytes txid = 1;
}
message TxdiscardResponse {
bytes unsigned_tx = 1;
bytes txid = 2;
}
message TxprepareRequest {
repeated OutputDesc outptus = 1;
optional Feerate feerate = 2;
optional uint32 minconf = 3;
repeated Utxo utxos = 4;
}
message TxprepareResponse {
string psbt = 1;
bytes unsigned_tx = 2;
bytes txid = 3;
}
message TxsendRequest {
bytes txid = 1;
}
message TxsendResponse {
string psbt = 1;
bytes tx = 2;
bytes txid = 3;
}

View file

@ -725,6 +725,111 @@ impl From<&responses::KeysendResponse> for pb::KeysendResponse {
} }
} }
#[allow(unused_variables)]
impl From<&responses::FundpsbtReservations> for pb::FundpsbtReservations {
fn from(c: &responses::FundpsbtReservations) -> Self {
Self {
txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid
vout: c.vout.clone(), // Rule #2 for type u32
was_reserved: c.was_reserved.clone(), // Rule #2 for type boolean
reserved: c.reserved.clone(), // Rule #2 for type boolean
reserved_to_block: c.reserved_to_block.clone(), // Rule #2 for type u32
}
}
}
#[allow(unused_variables)]
impl From<&responses::FundpsbtResponse> for pb::FundpsbtResponse {
fn from(c: &responses::FundpsbtResponse) -> Self {
Self {
psbt: c.psbt.clone(), // Rule #2 for type string
feerate_per_kw: c.feerate_per_kw.clone(), // Rule #2 for type u32
estimated_final_weight: c.estimated_final_weight.clone(), // Rule #2 for type u32
excess_msat: Some(c.excess_msat.into()), // Rule #2 for type msat
change_outnum: c.change_outnum.clone(), // Rule #2 for type u32?
reservations: c.reservations.iter().map(|i| i.into()).collect(),
}
}
}
#[allow(unused_variables)]
impl From<&responses::SendpsbtResponse> for pb::SendpsbtResponse {
fn from(c: &responses::SendpsbtResponse) -> Self {
Self {
tx: hex::decode(&c.tx).unwrap(), // Rule #2 for type hex
txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid
}
}
}
#[allow(unused_variables)]
impl From<&responses::SignpsbtResponse> for pb::SignpsbtResponse {
fn from(c: &responses::SignpsbtResponse) -> Self {
Self {
signed_psbt: c.signed_psbt.clone(), // Rule #2 for type string
}
}
}
#[allow(unused_variables)]
impl From<&responses::UtxopsbtReservations> for pb::UtxopsbtReservations {
fn from(c: &responses::UtxopsbtReservations) -> Self {
Self {
txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid
vout: c.vout.clone(), // Rule #2 for type u32
was_reserved: c.was_reserved.clone(), // Rule #2 for type boolean
reserved: c.reserved.clone(), // Rule #2 for type boolean
reserved_to_block: c.reserved_to_block.clone(), // Rule #2 for type u32
}
}
}
#[allow(unused_variables)]
impl From<&responses::UtxopsbtResponse> for pb::UtxopsbtResponse {
fn from(c: &responses::UtxopsbtResponse) -> Self {
Self {
psbt: c.psbt.clone(), // Rule #2 for type string
feerate_per_kw: c.feerate_per_kw.clone(), // Rule #2 for type u32
estimated_final_weight: c.estimated_final_weight.clone(), // Rule #2 for type u32
excess_msat: Some(c.excess_msat.into()), // Rule #2 for type msat
change_outnum: c.change_outnum.clone(), // Rule #2 for type u32?
reservations: c.reservations.iter().map(|i| i.into()).collect(),
}
}
}
#[allow(unused_variables)]
impl From<&responses::TxdiscardResponse> for pb::TxdiscardResponse {
fn from(c: &responses::TxdiscardResponse) -> Self {
Self {
unsigned_tx: hex::decode(&c.unsigned_tx).unwrap(), // Rule #2 for type hex
txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid
}
}
}
#[allow(unused_variables)]
impl From<&responses::TxprepareResponse> for pb::TxprepareResponse {
fn from(c: &responses::TxprepareResponse) -> Self {
Self {
psbt: c.psbt.clone(), // Rule #2 for type string
unsigned_tx: hex::decode(&c.unsigned_tx).unwrap(), // Rule #2 for type hex
txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid
}
}
}
#[allow(unused_variables)]
impl From<&responses::TxsendResponse> for pb::TxsendResponse {
fn from(c: &responses::TxsendResponse) -> Self {
Self {
psbt: c.psbt.clone(), // Rule #2 for type string
tx: hex::decode(&c.tx).unwrap(), // Rule #2 for type hex
txid: hex::decode(&c.txid).unwrap(), // Rule #2 for type txid
}
}
}
#[allow(unused_variables)] #[allow(unused_variables)]
impl From<&pb::GetinfoRequest> for requests::GetinfoRequest { impl From<&pb::GetinfoRequest> for requests::GetinfoRequest {
fn from(c: &pb::GetinfoRequest) -> Self { fn from(c: &pb::GetinfoRequest) -> Self {
@ -1074,3 +1179,81 @@ impl From<&pb::KeysendRequest> for requests::KeysendRequest {
} }
} }
#[allow(unused_variables)]
impl From<&pb::FundpsbtRequest> for requests::FundpsbtRequest {
fn from(c: &pb::FundpsbtRequest) -> Self {
Self {
satoshi: c.satoshi.as_ref().unwrap().into(), // Rule #1 for type msat
feerate: c.feerate.as_ref().unwrap().into(), // Rule #1 for type feerate
startweight: c.startweight.clone(), // Rule #1 for type number
minconf: c.minconf.clone(), // Rule #1 for type number?
reserve: c.reserve.clone(), // Rule #1 for type number?
locktime: c.locktime.clone(), // Rule #1 for type number?
min_witness_weight: c.min_witness_weight.clone(), // Rule #1 for type u32?
}
}
}
#[allow(unused_variables)]
impl From<&pb::SendpsbtRequest> for requests::SendpsbtRequest {
fn from(c: &pb::SendpsbtRequest) -> Self {
Self {
psbt: c.psbt.clone(), // Rule #1 for type string
}
}
}
#[allow(unused_variables)]
impl From<&pb::SignpsbtRequest> for requests::SignpsbtRequest {
fn from(c: &pb::SignpsbtRequest) -> Self {
Self {
psbt: c.psbt.clone(), // Rule #1 for type string
}
}
}
#[allow(unused_variables)]
impl From<&pb::UtxopsbtRequest> for requests::UtxopsbtRequest {
fn from(c: &pb::UtxopsbtRequest) -> Self {
Self {
satoshi: c.satoshi.as_ref().unwrap().into(), // Rule #1 for type msat
feerate: c.feerate.as_ref().unwrap().into(), // Rule #1 for type feerate
startweight: c.startweight.clone(), // Rule #1 for type number
utxos: c.utxos.iter().map(|s| s.into()).collect(),
reserve: c.reserve.clone(), // Rule #1 for type number?
locktime: c.locktime.clone(), // Rule #1 for type number?
min_witness_weight: c.min_witness_weight.clone(), // Rule #1 for type u32?
}
}
}
#[allow(unused_variables)]
impl From<&pb::TxdiscardRequest> for requests::TxdiscardRequest {
fn from(c: &pb::TxdiscardRequest) -> Self {
Self {
txid: hex::encode(&c.txid), // Rule #1 for type hex
}
}
}
#[allow(unused_variables)]
impl From<&pb::TxprepareRequest> for requests::TxprepareRequest {
fn from(c: &pb::TxprepareRequest) -> Self {
Self {
outptus: c.outptus.iter().map(|s| s.into()).collect(),
feerate: c.feerate.as_ref().map(|a| a.into()), // Rule #1 for type feerate?
minconf: c.minconf.clone(), // Rule #1 for type u32?
utxos: c.utxos.iter().map(|s| s.into()).collect(),
}
}
}
#[allow(unused_variables)]
impl From<&pb::TxsendRequest> for requests::TxsendRequest {
fn from(c: &pb::TxsendRequest) -> Self {
Self {
txid: hex::encode(&c.txid), // Rule #1 for type hex
}
}
}

View file

@ -926,4 +926,214 @@ async fn key_send(
} }
async fn fund_psbt(
&self,
request: tonic::Request<pb::FundpsbtRequest>,
) -> Result<tonic::Response<pb::FundpsbtResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::FundpsbtRequest = (&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::FundPsbt(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method FundPsbt: {:?}", e)))?;
match result {
Response::FundPsbt(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call FundPsbt",
r
)
)),
}
}
async fn send_psbt(
&self,
request: tonic::Request<pb::SendpsbtRequest>,
) -> Result<tonic::Response<pb::SendpsbtResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::SendpsbtRequest = (&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::SendPsbt(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method SendPsbt: {:?}", e)))?;
match result {
Response::SendPsbt(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call SendPsbt",
r
)
)),
}
}
async fn sign_psbt(
&self,
request: tonic::Request<pb::SignpsbtRequest>,
) -> Result<tonic::Response<pb::SignpsbtResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::SignpsbtRequest = (&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::SignPsbt(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method SignPsbt: {:?}", e)))?;
match result {
Response::SignPsbt(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call SignPsbt",
r
)
)),
}
}
async fn utxo_psbt(
&self,
request: tonic::Request<pb::UtxopsbtRequest>,
) -> Result<tonic::Response<pb::UtxopsbtResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::UtxopsbtRequest = (&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::UtxoPsbt(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method UtxoPsbt: {:?}", e)))?;
match result {
Response::UtxoPsbt(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call UtxoPsbt",
r
)
)),
}
}
async fn tx_discard(
&self,
request: tonic::Request<pb::TxdiscardRequest>,
) -> Result<tonic::Response<pb::TxdiscardResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::TxdiscardRequest = (&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::TxDiscard(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method TxDiscard: {:?}", e)))?;
match result {
Response::TxDiscard(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call TxDiscard",
r
)
)),
}
}
async fn tx_prepare(
&self,
request: tonic::Request<pb::TxprepareRequest>,
) -> Result<tonic::Response<pb::TxprepareResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::TxprepareRequest = (&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::TxPrepare(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method TxPrepare: {:?}", e)))?;
match result {
Response::TxPrepare(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call TxPrepare",
r
)
)),
}
}
async fn tx_send(
&self,
request: tonic::Request<pb::TxsendRequest>,
) -> Result<tonic::Response<pb::TxsendResponse>, tonic::Status> {
let req = request.into_inner();
let req: requests::TxsendRequest = (&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::TxSend(req))
.await
.map_err(|e| Status::new(
Code::Unknown,
format!("Error calling method TxSend: {:?}", e)))?;
match result {
Response::TxSend(r) => Ok(
tonic::Response::new((&r).into())
),
r => Err(Status::new(
Code::Internal,
format!(
"Unexpected result {:?} to method call TxSend",
r
)
)),
}
}
} }

View file

@ -46,6 +46,13 @@ pub enum Request {
NewAddr(requests::NewaddrRequest), NewAddr(requests::NewaddrRequest),
Withdraw(requests::WithdrawRequest), Withdraw(requests::WithdrawRequest),
KeySend(requests::KeysendRequest), KeySend(requests::KeysendRequest),
FundPsbt(requests::FundpsbtRequest),
SendPsbt(requests::SendpsbtRequest),
SignPsbt(requests::SignpsbtRequest),
UtxoPsbt(requests::UtxopsbtRequest),
TxDiscard(requests::TxdiscardRequest),
TxPrepare(requests::TxprepareRequest),
TxSend(requests::TxsendRequest),
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
@ -82,6 +89,13 @@ pub enum Response {
NewAddr(responses::NewaddrResponse), NewAddr(responses::NewaddrResponse),
Withdraw(responses::WithdrawResponse), Withdraw(responses::WithdrawResponse),
KeySend(responses::KeysendResponse), KeySend(responses::KeysendResponse),
FundPsbt(responses::FundpsbtResponse),
SendPsbt(responses::SendpsbtResponse),
SignPsbt(responses::SignpsbtResponse),
UtxoPsbt(responses::UtxopsbtResponse),
TxDiscard(responses::TxdiscardResponse),
TxPrepare(responses::TxprepareResponse),
TxSend(responses::TxsendResponse),
} }
pub mod requests { pub mod requests {
@ -490,6 +504,78 @@ pub mod requests {
pub exemptfee: Option<Amount>, pub exemptfee: Option<Amount>,
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct FundpsbtRequest {
#[serde(alias = "satoshi")]
pub satoshi: Amount,
#[serde(alias = "feerate")]
pub feerate: Feerate,
#[serde(alias = "startweight")]
pub startweight: i64,
#[serde(alias = "minconf", skip_serializing_if = "Option::is_none")]
pub minconf: Option<i64>,
#[serde(alias = "reserve", skip_serializing_if = "Option::is_none")]
pub reserve: Option<i64>,
#[serde(alias = "locktime", skip_serializing_if = "Option::is_none")]
pub locktime: Option<i64>,
#[serde(alias = "min_witness_weight", skip_serializing_if = "Option::is_none")]
pub min_witness_weight: Option<u32>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SendpsbtRequest {
#[serde(alias = "psbt")]
pub psbt: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SignpsbtRequest {
#[serde(alias = "psbt")]
pub psbt: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UtxopsbtRequest {
#[serde(alias = "satoshi")]
pub satoshi: Amount,
#[serde(alias = "feerate")]
pub feerate: Feerate,
#[serde(alias = "startweight")]
pub startweight: i64,
#[serde(alias = "utxos")]
pub utxos: Vec<Utxo>,
#[serde(alias = "reserve", skip_serializing_if = "Option::is_none")]
pub reserve: Option<i64>,
#[serde(alias = "locktime", skip_serializing_if = "Option::is_none")]
pub locktime: Option<i64>,
#[serde(alias = "min_witness_weight", skip_serializing_if = "Option::is_none")]
pub min_witness_weight: Option<u32>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TxdiscardRequest {
#[serde(alias = "txid")]
pub txid: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TxprepareRequest {
#[serde(alias = "outptus")]
pub outptus: Vec<OutputDesc>,
#[serde(alias = "feerate", skip_serializing_if = "Option::is_none")]
pub feerate: Option<Feerate>,
#[serde(alias = "minconf", skip_serializing_if = "Option::is_none")]
pub minconf: Option<u32>,
#[serde(alias = "utxos")]
pub utxos: Vec<Utxo>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TxsendRequest {
#[serde(alias = "txid")]
pub txid: String,
}
} }
@ -1987,5 +2073,107 @@ pub mod responses {
pub status: KeysendStatus, pub status: KeysendStatus,
} }
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct FundpsbtReservations {
#[serde(alias = "txid")]
pub txid: String,
#[serde(alias = "vout")]
pub vout: u32,
#[serde(alias = "was_reserved")]
pub was_reserved: bool,
#[serde(alias = "reserved")]
pub reserved: bool,
#[serde(alias = "reserved_to_block")]
pub reserved_to_block: u32,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct FundpsbtResponse {
#[serde(alias = "psbt")]
pub psbt: String,
#[serde(alias = "feerate_per_kw")]
pub feerate_per_kw: u32,
#[serde(alias = "estimated_final_weight")]
pub estimated_final_weight: u32,
#[serde(alias = "excess_msat")]
pub excess_msat: Amount,
#[serde(alias = "change_outnum", skip_serializing_if = "Option::is_none")]
pub change_outnum: Option<u32>,
#[serde(alias = "reservations")]
pub reservations: Vec<FundpsbtReservations>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SendpsbtResponse {
#[serde(alias = "tx")]
pub tx: String,
#[serde(alias = "txid")]
pub txid: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct SignpsbtResponse {
#[serde(alias = "signed_psbt")]
pub signed_psbt: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UtxopsbtReservations {
#[serde(alias = "txid")]
pub txid: String,
#[serde(alias = "vout")]
pub vout: u32,
#[serde(alias = "was_reserved")]
pub was_reserved: bool,
#[serde(alias = "reserved")]
pub reserved: bool,
#[serde(alias = "reserved_to_block")]
pub reserved_to_block: u32,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UtxopsbtResponse {
#[serde(alias = "psbt")]
pub psbt: String,
#[serde(alias = "feerate_per_kw")]
pub feerate_per_kw: u32,
#[serde(alias = "estimated_final_weight")]
pub estimated_final_weight: u32,
#[serde(alias = "excess_msat")]
pub excess_msat: Amount,
#[serde(alias = "change_outnum", skip_serializing_if = "Option::is_none")]
pub change_outnum: Option<u32>,
#[serde(alias = "reservations")]
pub reservations: Vec<UtxopsbtReservations>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TxdiscardResponse {
#[serde(alias = "unsigned_tx")]
pub unsigned_tx: String,
#[serde(alias = "txid")]
pub txid: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TxprepareResponse {
#[serde(alias = "psbt")]
pub psbt: String,
#[serde(alias = "unsigned_tx")]
pub unsigned_tx: String,
#[serde(alias = "txid")]
pub txid: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TxsendResponse {
#[serde(alias = "psbt")]
pub psbt: String,
#[serde(alias = "tx")]
pub tx: String,
#[serde(alias = "txid")]
pub txid: String,
}
} }

View file

@ -70,6 +70,13 @@ def load_jsonrpc_service():
"NewAddr", "NewAddr",
"Withdraw", "Withdraw",
"KeySend", "KeySend",
"FundPsbt",
"SendPsbt",
"SignPsbt",
"UtxoPsbt",
"TxDiscard",
"TxPrepare",
"TxSend",
# "decodepay", # "decodepay",
# "decode", # "decode",
# "delpay", # "delpay",
@ -110,15 +117,11 @@ def load_jsonrpc_service():
# "setchannelfee", # "setchannelfee",
# "signmessage", # "signmessage",
# "signpsbt", # "signpsbt",
# "txdiscard",
# "txprepare",
# "txsend",
# "unreserveinputs", # "unreserveinputs",
# "waitblockheight", # "waitblockheight",
# "ListConfigs", # "ListConfigs",
# "check", # No point in mapping this one # "check", # No point in mapping this one
# "Stop", # Breaks a core assumption (root is an object) can't map unless we change this # "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 # "notifications", # No point in mapping this
# "help", # "help",
] ]

View file

@ -395,6 +395,7 @@ class GrpcUnconverterGenerator(GrpcConverterGenerator):
'pubkey?': f'c.{name}.clone().map(|v| hex::encode(v))', 'pubkey?': f'c.{name}.clone().map(|v| hex::encode(v))',
'msat': f'c.{name}.as_ref().unwrap().into()', 'msat': f'c.{name}.as_ref().unwrap().into()',
'msat?': f'c.{name}.as_ref().map(|a| a.into())', 'msat?': f'c.{name}.as_ref().map(|a| a.into())',
'feerate': f'c.{name}.as_ref().unwrap().into()',
'feerate?': f'c.{name}.as_ref().map(|a| a.into())', 'feerate?': f'c.{name}.as_ref().map(|a| a.into())',
}.get( }.get(
typ, typ,

View file

@ -0,0 +1,36 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"satoshi",
"feerate",
"startweight"
],
"properties": {
"satoshi": {
"type": "msat"
},
"feerate": {
"type": "feerate"
},
"startweight": {
"type": "number"
},
"minconf": {
"type": "number"
},
"reserve": {
"type": "number",
"description": "reserve is a number: if non-zero number then reserveinputs is called (successfully, with exclusive true) on the returned PSBT for this number of blocks (default: 72)."
},
"locktime": {
"type": "number"
},
"min_witness_weight": {
"type": "u32"
},
"excess_as_change": {
"type": "bool"
}
}
}

View file

@ -0,0 +1,15 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"psbt"
],
"properties": {
"psbt": {
"type": "string"
},
"reserve": {
"type": "bool"
}
}
}

View file

@ -0,0 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"psbt"
],
"properties": {
"psbt": {
"type": "string"
}
}
}

View file

@ -0,0 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"txid"
],
"properties": {
"txid": {
"type": "hex"
}
}
}

View file

@ -0,0 +1,27 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"outputs"
],
"properties": {
"outptus": {
"type": "array",
"items": {
"type": "OutputDesc"
}
},
"feerate": {
"type": "feerate"
},
"minconf": {
"type": "u32"
},
"utxos": {
"type": "array",
"items": {
"type": "utxo"
}
}
}
}

View file

@ -0,0 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"txid"
],
"properties": {
"txid": {
"type": "hex"
}
}
}

View file

@ -0,0 +1,43 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": [
"satoshi",
"feerate",
"startweight",
"utxos"
],
"properties": {
"satoshi": {
"type": "msat"
},
"feerate": {
"type": "feerate"
},
"startweight": {
"type": "number"
},
"utxos": {
"type": "array",
"items": {
"type": "utxo"
}
},
"reserve": {
"type": "number",
"description": "reserve is a number: if non-zero number then reserveinputs is called (successfully, with exclusive true) on the returned PSBT for this number of blocks (default: 72)."
},
"reservedok": {
"type": "bool"
},
"locktime": {
"type": "number"
},
"min_witness_weight": {
"type": "u32"
},
"excess_as_change": {
"type": "bool"
}
}
}