@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
1010use std:: time:: Duration ;
1111
1212const 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 ) ]
6882pub enum AboutError {
@@ -77,8 +91,9 @@ pub struct DefaultNilauthClient {
7791}
7892
7993impl 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