fix: grpc set mint urls, updating description and add get quote ttl (#716)

* fix: grpc set mint urls

* refactor: Extract payment processor retrieval into helper method

* fix: only allow updates to nut04/05 where there is a backend

* feat: Add GetQuoteTtl RPC method to retrieve quote TTL settings

* fix: update long desctiption
This commit is contained in:
thesimplekid
2025-04-09 15:28:25 +01:00
committed by GitHub
parent fb613b2e21
commit f44f79d3e0
9 changed files with 98 additions and 50 deletions

View File

@@ -16,7 +16,7 @@ const DEFAULT_WORK_DIR: &str = ".cdk-mint-rpc-cli";
#[command(version, about, long_about = None)]
struct Cli {
/// Address of RPC server
#[arg(short, long, default_value = "http://127.0.0.1:8086")]
#[arg(short, long, default_value = "https://127.0.0.1:8086")]
addr: String,
/// Logging level
@@ -59,6 +59,8 @@ enum Commands {
UpdateNut05(subcommands::UpdateNut05Command),
/// Update quote ttl
UpdateQuoteTtl(subcommands::UpdateQuoteTtlCommand),
/// Get quote ttl
GetQuoteTtl,
/// Update Nut04 quote
UpdateNut04QuoteState(subcommands::UpdateNut04QuoteCommand),
/// Rotate next keyset
@@ -181,6 +183,9 @@ async fn main() -> Result<()> {
Commands::UpdateNut05(sub_command_args) => {
subcommands::update_nut05(&mut client, &sub_command_args).await?;
}
Commands::GetQuoteTtl => {
subcommands::get_quote_ttl(&mut client).await?;
}
Commands::UpdateQuoteTtl(sub_command_args) => {
subcommands::update_quote_ttl(&mut client, &sub_command_args).await?;
}

View File

@@ -1,27 +0,0 @@
use thiserror::Error;
use crate::cdk_mint_rpc::cdk_mint_client::CdkMintClient;
use crate::cdk_mint_rpc::cdk_mint_server::CdkMint;
/// Error
#[derive(Debug, Error)]
pub enum Error {
/// Transport error
#[error(transparent)]
Transport(#[from] tonic::transport::Error),
}
pub struct MintRPCClient {
inner: CdkMintClient<tonic::transport::Channel>,
}
impl MintRPCClient {
pub async fn new(url: String) -> Result<Self, Error> {
Ok(Self {
inner: CdkMintClient::connect(url).await?,
})
}
}
#[tonic::async_trait]
impl CdkMint for MintRPCClient {}

View File

@@ -33,5 +33,5 @@ pub use update_nut04::{update_nut04, UpdateNut04Command};
pub use update_nut04_quote::{update_nut04_quote_state, UpdateNut04QuoteCommand};
pub use update_nut05::{update_nut05, UpdateNut05Command};
pub use update_short_description::{update_short_description, UpdateShortDescriptionCommand};
pub use update_ttl::{update_quote_ttl, UpdateQuoteTtlCommand};
pub use update_ttl::{get_quote_ttl, update_quote_ttl, UpdateQuoteTtlCommand};
pub use update_urls::{add_url, remove_url, AddUrlCommand, RemoveUrlCommand};

View File

@@ -4,7 +4,7 @@ use tonic::transport::Channel;
use tonic::Request;
use crate::cdk_mint_client::CdkMintClient;
use crate::UpdateQuoteTtlRequest;
use crate::{GetQuoteTtlRequest, UpdateQuoteTtlRequest};
/// Command to update the time-to-live (TTL) settings for quotes
///
@@ -40,3 +40,28 @@ pub async fn update_quote_ttl(
Ok(())
}
/// Command to get the current time-to-live (TTL) settings for quotes
///
/// This command retrieves the current TTL settings for mint and melt quotes.
#[derive(Args)]
pub struct GetQuoteTtlCommand {}
/// Executes the get_quote_ttl command against the mint server
///
/// This function sends an RPC request to retrieve the current TTL settings for mint and melt quotes.
///
/// # Arguments
/// * `client` - The RPC client used to communicate with the mint
pub async fn get_quote_ttl(client: &mut CdkMintClient<Channel>) -> Result<()> {
let response = client
.get_quote_ttl(Request::new(GetQuoteTtlRequest {}))
.await?
.into_inner();
println!("Quote TTL Settings:");
println!(" Mint TTL: {} seconds", response.mint_ttl);
println!(" Melt TTL: {} seconds", response.melt_ttl);
Ok(())
}

View File

@@ -16,6 +16,7 @@ service CdkMint {
rpc UpdateNut04(UpdateNut04Request) returns (UpdateResponse) {}
rpc UpdateNut05(UpdateNut05Request) returns (UpdateResponse) {}
rpc UpdateQuoteTtl(UpdateQuoteTtlRequest) returns (UpdateResponse) {}
rpc GetQuoteTtl(GetQuoteTtlRequest) returns (GetQuoteTtlResponse) {}
rpc UpdateNut04Quote(UpdateNut04QuoteRequest) returns (UpdateNut04QuoteRequest) {}
rpc RotateNextKeyset(RotateNextKeysetRequest) returns (RotateNextKeysetResponse) {}
}
@@ -94,6 +95,14 @@ message UpdateQuoteTtlRequest {
optional uint64 melt_ttl = 2;
}
message GetQuoteTtlRequest {
}
message GetQuoteTtlResponse {
uint64 mint_ttl = 1;
uint64 melt_ttl = 2;
}
message UpdateNut04QuoteRequest {
string quote_id = 1;

View File

@@ -18,10 +18,11 @@ use tonic::{Request, Response, Status};
use crate::cdk_mint_server::{CdkMint, CdkMintServer};
use crate::{
ContactInfo, GetInfoRequest, GetInfoResponse, RotateNextKeysetRequest,
RotateNextKeysetResponse, UpdateContactRequest, UpdateDescriptionRequest, UpdateIconUrlRequest,
UpdateMotdRequest, UpdateNameRequest, UpdateNut04QuoteRequest, UpdateNut04Request,
UpdateNut05Request, UpdateQuoteTtlRequest, UpdateResponse, UpdateUrlRequest,
ContactInfo, GetInfoRequest, GetInfoResponse, GetQuoteTtlRequest, GetQuoteTtlResponse,
RotateNextKeysetRequest, RotateNextKeysetResponse, UpdateContactRequest,
UpdateDescriptionRequest, UpdateIconUrlRequest, UpdateMotdRequest, UpdateNameRequest,
UpdateNut04QuoteRequest, UpdateNut04Request, UpdateNut05Request, UpdateQuoteTtlRequest,
UpdateResponse, UpdateUrlRequest,
};
/// Error
@@ -283,7 +284,7 @@ impl CdkMint for MintRPCServer {
.await
.map_err(|err| Status::internal(err.to_string()))?;
info.description = Some(description);
info.description_long = Some(description);
self.mint
.set_mint_info(info)
@@ -346,10 +347,10 @@ impl CdkMint for MintRPCServer {
.mint_info()
.await
.map_err(|err| Status::internal(err.to_string()))?;
let urls = info.urls;
urls.clone().unwrap_or_default().push(url);
let mut urls = info.urls.unwrap_or_default();
urls.push(url);
info.urls = urls;
info.urls = Some(urls.clone());
self.mint
.set_mint_info(info)
@@ -452,6 +453,10 @@ impl CdkMint for MintRPCServer {
let payment_method = PaymentMethod::from_str(&request_inner.method)
.map_err(|_| Status::invalid_argument("Invalid method".to_string()))?;
self.mint
.get_payment_processor(unit.clone(), payment_method.clone())
.map_err(|_| Status::invalid_argument("Unit payment method pair is not supported"))?;
let current_nut04_settings = nut04_settings.remove_settings(&unit, &payment_method);
let mut methods = nut04_settings.methods.clone();
@@ -512,6 +517,10 @@ impl CdkMint for MintRPCServer {
let payment_method = PaymentMethod::from_str(&request_inner.method)
.map_err(|_| Status::invalid_argument("Invalid method".to_string()))?;
self.mint
.get_payment_processor(unit.clone(), payment_method.clone())
.map_err(|_| Status::invalid_argument("Unit payment method pair is not supported"))?;
let current_nut05_settings = nut05_settings.remove_settings(&unit, &payment_method);
let mut methods = nut05_settings.methods;
@@ -576,6 +585,23 @@ impl CdkMint for MintRPCServer {
Ok(Response::new(UpdateResponse {}))
}
/// Gets the mint's quote time-to-live settings
async fn get_quote_ttl(
&self,
_request: Request<GetQuoteTtlRequest>,
) -> Result<Response<GetQuoteTtlResponse>, Status> {
let ttl = self
.mint
.quote_ttl()
.await
.map_err(|err| Status::internal(err.to_string()))?;
Ok(Response::new(GetQuoteTtlResponse {
mint_ttl: ttl.mint_ttl,
melt_ttl: ttl.melt_ttl,
}))
}
/// Updates a specific NUT-04 quote's state
async fn update_nut04_quote(
&self,

View File

@@ -620,7 +620,11 @@ async fn main() -> anyhow::Result<()> {
if mint.mint_info().await.is_err() {
tracing::info!("Mint info not set on mint, setting.");
mint.set_mint_info(mint_builder.mint_info).await?;
mint.set_quote_ttl(QuoteTTL::new(10_000, 10_000)).await?;
} else {
if mint.localstore.get_quote_ttl().await.is_err() {
mint.set_quote_ttl(QuoteTTL::new(10_000, 10_000)).await?;
}
tracing::info!("Mint info already set, not using config file settings.");
}
} else {

View File

@@ -7,7 +7,6 @@ use crate::mint::{
MintQuoteBolt11Response, MintQuoteState, NotificationPayload, PublicKey, Verification,
};
use crate::nuts::PaymentMethod;
use crate::types::PaymentProcessorKey;
use crate::util::unix_time;
use crate::{ensure_cdk, Amount, Error, Mint};
@@ -62,17 +61,7 @@ impl Mint {
self.check_mint_request_acceptable(amount, &unit).await?;
let ln = self
.ln
.get(&PaymentProcessorKey::new(
unit.clone(),
PaymentMethod::Bolt11,
))
.ok_or_else(|| {
tracing::info!("Bolt11 mint request for unsupported unit");
Error::UnsupportedUnit
})?;
let ln = self.get_payment_processor(unit.clone(), PaymentMethod::Bolt11)?;
let mint_ttl = self.localstore.get_quote_ttl().await?.mint_ttl;

View File

@@ -67,6 +67,23 @@ pub struct Mint {
}
impl Mint {
/// Get the payment processor for the given unit and payment method
pub fn get_payment_processor(
&self,
unit: CurrencyUnit,
payment_method: PaymentMethod,
) -> Result<Arc<dyn MintPayment<Err = cdk_payment::Error> + Send + Sync>, Error> {
let key = PaymentProcessorKey::new(unit.clone(), payment_method.clone());
self.ln.get(&key).cloned().ok_or_else(|| {
tracing::info!(
"No payment processor set for pair {}, {}",
unit,
payment_method
);
Error::UnsupportedUnit
})
}
/// Create new [`Mint`] without authentication
pub async fn new(
seed: &[u8],