Răsfoiți Sursa

walletdb: add the option to set/get the default keypair

ghassmo 4 ani în urmă
părinte
comite
49e1699702
3 a modificat fișierele cu 59 adăugiri și 8 ștergeri
  1. 2 1
      sql/keys.sql
  2. 9 5
      src/client.rs
  3. 48 2
      src/wallet/walletdb.rs

+ 2 - 1
sql/keys.sql

@@ -1,5 +1,6 @@
 CREATE TABLE IF NOT EXISTS keys(
 	key_id INTEGER PRIMARY KEY NOT NULL,
 	public BLOB NOT NULL,
-	secret BLOB NOT NULL
+	secret BLOB NOT NULL,
+	is_default Boolean NOT NULL
 );

+ 9 - 5
src/client.rs

@@ -87,9 +87,14 @@ impl Client {
     ) -> Result<Self> {
         wallet.init_db().await?;
 
-        // Generate a new keypair if we don't have any.
-        if wallet.get_keypairs().await?.is_empty() {
-            wallet.key_gen().await?;
+        // Check if there is a default keypair
+        if wallet.get_default_keypair().await.is_err() {
+            // Generate a new keypair if we don't have any.
+            if wallet.get_keypairs().await?.is_empty() {
+                wallet.key_gen().await?;
+            }
+            // set the first keypair as the default one
+            wallet.set_default_keypair(&wallet.get_keypairs().await?[0].public).await?;
         }
 
         // Generate merkle tree if we don't have one.
@@ -97,8 +102,7 @@ impl Client {
             wallet.tree_gen().await?;
         }
 
-        // TODO: Think about multiple keypairs
-        let main_keypair = wallet.get_keypairs().await?[0];
+        let main_keypair = wallet.get_default_keypair().await?;
         info!("Main keypair: {}", bs58::encode(&serialize(&main_keypair.public)).into_string());
 
         trace!("Creating GatewayClient");

+ 48 - 2
src/wallet/walletdb.rs

@@ -104,17 +104,55 @@ impl WalletDb {
         debug!("Writing keypair into the wallet database");
         let pubkey = serialize(&keypair.public);
         let secret = serialize(&keypair.secret);
+        let is_default = 0;
 
         let mut conn = self.conn.acquire().await?;
-        sqlx::query("INSERT INTO keys(public, secret) VALUES (?1, ?2)")
+
+        sqlx::query("INSERT INTO keys(public, secret, is_default) VALUES (?1, ?2, ?3)")
             .bind(pubkey)
             .bind(secret)
+            .bind(is_default)
+            .execute(&mut conn)
+            .await?;
+
+        Ok(())
+    }
+
+    pub async fn set_default_keypair(&self, public: &PublicKey) -> Result<()> {
+        debug!("Set default keypair");
+        let mut conn = self.conn.acquire().await?;
+
+        let pubkey = serialize(public);
+
+        // unset previous default keypair
+        sqlx::query("UPDATE keys SET is_default = 0;").execute(&mut conn).await?;
+
+        // set new default keypair
+        sqlx::query("UPDATE keys SET is_default = 1 WHERE public = ?1;")
+            .bind(pubkey)
             .execute(&mut conn)
             .await?;
 
         Ok(())
     }
 
+    pub async fn get_default_keypair(&self) -> Result<Keypair> {
+        debug!("Returning default keypair");
+        let mut conn = self.conn.acquire().await?;
+
+        let is_default = 1;
+
+        let row = sqlx::query("SELECT * FROM keys WHERE is_default = ?1;")
+            .bind(is_default)
+            .fetch_one(&mut conn)
+            .await?;
+
+        let public: PublicKey = self.get_value_deserialized(row.get("public"))?;
+        let secret: SecretKey = self.get_value_deserialized(row.get("secret"))?;
+
+        Ok(Keypair { secret, public })
+    }
+
     pub async fn get_keypairs(&self) -> Result<Vec<Keypair>> {
         debug!("Returning keypairs");
         let mut conn = self.conn.acquire().await?;
@@ -426,12 +464,20 @@ mod tests {
         assert_eq!(balances.list[2].value, 42);
         assert_eq!(balances.list[3].token_id, token_id);
 
-        // get_keypairs()
+        /////////////////
+        //// keypair ////
+        /////////////////
         let keypair2 = Keypair::random(&mut OsRng);
+        // add new keypair
         wallet.put_keypair(&keypair2).await?;
+        // get all keypairs
         let keypairs = wallet.get_keypairs().await?;
         assert_eq!(keypair, keypairs[0]);
         assert_eq!(keypair2, keypairs[1]);
+        // set the keypair at index 1 as the default keypair
+        wallet.set_default_keypair(&keypair2.public).await?;
+        // get default keypair
+        assert_eq!(keypair2, wallet.get_default_keypair().await?);
 
         // get_own_coins()
         let own_coins = wallet.get_own_coins().await?;