@@ -11,6 +11,7 @@ use reqwest::Client;
1111use serde:: { de:: DeserializeOwned , Serialize } ;
1212use serde_json:: { json, Value } ;
1313use std:: env;
14+ use std:: sync:: Mutex ;
1415
1516pub use dstack_sdk_types:: dstack:: * ;
1617
@@ -60,6 +61,14 @@ pub enum ClientKind {
6061
6162pub trait BaseClient { }
6263
64+ /// Algorithms that require OS >= 0.5.7 (i.e., Version RPC support).
65+ fn requires_version_check ( algorithm : & str ) -> bool {
66+ !matches ! (
67+ algorithm,
68+ "secp256k1" | "secp256k1_prehashed" | "k256" | ""
69+ )
70+ }
71+
6372/// The main client for interacting with the dstack service
6473pub struct DstackClient {
6574 /// The base URL for HTTP requests
@@ -68,6 +77,8 @@ pub struct DstackClient {
6877 endpoint : String ,
6978 /// The type of client (HTTP or Unix domain socket)
7079 client : ClientKind ,
80+ /// Cached result of version check: None = not checked, Some(true) = new OS, Some(false) = old OS
81+ version_checked : Mutex < Option < bool > > ,
7182}
7283
7384impl BaseClient for DstackClient { }
@@ -86,6 +97,7 @@ impl DstackClient {
8697 base_url,
8798 endpoint,
8899 client,
100+ version_checked : Mutex :: new ( None ) ,
89101 }
90102 }
91103
@@ -126,15 +138,43 @@ impl DstackClient {
126138 }
127139 }
128140
141+ /// Check if the OS supports the given algorithm, querying version if needed.
142+ async fn ensure_algorithm_supported ( & self , algorithm : & str ) -> Result < ( ) > {
143+ if !requires_version_check ( algorithm) {
144+ return Ok ( ( ) ) ;
145+ }
146+ let already_checked = self . version_checked . lock ( ) . unwrap ( ) . clone ( ) ;
147+ match already_checked {
148+ Some ( true ) => Ok ( ( ) ) ,
149+ Some ( false ) => anyhow:: bail!(
150+ "algorithm \" {algorithm}\" is not supported: OS version too old (Version RPC unavailable)"
151+ ) ,
152+ None => {
153+ let supported = self . version ( ) . await . is_ok ( ) ;
154+ * self . version_checked . lock ( ) . unwrap ( ) = Some ( supported) ;
155+ if supported {
156+ Ok ( ( ) )
157+ } else {
158+ anyhow:: bail!(
159+ "algorithm \" {algorithm}\" is not supported: OS version too old (Version RPC unavailable)"
160+ )
161+ }
162+ }
163+ }
164+ }
165+
129166 pub async fn get_key (
130167 & self ,
131168 path : Option < String > ,
132169 purpose : Option < String > ,
170+ algorithm : Option < String > ,
133171 ) -> Result < GetKeyResponse > {
172+ let algorithm = algorithm. unwrap_or_else ( || "secp256k1" . to_string ( ) ) ;
173+ self . ensure_algorithm_supported ( & algorithm) . await ?;
134174 let data = json ! ( {
135175 "path" : path. unwrap_or_default( ) ,
136176 "purpose" : purpose. unwrap_or_default( ) ,
137- "algorithm" : "secp256k1" , // Default or specify as needed
177+ "algorithm" : algorithm ,
138178 } ) ;
139179 let response = self . send_rpc_request ( "/GetKey" , & data) . await ?;
140180 let response = serde_json:: from_value :: < GetKeyResponse > ( response) ?;
0 commit comments