diff --git a/.gitignore b/.gitignore index a3eb24d60..c6be4d084 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,8 @@ __pycache__ # Python/Poetry projects .venv/ +env/ +venv/ # Node node_modules/ diff --git a/signer/src/service/api/mod.rs b/signer/src/service/api/mod.rs index 91971a9e6..acd526799 100644 --- a/signer/src/service/api/mod.rs +++ b/signer/src/service/api/mod.rs @@ -72,31 +72,86 @@ fn signer_service_api_inner(command: JsonCommandRequest) -> Result { - let account_info = service::get_account(&mnemonic)?; - JsonCommandResponse::get_account { account_info } - } + JsonCommandRequest::get_account { + mnemonic, + bip39_entropy, + } => match (mnemonic, bip39_entropy) { + (Some(mnemonic), None) => { + let account_info = service::get_account_by_mnemonic(&mnemonic)?; + JsonCommandResponse::get_account { account_info } + } + (None, Some(bip39_entropy)) => { + let account_info = service::get_account_by_bip39_entropy(&bip39_entropy)?; + JsonCommandResponse::get_account { account_info } + } + (None, None) => { + return Err(anyhow!("Either mnemonic or bip39_entropy must be provided")); + } + _ => { + return Err(anyhow!( + "Only one of mnemonic or bip39_entropy can be provided" + )) + } + }, JsonCommandRequest::sign_tx { mnemonic, + bip39_entropy, unsigned_tx_proposal, - } => { - let signed_tx = service::sign_tx( - &mnemonic, - (&unsigned_tx_proposal) - .try_into() - .map_err(|e: String| anyhow!(e))?, - )?; - JsonCommandResponse::sign_tx { - tx_proposal: (&signed_tx).try_into().map_err(|e: String| anyhow!(e))?, + } => match (mnemonic, bip39_entropy) { + (Some(mnemonic), None) => { + let signed_tx = service::sign_tx_with_mnemonic( + &mnemonic, + (&unsigned_tx_proposal) + .try_into() + .map_err(|e: String| anyhow!(e))?, + )?; + JsonCommandResponse::sign_tx { + tx_proposal: (&signed_tx).try_into().map_err(|e: String| anyhow!(e))?, + } } - } + (None, Some(bip39_entropy)) => { + let signed_tx = service::sign_tx_with_bip39_entropy( + &bip39_entropy, + (&unsigned_tx_proposal) + .try_into() + .map_err(|e: String| anyhow!(e))?, + )?; + JsonCommandResponse::sign_tx { + tx_proposal: (&signed_tx).try_into().map_err(|e: String| anyhow!(e))?, + } + } + (None, None) => { + return Err(anyhow!("Either mnemonic or bip39_entropy must be provided")); + } + _ => { + return Err(anyhow!( + "Only one of mnemonic or bip39_entropy can be provided" + )) + } + }, JsonCommandRequest::sync_txos { mnemonic, + bip39_entropy, txos_unsynced, - } => { - let txos_synced = service::sync_txos(&mnemonic, txos_unsynced)?; - JsonCommandResponse::sync_txos { txos_synced } - } + } => match (mnemonic, bip39_entropy) { + (Some(mnemonic), None) => { + let txos_synced = service::sync_txos_by_mnemonic(&mnemonic, txos_unsynced)?; + JsonCommandResponse::sync_txos { txos_synced } + } + (None, Some(bip39_entropy)) => { + let txos_synced = + service::sync_txos_by_bip39_entropy(&bip39_entropy, txos_unsynced)?; + JsonCommandResponse::sync_txos { txos_synced } + } + (None, None) => { + return Err(anyhow!("Either mnemonic or bip39_entropy must be provided")); + } + _ => { + return Err(anyhow!( + "Only one of mnemonic or bip39_entropy can be provided" + )) + } + }, }; Ok(response) diff --git a/signer/src/service/api/request.rs b/signer/src/service/api/request.rs index f24834362..83f7ab79e 100644 --- a/signer/src/service/api/request.rs +++ b/signer/src/service/api/request.rs @@ -33,14 +33,17 @@ impl TryFrom<&JsonRPCRequest> for JsonCommandRequest { pub enum JsonCommandRequest { create_account {}, get_account { - mnemonic: String, + mnemonic: Option, + bip39_entropy: Option, }, sign_tx { - mnemonic: String, + mnemonic: Option, + bip39_entropy: Option, unsigned_tx_proposal: UnsignedTxProposal, }, sync_txos { - mnemonic: String, + mnemonic: Option, + bip39_entropy: Option, txos_unsynced: Vec, }, } diff --git a/signer/src/service/mod.rs b/signer/src/service/mod.rs index bf7cd77c9..d669b77f9 100644 --- a/signer/src/service/mod.rs +++ b/signer/src/service/mod.rs @@ -24,8 +24,19 @@ pub fn create_account() -> (Mnemonic, AccountInfo) { (mnemonic, account_info) } -pub fn get_account(mnemonic: &str) -> Result { +pub fn get_account_by_mnemonic(mnemonic: &str) -> Result { let mnemonic = Mnemonic::from_phrase(mnemonic, Language::English)?; + get_account(mnemonic) +} + +pub fn get_account_by_bip39_entropy(bip39_entropy: &str) -> Result { + let mut entropy = [0u8; 32]; + hex::decode_to_slice(bip39_entropy, &mut entropy)?; + let mnemonic = Mnemonic::from_entropy(&entropy, Language::English)?; + get_account(mnemonic) +} + +fn get_account(mnemonic: Mnemonic) -> Result { let account = get_account_from_mnemonic(mnemonic); Ok(AccountInfo { @@ -34,9 +45,22 @@ pub fn get_account(mnemonic: &str) -> Result { account_index: 0, }) } - -pub fn sync_txos(mnemonic: &str, txos: Vec) -> Result> { +pub fn sync_txos_by_mnemonic(mnemonic: &str, txos: Vec) -> Result> { let mnemonic = Mnemonic::from_phrase(mnemonic, Language::English)?; + sync_txos(mnemonic, txos) +} + +pub fn sync_txos_by_bip39_entropy( + bip39_entropy: &str, + txos: Vec, +) -> Result> { + let mut entropy = [0u8; 32]; + hex::decode_to_slice(bip39_entropy, &mut entropy)?; + let mnemonic = Mnemonic::from_entropy(&entropy, Language::English)?; + sync_txos(mnemonic, txos) +} + +pub fn sync_txos(mnemonic: Mnemonic, txos: Vec) -> Result> { let account = get_account_from_mnemonic(mnemonic); let mut synced: Vec = Vec::new(); @@ -56,8 +80,25 @@ pub fn sync_txos(mnemonic: &str, txos: Vec) -> Result Result { +pub fn sign_tx_with_mnemonic( + mnemonic: &str, + unsigned_tx_proposal: UnsignedTxProposal, +) -> Result { let mnemonic = Mnemonic::from_phrase(mnemonic, Language::English)?; + sign_tx(mnemonic, unsigned_tx_proposal) +} + +pub fn sign_tx_with_bip39_entropy( + bip39_entropy: &str, + unsigned_tx_proposal: UnsignedTxProposal, +) -> Result { + let mut entropy = [0u8; 32]; + hex::decode_to_slice(bip39_entropy, &mut entropy)?; + let mnemonic = Mnemonic::from_entropy(&entropy, Language::English)?; + sign_tx(mnemonic, unsigned_tx_proposal) +} + +pub fn sign_tx(mnemonic: Mnemonic, unsigned_tx_proposal: UnsignedTxProposal) -> Result { let account = get_account_from_mnemonic(mnemonic); let account_key = AccountKey::new( account.spend_private_key().as_ref(),