Skip to content

Commit

Permalink
feat: zcash connect wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
soralit committed Sep 27, 2024
1 parent 17c39a3 commit 4d593a4
Show file tree
Hide file tree
Showing 14 changed files with 519 additions and 39 deletions.
324 changes: 311 additions & 13 deletions rust/apps/wallets/Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion rust/apps/wallets/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2023-06-26
nightly
1 change: 1 addition & 0 deletions rust/apps/wallets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub mod solana;
pub mod sui;
pub mod thor_wallet;
pub mod tonkeeper;
pub mod zcash;
mod utils;
pub mod xbull;
pub mod xrp_toolkit;
Expand Down
72 changes: 72 additions & 0 deletions rust/apps/wallets/src/zcash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use alloc::string::{String, ToString};
use alloc::vec;
use alloc::vec::Vec;

use app_utils::impl_public_struct;
use keystore::algorithms::zcash::vendor::{
zcash_keys::keys::UnifiedFullViewingKey, zcash_protocol::consensus::MainNetwork,
};
use third_party::ur_registry::{
crypto_hd_key::CryptoHDKey,
crypto_key_path::CryptoKeyPath,
error::{URError, URResult},
zcash::{
zcash_accounts::ZcashAccounts, zcash_full_viewing_key::ZcashFullViewingKey,
zcash_unified_full_viewing_key::ZcashUnifiedFullViewingKey,
},
};

impl_public_struct!(UFVKInfo {
key_text: String,
key_name: String,
transparent_key_path: String,
orchard_key_path: String
});

pub fn generate_sync_ur(key_infos: Vec<UFVKInfo>, mfp: [u8; 4]) -> URResult<ZcashAccounts> {
let keys = key_infos
.iter()
.map(|info| {
let ufvk = UnifiedFullViewingKey::decode(&MainNetwork, &info.key_text)
.map_err(|e| URError::UrEncodeError(e.to_string()))?;

let transprant = ufvk.transparent().and_then(|v| Some(v.serialize()));
let orchard = ufvk
.orchard()
.and_then(|v| Some(v.to_bytes()))
.ok_or(URError::UrEncodeError(format!("Zcash missing orchard fvk")))?;

let transparent_key = transprant
.map(|v| {
let (chaincode, pubkey) = v.split_at(32);
let keypath = CryptoKeyPath::from_path(info.transparent_key_path.clone(), None)
.map_err(|e| URError::UrEncodeError(e))?;
Ok(CryptoHDKey::new_extended_key(
None,
pubkey.to_vec(),
Some(chaincode.to_vec()),
None,
Some(keypath),
None,
None,
None,
None,
))
})
.transpose()?;

let keypath = CryptoKeyPath::from_path(info.orchard_key_path.clone(), None)
.map_err(|e| URError::UrEncodeError(e))?;

let orchard_key = ZcashFullViewingKey::new(keypath, orchard.to_vec());

Ok(ZcashUnifiedFullViewingKey::new(
transparent_key,
orchard_key,
Some(info.key_name.clone()),
))
})
.collect::<URResult<Vec<ZcashUnifiedFullViewingKey>>>()?;
let accounts = ZcashAccounts::new(mfp, keys);
Ok(accounts)
}
Empty file added rust/docs/README.md
Empty file.
23 changes: 21 additions & 2 deletions rust/keystore/Cargo.lock

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

4 changes: 2 additions & 2 deletions rust/rust_c/Cargo.lock

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

28 changes: 28 additions & 0 deletions rust/rust_c/src/common/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,31 @@ impl Free for PtrT<ExtendedPublicKey> {
}
}
}

#[repr(C)]
pub struct ZcashKey {
pub key_text: PtrString,
pub key_name: PtrString,
pub transparent_key_path: PtrString,
pub orchard_key_path: PtrString,
}

impl_c_ptr!(ZcashKey);

impl Free for ZcashKey {
fn free(&self) {
free_str_ptr!(self.key_text);
free_str_ptr!(self.key_name);
free_str_ptr!(self.transparent_key_path);
free_str_ptr!(self.orchard_key_path);
}
}

