mirror of
https://github.com/Qortal/piratewallet-light-cli.git
synced 2025-02-01 03:12: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
|
# 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>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Hello wasm-pack!</title>
|
<title>Zcash Demo Wallet</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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>
|
<script src="./bootstrap.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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.
|
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||||
wee_alloc = { version = "0.4.2", optional = true }
|
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]
|
[dev-dependencies]
|
||||||
wasm-bindgen-test = "0.2"
|
wasm-bindgen-test = "0.2"
|
||||||
|
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
mod utils;
|
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::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
// 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;
|
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
extern {
|
extern "C" {
|
||||||
fn alert(s: &str);
|
fn alert(s: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
struct SaplingNoteData {
|
||||||
pub fn greet() {
|
account: usize,
|
||||||
alert("Hello, zcash-client-backend-wasm!");
|
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 () {
|
const COIN = 100000000
|
||||||
wasm.greet()
|
|
||||||
|
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