Skip to content

Commit

Permalink
feat: support zcash receive address
Browse files Browse the repository at this point in the history
  • Loading branch information
soralit committed Sep 25, 2024
1 parent 5b7382d commit 9440e7f
Show file tree
Hide file tree
Showing 27 changed files with 465 additions and 15 deletions.
Binary file added images/coin/coinZec.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/wallet/walletZashi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/walletList/walletListZashi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions rust/apps/zcash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use keystore::algorithms::zcash::vendor::{
zcash_protocol::consensus::MainNetwork,
};

pub fn get_address(ufvk_text: String) -> Result<String> {
let ufvk = UnifiedFullViewingKey::decode(&MainNetwork, &ufvk_text)
pub fn get_address(ufvk_text: &str) -> Result<String> {
let ufvk = UnifiedFullViewingKey::decode(&MainNetwork, ufvk_text)
.map_err(|e| ZcashError::GenerateAddressError(e.to_string()))?;
let (address, _) = ufvk
.default_address(UnifiedAddressRequest::all().unwrap())
.map_err(|e| ZcashError::GenerateAddressError(e.to_string()))?;
Ok(address.encode(&MainNetwork))
}
}
11 changes: 6 additions & 5 deletions rust/keystore/src/algorithms/zcash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub fn test_sign_zec(seed: &[u8], alpha: [u8; 32], msg: &[u8]) -> [u8; 64] {
mod tests {
use crate::algorithms::zcash::vendor::{
zcash_keys::keys::{UnifiedAddressRequest, UnifiedSpendingKey},
zcash_protocol::consensus::MAIN_NETWORK,
zcash_protocol::consensus::{MainNetwork, MAIN_NETWORK},
zip32::AccountId,
};

Expand All @@ -76,12 +76,13 @@ mod tests {

let ufvk = usk.to_unified_full_viewing_key();

println!(
"{}",
ufvk.to_unified_incoming_viewing_key().encode(&MAIN_NETWORK)
);
// println!(
// "{}",
// ufvk.to_unified_incoming_viewing_key().encode(&MAIN_NETWORK)
// );
//uivk1xhvuufquepxdr5zyacha4kde0479wr25hk26w07jmtn0ec08t4fh0yqudc7v8ddya5rrx4q34yuuxy524p59radjndx5u3rqgvs6w5q8s9246q4h8ykuqtfmn7tyzdlvnen2x6p0cjlqvr48hqrgf72tr7l9z0vdnh8xwu42ausdrvuvd3w9h50ql64g0plucqfyx9ewjqjr5k7lhv9qrl7whu93jp6t38rpcyl060pz5sqnancrh
println!("{}", hex::encode(ufvk.transparent().unwrap().serialize()));
println!("{}", hex::encode(ufvk.orchard().unwrap().to_bytes()));
println!("{}", ufvk.encode(&MAIN_NETWORK));
let address = ufvk
.default_address(UnifiedAddressRequest::all().unwrap())
Expand Down
1 change: 1 addition & 0 deletions rust/rust_c/Cargo.lock

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

5 changes: 4 additions & 1 deletion rust/rust_c/cbindgen.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include_guard = "_LIBRUST_C_H"

after_includes = "#define BUILD_MULTI_COINS\n#define SIMPLERESPONSE_C_CHAR_MAX_LEN 2048\n#define ADDRESS_MAX_LEN 128\n#define PATH_ITEM_MAX_LEN 32"
after_includes = "#define BUILD_MULTI_COINS\n#define SIMPLERESPONSE_C_CHAR_MAX_LEN 2048\n#define ADDRESS_MAX_LEN 256\n#define PATH_ITEM_MAX_LEN 32"

[defines]
"feature = multi-coins" = "BUILD_MULTI_COINS"
Expand All @@ -20,6 +20,7 @@ include = [
"cardano_rust_c",
"sui_rust_c",
"ton_rust_c",
"zcash_rust_c",
"tron_rust_c",
"xrp_rust_c",
"arweave_rust_c",
Expand All @@ -42,6 +43,7 @@ extra_bindings = [
"cardano_rust_c",
"sui_rust_c",
"ton_rust_c",
"zcash_rust_c",
"tron_rust_c",
"xrp_rust_c",
"arweave_rust_c",
Expand All @@ -62,6 +64,7 @@ crates = [
"ethereum_rust_c",
"solana_rust_c",
"ton_rust_c",
"zcash_rust_c",
"near_rust_c",
"aptos_rust_c",
"cosmos_rust_c",
Expand Down
2 changes: 1 addition & 1 deletion rust/rust_c/cbindgen_btc_only.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include_guard = "_LIBRUST_C_H"

after_includes = "#define SIMPLERESPONSE_C_CHAR_MAX_LEN 2048\n#define ADDRESS_MAX_LEN 128\n#define PATH_ITEM_MAX_LEN 32"
after_includes = "#define SIMPLERESPONSE_C_CHAR_MAX_LEN 2048\n#define ADDRESS_MAX_LEN 256\n#define PATH_ITEM_MAX_LEN 32"

[defines]
"feature = multi-coins" = "BUILD_MULTI_COINS"
Expand Down
3 changes: 2 additions & 1 deletion rust/rust_c/src/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ app_sui = {path = "../../../apps/sui", optional = true}
app_arweave = {path = "../../../apps/arweave", optional = true}
app_stellar = {path = "../../../apps/stellar", optional = true}
app_ton = {path = "../../../apps/ton", optional = true}
app_zcash = {path = "../../../apps/zcash", optional = true}

[features]
debug-memory = ["default"]
default = ["multi-coins"]
multi-coins = ["app_ethereum", "app_cardano", "app_tron", "app_solana", "app_near", "app_xrp", "app_cosmos", "app_aptos", "app_sui", "app_arweave", "app_ton", "app_stellar"]
multi-coins = ["app_ethereum", "app_cardano", "app_tron", "app_solana", "app_near", "app_xrp", "app_cosmos", "app_aptos", "app_sui", "app_arweave", "app_ton", "app_stellar", "app_zcash"]
#
btc-only = []
14 changes: 14 additions & 0 deletions rust/rust_c/src/common/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use app_ton::errors::TonError;
use app_tron::errors::TronError;
#[cfg(feature = "multi-coins")]
use app_xrp::errors::XRPError;
use app_zcash::errors::ZcashError;
use keystore::errors::KeystoreError;
use third_party::thiserror;
use third_party::thiserror::Error;
Expand Down Expand Up @@ -196,6 +197,9 @@ pub enum ErrorCodes {
StellarInvalidData,
StellarParseTxError,
StellarKeystoreError,

// Zcash
ZcashGenerateAddressError = 1500,
}

impl ErrorCodes {
Expand Down Expand Up @@ -471,6 +475,16 @@ impl From<&TonError> for ErrorCodes {
}
}

#[cfg(feature = "multi-coins")]
impl From<&ZcashError> for ErrorCodes {
fn from(value: &ZcashError) -> Self {
match value {
ZcashError::GenerateAddressError(_) => Self::ZcashGenerateAddressError,
ZcashError::InvalidDataError(_) => Self::InvalidData
}
}
}

pub type R<T> = Result<T, RustCError>;

#[derive(Error, Debug, PartialEq)]
Expand Down
7 changes: 7 additions & 0 deletions rust/rust_c/src/common/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,13 @@ macro_rules! impl_simple_new_error {
}
}

#[cfg(feature = "multi-coins")]
impl<$t> From<app_zcash::errors::ZcashError> for $name<$t> {
fn from(value: app_zcash::errors::ZcashError) -> Self {
Self::error(ErrorCodes::from(&value), value.to_string())
}
}

impl<$t> From<RustCError> for $name<$t> {
fn from(value: RustCError) -> Self {
Self::error(ErrorCodes::from(&value), value.to_string())
Expand Down
2 changes: 2 additions & 0 deletions rust/rust_c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ use ton_rust_c;
use tron_rust_c;
#[cfg(feature = "multi-coins")]
use xrp_rust_c;
#[cfg(feature = "multi-coins")]
use zcash_rust_c;
33 changes: 32 additions & 1 deletion rust/rust_c/src/zcash/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
#![no_std]
#![no_std]

use core::slice;

use common_rust_c::{
structs::{Response, SimpleResponse},
types::{PtrBytes, PtrString},
utils::{convert_c_char, recover_c_char},
};
use keystore::algorithms::zcash::{self, derive_ufvk};
use third_party::cty::c_char;
use app_zcash::get_address;

#[no_mangle]
pub extern "C" fn derive_zcash_ufvk(seed: PtrBytes, seed_len: u32) -> *mut SimpleResponse<c_char> {
let seed = unsafe { slice::from_raw_parts(seed, seed_len as usize) };
let ufvk_text = derive_ufvk(seed);
match ufvk_text {
Ok(text) => SimpleResponse::success(convert_c_char(text)).simple_c_ptr(),
Err(e) => SimpleResponse::from(e).simple_c_ptr(),
}
}

#[no_mangle]
pub extern "C" fn generate_zcash_default_address(ufvk_text: PtrString) -> *mut SimpleResponse<c_char> {
let ufvk_text = recover_c_char(ufvk_text);
let address = get_address(&ufvk_text);
match address {
Ok(text) => SimpleResponse::success(convert_c_char(text)).simple_c_ptr(),
Err(e) => SimpleResponse::from(e).simple_c_ptr(),
}
}
2 changes: 2 additions & 0 deletions src/crypto/account_public_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,8 @@ int32_t AccountPublicInfoSwitch(uint8_t accountIndex, const char *password, bool
ret = AccountPublicSavePublicInfo(accountIndex, password, addr);
}

CalculateZcashUFVK(accountIndex, password);

#ifdef BTC_ONLY
initMultiSigWalletManager();
ret = LoadCurrentAccountMultisigWallet(password);
Expand Down
3 changes: 3 additions & 0 deletions src/error_codes/err_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ typedef enum {
ERR_MULTISIG_TRANSACTION_ALREADY_SIGNED,
ERR_EXPORT_XPUB_SDCARD_NOT_DETECTED,
ERR_EXPORT_FILE_TO_MICRO_CARD_FAILED,

ERR_ZCASH_INVALID_ACCOUNT_INDEX,

ERR_END,
} Error_Code;

Expand Down
38 changes: 37 additions & 1 deletion src/managers/account_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "secret_cache.h"
#include "log_print.h"
#include "user_memory.h"
#include "librust_c.h"
#ifdef COMPILE_SIMULATOR
#include "simulator_storage.h"
#include "simulator_storage.h"
Expand All @@ -31,6 +32,7 @@ static uint8_t g_currentAccountIndex = ACCOUNT_INDEX_LOGOUT;
static uint8_t g_lastAccountIndex = ACCOUNT_INDEX_LOGOUT;
static AccountInfo_t g_currentAccountInfo = {0};
static PublicInfo_t g_publicInfo = {0};
static ZcashUFVKCache_t g_zcashUFVKcache = {0};

/// @brief Get current account info from SE, and copy info to g_currentAccountInfo.
/// @return err code.
Expand Down Expand Up @@ -556,4 +558,38 @@ int32_t CreateNewTonAccount(uint8_t accountIndex, const char *mnemonic, const ch
CHECK_ERRCODE_RETURN_INT(ret);
return ret;
}
#endif

void SetZcashUFVK(uint8_t accountIndex, const char* ufvk) {
ASSERT(accountIndex <= 2);
g_zcashUFVKcache.accountIndex = accountIndex;
memset_s(g_zcashUFVKcache.ufvkCache, ZCASH_UFVK_MAX_LEN, '\0', ZCASH_UFVK_MAX_LEN);
strcpy_s(g_zcashUFVKcache.ufvkCache, ZCASH_UFVK_MAX_LEN, ufvk);
printf("SetZcashUFVK, %s\r\n", g_zcashUFVKcache.ufvkCache);
}

int32_t GetZcashUFVK(uint8_t accountIndex, char* output) {
ASSERT(accountIndex <= 2);
if (g_zcashUFVKcache.accountIndex == accountIndex)
{
strcpy_s(output, ZCASH_UFVK_MAX_LEN, g_zcashUFVKcache.ufvkCache);
return SUCCESS_CODE;
}
return ERR_ZCASH_INVALID_ACCOUNT_INDEX;
}

int32_t CalculateZcashUFVK(uint8_t accountIndex, const char* password) {
ASSERT(accountIndex <= 2);
uint8_t seed[SEED_LEN];
int32_t ret = GetAccountSeed(accountIndex, &seed, password);
SimpleResponse_c_char *response = derive_zcash_ufvk(seed, SEED_LEN);
if (response->error_code != 0)
{
ret = response->error_code;
printf("error: %s\r\n", response->error_message);
return ret;
}
printf("CalculateZcashUFVK: %s\r\n", response->data);
SetZcashUFVK(accountIndex, response->data);
}
#endif

8 changes: 8 additions & 0 deletions src/managers/account_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "stdio.h"

#define WALLET_NAME_MAX_LEN 16
#define ZCASH_UFVK_MAX_LEN 384

typedef enum {
PASSCODE_TYPE_PIN,
Expand Down Expand Up @@ -45,6 +46,11 @@ typedef struct {
char walletName[WALLET_NAME_MAX_LEN + 1];
} AccountInfo_t;

typedef struct {
uint8_t accountIndex;
char ufvkCache[ZCASH_UFVK_MAX_LEN + 1];
} ZcashUFVKCache_t;

int32_t AccountManagerInit(void);
bool AccountManagerIsNeedReset(void);

Expand Down Expand Up @@ -91,5 +97,7 @@ uint16_t GetSlip39Id(void);
uint8_t GetSlip39Ie(void);

void AccountsDataCheck(void);
int32_t GetZcashUFVK(uint8_t accountIndex, char* output);
int32_t CalculateZcashUFVK(uint8_t accountIndex, const char* password);

#endif
Loading

0 comments on commit 9440e7f

Please sign in to comment.