mirror of
https://github.com/Qortal/piratewallet-light-cli.git
synced 2025-07-29 19:31:25 +00:00
Remove outdated directories
This commit is contained in:
9
build.sh
9
build.sh
@@ -1,9 +0,0 @@
|
||||
#!/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
demo-www/.gitignore
vendored
2
demo-www/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
node_modules
|
||||
dist
|
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
@@ -1,25 +0,0 @@
|
||||
Copyright (c) [year] [name]
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
@@ -1,67 +0,0 @@
|
||||
<div align="center">
|
||||
|
||||
<h1><code>create-wasm-wapp</code></h1>
|
||||
|
||||
<strong>An <code>npm init</code> template for kick starting a project that uses NPM packages containing Rust-generated WebAssembly and bundles them with Webpack.</strong>
|
||||
|
||||
<p>
|
||||
<a href="https://travis-ci.org/rustwasm/create-wasm-app"><img src="https://img.shields.io/travis/rustwasm/create-wasm-app.svg?style=flat-square" alt="Build Status" /></a>
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a href="#usage">Usage</a>
|
||||
<span> | </span>
|
||||
<a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a>
|
||||
</h3>
|
||||
|
||||
<sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub>
|
||||
</div>
|
||||
|
||||
## About
|
||||
|
||||
This template is designed for depending on NPM packages that contain
|
||||
Rust-generated WebAssembly and using them to create a Website.
|
||||
|
||||
* Want to create an NPM package with Rust and WebAssembly? [Check out
|
||||
`wasm-pack-template`.](https://github.com/rustwasm/wasm-pack-template)
|
||||
* Want to make a monorepo-style Website without publishing to NPM? Check out
|
||||
[`rust-webpack-template`](https://github.com/rustwasm/rust-webpack-template)
|
||||
and/or
|
||||
[`rust-parcel-template`](https://github.com/rustwasm/rust-parcel-template).
|
||||
|
||||
## 🚴 Usage
|
||||
|
||||
```
|
||||
npm init wasm-app
|
||||
```
|
||||
|
||||
## 🔋 Batteries Included
|
||||
|
||||
- `.gitignore`: ignores `node_modules`
|
||||
- `LICENSE-APACHE` and `LICENSE-MIT`: most Rust projects are licensed this way, so these are included for you
|
||||
- `README.md`: the file you are reading now!
|
||||
- `index.html`: a bare bones html document that includes the webpack bundle
|
||||
- `index.js`: example js file with a comment showing how to import and use a wasm pkg
|
||||
- `package.json` and `package-lock.json`:
|
||||
- pulls in devDependencies for using webpack:
|
||||
- [`webpack`](https://www.npmjs.com/package/webpack)
|
||||
- [`webpack-cli`](https://www.npmjs.com/package/webpack-cli)
|
||||
- [`webpack-dev-server`](https://www.npmjs.com/package/webpack-dev-server)
|
||||
- defines a `start` script to run `webpack-dev-server`
|
||||
- `webpack.config.js`: configuration file for bundling your js with webpack
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally
|
||||
submitted for inclusion in the work by you, as defined in the Apache-2.0
|
||||
license, shall be dual licensed as above, without any additional terms or
|
||||
conditions.
|
5
demo-www/bootstrap.js
vendored
5
demo-www/bootstrap.js
vendored
@@ -1,5 +0,0 @@
|
||||
// A dependency graph that contains any wasm must all be imported
|
||||
// asynchronously. This `bootstrap.js` file does the single async import, so
|
||||
// that no one else needs to worry about it again.
|
||||
import("./index.js")
|
||||
.catch(e => console.error("Error importing `index.js`:", e));
|
@@ -1,36 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<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>
|
||||
<h2 id="zcash-client-spendable-balance"></h2>
|
||||
<table id="zcash-client-yes-balance">
|
||||
<tr>
|
||||
<td><label for="zcash-client-send-to-address">To:</label></td>
|
||||
<td><input id="zcash-client-send-to-address" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="zcash-client-send-value">Amount:</label></td>
|
||||
<td><input id="zcash-client-send-value" type="number" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button id="zcash-client-send-action">Send!</button></td>
|
||||
</tr>
|
||||
</div>
|
||||
<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>
|
||||
<p id="zcash-client-sync-status">Syncing...</p>
|
||||
</div>
|
||||
<script src="./bootstrap.js"></script>
|
||||
</body>
|
||||
</html>
|
@@ -1,64 +0,0 @@
|
||||
import { ZcashClient } from 'zcash-client-sdk'
|
||||
|
||||
const address = document.getElementById('zcash-client-address')
|
||||
const balance = document.getElementById('zcash-client-balance')
|
||||
const spendableBalance = document.getElementById('zcash-client-spendable-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', {
|
||||
setAddress: (newAddress) => {
|
||||
address.textContent = newAddress
|
||||
},
|
||||
updateBalance: (newBalance, newVerifiedBalance) => {
|
||||
balance.textContent = `Balance: ${newBalance} TAZ`
|
||||
spendableBalance.textContent = `Spendable: ${newVerifiedBalance} TAZ`
|
||||
if (newBalance > 0) {
|
||||
noBalance.style.display = 'none'
|
||||
} else {
|
||||
noBalance.style.display = ''
|
||||
}
|
||||
if (newVerifiedBalance > 0) {
|
||||
yesBalance.style.display = ''
|
||||
} else {
|
||||
yesBalance.style.display = 'none'
|
||||
}
|
||||
},
|
||||
updateSyncStatus: (syncedHeight, latestHeight) => {
|
||||
if (syncedHeight === latestHeight) {
|
||||
syncStatus.textContent = `Synced! Latest height: ${latestHeight}`
|
||||
} else {
|
||||
syncStatus.textContent = `Syncing (${syncedHeight} / ${latestHeight})...`
|
||||
}
|
||||
}
|
||||
}, {
|
||||
height: 500000,
|
||||
hash: '004fada8d4dbc5e80b13522d2c6bd0116113c9b7197f0c6be69bc7a62f2824cd',
|
||||
sapling_tree: '01b733e839b5f844287a6a491409a991ec70277f39a50c99163ed378d23a829a0700100001916db36dfb9a0cf26115ed050b264546c0fa23459433c31fd72f63d188202f2400011f5f4e3bd18da479f48d674dbab64454f6995b113fa21c9d8853a9e764fb3e1f01df9d2c233ca60360e3c2bb73caf5839a1be634c8b99aea22d02abda2e747d9100001970d41722c078288101acd0a75612acfb4c434f2a55aab09fb4e812accc2ba7301485150f0deac7774dcd0fe32043bde9ba2b6bbfff787ad074339af68e88ee70101601324f1421e00a43ef57f197faf385ee4cac65aab58048016ecbd94e022973701e1b17f4bd9d1b6ca1107f619ac6d27b53dd3350d5be09b08935923cbed97906c0000000000011f8322ef806eb2430dc4a7a41c1b344bea5be946efc7b4349c1c9edb14ff9d39'
|
||||
})
|
||||
|
||||
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 = ''
|
||||
|
||||
zcashClient.sync()
|
||||
})
|
5761
demo-www/package-lock.json
generated
5761
demo-www/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
||||
{
|
||||
"name": "create-wasm-app",
|
||||
"version": "0.1.0",
|
||||
"description": "create an app to consume rust-generated wasm packages",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"create-wasm-app": ".bin/create-wasm-app.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"start": "webpack-dev-server"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
|
||||
},
|
||||
"keywords": [
|
||||
"webassembly",
|
||||
"wasm",
|
||||
"rust",
|
||||
"webpack"
|
||||
],
|
||||
"author": "Ashley Williams <ashley666ashley@gmail.com>",
|
||||
"license": "(MIT OR Apache-2.0)",
|
||||
"bugs": {
|
||||
"url": "https://github.com/rustwasm/create-wasm-app/issues"
|
||||
},
|
||||
"homepage": "https://github.com/rustwasm/create-wasm-app#readme",
|
||||
"devDependencies": {
|
||||
"copy-webpack-plugin": "^5.0.0",
|
||||
"webpack": "^4.29.3",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "^3.1.5",
|
||||
"zcash-client-sdk": "file:../zcash-client-sdk-js"
|
||||
}
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: "./bootstrap.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "bootstrap.js",
|
||||
},
|
||||
mode: "development",
|
||||
plugins: [
|
||||
new CopyWebpackPlugin(['index.html'])
|
||||
],
|
||||
};
|
@@ -1,3 +0,0 @@
|
||||
FROM envoyproxy/envoy:v1.10.0
|
||||
COPY ./envoy.yaml /etc/envoy/envoy.yaml
|
||||
CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml
|
@@ -1,45 +0,0 @@
|
||||
admin:
|
||||
access_log_path: /tmp/admin_access.log
|
||||
address:
|
||||
socket_address: { address: 0.0.0.0, port_value: 9901 }
|
||||
|
||||
static_resources:
|
||||
listeners:
|
||||
- name: listener_0
|
||||
address:
|
||||
socket_address: { address: 0.0.0.0, port_value: 8081 }
|
||||
filter_chains:
|
||||
- filters:
|
||||
- name: envoy.http_connection_manager
|
||||
config:
|
||||
codec_type: auto
|
||||
stat_prefix: ingress_http
|
||||
route_config:
|
||||
name: local_route
|
||||
virtual_hosts:
|
||||
- name: local_service
|
||||
domains: ["*"]
|
||||
routes:
|
||||
- match: { prefix: "/" }
|
||||
route:
|
||||
cluster: lightwalletd_frontend
|
||||
max_grpc_timeout: 0s
|
||||
cors:
|
||||
allow_origin:
|
||||
- "*"
|
||||
allow_methods: GET, PUT, DELETE, POST, OPTIONS
|
||||
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
|
||||
max_age: "1728000"
|
||||
expose_headers: custom-header-1,grpc-status,grpc-message
|
||||
enabled: true
|
||||
http_filters:
|
||||
- name: envoy.grpc_web
|
||||
- name: envoy.cors
|
||||
- name: envoy.router
|
||||
clusters:
|
||||
- name: lightwalletd_frontend
|
||||
connect_timeout: 0.25s
|
||||
type: logical_dns
|
||||
http2_protocol_options: {}
|
||||
lb_policy: round_robin
|
||||
hosts: [{ socket_address: { address: localhost, port_value: 9067 }}]
|
@@ -1,11 +0,0 @@
|
||||
install:
|
||||
- appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||
- if not defined RUSTFLAGS rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain nightly
|
||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||
- rustc -V
|
||||
- cargo -V
|
||||
|
||||
build: false
|
||||
|
||||
test_script:
|
||||
- cargo test --locked
|
6
zcash-client-backend-wasm/.gitignore
vendored
6
zcash-client-backend-wasm/.gitignore
vendored
@@ -1,6 +0,0 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
bin/
|
||||
pkg/
|
||||
wasm-pack.log
|
@@ -1,69 +0,0 @@
|
||||
language: rust
|
||||
sudo: false
|
||||
|
||||
cache: cargo
|
||||
|
||||
matrix:
|
||||
include:
|
||||
|
||||
# Builds with wasm-pack.
|
||||
- rust: beta
|
||||
env: RUST_BACKTRACE=1
|
||||
addons:
|
||||
firefox: latest
|
||||
chrome: stable
|
||||
before_script:
|
||||
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
|
||||
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
|
||||
- cargo install-update -a
|
||||
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
|
||||
script:
|
||||
- cargo generate --git . --name testing
|
||||
# Having a broken Cargo.toml (in that it has curlies in fields) anywhere
|
||||
# in any of our parent dirs is problematic.
|
||||
- mv Cargo.toml Cargo.toml.tmpl
|
||||
- cd testing
|
||||
- wasm-pack build
|
||||
- wasm-pack test --chrome --firefox --headless
|
||||
|
||||
# Builds on nightly.
|
||||
- rust: nightly
|
||||
env: RUST_BACKTRACE=1
|
||||
before_script:
|
||||
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
|
||||
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
|
||||
- cargo install-update -a
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
script:
|
||||
- cargo generate --git . --name testing
|
||||
- mv Cargo.toml Cargo.toml.tmpl
|
||||
- cd testing
|
||||
- cargo check
|
||||
- cargo check --target wasm32-unknown-unknown
|
||||
- cargo check --no-default-features
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features
|
||||
- cargo check --no-default-features --features console_error_panic_hook
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
|
||||
- cargo check --no-default-features --features "console_error_panic_hook wee_alloc"
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features --features "console_error_panic_hook wee_alloc"
|
||||
|
||||
# Builds on beta.
|
||||
- rust: beta
|
||||
env: RUST_BACKTRACE=1
|
||||
before_script:
|
||||
- (test -x $HOME/.cargo/bin/cargo-install-update || cargo install cargo-update)
|
||||
- (test -x $HOME/.cargo/bin/cargo-generate || cargo install --vers "^0.2" cargo-generate)
|
||||
- cargo install-update -a
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
script:
|
||||
- cargo generate --git . --name testing
|
||||
- mv Cargo.toml Cargo.toml.tmpl
|
||||
- cd testing
|
||||
- cargo check
|
||||
- cargo check --target wasm32-unknown-unknown
|
||||
- cargo check --no-default-features
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features
|
||||
- cargo check --no-default-features --features console_error_panic_hook
|
||||
- cargo check --target wasm32-unknown-unknown --no-default-features --features console_error_panic_hook
|
||||
# Note: no enabling the `wee_alloc` feature here because it requires
|
||||
# nightly for now.
|
@@ -1,71 +0,0 @@
|
||||
[package]
|
||||
name = "zcash-client-backend-wasm"
|
||||
version = "0.0.1"
|
||||
authors = ["Jack Grigg <jack@z.cash>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[features]
|
||||
default = ["console_error_panic_hook"]
|
||||
|
||||
[dependencies]
|
||||
hex = "0.3"
|
||||
protobuf = "2"
|
||||
wasm-bindgen = "0.2"
|
||||
web-sys = { version = "0.3", features = ["console", "Performance", "Window"] }
|
||||
|
||||
# We don't use these crates directly, but we add it as a dependency so we can
|
||||
# enable necessary features for WASM compatibility.
|
||||
rand = { version = "0.6", features = ["wasm-bindgen"] }
|
||||
|
||||
# The `console_error_panic_hook` crate provides better debugging of panics by
|
||||
# logging them with `console.error`. This is great for development, but requires
|
||||
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
|
||||
# code size when deploying.
|
||||
console_error_panic_hook = { version = "0.1.1", optional = true }
|
||||
|
||||
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
|
||||
# compared to the default allocator's ~10K. It is slower than the default
|
||||
# allocator, however.
|
||||
#
|
||||
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
|
||||
wee_alloc = { version = "0.4.2", optional = true }
|
||||
|
||||
[dependencies.bellman]
|
||||
git = "https://github.com/str4d/librustzcash.git"
|
||||
branch = "demo-wasm"
|
||||
default-features = false
|
||||
features = ["groth16"]
|
||||
|
||||
[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"
|
||||
default-features = false
|
||||
|
||||
[dependencies.zcash_client_backend]
|
||||
git = "https://github.com/str4d/librustzcash.git"
|
||||
branch = "demo-wasm"
|
||||
default-features = false
|
||||
|
||||
[dependencies.zcash_primitives]
|
||||
git = "https://github.com/str4d/librustzcash.git"
|
||||
branch = "demo-wasm"
|
||||
default-features = false
|
||||
|
||||
[dependencies.zcash_proofs]
|
||||
git = "https://github.com/str4d/librustzcash.git"
|
||||
branch = "demo-wasm"
|
||||
default-features = false
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.2"
|
||||
|
||||
[profile.release]
|
||||
# Tell `rustc` to optimize for small code size.
|
||||
# opt-level = "s"
|
@@ -1,176 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
@@ -1,25 +0,0 @@
|
||||
Copyright (c) 2018 Jack Grigg <jack@z.cash>
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
@@ -1,69 +0,0 @@
|
||||
<div align="center">
|
||||
|
||||
<h1><code>wasm-pack-template</code></h1>
|
||||
|
||||
<strong>A template for kick starting a Rust and WebAssembly project using <a href="https://github.com/rustwasm/wasm-pack">wasm-pack</a>.</strong>
|
||||
|
||||
<p>
|
||||
<a href="https://travis-ci.org/rustwasm/wasm-pack-template"><img src="https://img.shields.io/travis/rustwasm/wasm-pack-template.svg?style=flat-square" alt="Build Status" /></a>
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a href="https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html">Tutorial</a>
|
||||
<span> | </span>
|
||||
<a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a>
|
||||
</h3>
|
||||
|
||||
<sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub>
|
||||
</div>
|
||||
|
||||
## About
|
||||
|
||||
[**📚 Read this template tutorial! 📚**][template-docs]
|
||||
|
||||
This template is designed for compiling Rust libraries into WebAssembly and
|
||||
publishing the resulting package to NPM.
|
||||
|
||||
Be sure to check out [other `wasm-pack` tutorials online][tutorials] for other
|
||||
templates and usages of `wasm-pack`.
|
||||
|
||||
[tutorials]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html
|
||||
[template-docs]: https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/index.html
|
||||
|
||||
## 🚴 Usage
|
||||
|
||||
### 🐑 Use `cargo generate` to Clone this Template
|
||||
|
||||
[Learn more about `cargo generate` here.](https://github.com/ashleygwilliams/cargo-generate)
|
||||
|
||||
```
|
||||
cargo generate --git https://github.com/rustwasm/wasm-pack-template.git --name my-project
|
||||
cd my-project
|
||||
```
|
||||
|
||||
### 🛠️ Build with `wasm-pack build`
|
||||
|
||||
```
|
||||
wasm-pack build
|
||||
```
|
||||
|
||||
### 🔬 Test in Headless Browsers with `wasm-pack test`
|
||||
|
||||
```
|
||||
wasm-pack test --headless --firefox
|
||||
```
|
||||
|
||||
### 🎁 Publish to NPM with `wasm-pack publish`
|
||||
|
||||
```
|
||||
wasm-pack publish
|
||||
```
|
||||
|
||||
## 🔋 Batteries Included
|
||||
|
||||
* [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) for communicating
|
||||
between WebAssembly and JavaScript.
|
||||
* [`console_error_panic_hook`](https://github.com/rustwasm/console_error_panic_hook)
|
||||
for logging panic messages to the developer console.
|
||||
* [`wee_alloc`](https://github.com/rustwasm/wee_alloc), an allocator optimized
|
||||
for small code size.
|
@@ -1,56 +0,0 @@
|
||||
//! Structs for handling supported address types.
|
||||
|
||||
use pairing::bls12_381::Bls12;
|
||||
use sapling_crypto::primitives::PaymentAddress;
|
||||
use zcash_client_backend::encoding::{decode_payment_address, decode_transparent_address};
|
||||
use zcash_primitives::legacy::TransparentAddress;
|
||||
|
||||
use zcash_client_backend::constants::testnet::{
|
||||
B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX, HRP_SAPLING_PAYMENT_ADDRESS,
|
||||
};
|
||||
|
||||
/// An address that funds can be sent to.
|
||||
pub enum RecipientAddress {
|
||||
Shielded(PaymentAddress<Bls12>),
|
||||
Transparent(TransparentAddress),
|
||||
}
|
||||
|
||||
impl From<PaymentAddress<Bls12>> for RecipientAddress {
|
||||
fn from(addr: PaymentAddress<Bls12>) -> Self {
|
||||
RecipientAddress::Shielded(addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransparentAddress> for RecipientAddress {
|
||||
fn from(addr: TransparentAddress) -> Self {
|
||||
RecipientAddress::Transparent(addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl RecipientAddress {
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
if let Some(pa) = match decode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, s) {
|
||||
Ok(ret) => ret,
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
return None;
|
||||
}
|
||||
} {
|
||||
Some(RecipientAddress::Shielded(pa))
|
||||
} else if let Some(addr) = match decode_transparent_address(
|
||||
&B58_PUBKEY_ADDRESS_PREFIX,
|
||||
&B58_SCRIPT_ADDRESS_PREFIX,
|
||||
s,
|
||||
) {
|
||||
Ok(ret) => ret,
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
return None;
|
||||
}
|
||||
} {
|
||||
Some(RecipientAddress::Transparent(addr))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,549 +0,0 @@
|
||||
macro_rules! log {
|
||||
( $( $t:tt )* ) => {
|
||||
web_sys::console::log_1(&format!( $( $t )* ).into());
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! error {
|
||||
( $( $t:tt )* ) => {
|
||||
web_sys::console::error_1(&format!( $( $t )* ).into());
|
||||
};
|
||||
}
|
||||
|
||||
mod address;
|
||||
mod prover;
|
||||
mod utils;
|
||||
|
||||
use pairing::bls12_381::Bls12;
|
||||
use protobuf::parse_from_bytes;
|
||||
use sapling_crypto::primitives::{Diversifier, Note, PaymentAddress};
|
||||
use std::cmp;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use zcash_client_backend::{
|
||||
constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS, encoding::encode_payment_address,
|
||||
proto::compact_formats::CompactBlock, welding_rig::scan_block,
|
||||
};
|
||||
use zcash_primitives::{
|
||||
block::BlockHash,
|
||||
merkle_tree::{CommitmentTree, IncrementalWitness},
|
||||
sapling::Node,
|
||||
transaction::{
|
||||
builder::{Builder, DEFAULT_FEE},
|
||||
components::Amount,
|
||||
TxId,
|
||||
},
|
||||
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
|
||||
JUBJUB,
|
||||
};
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
|
||||
// allocator.
|
||||
#[cfg(feature = "wee_alloc")]
|
||||
#[global_allocator]
|
||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
||||
|
||||
const ANCHOR_OFFSET: u32 = 10;
|
||||
|
||||
const SAPLING_ACTIVATION_HEIGHT: i32 = 280_000;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
fn alert(s: &str);
|
||||
}
|
||||
|
||||
fn now() -> f64 {
|
||||
web_sys::window()
|
||||
.expect("should have a Window")
|
||||
.performance()
|
||||
.expect("should have a Performance")
|
||||
.now()
|
||||
}
|
||||
|
||||
struct BlockData {
|
||||
height: i32,
|
||||
hash: BlockHash,
|
||||
tree: CommitmentTree<Node>,
|
||||
}
|
||||
|
||||
struct SaplingNoteData {
|
||||
account: usize,
|
||||
diversifier: Diversifier,
|
||||
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,
|
||||
diversifier: output.to.diversifier,
|
||||
note: output.note,
|
||||
witnesses: vec![witness],
|
||||
nullifier: nf,
|
||||
spent: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct WalletTx {
|
||||
block: i32,
|
||||
notes: Vec<SaplingNoteData>,
|
||||
}
|
||||
|
||||
struct SpendableNote {
|
||||
txid: TxId,
|
||||
nullifier: [u8; 32],
|
||||
diversifier: Diversifier,
|
||||
note: Note<Bls12>,
|
||||
witness: IncrementalWitness<Node>,
|
||||
}
|
||||
|
||||
impl SpendableNote {
|
||||
fn from(txid: TxId, nd: &SaplingNoteData, anchor_offset: usize) -> Option<Self> {
|
||||
if nd.spent.is_none() {
|
||||
let witness = nd.witnesses.get(nd.witnesses.len() - anchor_offset - 1);
|
||||
|
||||
witness.map(|w| SpendableNote {
|
||||
txid,
|
||||
nullifier: nd.nullifier,
|
||||
diversifier: nd.diversifier,
|
||||
note: nd.note.clone(),
|
||||
witness: w.clone(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Client {
|
||||
extsks: [ExtendedSpendingKey; 1],
|
||||
extfvks: [ExtendedFullViewingKey; 1],
|
||||
address: PaymentAddress<Bls12>,
|
||||
blocks: Arc<RwLock<Vec<BlockData>>>,
|
||||
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,
|
||||
blocks: Arc::new(RwLock::new(vec![])),
|
||||
txs: Arc::new(RwLock::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_initial_block(&self, height: i32, hash: &str, sapling_tree: &str) -> bool {
|
||||
let mut blocks = self.blocks.write().unwrap();
|
||||
if !blocks.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let hash = match hex::decode(hash) {
|
||||
Ok(hash) => BlockHash::from_slice(&hash),
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
let sapling_tree = match hex::decode(sapling_tree) {
|
||||
Ok(tree) => tree,
|
||||
Err(e) => {
|
||||
error!("{}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if let Ok(tree) = CommitmentTree::read(&sapling_tree[..]) {
|
||||
blocks.push(BlockData { height, hash, tree });
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last_scanned_height(&self) -> i32 {
|
||||
self.blocks
|
||||
.read()
|
||||
.unwrap()
|
||||
.last()
|
||||
.map(|block| block.height)
|
||||
.unwrap_or(SAPLING_ACTIVATION_HEIGHT - 1)
|
||||
}
|
||||
|
||||
/// Determines the target height for a transaction, and the offset from which to
|
||||
/// select anchors, based on the current synchronised block chain.
|
||||
fn get_target_height_and_anchor_offset(&self) -> Option<(u32, usize)> {
|
||||
match {
|
||||
let blocks = self.blocks.read().unwrap();
|
||||
(
|
||||
blocks.first().map(|block| block.height as u32),
|
||||
blocks.last().map(|block| block.height as u32),
|
||||
)
|
||||
} {
|
||||
(Some(min_height), Some(max_height)) => {
|
||||
let target_height = max_height + 1;
|
||||
|
||||
// Select an anchor ANCHOR_OFFSET back from the target block,
|
||||
// unless that would be before the earliest block we have.
|
||||
let anchor_height =
|
||||
cmp::max(target_height.saturating_sub(ANCHOR_OFFSET), min_height);
|
||||
|
||||
Some((target_height, (target_height - anchor_height) as usize))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// 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 verified_balance(&self) -> u32 {
|
||||
let anchor_height = match self.get_target_height_and_anchor_offset() {
|
||||
Some((height, anchor_offset)) => height - anchor_offset as u32,
|
||||
None => return 0,
|
||||
};
|
||||
|
||||
self.txs
|
||||
.read()
|
||||
.unwrap()
|
||||
.values()
|
||||
.map(|tx| {
|
||||
if tx.block as u32 <= anchor_height {
|
||||
tx.notes
|
||||
.iter()
|
||||
.map(|nd| if nd.spent.is_none() { nd.note.value } else { 0 })
|
||||
.sum::<u64>()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
})
|
||||
.sum::<u64>() as u32
|
||||
}
|
||||
|
||||
pub fn scan_block(&self, block: &[u8]) -> bool {
|
||||
let block: CompactBlock = match parse_from_bytes(block) {
|
||||
Ok(block) => block,
|
||||
Err(e) => {
|
||||
error!("Could not parse CompactBlock from bytes: {}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Scanned blocks MUST be height-sequential.
|
||||
let height = block.get_height() as i32;
|
||||
if height == self.last_scanned_height() {
|
||||
// If the last scanned block is rescanned, check it still matches.
|
||||
if let Some(hash) = self.blocks.read().unwrap().last().map(|block| block.hash) {
|
||||
if block.hash() != hash {
|
||||
error!("Block hash does not match");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if height != (self.last_scanned_height() + 1) {
|
||||
error!(
|
||||
"Block is not height-sequential (expected {}, found {})",
|
||||
self.last_scanned_height() + 1,
|
||||
height
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the most recent scanned data.
|
||||
let mut block_data = BlockData {
|
||||
height,
|
||||
hash: block.hash(),
|
||||
tree: self
|
||||
.blocks
|
||||
.read()
|
||||
.unwrap()
|
||||
.last()
|
||||
.map(|block| block.tree.clone())
|
||||
.unwrap_or(CommitmentTree::new()),
|
||||
};
|
||||
let mut txs = self.txs.write().unwrap();
|
||||
|
||||
// Create a Vec containing all unspent nullifiers.
|
||||
let nfs: Vec<_> = txs
|
||||
.iter()
|
||||
.map(|(txid, tx)| {
|
||||
let txid = *txid;
|
||||
tx.notes.iter().filter_map(move |nd| {
|
||||
if nd.spent.is_none() {
|
||||
Some((nd.nullifier, nd.account, txid))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
// Prepare the note witnesses for updating
|
||||
for tx in txs.values_mut() {
|
||||
for nd in tx.notes.iter_mut() {
|
||||
// Duplicate the most recent witness
|
||||
if let Some(witness) = nd.witnesses.last() {
|
||||
nd.witnesses.push(witness.clone());
|
||||
}
|
||||
// Trim the oldest witnesses
|
||||
nd.witnesses = nd
|
||||
.witnesses
|
||||
.split_off(nd.witnesses.len().saturating_sub(100));
|
||||
}
|
||||
}
|
||||
|
||||
let new_txs = {
|
||||
let nf_refs: Vec<_> = nfs.iter().map(|(nf, acc, _)| (&nf[..], *acc)).collect();
|
||||
|
||||
// Create a single mutable slice of all the newly-added witnesses.
|
||||
let mut witness_refs: Vec<_> = txs
|
||||
.values_mut()
|
||||
.map(|tx| tx.notes.iter_mut().filter_map(|nd| nd.witnesses.last_mut()))
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
scan_block(
|
||||
block,
|
||||
&self.extfvks,
|
||||
&nf_refs[..],
|
||||
&mut block_data.tree,
|
||||
&mut witness_refs[..],
|
||||
)
|
||||
};
|
||||
|
||||
for (tx, new_witnesses) in new_txs {
|
||||
// Mark notes as spent.
|
||||
for spend in &tx.shielded_spends {
|
||||
let txid = nfs
|
||||
.iter()
|
||||
.find(|(nf, _, _)| &nf[..] == &spend.nf[..])
|
||||
.unwrap()
|
||||
.2;
|
||||
let mut spent_note = txs
|
||||
.get_mut(&txid)
|
||||
.unwrap()
|
||||
.notes
|
||||
.iter_mut()
|
||||
.find(|nd| &nd.nullifier[..] == &spend.nf[..])
|
||||
.unwrap();
|
||||
spent_note.spent = Some(tx.txid);
|
||||
}
|
||||
|
||||
// Find the existing transaction entry, or create a new one.
|
||||
if !txs.contains_key(&tx.txid) {
|
||||
let tx_entry = WalletTx {
|
||||
block: block_data.height,
|
||||
notes: vec![],
|
||||
};
|
||||
txs.insert(tx.txid, tx_entry);
|
||||
}
|
||||
let tx_entry = txs.get_mut(&tx.txid).unwrap();
|
||||
|
||||
// Save notes.
|
||||
for (output, witness) in tx
|
||||
.shielded_outputs
|
||||
.into_iter()
|
||||
.zip(new_witnesses.into_iter())
|
||||
{
|
||||
tx_entry.notes.push(SaplingNoteData::new(
|
||||
&self.extfvks[output.account],
|
||||
output,
|
||||
witness,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
// Store scanned data for this block.
|
||||
self.blocks.write().unwrap().push(block_data);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn send_to_address(
|
||||
&self,
|
||||
consensus_branch_id: u32,
|
||||
spend_params: &[u8],
|
||||
output_params: &[u8],
|
||||
to: &str,
|
||||
value: u32,
|
||||
) -> Option<Box<[u8]>> {
|
||||
let start_time = now();
|
||||
log!(
|
||||
"0: Creating transaction sending {} tazoshis to {}",
|
||||
value,
|
||||
to
|
||||
);
|
||||
|
||||
let extsk = &self.extsks[0];
|
||||
let extfvk = &self.extfvks[0];
|
||||
let ovk = extfvk.fvk.ovk;
|
||||
|
||||
let to = match address::RecipientAddress::from_str(to) {
|
||||
Some(to) => to,
|
||||
None => {
|
||||
error!("Invalid recipient address");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let value = Amount(value as i64);
|
||||
|
||||
// Target the next block, assuming we are up-to-date.
|
||||
let (height, anchor_offset) = match self.get_target_height_and_anchor_offset() {
|
||||
Some(res) => res,
|
||||
None => {
|
||||
error!("Cannot send funds before scanning any blocks");
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
// Select notes to cover the target value
|
||||
log!("{}: Selecting notes", now() - start_time);
|
||||
let target_value = value.0 + DEFAULT_FEE.0;
|
||||
let notes: Vec<_> = self
|
||||
.txs
|
||||
.read()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|(txid, tx)| tx.notes.iter().map(move |note| (*txid, note)))
|
||||
.flatten()
|
||||
.filter_map(|(txid, note)| SpendableNote::from(txid, note, anchor_offset))
|
||||
.scan(0, |running_total, spendable| {
|
||||
let value = spendable.note.value;
|
||||
let ret = if *running_total < target_value as u64 {
|
||||
Some(spendable)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
*running_total = *running_total + value;
|
||||
ret
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Confirm we were able to select sufficient value
|
||||
let selected_value = notes
|
||||
.iter()
|
||||
.map(|selected| selected.note.value)
|
||||
.sum::<u64>();
|
||||
if selected_value < target_value as u64 {
|
||||
error!(
|
||||
"Insufficient funds (have {}, need {})",
|
||||
selected_value, target_value
|
||||
);
|
||||
return None;
|
||||
}
|
||||
|
||||
// Create the transaction
|
||||
log!("{}: Adding {} inputs", now() - start_time, notes.len());
|
||||
let mut builder = Builder::new(height);
|
||||
for selected in notes.iter() {
|
||||
if let Err(e) = builder.add_sapling_spend(
|
||||
extsk.clone(),
|
||||
selected.diversifier,
|
||||
selected.note.clone(),
|
||||
selected.witness.clone(),
|
||||
) {
|
||||
error!("Error adding note: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
log!("{}: Adding output", now() - start_time);
|
||||
if let Err(e) = match to {
|
||||
address::RecipientAddress::Shielded(to) => {
|
||||
builder.add_sapling_output(ovk, to.clone(), value, None)
|
||||
}
|
||||
address::RecipientAddress::Transparent(to) => {
|
||||
builder.add_transparent_output(&to, value)
|
||||
}
|
||||
} {
|
||||
error!("Error adding output: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
log!("{}: Building transaction", now() - start_time);
|
||||
let (tx, _) = match builder.build(
|
||||
consensus_branch_id,
|
||||
prover::InMemTxProver::new(spend_params, output_params),
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(e) => {
|
||||
error!("Error creating transaction: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
log!("{}: Transaction created", now() - start_time);
|
||||
log!("Transaction ID: {}", tx.txid());
|
||||
|
||||
// Mark notes as spent.
|
||||
let mut txs = self.txs.write().unwrap();
|
||||
for selected in notes {
|
||||
let mut spent_note = txs
|
||||
.get_mut(&selected.txid)
|
||||
.unwrap()
|
||||
.notes
|
||||
.iter_mut()
|
||||
.find(|nd| &nd.nullifier[..] == &selected.nullifier[..])
|
||||
.unwrap();
|
||||
spent_note.spent = Some(tx.txid());
|
||||
}
|
||||
|
||||
// Return the encoded transaction, so the caller can send it.
|
||||
let mut raw_tx = vec![];
|
||||
tx.write(&mut raw_tx).unwrap();
|
||||
Some(raw_tx.into_boxed_slice())
|
||||
}
|
||||
}
|
@@ -1,122 +0,0 @@
|
||||
//! Abstractions over the proving system and parameters for ease of use.
|
||||
|
||||
use bellman::groth16::{prepare_verifying_key, Parameters, PreparedVerifyingKey};
|
||||
use pairing::bls12_381::{Bls12, Fr};
|
||||
use sapling_crypto::{
|
||||
jubjub::{edwards, fs::Fs, Unknown},
|
||||
primitives::{Diversifier, PaymentAddress, ProofGenerationKey},
|
||||
redjubjub::{PublicKey, Signature},
|
||||
};
|
||||
use zcash_primitives::{
|
||||
merkle_tree::CommitmentTreeWitness, prover::TxProver, sapling::Node,
|
||||
transaction::components::GROTH_PROOF_SIZE, JUBJUB,
|
||||
};
|
||||
use zcash_proofs::sapling::SaplingProvingContext;
|
||||
|
||||
/// An implementation of [`TxProver`] using Sapling Spend and Output parameters provided
|
||||
/// in-memory.
|
||||
pub struct InMemTxProver {
|
||||
spend_params: Parameters<Bls12>,
|
||||
spend_vk: PreparedVerifyingKey<Bls12>,
|
||||
output_params: Parameters<Bls12>,
|
||||
}
|
||||
|
||||
impl InMemTxProver {
|
||||
pub fn new(spend_params: &[u8], output_params: &[u8]) -> Self {
|
||||
// Deserialize params
|
||||
let spend_params = Parameters::<Bls12>::read(spend_params, false)
|
||||
.expect("couldn't deserialize Sapling spend parameters file");
|
||||
let output_params = Parameters::<Bls12>::read(output_params, false)
|
||||
.expect("couldn't deserialize Sapling spend parameters file");
|
||||
|
||||
// Prepare verifying keys
|
||||
let spend_vk = prepare_verifying_key(&spend_params.vk);
|
||||
|
||||
InMemTxProver {
|
||||
spend_params,
|
||||
spend_vk,
|
||||
output_params,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TxProver for InMemTxProver {
|
||||
type SaplingProvingContext = SaplingProvingContext;
|
||||
|
||||
fn new_sapling_proving_context(&self) -> Self::SaplingProvingContext {
|
||||
SaplingProvingContext::new()
|
||||
}
|
||||
|
||||
fn spend_proof(
|
||||
&self,
|
||||
ctx: &mut Self::SaplingProvingContext,
|
||||
proof_generation_key: ProofGenerationKey<Bls12>,
|
||||
diversifier: Diversifier,
|
||||
rcm: Fs,
|
||||
ar: Fs,
|
||||
value: u64,
|
||||
anchor: Fr,
|
||||
witness: CommitmentTreeWitness<Node>,
|
||||
) -> Result<
|
||||
(
|
||||
[u8; GROTH_PROOF_SIZE],
|
||||
edwards::Point<Bls12, Unknown>,
|
||||
PublicKey<Bls12>,
|
||||
),
|
||||
(),
|
||||
> {
|
||||
let (proof, cv, rk) = ctx.spend_proof(
|
||||
proof_generation_key,
|
||||
diversifier,
|
||||
rcm,
|
||||
ar,
|
||||
value,
|
||||
anchor,
|
||||
witness,
|
||||
&self.spend_params,
|
||||
&self.spend_vk,
|
||||
&JUBJUB,
|
||||
)?;
|
||||
|
||||
let mut zkproof = [0u8; GROTH_PROOF_SIZE];
|
||||
proof
|
||||
.write(&mut zkproof[..])
|
||||
.expect("should be able to serialize a proof");
|
||||
|
||||
Ok((zkproof, cv, rk))
|
||||
}
|
||||
|
||||
fn output_proof(
|
||||
&self,
|
||||
ctx: &mut Self::SaplingProvingContext,
|
||||
esk: Fs,
|
||||
payment_address: PaymentAddress<Bls12>,
|
||||
rcm: Fs,
|
||||
value: u64,
|
||||
) -> ([u8; GROTH_PROOF_SIZE], edwards::Point<Bls12, Unknown>) {
|
||||
let (proof, cv) = ctx.output_proof(
|
||||
esk,
|
||||
payment_address,
|
||||
rcm,
|
||||
value,
|
||||
&self.output_params,
|
||||
&JUBJUB,
|
||||
);
|
||||
|
||||
let mut zkproof = [0u8; GROTH_PROOF_SIZE];
|
||||
proof
|
||||
.write(&mut zkproof[..])
|
||||
.expect("should be able to serialize a proof");
|
||||
|
||||
(zkproof, cv)
|
||||
}
|
||||
|
||||
fn binding_sig(
|
||||
&self,
|
||||
ctx: &mut Self::SaplingProvingContext,
|
||||
value_balance: i64,
|
||||
sighash: &[u8; 32],
|
||||
) -> Result<Signature, ()> {
|
||||
ctx.binding_sig(value_balance, sighash, &JUBJUB)
|
||||
}
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
pub fn set_panic_hook() {
|
||||
// When the `console_error_panic_hook` feature is enabled, we can call the
|
||||
// `set_panic_hook` function at least once during initialization, and then
|
||||
// we will get better error messages if our code ever panics.
|
||||
//
|
||||
// For more details see
|
||||
// https://github.com/rustwasm/console_error_panic_hook#readme
|
||||
#[cfg(feature = "console_error_panic_hook")]
|
||||
console_error_panic_hook::set_once();
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
//! Test suite for the Web and headless browsers.
|
||||
|
||||
#![cfg(target_arch = "wasm32")]
|
||||
|
||||
extern crate wasm_bindgen_test;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn pass() {
|
||||
assert_eq!(1 + 1, 2);
|
||||
}
|
1
zcash-client-sdk-js/.gitignore
vendored
1
zcash-client-sdk-js/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
node_modules/
|
4235
zcash-client-sdk-js/package-lock.json
generated
4235
zcash-client-sdk-js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"name": "zcash-client-sdk",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"zcash"
|
||||
],
|
||||
"author": "Jack Grigg <jack@z.cash>",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"google-protobuf": "3.8.0",
|
||||
"grpc": "1.21.1",
|
||||
"grpc-web": "1.0.4",
|
||||
"webpack": "4.33.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"zcash-client-backend-wasm": "file:../zcash-client-backend-wasm/pkg"
|
||||
}
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
syntax = "proto3";
|
||||
package cash.z.wallet.sdk.rpc;
|
||||
option go_package = "walletrpc";
|
||||
|
||||
// Remember that proto3 fields are all optional. A field that is not present will be set to its zero value.
|
||||
// bytes fields of hashes are in canonical little-endian format.
|
||||
|
||||
// CompactBlock is a packaging of ONLY the data from a block that's needed to:
|
||||
// 1. Detect a payment to your shielded Sapling address
|
||||
// 2. Detect a spend of your shielded Sapling notes
|
||||
// 3. Update your witnesses to generate new Sapling spend proofs.
|
||||
message CompactBlock {
|
||||
uint32 protoVersion = 1; // the version of this wire format, for storage
|
||||
uint64 height = 2; // the height of this block
|
||||
bytes hash = 3;
|
||||
bytes prevHash = 4;
|
||||
uint32 time = 5;
|
||||
bytes header = 6; // (hash, prevHash, and time) OR (full header)
|
||||
repeated CompactTx vtx = 7; // compact transactions from this block
|
||||
}
|
||||
|
||||
message CompactTx {
|
||||
// Index and hash will allow the receiver to call out to chain
|
||||
// explorers or other data structures to retrieve more information
|
||||
// about this transaction.
|
||||
uint64 index = 1;
|
||||
bytes hash = 2;
|
||||
|
||||
// The transaction fee: present if server can provide. In the case of a
|
||||
// stateless server and a transaction with transparent inputs, this will be
|
||||
// unset because the calculation requires reference to prior transactions.
|
||||
// in a pure-Sapling context, the fee will be calculable as:
|
||||
// valueBalance + (sum(vPubNew) - sum(vPubOld) - sum(tOut))
|
||||
uint32 fee = 3;
|
||||
|
||||
repeated CompactSpend spends = 4;
|
||||
repeated CompactOutput outputs = 5;
|
||||
}
|
||||
|
||||
message CompactSpend {
|
||||
bytes nf = 1;
|
||||
}
|
||||
|
||||
message CompactOutput {
|
||||
bytes cmu = 1;
|
||||
bytes epk = 2;
|
||||
bytes ciphertext = 3;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,202 +0,0 @@
|
||||
import { Client } from 'zcash-client-backend-wasm'
|
||||
|
||||
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 = 0x2bb40e60
|
||||
|
||||
const CHAIN_REFRESH_INTERVAL = 60 * 1000
|
||||
const BATCH_SIZE = 1000
|
||||
|
||||
export class ZcashClient {
|
||||
constructor (lightwalletdURL, uiHandlers, checkpoint) {
|
||||
this.lightwalletd = new CompactTxStreamerClient(lightwalletdURL)
|
||||
this.client = Client.new()
|
||||
this.uiHandlers = uiHandlers
|
||||
|
||||
if (!this.client.set_initial_block(checkpoint.height, checkpoint.hash, checkpoint.sapling_tree)) {
|
||||
console.error('Invalid checkpoint data')
|
||||
}
|
||||
}
|
||||
|
||||
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, this.client.verified_balance() / COIN)
|
||||
}
|
||||
|
||||
sync () {
|
||||
var self = this
|
||||
|
||||
var chainSpec = new ChainSpec()
|
||||
|
||||
self.lightwalletd.getLatestBlock(chainSpec, {}, (err, latestBlock) => {
|
||||
if (err) {
|
||||
console.error('Error fetching latest block')
|
||||
console.error(`Error code: ${err.code} "${err.message}"`)
|
||||
return
|
||||
}
|
||||
|
||||
var startHeight = self.client.last_scanned_height()
|
||||
var latestHeight = latestBlock.getHeight()
|
||||
if (startHeight === latestHeight) {
|
||||
console.log('No new blocks')
|
||||
window.setTimeout(() => { self.sync() }, CHAIN_REFRESH_INTERVAL)
|
||||
return
|
||||
}
|
||||
|
||||
var endHeight
|
||||
if (latestHeight - startHeight < BATCH_SIZE) {
|
||||
endHeight = latestHeight
|
||||
} else {
|
||||
endHeight = startHeight + BATCH_SIZE - 1
|
||||
}
|
||||
console.debug(`Latest block: ${latestHeight}`)
|
||||
console.debug(`Requesting blocks in range [${startHeight}, ${endHeight}]`)
|
||||
|
||||
var blockStart = new BlockID()
|
||||
blockStart.setHeight(startHeight)
|
||||
var blockEnd = new BlockID()
|
||||
blockEnd.setHeight(endHeight)
|
||||
var blockRange = new BlockRange()
|
||||
blockRange.setStart(blockStart)
|
||||
blockRange.setEnd(blockEnd)
|
||||
|
||||
var stream = self.lightwalletd.getBlockRange(blockRange, {})
|
||||
stream.on('data', (block) => {
|
||||
// Scan the block
|
||||
if (!self.client.scan_block(block.serializeBinary())) {
|
||||
console.error('Failed to scan block')
|
||||
}
|
||||
})
|
||||
stream.on('status', (status) => {
|
||||
if (status.metadata) {
|
||||
console.debug('Received metadata')
|
||||
console.debug(status.metadata)
|
||||
}
|
||||
if (status.code !== grpc.web.StatusCode.OK) {
|
||||
console.error(`Error code: ${status.code} "${status.details}"`)
|
||||
}
|
||||
|
||||
// Perform end-of-stream updates here, because we don't always get the
|
||||
// 'end' event for some reason, but we do always get the 'status' event.
|
||||
|
||||
var syncedHeight = self.client.last_scanned_height()
|
||||
if (endHeight !== syncedHeight) {
|
||||
console.error('Block stream finished before expected end height')
|
||||
}
|
||||
|
||||
// Update UI for current chain status
|
||||
console.log(`Scanned to height: ${syncedHeight}`)
|
||||
self.updateUI()
|
||||
self.uiHandlers.updateSyncStatus(syncedHeight, latestHeight)
|
||||
|
||||
// Queue up the next sync
|
||||
if (syncedHeight === latestHeight) {
|
||||
console.log('Finished syncing!')
|
||||
window.setTimeout(() => { self.sync() }, CHAIN_REFRESH_INTERVAL)
|
||||
} else {
|
||||
self.sync()
|
||||
}
|
||||
})
|
||||
stream.on('error', (err) => {
|
||||
console.error('Error while streaming blocks')
|
||||
console.error(`Error code: ${err.code} "${err.message}"`)
|
||||
})
|
||||
stream.on('end', () => {
|
||||
console.debug('Block stream end signal received')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
self.uiHandlers.setAddress(self.client.address())
|
||||
self.updateUI()
|
||||
|
||||
// Finished loading!
|
||||
onFinished()
|
||||
}
|
||||
|
||||
// document.addEventListener('DOMContentLoaded', loader, false)
|
||||
loader()
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
syntax = "proto3";
|
||||
package cash.z.wallet.sdk.rpc;
|
||||
option go_package = "walletrpc";
|
||||
|
||||
import "compact_formats.proto";
|
||||
|
||||
// A BlockID message contains identifiers to select a block: a height or a
|
||||
// hash. If the hash is present it takes precedence.
|
||||
message BlockID {
|
||||
uint64 height = 1;
|
||||
bytes hash = 2;
|
||||
}
|
||||
|
||||
// BlockRange technically allows ranging from hash to hash etc but this is not
|
||||
// currently intended for support, though there is no reason you couldn't do
|
||||
// it. Further permutations are left as an exercise.
|
||||
message BlockRange {
|
||||
BlockID start = 1;
|
||||
BlockID end = 2;
|
||||
}
|
||||
|
||||
// A TxFilter contains the information needed to identify a particular
|
||||
// transaction: either a block and an index, or a direct transaction hash.
|
||||
message TxFilter {
|
||||
BlockID block = 1;
|
||||
uint64 index = 2;
|
||||
bytes hash = 3;
|
||||
}
|
||||
|
||||
// RawTransaction contains the complete transaction data.
|
||||
message RawTransaction {
|
||||
bytes data = 1;
|
||||
}
|
||||
|
||||
message SendResponse {
|
||||
int32 errorCode = 1;
|
||||
string errorMessage = 2;
|
||||
}
|
||||
|
||||
// Empty placeholder. Someday we may want to specify e.g. a particular chain fork.
|
||||
message ChainSpec {}
|
||||
|
||||
service CompactTxStreamer {
|
||||
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
|
||||
rpc GetBlock(BlockID) returns (CompactBlock) {}
|
||||
rpc GetBlockRange(BlockRange) returns (stream CompactBlock) {}
|
||||
rpc GetTransaction(TxFilter) returns (RawTransaction) {}
|
||||
rpc SendTransaction(RawTransaction) returns (SendResponse) {}
|
||||
}
|
@@ -1,366 +0,0 @@
|
||||
/**
|
||||
* @fileoverview gRPC-Web generated client stub for cash.z.wallet.sdk.rpc
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
|
||||
var compact_formats_pb = require('./compact_formats_pb.js')
|
||||
const proto = {};
|
||||
proto.cash = {};
|
||||
proto.cash.z = {};
|
||||
proto.cash.z.wallet = {};
|
||||
proto.cash.z.wallet.sdk = {};
|
||||
proto.cash.z.wallet.sdk.rpc = require('./service_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
/**
|
||||
* @private @const {?Object} The credentials to be used to connect
|
||||
* to the server
|
||||
*/
|
||||
this.credentials_ = credentials;
|
||||
|
||||
/**
|
||||
* @private @const {?Object} Options for the client
|
||||
*/
|
||||
this.options_ = options;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerPromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
/**
|
||||
* @private @const {?Object} The credentials to be used to connect
|
||||
* to the server
|
||||
*/
|
||||
this.credentials_ = credentials;
|
||||
|
||||
/**
|
||||
* @private @const {?Object} Options for the client
|
||||
*/
|
||||
this.options_ = options;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.cash.z.wallet.sdk.rpc.ChainSpec,
|
||||
* !proto.cash.z.wallet.sdk.rpc.BlockID>}
|
||||
*/
|
||||
const methodInfo_CompactTxStreamer_GetLatestBlock = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.cash.z.wallet.sdk.rpc.BlockID,
|
||||
/** @param {!proto.cash.z.wallet.sdk.rpc.ChainSpec} request */
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.cash.z.wallet.sdk.rpc.BlockID.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.ChainSpec} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.cash.z.wallet.sdk.rpc.BlockID)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.cash.z.wallet.sdk.rpc.BlockID>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerClient.prototype.getLatestBlock =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetLatestBlock,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.ChainSpec} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.cash.z.wallet.sdk.rpc.BlockID>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerPromiseClient.prototype.getLatestBlock =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetLatestBlock);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.cash.z.wallet.sdk.rpc.BlockID,
|
||||
* !proto.cash.z.wallet.sdk.rpc.CompactBlock>}
|
||||
*/
|
||||
const methodInfo_CompactTxStreamer_GetBlock = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
compact_formats_pb.CompactBlock,
|
||||
/** @param {!proto.cash.z.wallet.sdk.rpc.BlockID} request */
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
compact_formats_pb.CompactBlock.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.BlockID} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.cash.z.wallet.sdk.rpc.CompactBlock)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.cash.z.wallet.sdk.rpc.CompactBlock>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerClient.prototype.getBlock =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetBlock,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.BlockID} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.cash.z.wallet.sdk.rpc.CompactBlock>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerPromiseClient.prototype.getBlock =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetBlock);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.cash.z.wallet.sdk.rpc.BlockRange,
|
||||
* !proto.cash.z.wallet.sdk.rpc.CompactBlock>}
|
||||
*/
|
||||
const methodInfo_CompactTxStreamer_GetBlockRange = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
compact_formats_pb.CompactBlock,
|
||||
/** @param {!proto.cash.z.wallet.sdk.rpc.BlockRange} request */
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
compact_formats_pb.CompactBlock.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.BlockRange} request The request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.cash.z.wallet.sdk.rpc.CompactBlock>}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerClient.prototype.getBlockRange =
|
||||
function(request, metadata) {
|
||||
return this.client_.serverStreaming(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetBlockRange);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.BlockRange} request The request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.cash.z.wallet.sdk.rpc.CompactBlock>}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerPromiseClient.prototype.getBlockRange =
|
||||
function(request, metadata) {
|
||||
return this.client_.serverStreaming(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetBlockRange);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.cash.z.wallet.sdk.rpc.TxFilter,
|
||||
* !proto.cash.z.wallet.sdk.rpc.RawTransaction>}
|
||||
*/
|
||||
const methodInfo_CompactTxStreamer_GetTransaction = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.cash.z.wallet.sdk.rpc.RawTransaction,
|
||||
/** @param {!proto.cash.z.wallet.sdk.rpc.TxFilter} request */
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.cash.z.wallet.sdk.rpc.RawTransaction.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.TxFilter} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.cash.z.wallet.sdk.rpc.RawTransaction)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.cash.z.wallet.sdk.rpc.RawTransaction>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerClient.prototype.getTransaction =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetTransaction,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.TxFilter} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.cash.z.wallet.sdk.rpc.RawTransaction>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerPromiseClient.prototype.getTransaction =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_GetTransaction);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.cash.z.wallet.sdk.rpc.RawTransaction,
|
||||
* !proto.cash.z.wallet.sdk.rpc.SendResponse>}
|
||||
*/
|
||||
const methodInfo_CompactTxStreamer_SendTransaction = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.cash.z.wallet.sdk.rpc.SendResponse,
|
||||
/** @param {!proto.cash.z.wallet.sdk.rpc.RawTransaction} request */
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.cash.z.wallet.sdk.rpc.SendResponse.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.RawTransaction} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.cash.z.wallet.sdk.rpc.SendResponse)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.cash.z.wallet.sdk.rpc.SendResponse>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerClient.prototype.sendTransaction =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_SendTransaction,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.cash.z.wallet.sdk.rpc.RawTransaction} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.cash.z.wallet.sdk.rpc.SendResponse>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.cash.z.wallet.sdk.rpc.CompactTxStreamerPromiseClient.prototype.sendTransaction =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction',
|
||||
request,
|
||||
metadata || {},
|
||||
methodInfo_CompactTxStreamer_SendTransaction);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.cash.z.wallet.sdk.rpc;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
||||
var path = require('path')
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'zcash-client-sdk.js',
|
||||
library: 'zcashClientSdk'
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user