Skip to content

Commit 1517f74

Browse files
committed
add form address
1 parent 761d623 commit 1517f74

File tree

5 files changed

+137
-73
lines changed

5 files changed

+137
-73
lines changed

rust/apps/avalanche/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,8 @@ use alloc::{
1111
};
1212

1313
pub use address::get_address;
14-
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
1514
use bytes::{Buf, Bytes};
16-
use hex;
17-
use transactions::base_tx::BaseTx;
1815
use transactions::tx_header::Header;
19-
use ur_registry::pb::protoc;
2016

2117
use crate::errors::{AvaxError, Result};
2218
use core::{

rust/apps/avalanche/src/transactions/structs.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use crate::constants::NAVAX_TO_AVAX_RATIO;
12
use crate::errors::{AvaxError, Result};
3+
use crate::get_address;
24
use alloc::{
35
string::{String, ToString},
46
vec::Vec,

rust/rust_c/src/avalanche/mod.rs

+109-63
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::common::{
1212
structs::{ExtendedPublicKey, SimpleResponse, TransactionCheckResult, TransactionParseResult},
1313
types::{Ptr, PtrBytes, PtrString, PtrT, PtrUR},
1414
ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT, FRAGMENT_UNLIMITED_LENGTH},
15-
utils::recover_c_char,
15+
utils::{recover_c_array, recover_c_char},
1616
};
1717
use crate::{extract_ptr_with_type, impl_c_ptr};
1818
use alloc::{
@@ -31,7 +31,7 @@ use app_avalanche::{
3131
base_tx::{avax_base_sign, BaseTx},
3232
export::ExportTx,
3333
import::ImportTx,
34-
type_id::TypeId,
34+
type_id::{self, TypeId},
3535
C_chain::{evm_export::ExportTx as CchainExportTx, evm_import::ImportTx as CchainImportTx},
3636
P_chain::{
3737
add_permissionless_delegator::AddPermissLessionDelegatorTx,
@@ -49,61 +49,94 @@ use {
4949
},
5050
};
5151

52+
const C_CHAIN_PREFIX: &str = "m/44'/60'/0'";
53+
const X_P_CHAIN_PREFIX: &str = "m/44'/9000'/0'";
54+
55+
#[derive(Debug, Clone)]
56+
pub struct DerivationPath {
57+
pub base_path: String,
58+
pub full_path: String,
59+
}
60+
5261
#[no_mangle]
5362
pub extern "C" fn avax_parse_transaction(
5463
ptr: PtrUR,
5564
mfp: PtrBytes,
5665
mfp_len: u32,
5766
public_keys: PtrT<CSliceFFI<ExtendedPublicKey>>,
5867
) -> PtrT<TransactionParseResult<DisplayAvaxTx>> {
59-
let avax_sign_request = extract_ptr_with_type!(ptr, AvaxSignRequest);
60-
61-
match get_avax_tx_type_id(avax_sign_request.get_tx_data()) {
62-
Ok(type_id) => parse_transaction_by_type(type_id, avax_sign_request.get_tx_data()),
63-
Err(_) => {
64-
TransactionParseResult::from(RustCError::InvalidData("Invalid tx type".to_string()))
65-
.c_ptr()
66-
}
67-
}
68+
parse_transaction_by_type(extract_ptr_with_type!(ptr, AvaxSignRequest), public_keys)
6869
}
70+
extern crate std;
71+
use std::println;
6972

7073
fn parse_transaction_by_type(
71-
type_id: TypeId,
72-
tx_data: Vec<u8>,
74+
sign_request: &mut AvaxSignRequest,
75+
public_keys: PtrT<CSliceFFI<ExtendedPublicKey>>,
7376
) -> PtrT<TransactionParseResult<DisplayAvaxTx>> {
74-
macro_rules! parse_tx {
75-
($tx_type:ty) => {
76-
parse_avax_tx::<$tx_type>(tx_data)
77-
.map(|parse_data| {
78-
TransactionParseResult::success(DisplayAvaxTx::from(parse_data).c_ptr()).c_ptr()
79-
})
80-
.unwrap_or_else(|_| {
81-
TransactionParseResult::from(RustCError::InvalidMasterFingerprint).c_ptr()
82-
})
83-
};
84-
}
77+
let tx_data = sign_request.get_tx_data();
78+
let type_id = get_avax_tx_type_id(sign_request.get_tx_data()).unwrap();
8579

86-
match type_id {
87-
TypeId::BaseTx => {
88-
let header = get_avax_tx_header(tx_data.clone()).unwrap();
89-
if header.get_blockchain_id() == C_BLOCKCHAIN_ID
90-
|| header.get_blockchain_id() == C_TEST_BLOCKCHAIN_ID
91-
{
92-
return parse_tx!(CchainImportTx);
93-
} else {
94-
return parse_tx!(BaseTx);
80+
unsafe {
81+
let path = get_avax_tx_type_id(sign_request.get_tx_data())
82+
.map_err(|_| AvaxError::InvalidInput)
83+
.and_then(|type_id| {
84+
determine_derivation_path(type_id, &sign_request, sign_request.get_wallet_index())
85+
})
86+
.unwrap();
87+
88+
let mut address = String::new();
89+
for key in recover_c_array(public_keys).iter() {
90+
if recover_c_char(key.path) == path.base_path {
91+
address = app_avalanche::get_address(
92+
app_avalanche::network::Network::AvaxMainNet,
93+
&path.full_path.as_str(),
94+
&recover_c_char(key.xpub).as_str(),
95+
&path.base_path.as_str(),
96+
)
97+
.unwrap();
9598
}
9699
}
97-
TypeId::PchainExportTx | TypeId::XchainExportTx => parse_tx!(ExportTx),
98-
TypeId::XchainImportTx | TypeId::PchainImportTx => parse_tx!(ImportTx),
99-
TypeId::CchainExportTx => parse_tx!(CchainExportTx),
100-
TypeId::AddPermissLessionValidator => parse_tx!(AddPermissLessionValidatorTx),
101-
TypeId::AddPermissLessionDelegator => parse_tx!(AddPermissLessionDelegatorTx),
102-
_ => TransactionParseResult::from(RustCError::InvalidData(format!(
103-
"{:?} not support",
104-
type_id
105-
)))
106-
.c_ptr(),
100+
101+
macro_rules! parse_tx {
102+
($tx_type:ty) => {
103+
parse_avax_tx::<$tx_type>(tx_data)
104+
.map(|parse_data| {
105+
TransactionParseResult::success(
106+
DisplayAvaxTx::from(parse_data)
107+
.with_from_address(address.to_string(), path.full_path.to_string())
108+
.c_ptr(),
109+
)
110+
.c_ptr()
111+
})
112+
.unwrap_or_else(|_| {
113+
TransactionParseResult::from(RustCError::InvalidMasterFingerprint).c_ptr()
114+
})
115+
};
116+
}
117+
118+
match type_id {
119+
TypeId::BaseTx => {
120+
let header = get_avax_tx_header(tx_data.clone()).unwrap();
121+
if header.get_blockchain_id() == C_BLOCKCHAIN_ID
122+
|| header.get_blockchain_id() == C_TEST_BLOCKCHAIN_ID
123+
{
124+
return parse_tx!(CchainImportTx);
125+
} else {
126+
return parse_tx!(BaseTx);
127+
}
128+
}
129+
TypeId::PchainExportTx | TypeId::XchainExportTx => parse_tx!(ExportTx),
130+
TypeId::XchainImportTx | TypeId::PchainImportTx => parse_tx!(ImportTx),
131+
TypeId::CchainExportTx => parse_tx!(CchainExportTx),
132+
TypeId::AddPermissLessionValidator => parse_tx!(AddPermissLessionValidatorTx),
133+
TypeId::AddPermissLessionDelegator => parse_tx!(AddPermissLessionDelegatorTx),
134+
_ => TransactionParseResult::from(RustCError::InvalidData(format!(
135+
"{:?} not support",
136+
type_id
137+
)))
138+
.c_ptr(),
139+
}
107140
}
108141
}
109142

@@ -135,31 +168,43 @@ fn avax_sign_dynamic(
135168
)
136169
}
137170

138-
fn handle_base_tx_path(
171+
pub fn determine_derivation_path(
172+
type_id: TypeId,
139173
sign_request: &AvaxSignRequest,
140174
wallet_index: u64,
141-
) -> Result<String, AvaxError> {
142-
let blockchain_id = get_avax_tx_header(sign_request.get_tx_data())?.get_blockchain_id();
175+
) -> Result<DerivationPath, AvaxError> {
176+
println!("type_id = {:?}, wallet_index = {}", type_id, wallet_index);
177+
let wallet_suffix = format!("/0/{}", wallet_index);
178+
179+
let (base_path, full_path) = match type_id {
180+
TypeId::CchainExportTx => (
181+
C_CHAIN_PREFIX,
182+
format!("{}{}", C_CHAIN_PREFIX, wallet_suffix),
183+
),
184+
TypeId::BaseTx => {
185+
let blockchain_id = get_avax_tx_header(sign_request.get_tx_data())?.get_blockchain_id();
143186

144-
let path = match blockchain_id {
145-
id if id == C_BLOCKCHAIN_ID || id == C_TEST_BLOCKCHAIN_ID => {
146-
format!("m/44'/60'/0'/0/{}", wallet_index)
187+
if blockchain_id == C_BLOCKCHAIN_ID || blockchain_id == C_TEST_BLOCKCHAIN_ID {
188+
(
189+
C_CHAIN_PREFIX,
190+
format!("{}{}", C_CHAIN_PREFIX, wallet_suffix),
191+
)
192+
} else {
193+
(
194+
X_P_CHAIN_PREFIX,
195+
format!("{}{}", X_P_CHAIN_PREFIX, wallet_suffix),
196+
)
197+
}
147198
}
148-
_ => format!("m/44'/9000'/0'/0/{}", wallet_index),
199+
_ => (
200+
X_P_CHAIN_PREFIX,
201+
format!("{}{}", X_P_CHAIN_PREFIX, wallet_suffix),
202+
),
149203
};
150204

151-
Ok(path)
152-
}
153-
154-
fn determine_derivation_path(
155-
type_id: TypeId,
156-
sign_request: &AvaxSignRequest,
157-
wallet_index: u64,
158-
) -> Result<String, AvaxError> {
159-
Ok(match type_id {
160-
TypeId::CchainExportTx => format!("m/44'/60'/0'/0/{}", wallet_index),
161-
TypeId::BaseTx => handle_base_tx_path(sign_request, wallet_index)?,
162-
_ => format!("m/44'/9000'/0'/0/{}", wallet_index),
205+
Ok(DerivationPath {
206+
base_path: base_path.to_string(),
207+
full_path: full_path,
163208
})
164209
}
165210

@@ -170,7 +215,8 @@ fn build_sign_result(ptr: PtrUR, seed: &[u8]) -> Result<AvaxSignature, AvaxError
170215
.map_err(|_| AvaxError::InvalidInput)
171216
.and_then(|type_id| {
172217
determine_derivation_path(type_id, &sign_request, sign_request.get_wallet_index())
173-
})?;
218+
})?
219+
.full_path;
174220

175221
avax_base_sign(seed, path, sign_request.get_tx_data())
176222
.map(|signature| AvaxSignature::new(sign_request.get_request_id(), signature.to_vec()))

rust/rust_c/src/avalanche/structs.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ pub struct DisplayTxAvaxData {
4242
fee_amount: PtrString,
4343
reward_address: PtrString,
4444
method: PtrT<DisplayAvaxMethodInfo>,
45-
// from: PtrT<VecFFI<DisplayAddress>>,
4645
to: PtrT<VecFFI<DisplayAvaxFromToInfo>>,
46+
from: PtrT<DisplayAvaxFromToInfo>,
4747
}
4848

4949
impl_c_ptr!(DisplayTxAvaxData);
@@ -115,9 +115,30 @@ impl<T: AvaxTxInfo> From<T> for DisplayAvaxTx {
115115
}
116116
}
117117

118+
impl DisplayAvaxTx {
119+
pub fn with_from_address(mut self, address: String, path: String) -> Self {
120+
unsafe {
121+
let data = &mut *self.data;
122+
let from = &mut *data.from;
123+
from.address = convert_c_char(address);
124+
from.path = convert_c_char(path);
125+
}
126+
self
127+
}
128+
}
129+
118130
impl<T: AvaxTxInfo> From<T> for DisplayTxAvaxData {
119131
fn from(value: T) -> Self {
120132
DisplayTxAvaxData {
133+
from: DisplayAvaxFromToInfo {
134+
address: convert_c_char("".to_string()),
135+
amount: convert_c_char(format!(
136+
"{} AVAX",
137+
value.get_total_input_amount() as f64 / NAVAX_TO_AVAX_RATIO
138+
)),
139+
path: convert_c_char("".to_string()),
140+
}
141+
.c_ptr(),
121142
total_input_amount: convert_c_char(format!(
122143
"{} AVAX",
123144
value.get_total_input_amount() as f64 / NAVAX_TO_AVAX_RATIO

src/ui/gui_chain/multi/web3/gui_avax.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void *GuiGetAvaxGUIData(void)
9090
public_keys->size = NUMBER_OF_ARRAYS(keys);
9191
keys[0].path = "m/44'/60'/0'";
9292
keys[0].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_AVAX_BIP44_STANDARD);
93-
keys[1].path = "m/44'/9000'/0";
93+
keys[1].path = "m/44'/9000'/0'";
9494
keys[1].xpub = GetCurrentAccountPublicKey(XPUB_TYPE_AVAX_X_P);
9595
PtrT_TransactionParseResult_DisplayTonTransaction parseResult = avax_parse_transaction(data, mfp, sizeof(mfp), public_keys);
9696
SRAM_FREE(public_keys);
@@ -120,7 +120,7 @@ lv_obj_t *CreateTxOverviewFromTo(lv_obj_t *parent, void *from, int fromLen, void
120120
}
121121

122122
ptr = (DisplayUtxoFromTo *)to;
123-
uint16_t offset = 30 + 8 + (30 + 8) * fromLen + 16;
123+
uint16_t offset = 30 + 8 + (60 + 8) * fromLen + 16;
124124
label = GuiCreateNoticeLabel(container, _("To"));
125125
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 24, offset);
126126
for (int i = 0; i < toLen; i++) {
@@ -176,8 +176,7 @@ void GuiAvaxTxOverview(lv_obj_t *parent, void *totalData)
176176
GuiAlignToPrevObj(container, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 16);
177177
}
178178

179-
printf("txData->data->from->size->address: %s\n", txData->data->to->data[0].address);
180-
container = CreateTxOverviewFromTo(parent, NULL, 0, txData->data->to->data, txData->data->to->size);
179+
container = CreateTxOverviewFromTo(parent, txData->data->from, 1, txData->data->to->data, txData->data->to->size);
181180
GuiAlignToPrevObj(container, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 16);
182181
lv_obj_update_layout(parent);
183182
}
@@ -214,7 +213,7 @@ void GuiAvaxTxRawData(lv_obj_t *parent, void *totalData)
214213
container = CreateValueDetailValue(parent, txData->data->total_input_amount, txData->data->total_output_amount, txData->data->fee_amount);
215214
GuiAlignToPrevObj(container, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 16);
216215

217-
container = CreateTxDetailsFromTo(parent, "From", NULL, 0);
216+
container = CreateTxDetailsFromTo(parent, "From", txData->data->from, 1);
218217
GuiAlignToPrevObj(container, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 16);
219218

220219
container = CreateTxDetailsFromTo(parent, "To", txData->data->to->data, txData->data->to->size);

0 commit comments

Comments
 (0)