Compare commits

...

17 Commits

Author SHA1 Message Date
ec1c479156 Increase block cache size to 400k for faster wallet sync
- Increase default cache-size from 40,000 to 400,000 blocks
- Add Python gRPC protobuf bindings for testing
2026-03-21 03:50:55 -05:00
aae94a4f3c changes 2026-03-20 06:55:27 -05:00
3355c1ea85 stop server script 2026-03-20 06:26:15 -05:00
ebc38c9369 Fix lightwalletd sync loop for DragonX wallet
- Handle missing Sapling upgrade in getblockchaininfo response by
  defaulting activation height to 1 (DragonX has Sapling active from
  genesis but uses NO_ACTIVATION_HEIGHT in chainparams)
- Override consensus branch ID to Sapling (76b809bb) when node reports
  Sprout (00000000) due to disabled activation heights
- Include full serialized block header in CompactBlock so the SDK can
  validate hashFinalSaplingRoot against the Sapling commitment tree
- Set CompactBlock ProtoVersion to 1
2026-03-20 06:24:54 -05:00
f4ef38c42f fix sapling activation height and consensus branch id 2026-03-20 06:11:38 -05:00
dan-s
daab197a01 update for dragonx binary changes, added monitor script 2026-03-04 15:28:02 -06:00
dan-s
ef9b241cfd cleanup 2026-02-28 00:37:44 -06:00
Duke Leto
5bab463245 Use non-legacy conf file location 2022-11-20 17:25:33 +00:00
Duke Leto
24640b178e Update 'README.md' 2022-11-20 17:20:06 +00:00
Duke Leto
5b5533c890 Update 'README.md' 2022-10-31 13:07:18 +00:00
Duke Leto
c9f6e7d7f3 Update 'README.md' 2022-10-31 13:06:25 +00:00
Duke Leto
6cc055b07f Merge pull request 'Add myself to authors' (#21) from dev into master
Reviewed-on: https://git.hush.is/hush/lightwalletd/pulls/21
2021-10-29 02:43:10 +00:00
Duke Leto
8937561710 Add myself to authors 2021-10-28 22:42:37 -04:00
jahway603
0735c58b4c Merge pull request 'added AUTHORS file' (#20) from jahway into master
Reviewed-on: https://git.hush.is/hush/lightwalletd/pulls/20
2021-10-28 03:34:44 +00:00
jahway603
1217bade73 Merge branch 'master' into jahway 2021-10-28 03:34:21 +00:00
jahway603
8881b6f1d6 added AUTHORS file 2021-10-27 23:33:19 -04:00
jahway603
3ef370621c Merge pull request 'new build scripts for ARM' (#19) from jahway into master
Reviewed-on: https://git.hush.is/hush/lightwalletd/pulls/19
2021-10-25 22:22:51 +00:00
21 changed files with 878 additions and 86 deletions

32
.gitignore vendored
View File

@@ -1,5 +1,33 @@
# Compiled binaries
main
grpcfrontend
cert.pem
key.pem
lightwalletd
# TLS certificates and keys
*.pem
# Database files
*.db
*.sqlite
# Logs
*.log
# Go test binaries and output
*.test
*.out
*.prof
# IDE and editor files
.idea/
.vscode/
*.swp
*.swo
*~
# Temporary files
/tmp/
# Build output
/dist/
/build/

4
AUTHORS Normal file
View File

@@ -0,0 +1,4 @@
# The Hush Developers
Jahway603 https://git.hush.is/jahway603 https://github.com/jahway603
Duke Leto https://git.hush.is/duke

View File

@@ -1,7 +1,8 @@
# Copyright (c) 2021 Jahway603 & The Hush Developers
# Copyright (c) 2024-2026 The DragonX Developers
# Released under the GPLv3
#
# Hush Lightwalletd Makefile
# DragonX Lightwalletd Makefile
# author: jahway603
#
PROJECT_NAME := "lightwalletd"
@@ -19,9 +20,9 @@ build-arm:
# Build binary for ARM architecture (aarch64)
./util/build_arm.sh
# Stop the hushd process in the hushdlwd container
#docker_img_stop_hushd:
# docker exec -i hushdlwd hush-cli stop
# Stop the dragonxd process in the container
#docker_img_stop_dragonxd:
# docker exec -i dragonxdlwd dragonx-cli stop
# Remove and delete ALL images and containers in Docker; assumes containers are stopped
#docker_remove_all:

View File

@@ -1,21 +1,20 @@
# Overview
Hush Lightwalletd is a fork of [lightwalletd](https://github.com/adityapk00/lightwalletd) original from Zcash (ZEC).
DragonX Lightwalletd is a fork of [Hush lightwalletd](https://git.hush.is/hush/lightwalletd) which is itself a fork of [lightwalletd](https://github.com/adityapk00/lightwalletd) originally from Zcash (ZEC).
It is a backend service that provides a bandwidth-efficient interface to the Hush blockchain for [SilentDragonLite cli](https://git.hush.is/hush/silentdragonlite-light-cli) and [SilentDragonLite](https://git.hush.is/hush/SilentDragonLite).
It is a backend service that provides a bandwidth-efficient interface to the DragonX blockchain for light wallet clients.
## Changes from upstream lightwalletd
This version of lightwalletd extends lightwalletd and:
## Features
* Adds support for HUSH
* Adds support for transparent addresses
* Adds several new RPC calls for lightclients
* Support for DragonX (standalone chain with `dragonxd`)
* Support for transparent addresses
* Several RPC calls for light clients
* Lots of perf improvements
* Replaces SQLite with in-memory cache for Compact Blocks
* Replace local Txstore, delegating Tx lookups to hushd
* Remove the need for a separate ingestor
* In-memory cache for Compact Blocks (replaces SQLite)
* Tx lookups delegated to dragonxd
* No separate ingestor needed
## Running your own SDL lightwalletd
## Running your own DragonX lightwalletd
#### 0. First, install Go
You will need Go >= 1.13 which you can download from the official [download page](https://golang.org/dl/) or install via your OS package manager.
@@ -28,15 +27,15 @@ If you're using Ubuntu or Debian, try:
$ sudo apt install golang
```
#### 1. Run a Hush node.
Either compile or build the [Hush Daemon (hushd)](https://git.hush.is/hush/hush3).
#### 1. Run a DragonX node.
Install the DragonX daemon (`dragonxd`) and CLI (`dragonx-cli`).
Next, change your HUSH3.conf file to something like the following:
Next, ensure your DRAGONX.conf file (at `~/.hush/DRAGONX/DRAGONX.conf`) has something like the following:
```
rpcuser=user-CHANGETHIS
rpcpassword=pass-CHANGETHIS
rpcport=18031
rpcport=21769
server=1
txindex=1
rpcworkqueue=256
@@ -44,7 +43,7 @@ rpcallowip=127.0.0.1
rpcbind=127.0.0.1
```
Then start `hushd` in your command window. You might need to run with `-reindex` the first time if you are enabling the `txindex` or `insightexplorer` options for the first time. The reindex might take a while.
Then start `dragonxd`. You might need to run with `-reindex` the first time if you are enabling the `txindex` option for the first time. The reindex might take a while.
#### 2. Compile lightwalletd
Run the build script.
@@ -77,8 +76,8 @@ server {
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
# Replace localhost:9067 with the address and port of your gRPC server if using a custom port
grpc_pass grpc://your_host.net:9067;
# Replace localhost:9069 with the address and port of your gRPC server if using a custom port
grpc_pass grpc://your_host.net:9069;
}
}
```
@@ -86,28 +85,18 @@ server {
Then run the lightwalletd frontend with the following (Note: we use the "-no-tls" option as we are using NGINX as a reverse proxy and letting it handle the TLS authentication for us instead):
```
./lightwalletd -bind-addr your_host.net:9067 -conf-file ~/.komodo/HUSH3/HUSH3.conf -no-tls
./lightwalletd -bind-addr your_host.net:9069 -conf-file ~/.hush/DRAGONX/DRAGONX.conf -no-tls
```
##### Option B: "Let's Encrypt" certificate just using lightwalletd without NGINX
The other option is to configure lightwalletd to handle its own TLS authentication. Once you have a certificate that you want to use (from a certificate authority), pass the certificate to the frontend as follows:
```
./lightwalletd -bind-addr 127.0.0.1:9067 -conf-file ~/.komodo/HUSH3/HUSH3.conf -tls-cert /etc/letsencrypt/live/YOURWEBSITE/fullchain.pem -tls-key /etc/letsencrypt/live/YOURWEBSITE/privkey.pem
./lightwalletd -bind-addr 127.0.0.1:9069 -conf-file ~/.hush/DRAGONX/DRAGONX.conf -tls-cert /etc/letsencrypt/live/YOURWEBSITE/fullchain.pem -tls-key /etc/letsencrypt/live/YOURWEBSITE/privkey.pem
```
#### 4. Point the `silentdragonlite-cli` to this server
You should start seeing the frontend ingest and cache the Hush blocks after ~15 seconds.
Now, connect to your server! (Substitute with your own below)
```
git clone https://git.hush.is/hush/silentdragonlite-cli
cd silentdragonlite-cli
cargo build --release
./target/release/silentdragonlite-cli --server https://lite.example.org
```
* If you have trouble compiling silentdragonlite-cli, then [please refer to it's separate documentation here](https://git.hush.is/hush/silentdragonlite-cli) on how to build it and what pre-requisites need to be installed.
#### 4. Point a light wallet client to this server
You should start seeing the frontend ingest and cache the DragonX blocks after ~15 seconds.
## Lightwalletd Command-line Options
@@ -115,7 +104,7 @@ These are the current different command line options for lightwalletd:
| CLI option | Default | What it does |
|------------|:--------------:|------------------------------:|
| -bind-addr | 127.0.0.1:9067 | address and port to listen on |
| -bind-addr | 127.0.0.1:9069 | address and port to listen on |
| -tls-cert | blank | the path to a TLS certificate |
| -tls-key | blank | the path to a TLS key file |
| -no-tls | false | Disable TLS, serve un-encrypted traffic |
@@ -125,7 +114,12 @@ These are the current different command line options for lightwalletd:
| -cache-size| 40000 | number of blocks to hold in the cache |
## Support
For support or other questions, join us on [Telegram](https://hush.is/telegram), or tweet at [@MyHushTeam](https://twitter.com/MyHushTeam), or toot at our [Mastodon](https://fosstodon.org/@myhushteam) or join [Telegram Support](https://hush.is/telegram_support).
For support or other questions, join us on [Telegram](https://hush.is/telegram) or join [Telegram Support](https://hush.is/telegram_support).
## License
GPLv3 or later
# Copyright
2016-2022 The Hush Developers
2024-2026 The DragonX Developers

View File

@@ -77,32 +77,32 @@ func loggerFromContext(ctx context.Context) *logrus.Entry {
}
type Options struct {
bindAddr string `json:"bind_address,omitempty"`
tlsCertPath string `json:"tls_cert_path,omitempty"`
tlsKeyPath string `json:"tls_cert_key,omitempty"`
noTLS bool `json:no_tls,omitempty`
logLevel uint64 `json:"log_level,omitempty"`
logPath string `json:"log_file,omitempty"`
hush3ConfPath string `json:"hush3_conf,omitempty"`
cacheSize int `json:"hush3_conf,omitempty"`
bindAddr string `json:"bind_address,omitempty"`
tlsCertPath string `json:"tls_cert_path,omitempty"`
tlsKeyPath string `json:"tls_cert_key,omitempty"`
noTLS bool `json:no_tls,omitempty`
logLevel uint64 `json:"log_level,omitempty"`
logPath string `json:"log_file,omitempty"`
confPath string `json:"conf_file,omitempty"`
cacheSize int `json:"cache_size,omitempty"`
}
func main() {
var version = "0.1.1" // set version number
opts := &Options{}
flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9067", "the address to listen on")
flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9069", "the address to listen on")
flag.StringVar(&opts.tlsCertPath, "tls-cert", "", "the path to a TLS certificate (optional)")
flag.StringVar(&opts.tlsKeyPath, "tls-key", "", "the path to a TLS key file (optional)")
flag.BoolVar(&opts.noTLS, "no-tls", false, "Disable TLS, serve un-encrypted traffic.")
flag.Uint64Var(&opts.logLevel, "log-level", uint64(logrus.InfoLevel), "log level (logrus 1-7)")
flag.StringVar(&opts.logPath, "log-file", "", "log file to write to")
flag.StringVar(&opts.hush3ConfPath, "conf-file", "", "conf file to pull RPC creds from")
flag.IntVar(&opts.cacheSize, "cache-size", 40000, "number of blocks to hold in the cache")
flag.StringVar(&opts.confPath, "conf-file", "", "conf file to pull RPC creds from")
flag.IntVar(&opts.cacheSize, "cache-size", 400000, "number of blocks to hold in the cache")
// creating --version as a requirement of help2man
if len(os.Args) > 1 && (os.Args[1] == "--version" || os.Args[1] == "-v") {
fmt.Printf("Hush lightwalletd version " + version + "\n")
fmt.Printf("DragonX lightwalletd version " + version + "\n")
os.Exit(0)
}
@@ -110,14 +110,14 @@ func main() {
// TODO support config from file and env vars
flag.Parse()
if opts.hush3ConfPath == "" {
if opts.confPath == "" {
flag.Usage()
os.Exit(1)
}
if !opts.noTLS && (opts.tlsCertPath == "" || opts.tlsKeyPath == "") {
println("Please specify a TLS certificate/key to use. You can use a self-signed certificate.")
println("See https://git.hush.is/hush/lightwalletd/src/branch/master/README.md#running-your-own-sdl-lightwalletd")
println("See https://git.hush.is/hush/lightwalletd/src/branch/master/README.md")
os.Exit(1)
}
@@ -159,17 +159,17 @@ func main() {
reflection.Register(server)
}
// Initialize Hush RPC client. Right now (Jan 2018) this is only for
// Initialize DragonX RPC client. Right now this is only for
// sending transactions, but in the future it could back a different type
// of block streamer.
rpcClient, err := frontend.NewZRPCFromConf(opts.hush3ConfPath)
rpcClient, err := frontend.NewZRPCFromConf(opts.confPath)
if err != nil {
log.WithFields(logrus.Fields{
"error": err,
}).Warn("HUSH3.conf failed, will try empty credentials for rpc")
}).Warn("DRAGONX.conf failed, will try empty credentials for rpc")
rpcClient, err = frontend.NewZRPCFromCreds("127.0.0.1:18031", "", "")
rpcClient, err = frontend.NewZRPCFromCreds("127.0.0.1:21769", "", "")
if err != nil {
log.WithFields(logrus.Fields{

View File

@@ -25,7 +25,7 @@ func GetSaplingInfo(rpcClient *rpcclient.Client) (int, int, string, string, int,
if rpcErr != nil {
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
//Check to see if we are requesting a height the hushd doesn't have yet
//Check to see if we are requesting a height the dragonxd doesn't have yet
if err == nil && errCode == -8 {
return -1, -1, "", "", -1, -1, -1, nil
}
@@ -40,17 +40,34 @@ func GetSaplingInfo(rpcClient *rpcclient.Client) (int, int, string, string, int,
chainName := f.(map[string]interface{})["chain"].(string)
upgradeJSON := f.(map[string]interface{})["upgrades"]
saplingJSON := upgradeJSON.(map[string]interface{})["76b809bb"] // Sapling ID
saplingHeight := saplingJSON.(map[string]interface{})["activationheight"].(float64)
// DragonX has Sapling active from block 1 but sets NO_ACTIVATION_HEIGHT in
// chainparams, so dragonxd omits it from the upgrades map. Fall back to
// height 1 when the key is absent.
saplingHeight := float64(1)
upgradeJSON, ok := f.(map[string]interface{})["upgrades"]
if ok {
if upgradesMap, ok := upgradeJSON.(map[string]interface{}); ok {
if saplingJSON, ok := upgradesMap["76b809bb"]; ok {
saplingHeight = saplingJSON.(map[string]interface{})["activationheight"].(float64)
}
}
}
blockHeight := f.(map[string]interface{})["headers"].(float64)
difficulty := f.(map[string]interface{})["difficulty"].(float64)
longestchain := f.(map[string]interface{})["longestchain"].(float64)
notarized := f.(map[string]interface{})["notarized"].(float64)
consensus := f.(map[string]interface{})["consensus"]
branchID := consensus.(map[string]interface{})["nextblock"].(string)
// DragonX always uses Sapling consensus rules but CurrentEpochBranchId()
// returns Sprout (0) for full nodes because the activation heights are
// set to NO_ACTIVATION_HEIGHT. Override to the correct Sapling branch ID.
branchID := "76b809bb"
consensus, ok := f.(map[string]interface{})["consensus"]
if ok {
if nextblock, ok := consensus.(map[string]interface{})["nextblock"].(string); ok && nextblock != "00000000" {
branchID = nextblock
}
}
return int(saplingHeight), int(blockHeight), chainName, branchID, int(difficulty), int(longestchain), int(notarized), nil
}
@@ -65,7 +82,7 @@ func GetCoinsupply(rpcClient *rpcclient.Client) (string, string, int, int, int,
if rpcErr != nil {
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
//Check to see if we are requesting a height the hushd doesn't have yet
//Check to see if we are requesting a height the dragonxd doesn't have yet
if err == nil && errCode == -8 {
return "", "", -1, -1, -1, -1, nil
}
@@ -101,7 +118,7 @@ func getBlockFromRPC(rpcClient *rpcclient.Client, height int) (*walletrpc.Compac
if rpcErr != nil {
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
//Check to see if we are requesting a height the hushd doesn't have yet
//Check to see if we are requesting a height the dragonxd doesn't have yet
if err == nil && errCode == -8 {
return nil, nil
}
@@ -166,7 +183,7 @@ func BlockIngestor(rpcClient *rpcclient.Client, cache *BlockCache, log *logrus.E
if timeoutCount == 3 {
log.WithFields(logrus.Fields{
"timeouts": timeoutCount,
}).Warn("unable to issue RPC call to hushd node 3 times")
}).Warn("unable to issue RPC call to dragonxd node 3 times")
break
}
}
@@ -241,6 +258,12 @@ func GetBlockRange(rpcClient *rpcclient.Client, cache *BlockCache,
return
}
if block == nil {
errOut <- errors.New(
fmt.Sprintf("Block %d was nil without error", i))
return
}
blockOut <- *block
}

View File

@@ -23,13 +23,13 @@ func NewZRPCFromConf(confPath string) (*rpcclient.Client, error) {
}
func NewZRPCFromCreds(addr, username, password string) (*rpcclient.Client, error) {
// Connect to local hush RPC server using HTTP POST mode.
// Connect to local DragonX RPC server using HTTP POST mode.
connCfg := &rpcclient.ConnConfig{
Host: addr,
User: username,
Pass: password,
HTTPPostMode: true, // Hush only supports HTTP POST mode
DisableTLS: true, // Hush does not provide TLS by default
HTTPPostMode: true, // DragonX only supports HTTP POST mode
DisableTLS: true, // DragonX does not provide TLS by default
}
// Notice the notification parameter is nil since notifications are
// not supported in HTTP POST mode.

View File

@@ -42,6 +42,9 @@ func (s *SqlStreamer) GetCache() *common.BlockCache {
func (s *SqlStreamer) GetLatestBlock(ctx context.Context, placeholder *walletrpc.ChainSpec) (*walletrpc.BlockID, error) {
latestBlock := s.cache.GetLatestBlock()
s.log.WithFields(logrus.Fields{
"latestBlock": latestBlock,
}).Info("GetLatestBlock called")
if latestBlock == -1 {
return nil, errors.New("Cache is empty. Server is probably not yet ready.")
@@ -76,7 +79,7 @@ func (s *SqlStreamer) GetAddressTxids(addressBlockFilter *walletrpc.TransparentA
s.log.Errorf("Got error: %s", rpcErr.Error())
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
//Check to see if we are requesting a height the hushd doesn't have yet
//Check to see if we are requesting a height the dragonxd doesn't have yet
if err == nil && errCode == -8 {
return nil
}
@@ -136,21 +139,47 @@ func (s *SqlStreamer) GetBlock(ctx context.Context, id *walletrpc.BlockID) (*wal
}
func (s *SqlStreamer) GetBlockRange(span *walletrpc.BlockRange, resp walletrpc.CompactTxStreamer_GetBlockRangeServer) error {
s.log.WithFields(logrus.Fields{
"start": span.Start.Height,
"end": span.End.Height,
}).Info("GetBlockRange called")
blockChan := make(chan walletrpc.CompactBlock)
errChan := make(chan error)
go common.GetBlockRange(s.client, s.cache, blockChan, errChan, int(span.Start.Height), int(span.End.Height))
blockCount := 0
for {
select {
case err := <-errChan:
// this will also catch context.DeadlineExceeded from the timeout
if err != nil {
s.log.WithFields(logrus.Fields{
"start": span.Start.Height,
"end": span.End.Height,
"blocksSent": blockCount,
"error": err,
}).Error("GetBlockRange error")
} else {
s.log.WithFields(logrus.Fields{
"start": span.Start.Height,
"end": span.End.Height,
"blocksSent": blockCount,
}).Info("GetBlockRange completed")
}
return err
case cBlock := <-blockChan:
err := resp.Send(&cBlock)
if err != nil {
s.log.WithFields(logrus.Fields{
"start": span.Start.Height,
"end": span.End.Height,
"blocksSent": blockCount,
"error": err,
}).Error("GetBlockRange send error")
return err
}
blockCount++
}
}
@@ -181,7 +210,7 @@ func (s *SqlStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte
s.log.Errorf("Got error: %s", rpcErr.Error())
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
//Check to see if we are requesting a height the hushd doesn't have yet
//Check to see if we are requesting a height the dragonxd doesn't have yet
if err == nil && errCode == -8 {
return nil, err
}
@@ -211,7 +240,7 @@ func (s *SqlStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte
s.log.Errorf("Got error: %s", rpcErr.Error())
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
errCode, err = strconv.ParseInt(errParts[0], 10, 32)
//Check to see if we are requesting a height the hushd doesn't have yet
//Check to see if we are requesting a height the dragonxd doesn't have yet
if err == nil && errCode == -8 {
return nil, err
}
@@ -239,6 +268,13 @@ func (s *SqlStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte
func (s *SqlStreamer) GetLightdInfo(ctx context.Context, in *walletrpc.Empty) (*walletrpc.LightdInfo, error) {
saplingHeight, blockHeight, chainName, consensusBranchId, difficulty, longestchain, notarized, err := common.GetSaplingInfo(s.client)
s.log.WithFields(logrus.Fields{
"saplingHeight": saplingHeight,
"blockHeight": blockHeight,
"chainName": chainName,
"consensusBranchId": consensusBranchId,
}).Info("GetLightdInfo called")
if err != nil {
s.log.WithFields(logrus.Fields{
"error": err,
@@ -249,8 +285,8 @@ func (s *SqlStreamer) GetLightdInfo(ctx context.Context, in *walletrpc.Empty) (*
// TODO these are called Error but they aren't at the moment.
// A success will return code 0 and message txhash.
return &walletrpc.LightdInfo{
Version: "0.1.1-hushlightd",
Vendor: "Silentdragonlite LightWalletD",
Version: "0.1.1-dragonxlightd",
Vendor: "DragonX LightWalletD",
TaddrSupport: true,
ChainName: chainName,
SaplingActivationHeight: uint64(saplingHeight),
@@ -285,7 +321,7 @@ func (s *SqlStreamer) GetCoinsupply(ctx context.Context, in *walletrpc.Empty) (*
}, nil
}
// SendTransaction forwards raw transaction bytes to a hushd instance over JSON-RPC
// SendTransaction forwards raw transaction bytes to a dragonxd instance over JSON-RPC
func (s *SqlStreamer) SendTransaction(ctx context.Context, rawtx *walletrpc.RawTransaction) (*walletrpc.SendResponse, error) {
// sendrawtransaction "hexstring" ( allowhighfees )
//

123
monitor_lwd.sh Executable file
View File

@@ -0,0 +1,123 @@
#!/usr/bin/env bash
# Copyright 2024-2026 The DragonX Developers
# Released under GPLv3
#
# Monitors lightwalletd and restarts it automatically if it crashes.
# Usage: ./monitor_lwd.sh &
# or: nohup ./monitor_lwd.sh >> /tmp/lwd-monitor.log 2>&1 &
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
LWD_BIN="$SCRIPT_DIR/lightwalletd"
LWD_ARGS="-bind-addr lite.dragonx.is:9069 -conf-file $HOME/.hush/DRAGONX/DRAGONX.conf -no-tls"
LOGFILE="$SCRIPT_DIR/lwd-monitor.log"
PIDFILE="/tmp/lwd-monitor.pid"
RESTART_DELAY=5 # seconds to wait before restarting after a crash
MAX_RAPID_RESTARTS=5 # max restarts within the rapid window before backing off
RAPID_WINDOW=120 # seconds — if this many restarts happen within this window, back off
BACKOFF_DELAY=60 # seconds to wait when backing off
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() {
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOGFILE"
}
cleanup() {
log "${YELLOW}Monitor shutting down...${NC}"
if [[ -n "${LWD_PID:-}" ]] && kill -0 "$LWD_PID" 2>/dev/null; then
log "Stopping lightwalletd (PID $LWD_PID)..."
kill "$LWD_PID" 2>/dev/null || true
wait "$LWD_PID" 2>/dev/null || true
fi
rm -f "$PIDFILE"
log "Monitor stopped."
exit 0
}
trap cleanup SIGINT SIGTERM
# Prevent duplicate monitors
if [[ -f "$PIDFILE" ]]; then
OLD_PID=$(cat "$PIDFILE")
if kill -0 "$OLD_PID" 2>/dev/null; then
echo "Monitor already running (PID $OLD_PID). Exiting."
exit 1
fi
rm -f "$PIDFILE"
fi
echo $$ > "$PIDFILE"
# Check binary exists
if [[ ! -x "$LWD_BIN" ]]; then
log "${RED}ERROR: lightwalletd binary not found at $LWD_BIN${NC}"
log "Build it first with: make build"
rm -f "$PIDFILE"
exit 1
fi
# Check conf file exists
CONF_FILE="$HOME/.hush/DRAGONX/DRAGONX.conf"
if [[ ! -f "$CONF_FILE" ]]; then
log "${RED}ERROR: DRAGONX.conf not found at $CONF_FILE${NC}"
rm -f "$PIDFILE"
exit 1
fi
log "${GREEN}DragonX lightwalletd monitor started (PID $$)${NC}"
log "Binary: $LWD_BIN"
log "Args: $LWD_ARGS"
restart_times=()
LWD_PID=""
while true; do
# Start lightwalletd
log "${GREEN}Starting lightwalletd...${NC}"
$LWD_BIN $LWD_ARGS >> "$LOGFILE" 2>&1 &
LWD_PID=$!
log "lightwalletd started with PID $LWD_PID"
# Wait for it to exit
wait "$LWD_PID" || true
EXIT_CODE=$?
LWD_PID=""
if [[ $EXIT_CODE -eq 0 ]]; then
log "${YELLOW}lightwalletd exited cleanly (code 0). Not restarting.${NC}"
break
fi
log "${RED}lightwalletd crashed with exit code $EXIT_CODE${NC}"
# Track restart frequency for backoff
NOW=$(date +%s)
restart_times+=("$NOW")
# Trim old entries outside the rapid window
CUTOFF=$((NOW - RAPID_WINDOW))
filtered=()
for t in "${restart_times[@]}"; do
if (( t >= CUTOFF )); then
filtered+=("$t")
fi
done
restart_times=("${filtered[@]}")
if (( ${#restart_times[@]} >= MAX_RAPID_RESTARTS )); then
log "${YELLOW}Too many restarts (${#restart_times[@]} in ${RAPID_WINDOW}s). Backing off for ${BACKOFF_DELAY}s...${NC}"
sleep "$BACKOFF_DELAY"
restart_times=()
else
log "Restarting in ${RESTART_DELAY}s..."
sleep "$RESTART_DELAY"
fi
done
rm -f "$PIDFILE"
log "Monitor exiting."

View File

@@ -100,11 +100,11 @@ func (b *Block) GetPrevHash() []byte {
func (b *Block) ToCompact() *walletrpc.CompactBlock {
compactBlock := &walletrpc.CompactBlock{
//TODO ProtoVersion: 1,
Height: uint64(b.GetHeight()),
PrevHash: b.hdr.HashPrevBlock,
Hash: b.GetEncodableHash(),
Time: b.hdr.Time,
ProtoVersion: 1,
Height: uint64(b.GetHeight()),
PrevHash: b.hdr.HashPrevBlock,
Hash: b.GetEncodableHash(),
Time: b.hdr.Time,
}
// Only Sapling transactions have a meaningful compact encoding

View File

@@ -6,7 +6,9 @@
# you can choose either IPv4 or IPv6
# using ipv4 localhost
#./lightwalletd -bind-addr localhost:9067 -conf-file ~/.komodo/HUSH3/HUSH3.conf -no-tls
#./lightwalletd -bind-addr localhost:9067 -conf-file ~/.hush/HUSH3/HUSH3.conf -no-tls
# using ipv6 localhost
./lightwalletd -bind-addr ip6-localhost:9067 -conf-file ~/.komodo/HUSH3/HUSH3.conf -no-tls
#./lightwalletd -bind-addr ip6-localhost:9067 -conf-file ~/.hush/HUSH3/HUSH3.conf -no-tls
./lightwalletd -bind-addr lite.dragonx.is:9069 -conf-file ~/.hush/DRAGONX/DRAGONX.conf -no-tls &

6
start_server.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
# set -e
./lightwalletd -bind-addr lite.dragonx.is:9069 -conf-file ~/.hush/DRAGONX/DRAGONX.conf -no-tls

45
stop.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# Copyright 2024-2026 The DragonX Developers
# Released under GPLv3
#
# Stops lightwalletd and its monitor process.
set -euo pipefail
PIDFILE="/tmp/lwd-monitor.pid"
# Stop the monitor first (if running), which will also stop lightwalletd
if [[ -f "$PIDFILE" ]]; then
MON_PID=$(cat "$PIDFILE")
if kill -0 "$MON_PID" 2>/dev/null; then
echo "Stopping monitor (PID $MON_PID)..."
kill "$MON_PID"
# Wait briefly for cleanup
for i in $(seq 1 10); do
kill -0 "$MON_PID" 2>/dev/null || break
sleep 0.5
done
echo "Monitor stopped."
else
echo "Stale monitor pidfile found, removing."
rm -f "$PIDFILE"
fi
fi
# Kill any remaining lightwalletd processes
LWDPIDS=$(pgrep -f 'lightwalletd.*-conf-file' 2>/dev/null || true)
if [[ -n "$LWDPIDS" ]]; then
echo "Stopping lightwalletd (PID $LWDPIDS)..."
kill $LWDPIDS 2>/dev/null || true
sleep 1
# Force kill if still running
for pid in $LWDPIDS; do
if kill -0 "$pid" 2>/dev/null; then
echo "Force killing PID $pid..."
kill -9 "$pid" 2>/dev/null || true
fi
done
echo "lightwalletd stopped."
else
echo "No lightwalletd process found."
fi

View File

@@ -23,10 +23,10 @@ echo "+------'+------'+------'+------'+------'+------'+------'+------'+------'+-
# now to compiling...
echo ""
echo "You have go installed, so starting to compile Hush lightwalletd for you..."
echo "You have go installed, so starting to compile DragonX lightwalletd for you..."
cd `pwd`/cmd/server
go build -o lightwalletd main.go
mv lightwalletd `pwd`/../../lightwalletd
echo ""
echo "Hush lightwalletd is now compiled for you. Enjoy and reach out if you need support."
echo "DragonX lightwalletd is now compiled for you. Enjoy and reach out if you need support."
echo "For options, run ./lightwalletd --help"

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: compact_formats.proto
# Protobuf Python Version: 6.31.1
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
6,
31,
1,
'',
'compact_formats.proto'
)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x63ompact_formats.proto\x12\x15\x63\x61sh.z.wallet.sdk.rpc\"\xa1\x01\n\x0c\x43ompactBlock\x12\x14\n\x0cprotoVersion\x18\x01 \x01(\r\x12\x0e\n\x06height\x18\x02 \x01(\x04\x12\x0c\n\x04hash\x18\x03 \x01(\x0c\x12\x10\n\x08prevHash\x18\x04 \x01(\x0c\x12\x0c\n\x04time\x18\x05 \x01(\r\x12\x0e\n\x06header\x18\x06 \x01(\x0c\x12-\n\x03vtx\x18\x07 \x03(\x0b\x32 .cash.z.wallet.sdk.rpc.CompactTx\"\xa1\x01\n\tCompactTx\x12\r\n\x05index\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\x12\x0b\n\x03\x66\x65\x65\x18\x03 \x01(\r\x12\x33\n\x06spends\x18\x04 \x03(\x0b\x32#.cash.z.wallet.sdk.rpc.CompactSpend\x12\x35\n\x07outputs\x18\x05 \x03(\x0b\x32$.cash.z.wallet.sdk.rpc.CompactOutput\"\x1a\n\x0c\x43ompactSpend\x12\n\n\x02nf\x18\x01 \x01(\x0c\"=\n\rCompactOutput\x12\x0b\n\x03\x63mu\x18\x01 \x01(\x0c\x12\x0b\n\x03\x65pk\x18\x02 \x01(\x0c\x12\x12\n\nciphertext\x18\x03 \x01(\x0c\x42\x0bZ\twalletrpcb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compact_formats_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
_globals['DESCRIPTOR']._loaded_options = None
_globals['DESCRIPTOR']._serialized_options = b'Z\twalletrpc'
_globals['_COMPACTBLOCK']._serialized_start=49
_globals['_COMPACTBLOCK']._serialized_end=210
_globals['_COMPACTTX']._serialized_start=213
_globals['_COMPACTTX']._serialized_end=374
_globals['_COMPACTSPEND']._serialized_start=376
_globals['_COMPACTSPEND']._serialized_end=402
_globals['_COMPACTOUTPUT']._serialized_start=404
_globals['_COMPACTOUTPUT']._serialized_end=465
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,24 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import warnings
GRPC_GENERATED_VERSION = '1.78.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
try:
from grpc._utilities import first_version_is_lower
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
except ImportError:
_version_not_supported = True
if _version_not_supported:
raise RuntimeError(
f'The grpc package installed is at version {GRPC_VERSION},'
+ ' but the generated code in compact_formats_pb2_grpc.py depends on'
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
)

60
walletrpc/service_pb2.py Normal file
View File

@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# NO CHECKED-IN PROTOBUF GENCODE
# source: service.proto
# Protobuf Python Version: 6.31.1
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
_runtime_version.ValidateProtobufRuntimeVersion(
_runtime_version.Domain.PUBLIC,
6,
31,
1,
'',
'service.proto'
)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
import compact_formats_pb2 as compact__formats__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rservice.proto\x12\x15\x63\x61sh.z.wallet.sdk.rpc\x1a\x15\x63ompact_formats.proto\"\'\n\x07\x42lockID\x12\x0e\n\x06height\x18\x01 \x01(\x04\x12\x0c\n\x04hash\x18\x02 \x01(\x0c\"h\n\nBlockRange\x12-\n\x05start\x18\x01 \x01(\x0b\x32\x1e.cash.z.wallet.sdk.rpc.BlockID\x12+\n\x03\x65nd\x18\x02 \x01(\x0b\x32\x1e.cash.z.wallet.sdk.rpc.BlockID\"V\n\x08TxFilter\x12-\n\x05\x62lock\x18\x01 \x01(\x0b\x32\x1e.cash.z.wallet.sdk.rpc.BlockID\x12\r\n\x05index\x18\x02 \x01(\x04\x12\x0c\n\x04hash\x18\x03 \x01(\x0c\".\n\x0eRawTransaction\x12\x0c\n\x04\x64\x61ta\x18\x01 \x01(\x0c\x12\x0e\n\x06height\x18\x02 \x01(\x04\"7\n\x0cSendResponse\x12\x11\n\terrorCode\x18\x01 \x01(\x05\x12\x14\n\x0c\x65rrorMessage\x18\x02 \x01(\t\"\x0b\n\tChainSpec\"\x07\n\x05\x45mpty\"\xe4\x01\n\nLightdInfo\x12\x0f\n\x07version\x18\x01 \x01(\t\x12\x0e\n\x06vendor\x18\x02 \x01(\t\x12\x14\n\x0ctaddrSupport\x18\x03 \x01(\x08\x12\x11\n\tchainName\x18\x04 \x01(\t\x12\x1f\n\x17saplingActivationHeight\x18\x05 \x01(\x04\x12\x19\n\x11\x63onsensusBranchId\x18\x06 \x01(\t\x12\x13\n\x0b\x62lockHeight\x18\x07 \x01(\x04\x12\x12\n\ndifficulty\x18\x08 \x01(\x04\x12\x14\n\x0clongestchain\x18\t \x01(\x04\x12\x11\n\tnotarized\x18\n \x01(\x04\"i\n\nCoinsupply\x12\x0e\n\x06result\x18\x01 \x01(\t\x12\x0c\n\x04\x63oin\x18\x02 \x01(\t\x12\x0e\n\x06height\x18\x03 \x01(\x04\x12\x0e\n\x06supply\x18\x04 \x01(\x04\x12\x0e\n\x06zfunds\x18\x05 \x01(\x04\x12\r\n\x05total\x18\x06 \x01(\x04\"%\n\x12TransparentAddress\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\"b\n\x1dTransparentAddressBlockFilter\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\t\x12\x30\n\x05range\x18\x02 \x01(\x0b\x32!.cash.z.wallet.sdk.rpc.BlockRange2\xf2\x05\n\x11\x43ompactTxStreamer\x12T\n\x0eGetLatestBlock\x12 .cash.z.wallet.sdk.rpc.ChainSpec\x1a\x1e.cash.z.wallet.sdk.rpc.BlockID\"\x00\x12Q\n\x08GetBlock\x12\x1e.cash.z.wallet.sdk.rpc.BlockID\x1a#.cash.z.wallet.sdk.rpc.CompactBlock\"\x00\x12[\n\rGetBlockRange\x12!.cash.z.wallet.sdk.rpc.BlockRange\x1a#.cash.z.wallet.sdk.rpc.CompactBlock\"\x00\x30\x01\x12Z\n\x0eGetTransaction\x12\x1f.cash.z.wallet.sdk.rpc.TxFilter\x1a%.cash.z.wallet.sdk.rpc.RawTransaction\"\x00\x12_\n\x0fSendTransaction\x12%.cash.z.wallet.sdk.rpc.RawTransaction\x1a#.cash.z.wallet.sdk.rpc.SendResponse\"\x00\x12r\n\x0fGetAddressTxids\x12\x34.cash.z.wallet.sdk.rpc.TransparentAddressBlockFilter\x1a%.cash.z.wallet.sdk.rpc.RawTransaction\"\x00\x30\x01\x12R\n\rGetLightdInfo\x12\x1c.cash.z.wallet.sdk.rpc.Empty\x1a!.cash.z.wallet.sdk.rpc.LightdInfo\"\x00\x12R\n\rGetCoinsupply\x12\x1c.cash.z.wallet.sdk.rpc.Empty\x1a!.cash.z.wallet.sdk.rpc.Coinsupply\"\x00\x42\x0bZ\twalletrpcb\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'service_pb2', _globals)
if not _descriptor._USE_C_DESCRIPTORS:
_globals['DESCRIPTOR']._loaded_options = None
_globals['DESCRIPTOR']._serialized_options = b'Z\twalletrpc'
_globals['_BLOCKID']._serialized_start=63
_globals['_BLOCKID']._serialized_end=102
_globals['_BLOCKRANGE']._serialized_start=104
_globals['_BLOCKRANGE']._serialized_end=208
_globals['_TXFILTER']._serialized_start=210
_globals['_TXFILTER']._serialized_end=296
_globals['_RAWTRANSACTION']._serialized_start=298
_globals['_RAWTRANSACTION']._serialized_end=344
_globals['_SENDRESPONSE']._serialized_start=346
_globals['_SENDRESPONSE']._serialized_end=401
_globals['_CHAINSPEC']._serialized_start=403
_globals['_CHAINSPEC']._serialized_end=414
_globals['_EMPTY']._serialized_start=416
_globals['_EMPTY']._serialized_end=423
_globals['_LIGHTDINFO']._serialized_start=426
_globals['_LIGHTDINFO']._serialized_end=654
_globals['_COINSUPPLY']._serialized_start=656
_globals['_COINSUPPLY']._serialized_end=761
_globals['_TRANSPARENTADDRESS']._serialized_start=763
_globals['_TRANSPARENTADDRESS']._serialized_end=800
_globals['_TRANSPARENTADDRESSBLOCKFILTER']._serialized_start=802
_globals['_TRANSPARENTADDRESSBLOCKFILTER']._serialized_end=900
_globals['_COMPACTTXSTREAMER']._serialized_start=903
_globals['_COMPACTTXSTREAMER']._serialized_end=1657
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,403 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
"""Client and server classes corresponding to protobuf-defined services."""
import grpc
import warnings
import compact_formats_pb2 as compact__formats__pb2
import service_pb2 as service__pb2
GRPC_GENERATED_VERSION = '1.78.0'
GRPC_VERSION = grpc.__version__
_version_not_supported = False
try:
from grpc._utilities import first_version_is_lower
_version_not_supported = first_version_is_lower(GRPC_VERSION, GRPC_GENERATED_VERSION)
except ImportError:
_version_not_supported = True
if _version_not_supported:
raise RuntimeError(
f'The grpc package installed is at version {GRPC_VERSION},'
+ ' but the generated code in service_pb2_grpc.py depends on'
+ f' grpcio>={GRPC_GENERATED_VERSION}.'
+ f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}'
+ f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.'
)
class CompactTxStreamerStub(object):
"""Missing associated documentation comment in .proto file."""
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GetLatestBlock = channel.unary_unary(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock',
request_serializer=service__pb2.ChainSpec.SerializeToString,
response_deserializer=service__pb2.BlockID.FromString,
_registered_method=True)
self.GetBlock = channel.unary_unary(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock',
request_serializer=service__pb2.BlockID.SerializeToString,
response_deserializer=compact__formats__pb2.CompactBlock.FromString,
_registered_method=True)
self.GetBlockRange = channel.unary_stream(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange',
request_serializer=service__pb2.BlockRange.SerializeToString,
response_deserializer=compact__formats__pb2.CompactBlock.FromString,
_registered_method=True)
self.GetTransaction = channel.unary_unary(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction',
request_serializer=service__pb2.TxFilter.SerializeToString,
response_deserializer=service__pb2.RawTransaction.FromString,
_registered_method=True)
self.SendTransaction = channel.unary_unary(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction',
request_serializer=service__pb2.RawTransaction.SerializeToString,
response_deserializer=service__pb2.SendResponse.FromString,
_registered_method=True)
self.GetAddressTxids = channel.unary_stream(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressTxids',
request_serializer=service__pb2.TransparentAddressBlockFilter.SerializeToString,
response_deserializer=service__pb2.RawTransaction.FromString,
_registered_method=True)
self.GetLightdInfo = channel.unary_unary(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo',
request_serializer=service__pb2.Empty.SerializeToString,
response_deserializer=service__pb2.LightdInfo.FromString,
_registered_method=True)
self.GetCoinsupply = channel.unary_unary(
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetCoinsupply',
request_serializer=service__pb2.Empty.SerializeToString,
response_deserializer=service__pb2.Coinsupply.FromString,
_registered_method=True)
class CompactTxStreamerServicer(object):
"""Missing associated documentation comment in .proto file."""
def GetLatestBlock(self, request, context):
"""Compact Blocks
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetBlock(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetBlockRange(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetTransaction(self, request, context):
"""Transactions
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def SendTransaction(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetAddressTxids(self, request, context):
"""t-Address support
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetLightdInfo(self, request, context):
"""Misc
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetCoinsupply(self, request, context):
"""Missing associated documentation comment in .proto file."""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_CompactTxStreamerServicer_to_server(servicer, server):
rpc_method_handlers = {
'GetLatestBlock': grpc.unary_unary_rpc_method_handler(
servicer.GetLatestBlock,
request_deserializer=service__pb2.ChainSpec.FromString,
response_serializer=service__pb2.BlockID.SerializeToString,
),
'GetBlock': grpc.unary_unary_rpc_method_handler(
servicer.GetBlock,
request_deserializer=service__pb2.BlockID.FromString,
response_serializer=compact__formats__pb2.CompactBlock.SerializeToString,
),
'GetBlockRange': grpc.unary_stream_rpc_method_handler(
servicer.GetBlockRange,
request_deserializer=service__pb2.BlockRange.FromString,
response_serializer=compact__formats__pb2.CompactBlock.SerializeToString,
),
'GetTransaction': grpc.unary_unary_rpc_method_handler(
servicer.GetTransaction,
request_deserializer=service__pb2.TxFilter.FromString,
response_serializer=service__pb2.RawTransaction.SerializeToString,
),
'SendTransaction': grpc.unary_unary_rpc_method_handler(
servicer.SendTransaction,
request_deserializer=service__pb2.RawTransaction.FromString,
response_serializer=service__pb2.SendResponse.SerializeToString,
),
'GetAddressTxids': grpc.unary_stream_rpc_method_handler(
servicer.GetAddressTxids,
request_deserializer=service__pb2.TransparentAddressBlockFilter.FromString,
response_serializer=service__pb2.RawTransaction.SerializeToString,
),
'GetLightdInfo': grpc.unary_unary_rpc_method_handler(
servicer.GetLightdInfo,
request_deserializer=service__pb2.Empty.FromString,
response_serializer=service__pb2.LightdInfo.SerializeToString,
),
'GetCoinsupply': grpc.unary_unary_rpc_method_handler(
servicer.GetCoinsupply,
request_deserializer=service__pb2.Empty.FromString,
response_serializer=service__pb2.Coinsupply.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'cash.z.wallet.sdk.rpc.CompactTxStreamer', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
server.add_registered_method_handlers('cash.z.wallet.sdk.rpc.CompactTxStreamer', rpc_method_handlers)
# This class is part of an EXPERIMENTAL API.
class CompactTxStreamer(object):
"""Missing associated documentation comment in .proto file."""
@staticmethod
def GetLatestBlock(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLatestBlock',
service__pb2.ChainSpec.SerializeToString,
service__pb2.BlockID.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetBlock(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlock',
service__pb2.BlockID.SerializeToString,
compact__formats__pb2.CompactBlock.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetBlockRange(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetBlockRange',
service__pb2.BlockRange.SerializeToString,
compact__formats__pb2.CompactBlock.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetTransaction(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetTransaction',
service__pb2.TxFilter.SerializeToString,
service__pb2.RawTransaction.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def SendTransaction(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/SendTransaction',
service__pb2.RawTransaction.SerializeToString,
service__pb2.SendResponse.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetAddressTxids(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_stream(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetAddressTxids',
service__pb2.TransparentAddressBlockFilter.SerializeToString,
service__pb2.RawTransaction.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetLightdInfo(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetLightdInfo',
service__pb2.Empty.SerializeToString,
service__pb2.LightdInfo.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)
@staticmethod
def GetCoinsupply(request,
target,
options=(),
channel_credentials=None,
call_credentials=None,
insecure=False,
compression=None,
wait_for_ready=None,
timeout=None,
metadata=None):
return grpc.experimental.unary_unary(
request,
target,
'/cash.z.wallet.sdk.rpc.CompactTxStreamer/GetCoinsupply',
service__pb2.Empty.SerializeToString,
service__pb2.Coinsupply.FromString,
options,
channel_credentials,
insecure,
call_credentials,
compression,
wait_for_ready,
timeout,
metadata,
_registered_method=True)