mirror of
https://github.com/Qortal/piratewallet-light-cli.git
synced 2025-01-30 18:42:15 +00:00
Simple demo displaying address of a fixed spending key
This commit is contained in:
parent
a56c4c2630
commit
4caf14baa2
21
README.md
21
README.md
@ -1 +1,22 @@
|
||||
# Zcon1 WASM demo
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [Rust](https://www.rust-lang.org/tools/install)
|
||||
- [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
|
||||
- [npm](https://www.npmjs.com/get-npm)
|
||||
|
||||
## Building
|
||||
|
||||
```sh
|
||||
$ ./build.sh
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
```sh
|
||||
$ cd demo-www
|
||||
$ npm run start
|
||||
```
|
||||
|
||||
Then open http://localhost:8080/ in your browser.
|
||||
|
9
build.sh
Executable file
9
build.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env sh
|
||||
BASE_DIR=$(pwd)
|
||||
|
||||
cd "$BASE_DIR/zcash-client-backend-wasm"
|
||||
wasm-pack build
|
||||
cd "$BASE_DIR/zcash-client-sdk-js"
|
||||
npm install
|
||||
cd "$BASE_DIR/demo-www"
|
||||
npm install
|
@ -2,9 +2,20 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Hello wasm-pack!</title>
|
||||
<title>Zcash Demo Wallet</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to your demo Zcash wallet!</h1>
|
||||
<p>You can interact with it using a <code>zcashd</code> testnet node.</p>
|
||||
<div id="zcash-client-loading">
|
||||
<h2>Loading...</h2>
|
||||
</div>
|
||||
<div id="zcash-client-content" style="display: none">
|
||||
<h2 id="zcash-client-address"></h2>
|
||||
<p>That's your Zcash address!</p>
|
||||
<h2 id="zcash-client-balance"></h2>
|
||||
<p id="zcash-client-no-balance">You have no TAZ. Go <a href="https://faucet.testnet.z.cash/" target="blank">here</a> to get some!</p>
|
||||
</div>
|
||||
<script src="./bootstrap.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,3 +1,25 @@
|
||||
import * as wasm from 'zcash-client-sdk'
|
||||
import { ZcashClient } from 'zcash-client-sdk'
|
||||
|
||||
wasm.greet();
|
||||
const address = document.getElementById('zcash-client-address')
|
||||
const balance = document.getElementById('zcash-client-balance')
|
||||
const noBalance = document.getElementById('zcash-client-no-balance')
|
||||
|
||||
var zcashClient = new ZcashClient({
|
||||
setAddress: (newAddress) => {
|
||||
address.textContent = newAddress
|
||||
},
|
||||
updateBalance: (newBalance) => {
|
||||
balance.textContent = `Balance: ${newBalance} TAZ`
|
||||
if (newBalance > 0) {
|
||||
noBalance.style.display = 'none'
|
||||
} else {
|
||||
noBalance.style.display = ''
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
zcashClient.load(() => {
|
||||
// Loading complete, show the wallet
|
||||
document.getElementById('zcash-client-loading').remove()
|
||||
document.getElementById('zcash-client-content').style.display = ''
|
||||
})
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,32 @@
|
||||
import * as wasm from 'zcash-client-backend-wasm'
|
||||
import { Client } from 'zcash-client-backend-wasm'
|
||||
|
||||
export function greet () {
|
||||
wasm.greet()
|
||||
const COIN = 100000000
|
||||
|
||||
export class ZcashClient {
|
||||
constructor (uiHandlers) {
|
||||
this.client = Client.new()
|
||||
this.uiHandlers = uiHandlers
|
||||
}
|
||||
|
||||
updateUI () {
|
||||
this.uiHandlers.updateBalance(this.client.balance() / COIN)
|
||||
}
|
||||
|
||||
load (onFinished) {
|
||||
var self = this
|
||||
|
||||
var loader = () => {
|
||||
// Register event handlers
|
||||
|
||||
// Initial UI updates
|
||||
self.uiHandlers.setAddress(self.client.address())
|
||||
self.updateUI()
|
||||
|
||||
// Finished loading!
|
||||
onFinished()
|
||||
}
|
||||
|
||||
// document.addEventListener('DOMContentLoaded', loader, false)
|
||||
loader()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user