Rebase librustzcash / FB

This commit is contained in:
Hanh 2023-03-11 16:43:10 +10:00
parent fa009f21b7
commit 9a3d08959e
17 changed files with 1550 additions and 130 deletions

View File

@ -120,32 +120,39 @@ sqlcipher = ["rusqlite/bundled-sqlcipher-vendored-openssl"]
[dependencies.zcash_params]
git = "https://github.com/hhanh00/zcash-params.git"
rev = "bdb7aa490b32c204307c717f5dcea18358f7be3b"
rev = "c43d03dda4a78172fe5283168510cd41ee8f1430"
#path = "../zcash-params"
[dependencies.zcash_client_backend]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "ad4a1c61fdaf04ac4fb884976ad175196e695264"
rev = "7469d70261e8e72f2bbf3163704ddf8fd825b1aa"
#path = "../../librustzcash/zcash_client_backend"
[dependencies.zcash_primitives]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "ad4a1c61fdaf04ac4fb884976ad175196e695264"
rev = "7469d70261e8e72f2bbf3163704ddf8fd825b1aa"
#path = "../../librustzcash/zcash_primitives"
features = [ "transparent-inputs" ]
[dependencies.zcash_proofs]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "ad4a1c61fdaf04ac4fb884976ad175196e695264"
rev = "7469d70261e8e72f2bbf3163704ddf8fd825b1aa"
#path = "../../librustzcash/zcash_proofs"
[dependencies.zcash_address]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "ad4a1c61fdaf04ac4fb884976ad175196e695264"
rev = "7469d70261e8e72f2bbf3163704ddf8fd825b1aa"
#path = "../../librustzcash/components/zcash_address"
[dependencies.zcash_encoding]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "ad4a1c61fdaf04ac4fb884976ad175196e695264"
rev = "7469d70261e8e72f2bbf3163704ddf8fd825b1aa"
#path = "../../librustzcash/components/zcash_encoding"
[dependencies.zcash_note_encryption]
git = "https://github.com/hhanh00/librustzcash.git"
rev = "ad4a1c61fdaf04ac4fb884976ad175196e695264"
rev = "7469d70261e8e72f2bbf3163704ddf8fd825b1aa"
#path = "../../librustzcash/components/zcash_note_encryption"
[build-dependencies]
tonic-build = "0.7.2"

View File

