Skip to content

Commit

Permalink
feat: ikc add get_extended_public_key api [R2D2-10567] (#70)
Browse files Browse the repository at this point in the history
* feat: add ikc get_extended_public_key api

* fix: derive_sub_accounts returns data and adds path field

* fix: modify GetExtendedPublicKeysParam proto message tag number

* chore: modify pr reivew problem

* feat: add get_public_keys api and code optimization

1. add  get_public_keys api
2. remove btc_get_xpub api
3. get_extended_public_key interface removes ed25519 curve support
  • Loading branch information
xiaoguang1010 authored Mar 1, 2024
1 parent e9d4d1d commit e5deac3
Show file tree
Hide file tree
Showing 9 changed files with 378 additions and 54 deletions.
4 changes: 2 additions & 2 deletions imkey-core/ikc-common/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub fn check_path_validity(path: &str) -> Result<()> {
//check depth and length
let strings: Vec<&str> = path.split("/").collect();
let depth = strings.len();
if depth < 2 || depth > 10 {
if depth < 3 || depth > 10 {
return Err(CommonError::ImkeyPathIllegal.into());
}
Ok(())
Expand All @@ -16,7 +16,7 @@ pub fn check_path_max_five_depth(path: &str) -> Result<()> {
//check depth and length
let strings: Vec<&str> = path.split("/").collect();
let depth = strings.len();
if depth < 2 || depth > 6 {
if depth < 3 || depth > 6 {
return Err(CommonError::ImkeyPathIllegal.into());
}
Ok(())
Expand Down
22 changes: 22 additions & 0 deletions imkey-core/ikc-proto/src/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,26 @@ message DeriveSubAccountsParam {

message DeriveSubAccountsResult {
repeated AccountResponse accounts = 1;
}

message GetExtendedPublicKeysParam {
repeated PublicKeyDerivation derivations = 1;
}

message GetExtendedPublicKeysResult {
repeated string extendedPublicKeys = 1;
}

message PublicKeyDerivation {
string chainType = 1;
string path = 2;
string curve = 3;
}

message GetPublicKeysParam {
repeated PublicKeyDerivation derivations = 1;
}

message GetPublicKeysResult {
repeated string publicKeys = 1;
}
11 changes: 0 additions & 11 deletions imkey-core/ikc-proto/src/btc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,3 @@ message BtcTxOutput {
string txHash = 2;
string wtxHash = 3;
}

message BtcXpubReq {
string network = 1;
string path = 2;
}

message BtcXpubRes {
string xpub = 1;
}


14 changes: 0 additions & 14 deletions imkey-core/ikc-wallet/coin-bitcoin/src/btcapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,3 @@ pub struct BtcTxOutput {
#[prost(string, tag = "3")]
pub wtx_hash: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BtcXpubReq {
#[prost(string, tag = "1")]
pub network: ::prost::alloc::string::String,
#[prost(string, tag = "2")]
pub path: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BtcXpubRes {
#[prost(string, tag = "1")]
pub xpub: ::prost::alloc::string::String,
}
2 changes: 1 addition & 1 deletion imkey-core/ikc-wallet/coin-substrate/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl SubstrateAddress {
return Err(CoinError::ImkeySignatureVerifyFail.into());
}

Ok(pubkey.to_string())
Ok(pubkey.to_lowercase())
}

pub fn get_address(path: &str, address_type: &AddressType) -> Result<String> {
Expand Down
34 changes: 34 additions & 0 deletions imkey-core/ikc/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,37 @@ pub struct DeriveSubAccountsResult {
#[prost(message, repeated, tag = "1")]
pub accounts: ::prost::alloc::vec::Vec<AccountResponse>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetExtendedPublicKeysParam {
#[prost(message, repeated, tag = "1")]
pub derivations: ::prost::alloc::vec::Vec<PublicKeyDerivation>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetExtendedPublicKeysResult {
#[prost(string, repeated, tag = "1")]
pub extended_public_keys: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PublicKeyDerivation {
#[prost(string, tag = "1")]
pub chain_type: ::prost::alloc::string::String,
#[prost(string, tag = "2")]
pub path: ::prost::alloc::string::String,
#[prost(string, tag = "3")]
pub curve: ::prost::alloc::string::String,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetPublicKeysParam {
#[prost(message, repeated, tag = "1")]
pub derivations: ::prost::alloc::vec::Vec<PublicKeyDerivation>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct GetPublicKeysResult {
#[prost(string, repeated, tag = "1")]
pub public_keys: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
}
10 changes: 0 additions & 10 deletions imkey-core/ikc/src/btc_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,9 @@ use crate::error_handling::Result;
use crate::message_handler::encode_message;
use bitcoin::network::constants::Network;
use coin_bitcoin::address::BtcAddress;
use coin_bitcoin::btcapi::{BtcXpubReq, BtcXpubRes};
use ikc_common::utility::network_convert;
use prost::Message;

pub fn get_btc_xpub(data: &[u8]) -> Result<Vec<u8>> {
let input: BtcXpubReq = BtcXpubReq::decode(data).expect("imkey_illegal_param");
let network = network_convert(input.network.as_ref());
let xpub = BtcAddress::get_xpub(network, input.path.as_ref())?;

let address_message = BtcXpubRes { xpub };
encode_message(address_message)
}

pub fn get_address(param: &AddressParam) -> Result<Vec<u8>> {
let network = network_convert(param.network.as_ref());
let account_path = param.path.to_string();
Expand Down
52 changes: 50 additions & 2 deletions imkey-core/ikc/src/handler.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::api::{
AccountResponse, DeriveAccountsParam, DeriveAccountsResult, DeriveSubAccountsParam,
DeriveSubAccountsResult,
DeriveSubAccountsResult, GetExtendedPublicKeysParam, GetExtendedPublicKeysResult,
GetPublicKeysParam, GetPublicKeysResult,
};
use crate::message_handler::encode_message;
use crate::Result;
use anyhow::anyhow;
use bitcoin::hashes::hex::ToHex;
use bitcoin::util::bip32::ExtendedPubKey;
use bitcoin::Network;
use coin_bch::address::BchAddress;
use coin_bitcoin::address::BtcAddress;
use coin_btc_fork::address::BtcForkAddress;
Expand All @@ -22,7 +24,7 @@ use ikc_common::curve::CurveType;
use ikc_common::path::get_account_path;
use ikc_common::utility::{
encrypt_xpub, extended_pub_key_derive, from_ss58check_with_version, get_xpub_prefix,
network_convert, to_ss58check_with_version, uncompress_pubkey_2_compress,
hex_to_bytes, network_convert, to_ss58check_with_version, uncompress_pubkey_2_compress,
};
use prost::Message;
use std::str::FromStr;
Expand Down Expand Up @@ -168,6 +170,7 @@ pub(crate) fn derive_sub_accounts(data: &[u8]) -> Result<Vec<u8>> {
let ext_pub_key = extended_pub_key_derive(&xpub.0, &relative_path)?;
let pub_key_uncompressed = ext_pub_key.public_key.serialize_uncompressed().to_vec();
account.public_key = format!("0x{}", ext_pub_key.public_key.serialize().to_hex());
account.path = relative_path;
let address = match param.chain_type.as_str() {
"ETHEREUM" => EthAddress::from_pub_key(pub_key_uncompressed)?,
"BITCOIN" | "LITECOIN" => {
Expand Down Expand Up @@ -195,6 +198,51 @@ pub(crate) fn derive_sub_accounts(data: &[u8]) -> Result<Vec<u8>> {
})
}

pub(crate) fn get_extended_public_keys(data: &[u8]) -> Result<Vec<u8>> {
let param: GetExtendedPublicKeysParam = GetExtendedPublicKeysParam::decode(data)?;
let mut extended_public_keys = vec![];
for public_key_derivation in param.derivations.iter() {
// if "".eq(&public_key_derivation.path) || &public_key_derivation.path.split("/") { }
let extended_public_key = match public_key_derivation.curve.as_str() {
"secp256k1" => {
BtcAddress::get_xpub(Network::Bitcoin, public_key_derivation.path.as_str())?
}
_ => return Err(anyhow!("unsupported_curve_type")),
};
extended_public_keys.push(extended_public_key);
}
encode_message(GetExtendedPublicKeysResult {
extended_public_keys,
})
}

pub(crate) fn get_public_keys(data: &[u8]) -> Result<Vec<u8>> {
let param: GetPublicKeysParam = GetPublicKeysParam::decode(data)?;
let mut public_keys = vec![];
for public_key_derivation in param.derivations.iter() {
let mut public_key = match public_key_derivation.curve.as_str() {
"secp256k1" => uncompress_pubkey_2_compress(&BtcAddress::get_pub_key(
public_key_derivation.path.as_str(),
)?),
"ed25519" => SubstrateAddress::get_public_key(
public_key_derivation.path.as_str(),
&AddressType::Polkadot,
)?,
_ => return Err(anyhow!("unsupported_curve_type")),
};
if !public_key.starts_with("0x") {
public_key = format!("0x{}", public_key);
};
let public_key = match public_key_derivation.chain_type.as_str() {
"EOS" => EosPubkey::from_pub_key(hex_to_bytes(&public_key)?.as_slice())?,
_ => public_key,
};
public_keys.push(public_key);
}

encode_message(GetPublicKeysResult { public_keys })
}

#[cfg(test)]
mod test {
use crate::api::derive_accounts_param::Derivation;
Expand Down
Loading

0 comments on commit e5deac3

Please sign in to comment.