Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ikc add get_extended_public_key api [R2D2-10567] #70

Merged
merged 5 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里为什么要改成小写?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

现在返回给的公钥信息不都要统一成小写嘛?而且我看tcx这个接口返回的都是小写,为了保持统一。

}

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
Loading