From f9361b27d939979466ea0d9e4d55a57a0ccdd823 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 12 Jun 2019 23:03:25 +0100 Subject: [PATCH] ZcashClient.sendToAddress() --- README.md | 1 + demo-www/index.html | 13 ++++++ demo-www/index.js | 20 +++++++++ zcash-client-sdk-js/src/index.js | 75 +++++++++++++++++++++++++++++++- 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f40dd3b..9887636 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ $ docker run -d -p 8081:8081 --network=host lightwalletd/envoy ## Running the demo ```sh +$ ln -s "$HOME/.zcash-params" demo-www/params $ cd demo-www $ npm run start ``` diff --git a/demo-www/index.html b/demo-www/index.html index 79fe9df..bc1c323 100644 --- a/demo-www/index.html +++ b/demo-www/index.html @@ -14,6 +14,19 @@

That's your Zcash address!

+ + + + + + + + + + + + +

You have no TAZ. Go here to get some!

Syncing...

diff --git a/demo-www/index.js b/demo-www/index.js index f428828..1faa78b 100644 --- a/demo-www/index.js +++ b/demo-www/index.js @@ -2,7 +2,11 @@ import { ZcashClient } from 'zcash-client-sdk' const address = document.getElementById('zcash-client-address') const balance = document.getElementById('zcash-client-balance') +const yesBalance = document.getElementById('zcash-client-yes-balance') const noBalance = document.getElementById('zcash-client-no-balance') +const sendToAddress = document.getElementById('zcash-client-send-to-address') +const sendValue = document.getElementById('zcash-client-send-value') +const sendAction = document.getElementById('zcash-client-send-action') const syncStatus = document.getElementById('zcash-client-sync-status') var zcashClient = new ZcashClient('http://localhost:8081', { @@ -12,8 +16,10 @@ var zcashClient = new ZcashClient('http://localhost:8081', { updateBalance: (newBalance) => { balance.textContent = `Balance: ${newBalance} TAZ` if (newBalance > 0) { + yesBalance.style.display = '' noBalance.style.display = 'none' } else { + yesBalance.style.display = 'none' noBalance.style.display = '' } }, @@ -31,6 +37,20 @@ var zcashClient = new ZcashClient('http://localhost:8081', { }) zcashClient.load(() => { + // Register event handlers + sendAction.onclick = () => { + sendAction.disabled = true + sendAction.textContent = 'Sending...' + + var to = sendToAddress.value + var value = sendValue.value + + zcashClient.sendToAddress(to, value, () => { + sendAction.disabled = false + sendAction.textContent = 'Send!' + }) + } + // Loading complete, show the wallet document.getElementById('zcash-client-loading').remove() document.getElementById('zcash-client-content').style.display = '' diff --git a/zcash-client-sdk-js/src/index.js b/zcash-client-sdk-js/src/index.js index 88b4686..1bbfd03 100644 --- a/zcash-client-sdk-js/src/index.js +++ b/zcash-client-sdk-js/src/index.js @@ -1,12 +1,14 @@ import { Client } from 'zcash-client-backend-wasm' -const { BlockID, BlockRange, ChainSpec } = require('./service_pb.js') +const { BlockID, BlockRange, ChainSpec, RawTransaction } = require('./service_pb.js') const { CompactTxStreamerClient } = require('./service_grpc_web_pb.js') const grpc = {} grpc.web = require('grpc-web') const COIN = 100000000 +const SAPLING_CONSENSUS_BRANCH_ID = 0x76b809bb + const CHAIN_REFRESH_INTERVAL = 60 * 1000 const BATCH_SIZE = 1000 @@ -21,6 +23,40 @@ export class ZcashClient { } } + fetchSpendParams () { + var self = this + + var req = new XMLHttpRequest() + req.addEventListener('load', function () { + var buffer = req.response + if (buffer) { + self.spendParams = new Uint8Array(buffer) + } else { + console.error("Didn't receive sapling-spend.params") + } + }) + req.open('GET', 'params/sapling-spend.params') + req.responseType = 'arraybuffer' + req.send() + } + + fetchOutputParams () { + var self = this + + var req = new XMLHttpRequest() + req.addEventListener('load', function () { + var buffer = req.response + if (buffer) { + self.outputParams = new Uint8Array(buffer) + } else { + console.error("Didn't receive sapling-spend.params") + } + }) + req.open('GET', 'params/sapling-output.params') + req.responseType = 'arraybuffer' + req.send() + } + updateUI () { this.uiHandlers.updateBalance(this.client.balance() / COIN) } @@ -109,10 +145,47 @@ export class ZcashClient { }) } + sendToAddress (to, value, onFinished) { + var self = this + + console.log(`Sending ${value} TAZ to ${to}`) + + var tx = self.client.send_to_address( + SAPLING_CONSENSUS_BRANCH_ID, + self.spendParams, + self.outputParams, + to, + value * COIN) + if (tx == null) { + console.error('Failed to create transaction') + onFinished() + return + } + + var rawTx = new RawTransaction() + rawTx.setData(tx) + + console.log('Sending transaction...') + self.lightwalletd.sendTransaction(rawTx, {}, (response) => { + console.log('Sent transaction') + if (response != null) { + console.log(`Error code: ${response.getErrorcode()} "${response.getErrormessage()}"`) + } + + self.updateUI() + + onFinished() + }) + } + load (onFinished) { var self = this var loader = () => { + // Fetch Sapling parameters + self.fetchSpendParams() + self.fetchOutputParams() + // Register event handlers // Initial UI updates