impl Free for PtrT<ZcashKey> {
fn free(&self) {
unsafe {
let x = Box::from_raw(*self);
x.free()
}
}
}
1 change: 1 addition & 0 deletions rust/rust_c/src/wallet/src/multi_coins_wallet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod tonkeeper;
mod utils;
pub mod xbull;
pub mod xrp_toolkit;
pub mod zcash;

pub mod thor_wallet;

Expand Down
61 changes: 61 additions & 0 deletions rust/rust_c/src/wallet/src/multi_coins_wallet/src/zcash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use alloc::string::ToString;
use alloc::vec::Vec;
use alloc::{format, slice};
use app_wallets::zcash::{generate_sync_ur, UFVKInfo};
use common_rust_c::extract_array;
use common_rust_c::ffi::CSliceFFI;
use common_rust_c::structs::ZcashKey;
use common_rust_c::types::{Ptr, PtrBytes, PtrString};
use common_rust_c::ur::{UREncodeResult, FRAGMENT_MAX_LENGTH_DEFAULT};
use common_rust_c::utils::{recover_c_array, recover_c_char};
use third_party::ur_registry::bytes::Bytes;
use third_party::ur_registry::error::URError;
use third_party::ur_registry::traits::RegistryItem;
use third_party::ur_registry::zcash::zcash_accounts::ZcashAccounts;

#[no_mangle]
pub extern "C" fn get_connect_zcash_wallet_ur(
mfp: PtrBytes,
mfp_len: u32,
zcash_keys: Ptr<CSliceFFI<ZcashKey>>,
) -> *mut UREncodeResult {
if mfp_len != 4 {
return UREncodeResult::from(URError::UrEncodeError(format!(
"master fingerprint length must be 4, current is {}",
mfp_len
)))
.c_ptr();
}
let mfp = extract_array!(mfp, u8, mfp_len);
let mfp = match <[u8; 4]>::try_from(mfp) {
Ok(mfp) => mfp,
Err(e) => return UREncodeResult::from(URError::UrEncodeError(e.to_string())).c_ptr(),
};
unsafe {
let keys = recover_c_array(zcash_keys);
let ufvks: Vec<UFVKInfo> = keys
.iter()
.map(|v| {
UFVKInfo::new(
recover_c_char(v.key_text),
recover_c_char(v.key_name),
recover_c_char(v.transparent_key_path),
recover_c_char(v.orchard_key_path),
)
})
.collect();
let result = generate_sync_ur(ufvks, mfp);
match result.map(|v| v.try_into()) {
Ok(v) => match v {
Ok(data) => UREncodeResult::encode(
data,
ZcashAccounts::get_registry_type().get_type(),
FRAGMENT_MAX_LENGTH_DEFAULT,
)
.c_ptr(),
Err(e) => UREncodeResult::from(e).c_ptr(),
},
Err(e) => UREncodeResult::from(e).c_ptr(),
}
}
}
4 changes: 2 additions & 2 deletions rust/third_party/Cargo.lock

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

4 changes: 2 additions & 2 deletions rust/third_party/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ rsa = { version = "0.8.2", default-features = false }
sha1 = { version = "0.10.5", default-features = false }
cty = "0.2.2"
cstr_core = "0.2.6"
ur-registry = { git = "https://[email protected]/KeystoneHQ/keystone-sdk-rust.git", tag = "0.0.32" }
ur-parse-lib = { git = "https://[email protected]/KeystoneHQ/keystone-sdk-rust.git", tag = "0.0.32" }
ur-registry = { git = "https://[email protected]/KeystoneHQ/keystone-sdk-rust.git", tag = "0.0.33-alpha1" }
ur-parse-lib = { git = "https://[email protected]/KeystoneHQ/keystone-sdk-rust.git", tag = "0.0.33-alpha1" }
ed25519-bip32-core = { version = "0.1.1", default-features = false }
cryptoxide = "0.4"
itertools = { version = "0.10.5", default-features = false, features = [
Expand Down
1 change: 1 addition & 0 deletions src/ui/gui_components/gui_status_bar.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const static CoinWalletInfo_t g_walletBtn[] = {
{WALLET_LIST_TYPHON, "Typhon Wallet", &walletTyphon},
{WALLET_LIST_BLUE, "BlueWallet", &walletBluewallet},
{WALLET_LIST_SUB, "SubWallet", &walletSubwallet},
{WALLET_LIST_ZASHI, "Zashi", &walletZashi},
{WALLET_LIST_SOLFARE, "Solflare", &walletSolflare},
{WALLET_LIST_BACKPACK, "Backpack", &walletBackpack},
{WALLET_LIST_RABBY, "Rabby", &walletRabby},
Expand Down
33 changes: 16 additions & 17 deletions src/ui/gui_widgets/gui_connect_wallet_widgets.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ static void GuiInitWalletListArray()
}
}


// static void GuiInitWalletListArray()
// {
// SetWalletListEnable(true);
Expand Down Expand Up @@ -457,7 +456,6 @@ static void OpenQRCodeHandler(lv_event_t *e)
GuiEmitSignal(SIG_SETUP_VIEW_TILE_NEXT, NULL, 0);
}


