소스 검색

darkfid: add the option to import keypair from json file

ghassmo 4 년 전
부모
커밋
be1bdec8a2
5개의 변경된 파일71개의 추가작업 그리고 4개의 파일을 삭제
  1. 47 1
      src/bin/darkfid.rs
  2. 14 0
      src/bin/drk.rs
  3. 3 0
      src/cli/cli_parser.rs
  4. 4 0
      src/client.rs
  5. 3 3
      src/rpc/jsonrpc.rs

+ 47 - 1
src/bin/darkfid.rs

@@ -16,7 +16,10 @@ use drk::{
     circuit::{MintContract, SpendContract},
     cli::{CliDarkfid, Config, DarkfidConfig},
     client::Client,
-    crypto::{keypair::PublicKey, proof::VerifyingKey},
+    crypto::{
+        keypair::{Keypair, PublicKey, SecretKey},
+        proof::VerifyingKey,
+    },
     rpc::{
         jsonrpc::{
             error as jsonerr, request as jsonreq, response as jsonresp, send_raw_request,
@@ -75,6 +78,7 @@ impl RequestHandler for Darkfid {
             Some("get_key") => return self.get_key(req.id, req.params).await,
             Some("get_keys") => return self.get_keys(req.id, req.params).await,
             Some("export_keypair") => return self.export_keypair(req.id, req.params).await,
+            Some("import_keypair") => return self.import_keypair(req.id, req.params).await,
             Some("set_default_address") => {
                 return self.set_default_address(req.id, req.params).await
             }
@@ -198,6 +202,48 @@ impl Darkfid {
         }
     }
 
+    // --> {"method": "import_keypair", "params": "[path/]"}
+    // <-- {"result": true}
+    async fn import_keypair(&self, id: Value, params: Value) -> JsonResult {
+        let args = params.as_array();
+
+        if args.is_none() {
+            return JsonResult::Err(jsonerr(InvalidParams, None, id))
+        }
+
+        let arg = args.unwrap()[0].clone();
+
+        if arg.as_str().is_none() &&
+            expand_path(arg.as_str().unwrap()).is_ok() &&
+            expand_path(arg.as_str().unwrap()).unwrap().to_str().is_some()
+        {
+            return JsonResult::Err(jsonerr(InvalidParams, Some("invalid path".into()), id))
+        }
+
+        let path = expand_path(arg.as_str().unwrap()).unwrap();
+        let path = path.to_str().unwrap();
+
+        let result: Result<()> = async {
+            let keypair_str: String = std::fs::read_to_string(path)?;
+
+            let mut bytes = [0u8; 32];
+            let bytes_vec: Vec<u8> = serde_json::from_str(&keypair_str)?;
+            bytes.copy_from_slice(&bytes_vec.as_slice());
+
+            let secret: SecretKey = SecretKey::from_bytes(&bytes)?;
+            let public: PublicKey = PublicKey::from_secret(secret);
+
+            self.client.lock().await.put_keypair(&Keypair { secret, public }).await?;
+            Ok(())
+        }
+        .await;
+
+        match result {
+            Ok(_) => JsonResult::Resp(jsonresp(json!(true), id)),
+            Err(err) => JsonResult::Err(jsonerr(ServerError(-32004), Some(err.to_string()), id)),
+        }
+    }
+
     // --> {"method": "export_keypair", "params": "[path/]"}
     // <-- {"result": true}
     async fn export_keypair(&self, id: Value, params: Value) -> JsonResult {

+ 14 - 0
src/bin/drk.rs

@@ -123,6 +123,13 @@ impl Drk {
         Ok(self.request(req).await?)
     }
 
+    // --> {"jsonrpc": "2.0", "method": "import_keypair", "params": "[path/]", "id": 42}
+    // <-- {"jsonrpc": "2.0", "result": true, "id": 42}
+    async fn import_keypair(&self, path: &str) -> Result<Value> {
+        let req = jsonrpc::request(json!("import_keypair"), json!([path]));
+        Ok(self.request(req).await?)
+    }
+
     // --> {"jsonrpc": "2.0", "method": "get_key", "params": ["solana", "usdc"], "id": 42}
     // <-- {"jsonrpc": "2.0", "result": "vdNS7oBj7KvsMWWmo9r96SV4SqATLrGsH2a3PGpCfJC", "id": 42}
     async fn get_token_id(&self, network: &str, token: &str) -> Result<Value> {
@@ -201,6 +208,7 @@ async fn start(config: &DrkConfig, options: CliDrk) -> Result<()> {
             balances,
             addresses,
             export_keypair,
+            import_keypair,
             set_default_address,
         }) => {
             if create {
@@ -281,6 +289,12 @@ async fn start(config: &DrkConfig, options: CliDrk) -> Result<()> {
                 client.export_keypair(&path).await?;
                 return Ok(())
             }
+
+            if import_keypair.is_some() {
+                let path = import_keypair.unwrap();
+                client.import_keypair(&path).await?;
+                return Ok(())
+            }
         }
         Some(CliDrkSubCommands::Id { network, token }) => {
             let network = network.to_lowercase();

+ 3 - 0
src/cli/cli_parser.rs

@@ -26,6 +26,9 @@ pub enum CliDrkSubCommands {
         /// Export default address
         #[clap(long, value_name = "PATH")]
         export_keypair: Option<String>,
+        /// Import address
+        #[clap(long, value_name = "PATH")]
+        import_keypair: Option<String>,
         /// Get wallet balances
         #[clap(long)]
         balances: bool,

+ 4 - 0
src/client.rs

@@ -384,6 +384,10 @@ impl Client {
         self.wallet.get_keypairs().await
     }
 
+    pub async fn put_keypair(&self, keypair: &Keypair) -> Result<()> {
+        self.wallet.put_keypair(keypair).await
+    }
+
     pub async fn set_default_keypair(&mut self, public: &PublicKey) -> Result<()> {
         self.wallet.set_default_keypair(public).await?;
         self.main_keypair = self.wallet.get_default_keypair().await?;

+ 3 - 3
src/rpc/jsonrpc.rs

@@ -21,7 +21,7 @@ pub enum ErrorCode {
     InternalError,
     KeyGenError,
     GetAddressesError,
-    CreateFile,
+    ImportAndExportFile,
     SetDefaultAddress,
     InvalidAmountParam,
     InvalidNetworkParam,
@@ -41,7 +41,7 @@ impl ErrorCode {
             ErrorCode::InternalError => -32603,
             ErrorCode::KeyGenError => -32002,
             ErrorCode::GetAddressesError => -32003,
-            ErrorCode::CreateFile => -32004,
+            ErrorCode::ImportAndExportFile => -32004,
             ErrorCode::SetDefaultAddress => -32005,
             ErrorCode::InvalidAmountParam => -32010,
             ErrorCode::InvalidNetworkParam => -32011,
@@ -61,7 +61,7 @@ impl ErrorCode {
             ErrorCode::InternalError => "Internal error",
             ErrorCode::KeyGenError => "Key gen error",
             ErrorCode::GetAddressesError => "get addresses error",
-            ErrorCode::CreateFile => "error creating a file",
+            ErrorCode::ImportAndExportFile => "error import/export a file",
             ErrorCode::SetDefaultAddress => "error set default address",
             ErrorCode::InvalidAmountParam => "Invalid amount param",
             ErrorCode::InvalidNetworkParam => "Invalid network param",