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: imkey cosmos support multi-network function #133

Open
wants to merge 18 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
64 changes: 64 additions & 0 deletions .github/workflows/run-unittest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Run Tcx Unit Testing

on:
pull_request:
types:
- opened
- synchronize

concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.sha }}
cancel-in-progress: true

env:
CARGO_TERM_COLOR: always


jobs:
build:
name: Run Tcx Unit Testing
runs-on: macos-12
steps:
- name: Get the latest commit SHA
id: sha
uses: actions/github-script@v6
with:
result-encoding: string
script: |
const { owner, repo, number } = context.issue
const pr = await github.rest.pulls.get({
owner,
repo,
pull_number: number,
})
return pr.data.head.sha

- name: Checkout repository
uses: actions/checkout@v3
with:
ref: ${{ steps.sha.outputs.result }}
fetch-depth: 5

- name: Cache
uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
~/.rustup
target
key: ${{ runner.os }}-nightly

- name: Install Rust
run: |
rustup toolchain install nightly-2022-10-31
rustup default nightly-2022-10-31-x86_64-apple-darwin
rustup show

- name: Install dependency
run: |
brew install protobuf

- name: Run TCX Unit Testing
run: |
make test-tcx
18 changes: 7 additions & 11 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.4
2.8.0
1 change: 0 additions & 1 deletion imkey-core/ikc-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ edition = "2018"
hyper = { version = "=0.14.23", features = ["full"] }
hyper-tls = "=0.5.0"
hyper-timeout = "=0.4.1"
rustc-serialize = "=0.3.24"
serde = { version = "=1.0.147", features = ["derive"] }
serde_derive = "=1.0.147"
serde_json = "=1.0.89"
Expand Down
98 changes: 97 additions & 1 deletion imkey-core/ikc-common/src/apdu.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::constants::{BTC_AID, COSMOS_AID, EOS_AID, ETH_AID, LC_MAX};
use crate::error::ApduError;
use crate::hex::ToHex;
use crate::Result;
use hex;
use rustc_serialize::hex::ToHex;

