Skip to content

Commit 3b307cf

Browse files
Merge #84
84: feat: fetch the cost of a subscription before paying for it r=mfontanini a=mfontanini This hits the new endpoint to get the nilauth subscription cost before paying for it. See NillionNetwork/nilauth#16 Co-authored-by: Matias Fontanini <[email protected]>
2 parents c053db2 + 4f9dbac commit 3b307cf

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

libs/nilauth-client/examples/mint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
88
b"\x97\xf4\x98\x89\xfc\xee\xd8\x8a\x9c\xdd\xdb\x16\xa1a\xd1?j\x120|+9\x16?<<9|<-$4",
99
)?;
1010
let mut payer = NillionChainClient::new("http://localhost:26648".to_string(), payment_key).await?;
11-
let client = DefaultNilauthClient::new("http://127.0.0.1:30921");
11+
let client = DefaultNilauthClient::new("http://127.0.0.1:30921")?;
1212
let key = SecretKey::random(&mut rand::thread_rng());
1313
client.pay_subscription(&mut payer, &key.public_key()).await?;
1414
let token = client.request_token(&key).await?;

libs/nilauth-client/src/client.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
1010
use std::time::Duration;
1111

1212
const TOKEN_REQUEST_EXPIRATION: Duration = Duration::from_secs(60);
13+
const REQUEST_TIMEOUT: Duration = Duration::from_secs(30);
1314

1415
/// An interface to interact with nilauth.
1516
#[async_trait]
@@ -26,6 +27,9 @@ pub trait NilauthClient {
2627
payments_client: &mut NillionChainClient,
2728
key: &PublicKey,
2829
) -> Result<TxHash, PaySubscriptionError>;
30+
31+
/// Get the cost of a subscription.
32+
async fn subscription_cost(&self) -> Result<TokenAmount, SubscriptionCostError>;
2933
}
3034

3135
/// An error when requesting a token.
@@ -50,6 +54,9 @@ pub enum PaySubscriptionError {
5054
#[error("fetching server's about: {0}")]
5155
About(#[from] AboutError),
5256

57+
#[error("fetching subscription cost: {0}")]
58+
Cost(#[from] SubscriptionCostError),
59+
5360
#[error("serde: {0}")]
5461
Serde(#[from] serde_json::Error),
5562

@@ -63,6 +70,13 @@ pub enum PaySubscriptionError {
6370
Payment(String),
6471
}
6572

73+
/// An error when fetching the subscription cost.
74+
#[derive(Debug, thiserror::Error)]
75+
pub enum SubscriptionCostError {
76+
#[error("request: {0}")]
77+
Request(#[from] reqwest::Error),
78+
}
79+
6680
/// An error when requesting the information about a nilauth instance.
6781
#[derive(Debug, thiserror::Error)]
6882
pub enum AboutError {
@@ -77,8 +91,9 @@ pub struct DefaultNilauthClient {
7791
}
7892

7993
impl DefaultNilauthClient {
80-
pub fn new(base_url: impl Into<String>) -> Self {
81-
Self { client: reqwest::Client::new(), base_url: base_url.into() }
94+
pub fn new(base_url: impl Into<String>) -> Result<Self, reqwest::Error> {
95+
let client = reqwest::Client::builder().timeout(REQUEST_TIMEOUT).build()?;
96+
Ok(Self { client, base_url: base_url.into() })
8297
}
8398

8499
fn make_url(&self, path: &str) -> String {
@@ -121,11 +136,12 @@ impl NilauthClient for DefaultNilauthClient {
121136
key: &PublicKey,
122137
) -> Result<TxHash, PaySubscriptionError> {
123138
let about = self.about().await?;
139+
let cost = self.subscription_cost().await?;
124140
let payload = ValidatePaymentRequestPayload { nonce: rand::random(), service_public_key: about.public_key };
125141
let payload = serde_json::to_string(&payload)?;
126142
let hash = Sha256::digest(&payload);
127143
let tx_hash = payments_client
128-
.pay_for_resource(TokenAmount::Unil(1), hash.to_vec())
144+
.pay_for_resource(cost, hash.to_vec())
129145
.await
130146
.map_err(|e| PaySubscriptionError::Payment(e.to_string()))?;
131147

@@ -135,6 +151,12 @@ impl NilauthClient for DefaultNilauthClient {
135151
self.client.post(url).json(&request).send().await?.error_for_status()?;
136152
Ok(TxHash(tx_hash))
137153
}
154+
155+
async fn subscription_cost(&self) -> Result<TokenAmount, SubscriptionCostError> {
156+
let url = self.make_url("/api/v1/payments/cost");
157+
let response: GetCostResponse = self.client.get(url).send().await?.json().await?;
158+
Ok(TokenAmount::Unil(response.cost_unils))
159+
}
138160
}
139161

140162
/// A transaction hash.
@@ -202,3 +224,9 @@ struct ValidatePaymentRequestPayload {
202224
#[serde(serialize_with = "hex::serde::serialize")]
203225
service_public_key: [u8; 33],
204226
}
227+
228+
#[derive(Debug, Deserialize)]
229+
struct GetCostResponse {
230+
// The cost in unils.
231+
cost_unils: u64,
232+
}

0 commit comments

Comments
 (0)