Skip to content

Commit

Permalink
feat: add the sign feature (#24)
Browse files Browse the repository at this point in the history
  • Loading branch information
kayagokalp committed Aug 29, 2022
1 parent e385bef commit d78bba3
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ eth-keystore = { version = "0.4" }
fuel-crypto = "0.6"
fuel-types = "0.5"
fuels = { version = "0.20", default-features = false }
fuels-signers = { version = "0.20.0" }
home = "0.5.3"
rand = { version = "0.8.4", default-features = false }
rpassword = "6.0.1"
Expand Down
7 changes: 3 additions & 4 deletions src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use crate::utils::{
create_accounts_file, number_of_derived_accounts, Accounts, DEFAULT_WALLETS_VAULT_PATH,
};
use anyhow::{bail, Result};
use fuels::prelude::*;
use fuels::signers::wallet::Wallet;
use fuels::{prelude::*, signers::wallet::Wallet};
use std::path::PathBuf;

pub(crate) fn print_account_address(path: Option<String>, account_index: usize) -> Result<()> {
Expand All @@ -13,7 +12,7 @@ pub(crate) fn print_account_address(path: Option<String>, account_index: usize)
};
let existing_accounts = Accounts::from_dir(&wallet_path)?;
if let Some(account) = existing_accounts.addresses().iter().nth(account_index) {
println!("Account {} address: 0x{}", account_index, account);
println!("Account {} address: {}", account_index, account);
} else {
eprintln!("Account {} is not derived yet!", account_index);
}
Expand Down Expand Up @@ -43,6 +42,6 @@ pub(crate) fn new_account(path: Option<String>) -> Result<()> {
account_addresses.push(wallet.address().to_string());
create_accounts_file(&wallet_path, account_addresses)?;

println!("Wallet public address: {}", wallet.address());
println!("Wallet address: {}", wallet.address());
Ok(())
}
13 changes: 13 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
mod account;
mod init;
mod list;
mod sign;
mod utils;

use crate::{
account::{new_account, print_account_address},
init::init_wallet,
list::print_wallet_list,
sign::sign_transaction_manually,
};
use anyhow::Result;
use clap::{ArgEnum, Parser, Subcommand};
Expand Down Expand Up @@ -39,6 +41,12 @@ enum Command {
account_index: usize,
path: Option<String>,
},
/// Sign a transaction by providing its ID and the signing account's index
Sign {
id: String,
account_index: usize,
path: Option<String>,
},
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
Expand All @@ -60,6 +68,11 @@ async fn main() -> Result<()> {
account_index,
path,
} => print_account_address(path, account_index)?,
Command::Sign {
id,
account_index,
path,
} => sign_transaction_manually(&id, account_index, path).await?,
};
Ok(())
}
23 changes: 23 additions & 0 deletions src/sign.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::utils::{derive_account_with_index, DEFAULT_WALLETS_VAULT_PATH};
use anyhow::{anyhow, Result};
use fuel_crypto::{Message, Signature};
use fuel_types::Bytes32;
use fuels::prelude::*;
use std::{path::PathBuf, str::FromStr};

pub(crate) async fn sign_transaction_manually(
id: &str,
account_index: usize,
path: Option<String>,
) -> Result<(), Error> {
let wallet_path = match &path {
Some(path) => PathBuf::from(path),
None => home::home_dir().unwrap().join(DEFAULT_WALLETS_VAULT_PATH),
};
let tx_id = Bytes32::from_str(id).map_err(|e| anyhow!("{}", e))?;
let secret_key = derive_account_with_index(&wallet_path, account_index)?;
let message_hash = unsafe { Message::from_bytes_unchecked(*tx_id) };
let sig = Signature::sign(&secret_key, &message_hash);
println!("Signature: {sig}");
Ok(())
}
12 changes: 12 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::{anyhow, Result};
use fuel_crypto::SecretKey;
use serde::{Deserialize, Serialize};
use std::{fs, path::Path};

Expand Down Expand Up @@ -62,3 +63,14 @@ pub(crate) fn number_of_derived_accounts(path: &Path) -> usize {
0
}
}

pub(crate) fn derive_account_with_index(path: &Path, account_index: usize) -> Result<SecretKey> {
let password = rpassword::prompt_password(
"Please enter your password to decrypt initialized wallet's phrases: ",
)?;
let phrase_recovered = eth_keystore::decrypt_key(path.join(".wallet"), password)?;
let phrase = String::from_utf8(phrase_recovered)?;
let derive_path = format!("m/44'/1179993420'/{}'/0/0", account_index);
let secret_key = SecretKey::new_from_mnemonic_phrase_with_path(&phrase, &derive_path)?;
Ok(secret_key)
}

0 comments on commit d78bba3

Please sign in to comment.