pub trait CoinCommonApdu: Default {
fn select_applet() -> String;
Expand Down Expand Up @@ -69,6 +69,19 @@ impl BtcApdu {
apdu.to_hex().to_uppercase()
}

/**
*p2 00:sign psbt transaction 80: sign message
**/
pub fn btc_psbt_preview(data: &Vec<u8>, p2: u8) -> String {
if data.len() as u32 > LC_MAX {
panic!("data to long");
}
let mut apdu = ApduHeader::new(0x80, 0x4C, 0x00, p2, data.len() as u8).to_array();
apdu.extend(data.iter());
apdu.push(0x00);
apdu.to_hex().to_uppercase()
}

pub fn btc_sign(index: u8, hash_type: u8, path: &str) -> String {
let path_bytes = path.as_bytes();
let mut apdu =
Expand All @@ -93,6 +106,36 @@ impl BtcApdu {
apdu.to_hex().to_uppercase()
}

pub fn btc_taproot_sign(last_one: bool, data: Vec<u8>) -> String {
if data.len() as u32 > LC_MAX {
panic!("data to long");
}

let mut apdu = match last_one {
true => ApduHeader::new(0x80, 0x40, 0x80, 0x00, data.len() as u8).to_array(),
_ => ApduHeader::new(0x80, 0x40, 0x00, 0x00, data.len() as u8).to_array(),
};

apdu.extend(data.iter());
apdu.push(0x00);
apdu.to_hex().to_uppercase()
}

pub fn btc_taproot_script_sign(last_one: bool, data: Vec<u8>) -> String {
if data.len() as u32 > LC_MAX {
panic!("data to long");
}

let mut apdu = match last_one {
true => ApduHeader::new(0x80, 0x40, 0x80, 0x80, data.len() as u8).to_array(),
_ => ApduHeader::new(0x80, 0x40, 0x00, 0x80, data.len() as u8).to_array(),
};

apdu.extend(data.iter());
apdu.push(0x00);
apdu.to_hex().to_uppercase()
}

pub fn omni_prepare_data(p1: u8, data: Vec<u8>) -> String {
if data.len() as u32 > LC_MAX {
panic!("data to long");
Expand All @@ -111,6 +154,58 @@ impl BtcApdu {
data.extend(name);
Apdu::register_address(0x37, &data)
}

pub fn btc_single_utxo_sign_prepare(ins: u8, data: &Vec<u8>) -> Vec<String> {
let mut apdu_vec = Vec::new();
let apdu_number = (data.len() - 1) / LC_MAX as usize + 1;
for index in 0..apdu_number {
if index == 0 && index == apdu_number - 1 {
let length = if data.len() % LC_MAX as usize == 0 {
LC_MAX
} else {
(data.len() % LC_MAX as usize) as u32
};
let mut temp_apdu_vec =
ApduHeader::new(0x80, ins, 0x00, 0x80, length as u8).to_array();
temp_apdu_vec.extend_from_slice(&data[index * LC_MAX as usize..]);
apdu_vec.push(hex::encode_upper(temp_apdu_vec));
} else if index == 0 && index != apdu_number - 1 {
let mut temp_apdu_vec =
ApduHeader::new(0x80, ins, 0x00, 0x00, LC_MAX as u8).to_array();
temp_apdu_vec.extend_from_slice(
&data[index * LC_MAX as usize..((index + 1) * LC_MAX as usize) as usize],
);
apdu_vec.push(hex::encode_upper(temp_apdu_vec));
} else if index != 0 && index != apdu_number - 1 {
let mut temp_apdu_vec =
ApduHeader::new(0x80, ins, 0x80, 0x00, LC_MAX as u8).to_array();
temp_apdu_vec.extend_from_slice(
&data[index * LC_MAX as usize..((index + 1) * LC_MAX as usize) as usize],
);
apdu_vec.push(hex::encode_upper(temp_apdu_vec));
} else if index != 0 && index == apdu_number - 1 {
let length = if data.len() % LC_MAX as usize == 0 {
LC_MAX
} else {
(data.len() % LC_MAX as usize) as u32
};
let mut temp_apdu_vec =
ApduHeader::new(0x80, ins, 0x80, 0x80, length as u8).to_array();
temp_apdu_vec.extend_from_slice(&data[index * LC_MAX as usize..]);
apdu_vec.push(hex::encode_upper(temp_apdu_vec));
}
}
return apdu_vec;
}

pub fn btc_single_utxo_sign(index: u8, hash_type: u8, path: &str) -> String {
let path_bytes = path.as_bytes();
let mut apdu =
ApduHeader::new(0x80, 0x45, index, hash_type, path_bytes.len() as u8).to_array();
apdu.extend(path_bytes.iter());
apdu.push(0x00);
apdu.to_hex().to_uppercase()
}
}

pub struct EthApdu();
Expand Down Expand Up @@ -562,6 +657,7 @@ impl ApduCheck {
"F080" => Err(ApduError::ImkeyInMenuPage.into()),
"F081" => Err(ApduError::ImkeyPinNotVerified.into()),
"6F01" => Err(ApduError::ImkeyBluetoothChannelError.into()),
"6943" => Err(ApduError::ImkeyMnemonicCheckFailed.into()),
_ => Err(anyhow!("imkey_command_execute_fail_{}", response_data)), //Err(ApduError::ImkeyCommandExecuteFail.into())
}
}
Expand Down
14 changes: 12 additions & 2 deletions imkey-core/ikc-common/src/applet.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::constants::{
BCH_AID, BTC_AID, COSMOS_AID, EOS_AID, ETH_AID, FILECOIN_AID, IMK_AID, KUSAMA_AID, LTC_AID,
NERVOS_AID, POLKADOT_AID, TEZOS_AID, TRON_AID,
BCH_AID, BTC_AID, COSMOS_AID, DOGECOIN_AID, EOS_AID, ETH_AID, FILECOIN_AID, IMK_AID,
KUSAMA_AID, LTC_AID, NERVOS_AID, POLKADOT_AID, TEZOS_AID, TRON_AID,
};
// type __appletName = 'IMK' | 'Ethereum' | 'Bitcoin' | 'EOS' | 'Cosmos' | 'Filecoin' | 'Kusama' | 'Tezos' | 'Polkadot' | 'TRON' | 'Bitcoin Cash' | 'Litecoin' | 'Nervos'
pub fn get_appname_by_instid(instid: &str) -> Option<&str> {
Expand All @@ -18,6 +18,7 @@ pub fn get_appname_by_instid(instid: &str) -> Option<&str> {
IMK_AID => Some("IMK"),
NERVOS_AID => Some("Nervos"),
TEZOS_AID => Some("Tezos"),
DOGECOIN_AID => Some("Dogecoin"),
_ => None,
}
}
Expand All @@ -36,6 +37,7 @@ pub fn get_instid_by_appname(appname: &str) -> Option<&str> {
"Bitcoin Cash" => Some(BCH_AID),
"Litecoin" => Some(LTC_AID),
"IMK" => Some(IMK_AID),
"Dogecoin" => Some(DOGECOIN_AID),
_ => None,
}
}
Expand All @@ -56,6 +58,10 @@ mod tests {
assert_eq!(get_appname_by_instid("695F626368").unwrap(), "Bitcoin Cash");
assert_eq!(get_appname_by_instid("695F6C7463").unwrap(), "Litecoin");
assert_eq!(get_appname_by_instid("695F696D6B").unwrap(), "IMK");
assert_eq!(
get_appname_by_instid("695F646F6765636F696E").unwrap(),
"Dogecoin"
);
assert!(get_appname_by_instid("1111111111").is_none());
}

Expand All @@ -72,6 +78,10 @@ mod tests {
);
assert_eq!(get_instid_by_appname("Bitcoin Cash").unwrap(), "695F626368");
assert_eq!(get_instid_by_appname("Litecoin").unwrap(), "695F6C7463");
assert_eq!(
get_instid_by_appname("Dogecoin").unwrap(),
"695F646F6765636F696E"
);
assert!(get_instid_by_appname("APPLET").is_none());
}
}
Loading
Loading