@ -162,6 +162,34 @@ typedef struct CResult_bool {
#define Progress_VT_DOWNLOADED 8
#define KeyPack_VT_T_ADDR 4
#define KeyPack_VT_T_KEY 6
#define KeyPack_VT_Z_ADDR 8
#define KeyPack_VT_Z_KEY 10
#define Recipient_VT_REPLY_TO 10
#define Recipient_VT_MAX_AMOUNT_PER_NOTE 16
#define UnsignedTxSummary_VT_RECIPIENTS 4
#define TxOutput_VT_POOL 10
#define TxReport_VT_OUTPUTS 4
#define TxReport_VT_TRANSPARENT 6
#define TxReport_VT_NET_SAPLING 12
#define TxReport_VT_NET_ORCHARD 14
#define TxReport_VT_FEE 16
#define TxReport_VT_PRIVACY_LEVEL 18
void dummy_export(void);
void dart_post_cobject(DartPostCObjectFnType ptr);
@ -247,10 +275,11 @@ struct CResult______u8 scan_transparent_accounts(uint32_t gap_limit);
struct CResult_____c_char prepare_multi_payment(uint8_t coin,
uint32_t account,
char *recipients_json,
uint8_t *recipients_bytes,
uint64_t recipients_len,
uint32_t anchor_offset);
struct CResult_____c_char transaction_report(uint8_t coin, char *plan);
struct CResult______u8 transaction_report(uint8_t coin, char *plan);
struct CResult_____c_char sign(uint8_t coin, uint32_t account, char *tx_plan, int64_t _port);
@ -310,12 +339,12 @@ struct CResult_____c_char get_best_server(uint8_t *servers, uint64_t len);
void import_from_zwl(uint8_t coin, char *name, char *data);
struct CResult_____c_char derive_zip32(uint8_t coin,
uint32_t id_account,
uint32_t account,
uint32_t external,
bool has_address,
uint32_t address);
struct CResult______u8 derive_zip32(uint8_t coin,
uint32_t id_account,
uint32_t account,
uint32_t external,
bool has_address,
uint32_t address);
struct CResult_u8 clear_tx_details(uint8_t coin, uint32_t account);

View File

@ -4,7 +4,7 @@
use crate::coinconfig::CoinConfig;
use crate::db::data_generated::fb::{
AddressBalance, AddressBalanceArgs, AddressBalanceVec, AddressBalanceVecArgs, BackupT,
AddressBalance, AddressBalanceArgs, AddressBalanceVec, AddressBalanceVecArgs, BackupT, KeyPackT,
};
use crate::db::AccountData;
use crate::key2::decode_key;
@ -12,7 +12,6 @@ use crate::orchard::OrchardKeyBytes;
use crate::taddr::{derive_taddr, derive_tkeys};
use crate::unified::UnifiedAddressType;
use crate::zip32::derive_zip32;
use crate::KeyPack;
use anyhow::anyhow;
use bip39::{Language, Mnemonic};
use orchard::keys::{FullViewingKey, Scope};
@ -143,7 +142,7 @@ pub fn get_backup_package(coin: u8, id_account: u32) -> anyhow::Result<BackupT>
decode_extended_full_viewing_key(network.hrp_sapling_extended_full_viewing_key(), &fvk)
.unwrap();
let sapling_dfvk = sapling_efvk.to_diversifiable_full_viewing_key();
let orchard_fvk = orchard::keys::FullViewingKey::from_bytes(&ofvk);
let orchard_fvk = FullViewingKey::from_bytes(&ofvk);
let ufvk = UnifiedFullViewingKey::new(Some(sapling_dfvk), orchard_fvk).unwrap();
ufvk.encode(network)
});
@ -390,7 +389,7 @@ pub fn derive_keys(
account: u32,
external: u32,
address: Option<u32>,
) -> anyhow::Result<KeyPack> {
) -> anyhow::Result<KeyPackT> {
let c = CoinConfig::get(coin);
let db = c.db()?;
let AccountData { seed, .. } = db.get_account_info(id_account)?;

View File

@ -1,5 +1,5 @@
use crate::coinconfig::{init_coin, CoinConfig, MEMPOOL, MEMPOOL_RUNNER};
use crate::db::data_generated::fb::{ProgressT, SendTemplate, Servers};
use crate::db::data_generated::fb::{ProgressT, Recipients, SendTemplate, Servers};
use crate::db::FullEncryptedBackup;
use crate::note_selection::TransactionReport;
use crate::{ChainError, TransactionPlan, Tx};
@ -517,13 +517,19 @@ pub async unsafe extern "C" fn scan_transparent_accounts(gap_limit: u32) -> CRes
pub async unsafe extern "C" fn prepare_multi_payment(
coin: u8,
account: u32,
recipients_json: *mut c_char,
recipients_bytes: *mut u8,
recipients_len: u64,
anchor_offset: u32,
) -> CResult<*mut c_char> {
from_c_str!(recipients_json);
let res = async {
let last_height = crate::api::sync::get_latest_height().await?;
let recipients = crate::api::recipient::parse_recipients(&recipients_json)?;
let recipients_bytes: Vec<u8> = Vec::from_raw_parts(
recipients_bytes,
recipients_len as usize,
recipients_len as usize,
);
let recipients = flatbuffers::root::<Recipients>(&recipients_bytes)?;
let recipients = crate::api::recipient::parse_recipients(&recipients)?;
let tx = crate::api::payment_v2::build_tx_plan(
coin,
account,
@ -540,16 +546,18 @@ pub async unsafe extern "C" fn prepare_multi_payment(
}
#[no_mangle]
pub unsafe extern "C" fn transaction_report(coin: u8, plan: *mut c_char) -> CResult<*mut c_char> {
pub unsafe extern "C" fn transaction_report(coin: u8, plan: *mut c_char) -> CResult<*const u8> {
from_c_str!(plan);
let c = CoinConfig::get(coin);
let res = || {
let plan: TransactionPlan = serde_json::from_str(&plan)?;
let report = TransactionReport::from_plan(c.chain.network(), plan);
let report = serde_json::to_string(&report)?;
Ok(report)
let mut builder = FlatBufferBuilder::new();
let root = report.pack(&mut builder);
builder.finish(root, None);
Ok(builder.finished_data().to_vec())
};
to_cresult_str(res())
to_cresult_bytes(res())
}
#[tokio::main]
@ -841,14 +849,17 @@ pub unsafe extern "C" fn derive_zip32(
external: u32,
has_address: bool,
address: u32,
) -> CResult<*mut c_char> {
) -> CResult<*const u8> {
let res = || {
let address = if has_address { Some(address) } else { None };
let kp = crate::api::account::derive_keys(coin, id_account, account, external, address)?;
let result = serde_json::to_string(&kp)?;
Ok(result)
let mut builder = FlatBufferBuilder::new();
let data = kp.pack(&mut builder);
builder.finish(data, None);
let res = builder.finished_data().to_vec();
Ok(res)
};
to_cresult_str(res())
to_cresult_bytes(res())
}
#[no_mangle]

View File

@ -1,20 +1,10 @@
use crate::db::data_generated::fb::{Recipient, Recipients};
use crate::db::ZMessage;
use crate::{AccountData, CoinConfig};
use serde::Deserialize;
use std::str::FromStr;
use zcash_primitives::memo::Memo;
#[derive(Deserialize)]
pub struct Recipient {
pub address: String,
pub amount: u64,
pub fee_included: bool,
pub reply_to: bool,
pub subject: String,
pub memo: String,
pub max_amount_per_note: u64,
}
#[derive(Clone, Deserialize)]
pub struct RecipientShort {
pub address: String,
@ -32,17 +22,17 @@ pub struct RecipientMemo {
impl RecipientMemo {
pub fn from_recipient(from: &str, r: &Recipient) -> anyhow::Result<Self> {
let memo = if !r.reply_to && r.subject.is_empty() {
r.memo.clone()
let memo = if !r.reply_to() && r.subject().as_ref().unwrap().is_empty() {
r.memo().unwrap().to_string()
} else {
encode_memo(from, r.reply_to, &r.subject, &r.memo)
encode_memo(from, r.reply_to(), r.subject().unwrap(), r.memo().unwrap())
};
Ok(RecipientMemo {
address: r.address.clone(),
amount: r.amount,
fee_included: r.fee_included,
address: r.address().unwrap().to_string(),
amount: r.amount(),
fee_included: r.fee_included(),
memo: Memo::from_str(&memo)?,
max_amount_per_note: r.max_amount_per_note,
max_amount_per_note: r.max_amount_per_note(),
})
}
}
@ -107,13 +97,13 @@ pub fn decode_memo(
}
/// Parse a json document that contains a list of recipients
pub fn parse_recipients(recipients: &str) -> anyhow::Result<Vec<RecipientMemo>> {
pub fn parse_recipients(recipients: &Recipients) -> anyhow::Result<Vec<RecipientMemo>> {
let c = CoinConfig::get_active();
let AccountData { address, .. } = c.db()?.get_account_info(c.id_account)?;
let recipients: Vec<Recipient> = serde_json::from_str(recipients)?;
let recipients = recipients.values().unwrap();
let recipient_memos: anyhow::Result<Vec<_>> = recipients
.iter()
.map(|r| RecipientMemo::from_recipient(&address, r))
.map(|r| RecipientMemo::from_recipient(&address, &r))
.collect();
recipient_memos
}

View File

@ -25,6 +25,7 @@ use zcash_note_encryption::batch::try_compact_note_decryption;
use zcash_note_encryption::{Domain, EphemeralKeyBytes, ShieldedOutput, COMPACT_NOTE_SIZE};
use zcash_primitives::consensus::{BlockHeight, Network, NetworkUpgrade, Parameters};
use zcash_primitives::merkle_tree::{CommitmentTree, IncrementalWitness};
use zcash_primitives::sapling::note::ExtractedNoteCommitment;
use zcash_primitives::sapling::note_encryption::{PreparedIncomingViewingKey, SaplingDomain};
use zcash_primitives::sapling::{Node, Note, PaymentAddress};
use zcash_primitives::transaction::components::sapling::CompactOutputDescription;
@ -291,13 +292,12 @@ pub struct DecryptedNote {
#[allow(dead_code)]
pub fn to_output_description(co: &CompactSaplingOutput) -> CompactOutputDescription {
let cmu: [u8; 32] = co.cmu.clone().try_into().unwrap();
let cmu = bls12_381::Scalar::from_repr(cmu).unwrap();
let epk: [u8; 32] = co.epk.clone().try_into().unwrap();
let enc_ciphertext: [u8; 52] = co.ciphertext.clone().try_into().unwrap();
CompactOutputDescription {
ephemeral_key: EphemeralKeyBytes::from(epk),
cmu,
cmu: ExtractedNoteCommitment::from_bytes(&cmu).unwrap(),
enc_ciphertext,
}
}

File diff suppressed because it is too large Load Diff

View File

@ -139,7 +139,7 @@ fn collect_decrypted_notes(
usize::from_le_bytes(plaintext[52..60].try_into().unwrap());
let cmu = note.cmu().to_bytes();
if &cmu == co.cmu.as_slice() {
log::info!("Note {} {}", account, u64::from(note.value));
log::info!("Note {} {}", account, u64::from(note.value().inner()));
decrypted_notes.push(DecryptedNote {
account,
ivk: fvk.clone(),

View File

@ -123,7 +123,7 @@ fn derive_viewing_key(
network: &Network,
extsk: &ExtendedSpendingKey,
) -> anyhow::Result<(String, String)> {
let fvk = ExtendedFullViewingKey::from(extsk);
let fvk = extsk.to_extended_full_viewing_key();
let pa = derive_address(network, &fvk)?;
let fvk =
encode_extended_full_viewing_key(network.hrp_sapling_extended_full_viewing_key(), &fvk);

View File

@ -125,7 +125,6 @@ pub use crate::fountain::{FountainCodes, RaptorQDrops};
pub use crate::lw_rpc::compact_tx_streamer_client::CompactTxStreamerClient;
pub use crate::lw_rpc::*;
pub use crate::pay::{broadcast_tx, Tx, TxIn, TxOut};
pub use zip32::KeyPack;
// pub use crate::wallet::{decrypt_backup, encrypt_backup, RecipientMemo, Wallet, WalletBalance};
pub use note_selection::{

View File

@ -271,7 +271,7 @@ impl MemPoolImpl {
&self.pivk,
co,
) {
balance += note.value as i64; // value is incoming
balance += note.value().inner() as i64; // value is incoming
}
}
}

View File

@ -9,7 +9,7 @@ pub use optimize::build_tx_plan;
use std::str::FromStr;
pub use utxo::fetch_utxos;
use crate::api::recipient::Recipient;
use crate::db::data_generated::fb::Recipient;
use thiserror::Error;
use ua::decode;
use zcash_primitives::consensus::Network;
@ -47,13 +47,13 @@ pub fn recipients_to_orders(network: &Network, recipients: &[Recipient]) -> Resu
.iter()
.enumerate()
.map(|(i, r)| {
let destinations = decode(network, &r.address)?;
let destinations = decode(network, r.address().unwrap())?;
Ok::<_, TransactionBuilderError>(Order {
id: i as u32,
destinations,
raw_amount: r.amount,
take_fee: r.fee_included, // Caller must make sure that at most one recipient pays for the fees
memo: Memo::from_str(&r.memo).unwrap().into(),
raw_amount: r.amount(),
take_fee: r.fee_included(), // Caller must make sure that at most one recipient pays for the fees
memo: Memo::from_str(r.memo().unwrap()).unwrap().into(),
})
})
.collect();

View File

@ -29,7 +29,7 @@ use zcash_primitives::transaction::components::{Amount, OutPoint, TxOut};
use zcash_primitives::transaction::sighash::{signature_hash, SignableInput};
use zcash_primitives::transaction::txid::TxIdDigester;
use zcash_primitives::transaction::{Transaction, TransactionData, TxVersion};
use zcash_primitives::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey};
use zcash_primitives::zip32::ExtendedSpendingKey;
pub struct SecretKeys {
pub transparent: Option<SecretKey>,
@ -85,7 +85,7 @@ pub fn build_tx(
let sapling_fvk = skeys
.sapling
.as_ref()
.map(|sk| ExtendedFullViewingKey::from(sk));
.map(|sk| sk.to_extended_full_viewing_key());
let sapling_ovk = sapling_fvk.as_ref().map(|efvk| efvk.fvk.ovk.clone());
let okeys = skeys.orchard.map(|sk| {
@ -114,7 +114,9 @@ pub fn build_tx(
.ok_or(anyhow!("No transparent key"))
.map(|ta| ta.script())?,
};
builder.add_transparent_input(skeys.transparent.unwrap(), utxo, coin)?;
builder
.add_transparent_input(skeys.transparent.unwrap(), utxo, coin)
.map_err(|e| anyhow!(e.to_string()))?;
}
Source::Sapling {
diversifier,
@ -131,15 +133,17 @@ pub fn build_tx(
.to_payment_address(diversifier)
.unwrap();
let rseed = Rseed::BeforeZip212(Fr::from_bytes(rseed).unwrap());
let note = sapling_address.create_note(spend.amount, rseed).unwrap();
let note = sapling_address.create_note(spend.amount, rseed);
let witness = IncrementalWitness::<Node>::read(witness.as_slice())?;
let merkle_path = witness.path().unwrap();
builder.add_sapling_spend(
skeys.sapling.clone().ok_or(anyhow!("No Sapling Key"))?,
diversifier,
note,
merkle_path,
)?;
builder
.add_sapling_spend(
skeys.sapling.clone().ok_or(anyhow!("No Sapling Key"))?,
diversifier,
note,
merkle_path,
)
.map_err(|e| anyhow!(e.to_string()))?;
}
Source::Orchard {
id_note,
@ -180,16 +184,15 @@ pub fn build_tx(
match &output.destination {
Destination::Transparent(_addr) => {
let transparent_address = output.destination.transparent();
builder.add_transparent_output(&transparent_address, value)?;
builder
.add_transparent_output(&transparent_address, value)
.map_err(|e| anyhow!(e.to_string()))?;
}
Destination::Sapling(addr) => {
let sapling_address = PaymentAddress::from_bytes(addr).unwrap();
builder.add_sapling_output(
sapling_ovk,
sapling_address,
value,
output.memo.clone(),
)?;
builder
.add_sapling_output(sapling_ovk, sapling_address, value, output.memo.clone())
.map_err(|e| anyhow!(e.to_string()))?;
}
Destination::Orchard(addr) => {
has_orchard = true;

View File

@ -1,4 +1,5 @@
use crate::note_selection::types::{TransactionOutput, TransactionReport};
use crate::db::data_generated::fb::{TxOutputT, TxReportT};
use crate::note_selection::types::TransactionReport;
use crate::TransactionPlan;
use serde::{Deserialize, Serialize};
use zcash_primitives::consensus::Network;
@ -19,7 +20,7 @@ impl From<MemoBytesProxy> for MemoBytes {
}
impl TransactionReport {
pub fn from_plan(network: &Network, p: TransactionPlan) -> Self {
pub fn from_plan(network: &Network, p: TransactionPlan) -> TxReportT {
let mut spends = [0; 3];
let mut outs = [0; 3];
let mut changes = [0; 3];
@ -38,9 +39,9 @@ impl TransactionReport {
.outputs
.iter()
.filter_map(|o| {
o.id_order.map(|id| TransactionOutput {
o.id_order.map(|id| TxOutputT {
id,
address: o.destination.address(network),
address: Some(o.destination.address(network)),
amount: o.amount,
pool: o.destination.pool() as u8,
})
@ -60,8 +61,8 @@ impl TransactionReport {
3
};
let report = TransactionReport {
outputs,
let report = TxReportT {
outputs: Some(outputs),
transparent: spends[0] - changes[0],
sapling: spends[1] - changes[1],
orchard: spends[2] - changes[2],

View File

@ -3,7 +3,7 @@ use crate::db::SpendableNote;
use crate::api::recipient::RecipientMemo;
use crate::chain::get_latest_height;
use crate::coinconfig::CoinConfig;
use crate::{GetAddressUtxosReply, Hash, RawTransaction};
use crate::{GetAddressUtxosReply, RawTransaction};
use anyhow::anyhow;
use jubjub::Fr;
use rand::prelude::SliceRandom;
@ -14,8 +14,7 @@ use std::sync::mpsc;
use tonic::Request;
use zcash_client_backend::address::RecipientAddress;
use zcash_client_backend::encoding::{
decode_extended_full_viewing_key, decode_payment_address, encode_extended_full_viewing_key,
encode_payment_address,
decode_extended_full_viewing_key, encode_extended_full_viewing_key, encode_payment_address,
};
use zcash_params::coin::{get_coin_chain, CoinChain, CoinType};
use zcash_primitives::consensus::{BlockHeight, Parameters};
@ -28,6 +27,7 @@ use zcash_primitives::sapling::{Diversifier, Node, PaymentAddress, Rseed};
use zcash_primitives::transaction::builder::{Builder, Progress};
use zcash_primitives::transaction::components::amount::{DEFAULT_FEE, MAX_MONEY};
use zcash_primitives::transaction::components::{Amount, OutPoint, TxOut as ZTxOut};
use zcash_primitives::transaction::fees::fixed::FeeRule;
use zcash_primitives::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey};
#[derive(Serialize, Deserialize, Debug)]
@ -219,7 +219,7 @@ impl TxBuilder {
for n in notes.iter() {
if amount.is_positive() {
let a = amount.min(
Amount::from_u64(n.note.value)
Amount::from_u64(n.note.value().inner())
.map_err(|_| anyhow::anyhow!("Invalid amount"))?,
);
amount -= a;
@ -230,7 +230,7 @@ impl TxBuilder {
self.add_z_input(
&n.diversifier,
fvk,
Amount::from_u64(n.note.value).unwrap(),
Amount::from_u64(n.note.value().inner()).unwrap(),
&rseed.to_bytes(),
&witness_bytes,
)?;
@ -322,27 +322,22 @@ impl Tx {
let chain = get_coin_chain(self.coin_type);
let last_height = BlockHeight::from_u32(self.height as u32);
let mut builder = Builder::new(*chain.network(), last_height);
let efvk = ExtendedFullViewingKey::from(zsk);
let ovk: Hash = hex::decode(&self.ovk)?.try_into().unwrap();
builder.send_change_to(
OutgoingViewingKey(ovk),
decode_payment_address(chain.network().hrp_sapling_payment_address(), &self.change)
.unwrap(),
);
let efvk = zsk.to_extended_full_viewing_key();
if let Some(tsk) = tsk {
for txin in self.t_inputs.iter() {
let mut txid = [0u8; 32];
hex::decode_to_slice(&txin.op, &mut txid)?;
builder.add_transparent_input(
tsk,
OutPoint::new(txid, txin.n),
ZTxOut {
value: Amount::from_u64(txin.amount).unwrap(),
script_pubkey: Script(hex::decode(&txin.script).unwrap()),
},
)?;
builder
.add_transparent_input(
tsk,
OutPoint::new(txid, txin.n),
ZTxOut {
value: Amount::from_u64(txin.amount).unwrap(),
script_pubkey: Script(hex::decode(&txin.script).unwrap()),
},
)
.map_err(|e| anyhow!(e.to_string()))?;
}
} else if !self.t_inputs.is_empty() {
anyhow::bail!("Missing secret key of transparent account");
@ -364,14 +359,14 @@ impl Tx {
let mut rseed_bytes = [0u8; 32];
hex::decode_to_slice(&txin.rseed, &mut rseed_bytes)?;
let rseed = Fr::from_bytes(&rseed_bytes).unwrap();
let note = pa
.create_note(txin.amount, Rseed::BeforeZip212(rseed))
.unwrap();
let note = pa.create_note(txin.amount, Rseed::BeforeZip212(rseed));
let w = hex::decode(&txin.witness)?;
let witness = IncrementalWitness::<Node>::read(&*w)?;
let merkle_path = witness.path().unwrap();
builder.add_sapling_spend(zsk.clone(), diversifier, note, merkle_path)?;
builder
.add_sapling_spend(zsk.clone(), diversifier, note, merkle_path)
.map_err(|e| anyhow!(e.to_string()))?;
}
for txout in self.outputs.iter() {
@ -379,7 +374,9 @@ impl Tx {
let amount = Amount::from_u64(txout.amount).unwrap();
match recipient {
RecipientAddress::Transparent(ta) => {
builder.add_transparent_output(&ta, amount)?;
builder
.add_transparent_output(&ta, amount)
.map_err(|e| anyhow!(e.to_string()))?;
}
RecipientAddress::Shielded(pa) => {
let mut ovk = [0u8; 32];
@ -389,7 +386,9 @@ impl Tx {
let m = hex::decode(&txout.memo)?;
memo[..m.len()].copy_from_slice(&m);
let memo = MemoBytes::from_bytes(&memo)?;
builder.add_sapling_output(Some(ovk), pa, amount, memo)?;
builder
.add_sapling_output(Some(ovk), pa, amount, memo)
.map_err(|e| anyhow!(e.to_string()))?;
}
RecipientAddress::Unified(_ua) => {
todo!() // TODO
@ -406,7 +405,7 @@ impl Tx {
progress_callback(progress);
}
});
let (tx, _) = builder.build(prover)?;
let (tx, _) = builder.build(prover, &FeeRule::standard())?;
let mut raw_tx = vec![];
tx.write(&mut raw_tx)?;

View File

@ -67,7 +67,7 @@ impl<P: Parameters> DecryptedNote<SaplingDomain<P>, SaplingViewKey> for Decrypte
height: self.output_position.height,
output_index: self.output_position.output_index as u32,
diversifier: self.pa.diversifier().0.to_vec(),
value: self.note.value,
value: self.note.value().inner(),
rcm: self.note.rcm().to_repr().to_vec(),
nf: self.note.nf(&viewing_key.nk, position).to_vec(),
rho: None,

View File

@ -1,10 +1,10 @@
use crate::db::data_generated::fb::KeyPackT;
use crate::key2::split_key;
use anyhow::anyhow;
use base58check::ToBase58Check;
use bip39::{Language, Mnemonic, Seed};
use ripemd::{Digest, Ripemd160};
use secp256k1::{All, PublicKey, Secp256k1, SecretKey};
use serde::Serialize;
use sha2::Sha256;
use tiny_hderive::bip32::ExtendedPrivKey;
use zcash_client_backend::encoding::{
@ -14,21 +14,13 @@ use zcash_primitives::consensus::{Network, Parameters};
use zcash_primitives::legacy::TransparentAddress;
use zcash_primitives::zip32::{ChildIndex, ExtendedSpendingKey};
#[derive(Serialize)]
pub struct KeyPack {
pub t_addr: String,
pub t_key: String,
pub z_addr: String,
pub z_key: String,
}
pub fn derive_zip32(
network: &Network,
phrase: &str,
account_index: u32,
external: u32,
address_index: Option<u32>,
) -> anyhow::Result<KeyPack> {
) -> anyhow::Result<KeyPackT> {
let (phrase, password) = split_key(phrase);
let mnemonic = Mnemonic::from_phrase(&phrase, Language::English)?;
let seed = Seed::new(&mnemonic, &password);
@ -71,10 +63,10 @@ pub fn derive_zip32(
sk.push(0x01);
let t_key = sk.to_base58check(0x80);
Ok(KeyPack {
z_key,
z_addr,
t_key,
t_addr,
Ok(KeyPackT {
z_key: Some(z_key),
z_addr: Some(z_addr),
t_key: Some(t_key),
t_addr: Some(t_addr),
})
}