Skip to content

Commit

Permalink
feat: imKey bitcon support taproot and native segwit transaction[R2D2…
Browse files Browse the repository at this point in the history
…-11241] (#102)

* feat: add p2wpkhp2tr address generation

* feat: add bitcoin Mixed signature function

* test: modify p2wpkh test case

* feat: add bitcoin p2wpkh sign

* feat: add test case and add p2tr sign

* test: add test case

* test: modify btc test case

* feat: code optimization

* feat: modify display_addres and get_address

* feat: add bitcoin p2tr transaction

* test: add p2tr test case

* chore: remove useless serde-aux library (#103)

* test: add bitcoin transaction sign function test

* feat: code optimization

* fix: import mnemonic return wrong existed id (#104)

* feat: pass in the tweaked public key when signing

* chore: code format

* feat: allow import test wif in production env (#105)

* feat: taproot sign script (#98)

* Add PsbtSigner

* finish taproot sign in psbt

* feat: add taproot sign script

fix: rebase issue

fix: append script and control block to witness

* fix: sign tap script no need tweak privatekey

Fix after rebase

* fix: merge missing code

* chore: remove println hash

* add bip322 message signature

* add multi address type in bitcoin psbt

* add tests for bitcoin bip322 sign

---------

Co-authored-by: Sun Feng <[email protected]>

* fix: remove deprecated fil library (#106)

* fix: remove deprecated fil library

* feat: upgrade deprecated fil dep in ikc

* Update build-release-ios.yml runs-on

* Update build-release-ios.yml runs-on macos-14

* feat: remove forest_bigint support

* feat: add p2wpkhp2tr address generation

* feat: add bitcoin Mixed signature function

* test: modify p2wpkh test case

* feat: add bitcoin p2wpkh sign

* feat: add test case and add p2tr sign

* test: add test case

* test: modify btc test case

* feat: code optimization

* feat: modify display_addres and get_address

* feat: add bitcoin p2tr transaction

* test: add p2tr test case

* test: add bitcoin transaction sign function test

* feat: code optimization

* feat: pass in the tweaked public key when signing

* chore: code format

* chore: switch to staging env

* feat: derive_account and derive_sub_account support native segwit address and bech32 address

---------

Co-authored-by: Neal Xu <[email protected]>
Co-authored-by: Sun Feng <[email protected]>
  • Loading branch information
3 people authored Dec 23, 2024
1 parent 9681831 commit 818de5f
Show file tree
Hide file tree
Showing 23 changed files with 2,194 additions and 859 deletions.
67 changes: 67 additions & 0 deletions imkey-core/ikc-common/src/apdu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ 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 omni_prepare_data(p1: u8, data: Vec<u8>) -> String {
if data.len() as u32 > LC_MAX {
panic!("data to long");
Expand All @@ -111,6 +126,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
10 changes: 5 additions & 5 deletions imkey-core/ikc-common/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub const VERSION: &str = "2.15.2";
pub const URL: &str = "https://imkey.online:1000/imkey";
// pub const URL: &str = "https://imkeyserver.com:10444/imkey";
// pub const URL: &str = "https://imkey.online:1000/imkey";
pub const URL: &str = "https://imkeyserver.com:10444/imkey";

pub const TSM_ACTION_SE_SECURE_CHECK: &str = "/seSecureCheck";
pub const TSM_ACTION_APP_DOWNLOAD: &str = "/appDownload";
Expand Down Expand Up @@ -44,11 +44,11 @@ pub const TRON_PATH: &str = "m/44'/195'/0'/0/0";

pub const MAX_UTXO_NUMBER: usize = 252;
pub const EACH_ROUND_NUMBER: usize = 5;
pub const DUST_THRESHOLD: i64 = 2730;
pub const MIN_NONDUST_OUTPUT: i64 = 546;
pub const DUST_THRESHOLD: u64 = 2730;
pub const MIN_NONDUST_OUTPUT: u64 = 546;
// max op return size
pub const MAX_OPRETURN_SIZE: usize = 80;
pub const BTC_FORK_DUST: i64 = 546;
pub const BTC_FORK_DUST: u64 = 546;

// imkey device status
pub const IMKEY_DEV_STATUS_INACTIVATED: &str = "inactivated";
Expand Down
2 changes: 2 additions & 0 deletions imkey-core/ikc-common/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,6 @@ pub enum CoinError {
InvalidVersion,
#[error("invalid addr length")]
InvalidAddrLength,
#[error("invalid_utxo")]
InvalidUtxo,
}
2 changes: 1 addition & 1 deletion imkey-core/ikc-common/src/utility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn secp256k1_sign_verify(public: &[u8], signed: &[u8], message: &[u8]) -> Re
.is_ok())
}

pub fn bigint_to_byte_vec(val: i64) -> Vec<u8> {
pub fn bigint_to_byte_vec(val: u64) -> Vec<u8> {
let mut return_data = BigInt::from(val).to_signed_bytes_be();
while return_data.len() < 8 {
return_data.insert(0, 0x00);
Expand Down
2 changes: 1 addition & 1 deletion imkey-core/ikc-device/src/device_binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ pub fn bind_test() {
// pub const TEST_KEY_PATH: &str = "/tmp/";
// pub const TEST_BIND_CODE: &str = "MCYNK5AH";
pub const TEST_KEY_PATH: &str = "/tmp/";
pub const TEST_BIND_CODE: &str = "7FVRAJJ7";
pub const TEST_BIND_CODE: &str = "FT2Z3LT2";

#[cfg(test)]
mod test {
Expand Down
2 changes: 1 addition & 1 deletion imkey-core/ikc-proto/src/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ message AddressParam {
string chainType = 1;
string path = 2;
string network = 3;
bool isSegWit = 4;
string segWit = 4;
}

message AddressResult {
Expand Down
12 changes: 6 additions & 6 deletions imkey-core/ikc-proto/src/btc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package btcapi;

message Utxo {
string tx_hash = 1;
int32 vout = 2;
int64 amount = 3;
uint32 vout = 2;
uint64 amount = 3;
string address = 4;
string script_pubKey = 5;
string derived_path = 6;
Expand All @@ -18,13 +18,13 @@ message BtcTxExtra {
}
message BtcTxInput {
string to = 1;
int64 amount = 2;
int64 fee = 3;
uint32 change_address_index = 4;
uint64 amount = 2;
uint64 fee = 3;
optional uint32 change_address_index = 4;
repeated Utxo unspents = 5;
string segWit = 6;
string protocol = 7;
BtcTxExtra extra = 8;
optional BtcTxExtra extra = 8;
}

message BtcTxOutput {
Expand Down
8 changes: 4 additions & 4 deletions imkey-core/ikc-proto/src/btcfork.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package btcforkapi;

message Utxo {
string txHash = 1;
int32 vout = 2;
int64 amount = 3;
uint32 vout = 2;
uint64 amount = 3;
string address = 4;
string scriptPubKey = 5;
string derivedPath = 6;
Expand All @@ -13,9 +13,9 @@ message Utxo {

message BtcForkTxInput {
string to = 1;
int64 amount = 2;
uint64 amount = 2;
repeated Utxo unspents = 3;
int64 fee = 4;
uint64 fee = 4;
uint32 changeAddressIndex = 5;
string changeAddress = 6;
string segWit = 7;
Expand Down
14 changes: 7 additions & 7 deletions imkey-core/ikc-wallet/coin-bch/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use std::str::FromStr;
#[derive(Clone)]
pub struct Utxo {
pub txhash: String,
pub vout: i32,
pub amount: i64,
pub vout: u32,
pub amount: u64,
pub address: String,
pub script_pubkey: String,
pub derive_path: String,
Expand All @@ -35,9 +35,9 @@ pub struct Utxo {

pub struct BchTransaction {
pub to: String,
pub amount: i64,
pub amount: u64,
pub unspents: Vec<Utxo>,
pub fee: i64,
pub fee: u64,
}

impl BchTransaction {
Expand Down Expand Up @@ -278,15 +278,15 @@ impl BchTransaction {
})
}

pub fn get_total_amount(&self) -> i64 {
let mut total_amount: i64 = 0;
pub fn get_total_amount(&self) -> u64 {
let mut total_amount = 0;
for unspent in &self.unspents {
total_amount += unspent.amount;
}
total_amount
}

pub fn get_change_amount(&self) -> i64 {
pub fn get_change_amount(&self) -> u64 {
let total_amount = self.get_total_amount();
let change_amout = total_amount - self.amount - self.fee;
change_amout
Expand Down
Loading

0 comments on commit 818de5f

Please sign in to comment.