Simple demo displaying address of a fixed spending key

This commit is contained in:
Jack Grigg
2019-06-11 00:39:28 +01:00
parent a56c4c2630
commit 4caf14baa2
7 changed files with 214 additions and 10 deletions

View File

@@ -26,6 +26,22 @@ console_error_panic_hook = { version = "0.1.1", optional = true }
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
wee_alloc = { version = "0.4.2", optional = true }
[dependencies.pairing]
git = "https://github.com/str4d/librustzcash.git"
branch = "demo-wasm"
[dependencies.sapling-crypto]
git = "https://github.com/str4d/librustzcash.git"
branch = "demo-wasm"
[dependencies.zcash_client_backend]
git = "https://github.com/str4d/librustzcash.git"
branch = "demo-wasm"
[dependencies.zcash_primitives]
git = "https://github.com/str4d/librustzcash.git"
branch = "demo-wasm"
[dev-dependencies]
wasm-bindgen-test = "0.2"

View File

@@ -1,5 +1,20 @@
mod utils;
use pairing::bls12_381::Bls12;
use sapling_crypto::primitives::{Note, PaymentAddress};
use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use zcash_client_backend::{
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS, encoding::encode_payment_address,
};
use zcash_primitives::{
merkle_tree::IncrementalWitness,
sapling::Node,
transaction::TxId,
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
JUBJUB,
};
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
@@ -9,11 +24,94 @@ use wasm_bindgen::prelude::*;
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
extern {
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet() {
alert("Hello, zcash-client-backend-wasm!");
struct SaplingNoteData {
account: usize,
note: Note<Bls12>,
witnesses: Vec<IncrementalWitness<Node>>,
nullifier: [u8; 32],
spent: Option<TxId>,
}
impl SaplingNoteData {
fn new(
extfvk: &ExtendedFullViewingKey,
output: zcash_client_backend::wallet::WalletShieldedOutput,
witness: IncrementalWitness<Node>,
) -> Self {
let nf = {
let mut nf = [0; 32];
nf.copy_from_slice(
&output
.note
.nf(&extfvk.fvk.vk, witness.position() as u64, &JUBJUB),
);
nf
};
SaplingNoteData {
account: output.account,
note: output.note,
witnesses: vec![],
nullifier: nf,
spent: None,
}
}
}
struct WalletTx {
block: i32,
notes: Vec<SaplingNoteData>,
}
#[wasm_bindgen]
pub struct Client {
extsks: [ExtendedSpendingKey; 1],
extfvks: [ExtendedFullViewingKey; 1],
address: PaymentAddress<Bls12>,
txs: Arc<RwLock<HashMap<TxId, WalletTx>>>,
}
/// Public methods, exported to JavaScript.
#[wasm_bindgen]
impl Client {
pub fn new() -> Self {
utils::set_panic_hook();
let extsk = ExtendedSpendingKey::master(&[0; 32]);
let extfvk = ExtendedFullViewingKey::from(&extsk);
let address = extfvk.default_address().unwrap().1;
Client {
extsks: [extsk],
extfvks: [extfvk],
address,
txs: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn address(&self) -> String {
encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, &self.address)
}
// TODO: This will be inaccurate if the balance exceeds a u32, but u64 -> JavaScript
// requires BigUint64Array which has limited support across browsers, and is not
// implemented in the LTS version of Node.js. For now, let's assume that no one is
// going to use a web wallet with more than ~21 TAZ.
pub fn balance(&self) -> u32 {
self.txs
.read()
.unwrap()
.values()
.map(|tx| {
tx.notes
.iter()
.map(|nd| if nd.spent.is_none() { nd.note.value } else { 0 })
.sum::<u64>()
})
.sum::<u64>() as u32
}
}