#ifndef BTC_ONLY
void GuiConnectWalletPasswordErrorCount(void *param)
{
Expand Down Expand Up @@ -869,7 +867,6 @@ static void AddKeystoneWalletCoins(void)
lv_obj_align(img, LV_ALIGN_TOP_LEFT, 132, 2);
}


static void AddBlueWalletCoins(void)
{
if (lv_obj_get_child_cnt(g_coinCont) > 0) {
Expand Down Expand Up @@ -998,7 +995,6 @@ static void AddThorWalletCoins(void)
}
}


static void AddNightlyCoins(void)
{
if (lv_obj_get_child_cnt(g_coinCont) > 0) {
Expand All @@ -1013,8 +1009,6 @@ static void AddNightlyCoins(void)
}
}



static void AddChainAddress(void)
{
if (lv_obj_get_child_cnt(g_bottomCont) > 0) {
Expand Down Expand Up @@ -1181,7 +1175,6 @@ UREncodeResult *GuiGetKeplrData(void)
return GuiGetKeplrDataByIndex(GetConnectWalletAccountIndex(GetWalletNameByIndex(g_connectWalletTileView.walletIndex)));
}


UREncodeResult *GuiGetADAData(void)
{
return GuiGetADADataByIndex(GetWalletNameByIndex(g_connectWalletTileView.walletIndex));
Expand Down Expand Up @@ -1210,14 +1203,21 @@ UREncodeResult *GuiGetTonData(void)

UREncodeResult *GuiGetZecData(void)
{
uint8_t* mfp = NULL;
char* path = NULL;
char* xpub;
char* walletName = GetWalletName();
if (walletName == NULL) {
walletName = "Keystone";
}
return get_tonkeeper_wallet_ur(xpub, walletName, mfp, mfp == NULL ? 0 : 4, path);
uint8_t mfp[4];
GetMasterFingerPrint(mfp);
CSliceFFI_ZcashKey *keys = SRAM_MALLOC(sizeof(CSliceFFI_ZcashKey));
ZcashKey data[1];
keys->data = data;
keys->size = 1;
char ufvk[384] = {'\0'};
GetZcashUFVK(GetCurrentAccountIndex(), ufvk);
data[0].key_text = ufvk;
data[0].key_name = GetWalletName();
char transparent_path[24] = "m/44'/133'/0'";
char orchard_path[24] = "m/32'/133'/0'";
data[0].transparent_key_path = transparent_path;
data[0].orchard_key_path = orchard_path;
return get_connect_zcash_wallet_ur(mfp, mfp == NULL ? 0 : 4, keys);
}

void GuiPrepareArConnectWalletView(void)
Expand Down Expand Up @@ -1346,7 +1346,7 @@ void GuiConnectWalletSetQrdata(WALLET_LIST_INDEX_ENUM index)
AddTonCoins();
break;
case WALLET_LIST_ZASHI:
func = GuiGetTonData;
func = GuiGetZecData;
AddZecCoins();
break;
case WALLET_LIST_KEYSTONE:
Expand Down Expand Up @@ -1996,7 +1996,6 @@ int8_t GuiConnectWalletNextTile(void)
return SUCCESS_CODE;
}


int8_t GuiConnectWalletPrevTile(void)
{
switch (g_connectWalletTileView.currentTile) {
Expand Down

0 comments on commit 4d593a4

Please sign in to comment.