diff --git a/rpcclient/examples/lbcdblocknotify/README.md b/rpcclient/examples/lbcdblocknotify/README.md new file mode 100644 index 00000000..45ab3b29 --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/README.md @@ -0,0 +1,46 @@ +# lbcd Websockets Example + +This example shows how to use the rpcclient package to connect to a btcd RPC +server using TLS-secured websockets, register for block connected and block +disconnected notifications, and get the current block count. + +## Running the Example + +The first step is to clone the lbcd package: + +```bash +$ git clone github.com/lbryio/lbcd +``` + +Display available options: + +```bash +$ go run . -h + + -coinid string + Coin ID (default "1425") + -rpcpass string + LBCD RPC password (default "rpcpass") + -rpcserver string + LBCD RPC server (default "localhost:9245") + -rpcuser string + LBCD RPC username (default "rpcuser") + -stratum string + Stratum server (default "lbrypool.net:3334") + -stratumpass string + Stratum server password (default "password") +``` + +Start the program: + +```bash +$ go run . -stratumpass -rpcuser -rpcpass + +2022/01/10 23:16:21 NotifyBlocks: Registration Complete +2022/01/10 23:16:21 Block count: 1093112 +... +``` + +## License + +This example is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/rpcclient/examples/lbcdblocknotify/main.go b/rpcclient/examples/lbcdblocknotify/main.go new file mode 100644 index 00000000..431331ee --- /dev/null +++ b/rpcclient/examples/lbcdblocknotify/main.go @@ -0,0 +1,105 @@ +// Copyright (c) 2014-2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "net" + "path/filepath" + + "github.com/lbryio/lbcd/rpcclient" + "github.com/lbryio/lbcd/wire" + "github.com/lbryio/lbcutil" +) + +func send(stratum, stratumPass, coinid, blockHash string) error { + addr, err := net.ResolveTCPAddr("tcp", stratum) + if err != nil { + return fmt.Errorf("can't resolve addr: %w", err) + } + + conn, err := net.DialTCP("tcp", nil, addr) + if err != nil { + return fmt.Errorf("can't dial tcp: %w", err) + } + defer conn.Close() + + msg := fmt.Sprintf(`{"id":1,"method":"mining.update_block","params":[%q,%q,%q]}`, + stratumPass, coinid, blockHash) + + _, err = conn.Write([]byte(msg)) + if err != nil { + return fmt.Errorf("can't write message: %w", err) + } + + return nil +} + +func main() { + + var ( + coinid = flag.String("coinid", "1425", "Coin ID") + stratum = flag.String("stratum", "lbrypool.net:3334", "Stratum server") + stratumPass = flag.String("stratumpass", "password", "Stratum server password") + rpcserver = flag.String("rpcserver", "localhost:9245", "LBCD RPC server") + rpcuser = flag.String("rpcuser", "rpcuser", "LBCD RPC username") + rpcpass = flag.String("rpcpass", "rpcpass", "LBCD RPC password") + notls = flag.Bool("notls", false, "Connect to LBCD with TLS disabled") + ) + + flag.Parse() + + ntfnHandlers := rpcclient.NotificationHandlers{ + OnFilteredBlockConnected: func(height int32, header *wire.BlockHeader, txns []*lbcutil.Tx) { + + blockHash := header.BlockHash().String() + + log.Printf("Block connected: %v (%d) %v", blockHash, height, header.Timestamp) + + if err := send(*stratum, *stratumPass, *coinid, blockHash); err != nil { + log.Printf("ERROR: failed to notify stratum: %s", err) + } + }, + } + + // Connect to local lbcd RPC server using websockets. + lbcdHomeDir := lbcutil.AppDataDir("lbcd", false) + certs, err := ioutil.ReadFile(filepath.Join(lbcdHomeDir, "rpc.cert")) + if err != nil { + log.Fatalf("can't read lbcd certificate: %s", err) + } + connCfg := &rpcclient.ConnConfig{ + Host: *rpcserver, + Endpoint: "ws", + User: *rpcuser, + Pass: *rpcpass, + Certificates: certs, + DisableTLS: *notls, + } + client, err := rpcclient.New(connCfg, &ntfnHandlers) + if err != nil { + log.Fatalf("can't create rpc client: %s", err) + } + + // Register for block connect and disconnect notifications. + if err = client.NotifyBlocks(); err != nil { + log.Fatalf("can't register block notification: %s", err) + } + log.Printf("NotifyBlocks: Registration Complete") + + // Get the current block count. + blockCount, err := client.GetBlockCount() + if err != nil { + log.Fatalf("can't get block count: %s", err) + } + log.Printf("Block count: %d", blockCount) + + // Wait until the client either shuts down gracefully (or the user + // terminates the process with Ctrl+C). + client.WaitForShutdown() +}