Full Code of square/beancounter for AI

master 196b8eb5b826 cached
374 files
4.7 MB
1.3M tokens
4827 symbols
1 requests
Download .txt
Showing preview only (4,998K chars total). Download the full file or copy to clipboard to get everything.
Repository: square/beancounter
Branch: master
Commit: 196b8eb5b826
Files: 374
Total size: 4.7 MB

Directory structure:
gitextract_x09c0s2c/

├── .github/
│   └── dependabot.yml
├── .gitignore
├── .travis.yml
├── BUG-BOUNTY.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── WHY.md
├── accounter/
│   ├── accounter.go
│   ├── accounter_test.go
│   └── testdata/
│       └── tpub_data.json
├── backend/
│   ├── backend.go
│   ├── btcd_backend.go
│   ├── common.go
│   ├── electrum/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── blockchain.go
│   │   └── tcp.go
│   ├── electrum_backend.go
│   ├── electrum_backend_test.go
│   ├── fixture_backend.go
│   ├── fixture_backend_test.go
│   ├── recorder_backend.go
│   └── testdata/
│       └── nonjsonfixture
├── blockfinder/
│   ├── blockfinder.go
│   └── blockfinder_test.go
├── deriver/
│   ├── address_deriver.go
│   └── address_deriver_test.go
├── fixtures/
│   └── blocks.json
├── go.mod
├── go.sum
├── main.go
├── reporter/
│   └── reporter.go
├── utils/
│   ├── utils.go
│   └── utils_test.go
└── vendor/
    ├── github.com/
    │   ├── Masterminds/
    │   │   └── semver/
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE.txt
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── collection.go
    │   │       ├── constraints.go
    │   │       ├── doc.go
    │   │       └── version.go
    │   ├── alecthomas/
    │   │   ├── template/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── doc.go
    │   │   │   ├── exec.go
    │   │   │   ├── funcs.go
    │   │   │   ├── helper.go
    │   │   │   ├── parse/
    │   │   │   │   ├── lex.go
    │   │   │   │   ├── node.go
    │   │   │   │   └── parse.go
    │   │   │   └── template.go
    │   │   └── units/
    │   │       ├── COPYING
    │   │       ├── README.md
    │   │       ├── bytes.go
    │   │       ├── doc.go
    │   │       ├── si.go
    │   │       └── util.go
    │   ├── bcext/
    │   │   ├── cashutil/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── address.go
    │   │   │   ├── amount.go
    │   │   │   ├── appdata.go
    │   │   │   ├── base58/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── alphabet.go
    │   │   │   │   ├── base58.go
    │   │   │   │   ├── base58check.go
    │   │   │   │   ├── cov_report.sh
    │   │   │   │   ├── doc.go
    │   │   │   │   └── genalphabet.go
    │   │   │   ├── block.go
    │   │   │   ├── cashaddr.go
    │   │   │   ├── cashaddrconv.go
    │   │   │   ├── certgen.go
    │   │   │   ├── const.go
    │   │   │   ├── cov_report.sh
    │   │   │   ├── doc.go
    │   │   │   ├── glide.yaml
    │   │   │   ├── goclean.sh
    │   │   │   ├── hash160.go
    │   │   │   ├── net.go
    │   │   │   ├── net_noop.go
    │   │   │   ├── profile.cov
    │   │   │   ├── test_coverage.txt
    │   │   │   ├── tx.go
    │   │   │   └── wif.go
    │   │   └── gcash/
    │   │       ├── LICENSE
    │   │       ├── btcec/
    │   │       │   ├── README.md
    │   │       │   ├── btcec.go
    │   │       │   ├── ciphering.go
    │   │       │   ├── doc.go
    │   │       │   ├── field.go
    │   │       │   ├── genprecomps.go
    │   │       │   ├── gensecp256k1.go
    │   │       │   ├── precompute.go
    │   │       │   ├── privkey.go
    │   │       │   ├── pubkey.go
    │   │       │   ├── secp256k1.go
    │   │       │   └── signature.go
    │   │       ├── chaincfg/
    │   │       │   ├── README.md
    │   │       │   ├── chainhash/
    │   │       │   │   ├── README.md
    │   │       │   │   ├── doc.go
    │   │       │   │   ├── hash.go
    │   │       │   │   └── hashfuncs.go
    │   │       │   ├── doc.go
    │   │       │   ├── genesis.go
    │   │       │   └── params.go
    │   │       └── wire/
    │   │           ├── README.md
    │   │           ├── blockheader.go
    │   │           ├── common.go
    │   │           ├── doc.go
    │   │           ├── error.go
    │   │           ├── invvect.go
    │   │           ├── message.go
    │   │           ├── msgaddr.go
    │   │           ├── msgalert.go
    │   │           ├── msgblock.go
    │   │           ├── msgcfcheckpt.go
    │   │           ├── msgcfheaders.go
    │   │           ├── msgcfilter.go
    │   │           ├── msgfeefilter.go
    │   │           ├── msgfilteradd.go
    │   │           ├── msgfilterclear.go
    │   │           ├── msgfilterload.go
    │   │           ├── msggetaddr.go
    │   │           ├── msggetblocks.go
    │   │           ├── msggetcfcheckpt.go
    │   │           ├── msggetcfheaders.go
    │   │           ├── msggetcfilters.go
    │   │           ├── msggetdata.go
    │   │           ├── msggetheaders.go
    │   │           ├── msgheaders.go
    │   │           ├── msginv.go
    │   │           ├── msgmempool.go
    │   │           ├── msgmerkleblock.go
    │   │           ├── msgnotfound.go
    │   │           ├── msgping.go
    │   │           ├── msgpong.go
    │   │           ├── msgreject.go
    │   │           ├── msgsendheaders.go
    │   │           ├── msgtx.go
    │   │           ├── msgverack.go
    │   │           ├── msgversion.go
    │   │           ├── netaddress.go
    │   │           └── protocol.go
    │   ├── btcsuite/
    │   │   ├── btcd/
    │   │   │   ├── LICENSE
    │   │   │   ├── btcec/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── btcec.go
    │   │   │   │   ├── ciphering.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── field.go
    │   │   │   │   ├── genprecomps.go
    │   │   │   │   ├── gensecp256k1.go
    │   │   │   │   ├── precompute.go
    │   │   │   │   ├── privkey.go
    │   │   │   │   ├── pubkey.go
    │   │   │   │   ├── secp256k1.go
    │   │   │   │   └── signature.go
    │   │   │   ├── btcjson/
    │   │   │   │   ├── CONTRIBUTORS
    │   │   │   │   ├── README.md
    │   │   │   │   ├── btcdextcmds.go
    │   │   │   │   ├── btcdextresults.go
    │   │   │   │   ├── btcwalletextcmds.go
    │   │   │   │   ├── chainsvrcmds.go
    │   │   │   │   ├── chainsvrresults.go
    │   │   │   │   ├── chainsvrwscmds.go
    │   │   │   │   ├── chainsvrwsntfns.go
    │   │   │   │   ├── chainsvrwsresults.go
    │   │   │   │   ├── cmdinfo.go
    │   │   │   │   ├── cmdparse.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── error.go
    │   │   │   │   ├── help.go
    │   │   │   │   ├── helpers.go
    │   │   │   │   ├── jsonrpc.go
    │   │   │   │   ├── jsonrpcerr.go
    │   │   │   │   ├── register.go
    │   │   │   │   ├── walletsvrcmds.go
    │   │   │   │   ├── walletsvrresults.go
    │   │   │   │   ├── walletsvrwscmds.go
    │   │   │   │   └── walletsvrwsntfns.go
    │   │   │   ├── chaincfg/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── chainhash/
    │   │   │   │   │   ├── README.md
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── hash.go
    │   │   │   │   │   └── hashfuncs.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── genesis.go
    │   │   │   │   └── params.go
    │   │   │   ├── rpcclient/
    │   │   │   │   ├── CONTRIBUTORS
    │   │   │   │   ├── README.md
    │   │   │   │   ├── chain.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── extensions.go
    │   │   │   │   ├── infrastructure.go
    │   │   │   │   ├── log.go
    │   │   │   │   ├── mining.go
    │   │   │   │   ├── net.go
    │   │   │   │   ├── notify.go
    │   │   │   │   ├── rawrequest.go
    │   │   │   │   ├── rawtransactions.go
    │   │   │   │   └── wallet.go
    │   │   │   ├── txscript/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── consensus.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── engine.go
    │   │   │   │   ├── error.go
    │   │   │   │   ├── hashcache.go
    │   │   │   │   ├── log.go
    │   │   │   │   ├── opcode.go
    │   │   │   │   ├── script.go
    │   │   │   │   ├── scriptbuilder.go
    │   │   │   │   ├── scriptnum.go
    │   │   │   │   ├── sigcache.go
    │   │   │   │   ├── sign.go
    │   │   │   │   ├── stack.go
    │   │   │   │   └── standard.go
    │   │   │   └── wire/
    │   │   │       ├── README.md
    │   │   │       ├── blockheader.go
    │   │   │       ├── common.go
    │   │   │       ├── doc.go
    │   │   │       ├── error.go
    │   │   │       ├── invvect.go
    │   │   │       ├── message.go
    │   │   │       ├── msgaddr.go
    │   │   │       ├── msgalert.go
    │   │   │       ├── msgblock.go
    │   │   │       ├── msgcfcheckpt.go
    │   │   │       ├── msgcfheaders.go
    │   │   │       ├── msgcfilter.go
    │   │   │       ├── msgfeefilter.go
    │   │   │       ├── msgfilteradd.go
    │   │   │       ├── msgfilterclear.go
    │   │   │       ├── msgfilterload.go
    │   │   │       ├── msggetaddr.go
    │   │   │       ├── msggetblocks.go
    │   │   │       ├── msggetcfcheckpt.go
    │   │   │       ├── msggetcfheaders.go
    │   │   │       ├── msggetcfilters.go
    │   │   │       ├── msggetdata.go
    │   │   │       ├── msggetheaders.go
    │   │   │       ├── msgheaders.go
    │   │   │       ├── msginv.go
    │   │   │       ├── msgmempool.go
    │   │   │       ├── msgmerkleblock.go
    │   │   │       ├── msgnotfound.go
    │   │   │       ├── msgping.go
    │   │   │       ├── msgpong.go
    │   │   │       ├── msgreject.go
    │   │   │       ├── msgsendheaders.go
    │   │   │       ├── msgtx.go
    │   │   │       ├── msgverack.go
    │   │   │       ├── msgversion.go
    │   │   │       ├── netaddress.go
    │   │   │       └── protocol.go
    │   │   ├── btclog/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── doc.go
    │   │   │   ├── goclean.sh
    │   │   │   ├── interface.go
    │   │   │   └── log.go
    │   │   ├── btcutil/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── address.go
    │   │   │   ├── amount.go
    │   │   │   ├── appdata.go
    │   │   │   ├── base58/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── alphabet.go
    │   │   │   │   ├── base58.go
    │   │   │   │   ├── base58check.go
    │   │   │   │   ├── cov_report.sh
    │   │   │   │   ├── doc.go
    │   │   │   │   └── genalphabet.go
    │   │   │   ├── bech32/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── bech32.go
    │   │   │   │   └── doc.go
    │   │   │   ├── block.go
    │   │   │   ├── certgen.go
    │   │   │   ├── const.go
    │   │   │   ├── cov_report.sh
    │   │   │   ├── doc.go
    │   │   │   ├── goclean.sh
    │   │   │   ├── hash160.go
    │   │   │   ├── hdkeychain/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── cov_report.sh
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── extendedkey.go
    │   │   │   │   └── test_coverage.txt
    │   │   │   ├── net.go
    │   │   │   ├── net_noop.go
    │   │   │   ├── test_coverage.txt
    │   │   │   ├── tx.go
    │   │   │   └── wif.go
    │   │   ├── go-socks/
    │   │   │   ├── LICENSE
    │   │   │   └── socks/
    │   │   │       ├── addr.go
    │   │   │       ├── conn.go
    │   │   │       └── dial.go
    │   │   └── websocket/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── AUTHORS
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── client.go
    │   │       ├── conn.go
    │   │       ├── doc.go
    │   │       ├── json.go
    │   │       ├── server.go
    │   │       └── util.go
    │   ├── davecgh/
    │   │   └── go-spew/
    │   │       ├── LICENSE
    │   │       └── spew/
    │   │           ├── bypass.go
    │   │           ├── bypasssafe.go
    │   │           ├── common.go
    │   │           ├── config.go
    │   │           ├── doc.go
    │   │           ├── dump.go
    │   │           ├── format.go
    │   │           └── spew.go
    │   ├── pkg/
    │   │   └── errors/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── errors.go
    │   │       └── stack.go
    │   ├── pmezard/
    │   │   └── go-difflib/
    │   │       ├── LICENSE
    │   │       └── difflib/
    │   │           └── difflib.go
    │   └── stretchr/
    │       └── testify/
    │           ├── LICENSE
    │           └── assert/
    │               ├── assertion_format.go
    │               ├── assertion_format.go.tmpl
    │               ├── assertion_forward.go
    │               ├── assertion_forward.go.tmpl
    │               ├── assertions.go
    │               ├── doc.go
    │               ├── errors.go
    │               ├── forward_assertions.go
    │               └── http_assertions.go
    ├── golang.org/
    │   └── x/
    │       └── crypto/
    │           ├── AUTHORS
    │           ├── CONTRIBUTORS
    │           ├── LICENSE
    │           ├── PATENTS
    │           └── ripemd160/
    │               ├── ripemd160.go
    │               └── ripemd160block.go
    ├── gopkg.in/
    │   └── alecthomas/
    │       └── kingpin.v2/
    │           ├── .travis.yml
    │           ├── COPYING
    │           ├── README.md
    │           ├── actions.go
    │           ├── app.go
    │           ├── args.go
    │           ├── cmd.go
    │           ├── completions.go
    │           ├── doc.go
    │           ├── envar.go
    │           ├── flags.go
    │           ├── global.go
    │           ├── guesswidth.go
    │           ├── guesswidth_unix.go
    │           ├── model.go
    │           ├── parser.go
    │           ├── parsers.go
    │           ├── templates.go
    │           ├── usage.go
    │           ├── values.go
    │           ├── values.json
    │           └── values_generated.go
    └── modules.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: gomod
  directory: "/"
  schedule:
    interval: daily
  open-pull-requests-limit: 10


================================================
FILE: .gitignore
================================================
tmp/
beancounter
*.csv


================================================
FILE: .travis.yml
================================================
---

language: go

go:
  - '1.13.4'

before_install:
  - go get github.com/mattn/goveralls

install:
  - GOOS=linux GOARCH=amd64 go build -o beancounter-${TRAVIS_TAG}-linux-amd64
  - GOOS=darwin GOARCH=amd64 go build -o beancounter-${TRAVIS_TAG}-osx-amd64
  - GOOS=windows GOARCH=amd64 go build -o beancounter-${TRAVIS_TAG}-windows-amd64.exe

script:
  - go test -v ./... -coverprofile coverage.out

after_success:
  - $HOME/gopath/bin/goveralls -coverprofile coverage.out -service=travis-ci


================================================
FILE: BUG-BOUNTY.md
================================================
Serious about security
======================

Square recognizes the important contributions the security research community
can make. We therefore encourage reporting security issues with the code
contained in this repository.

If you believe you have discovered a security vulnerability, please follow the
guidelines at <https://bugcrowd.com/squareopensource>.



================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

We appreciate your desire to contribute code to this repo. You may do so through GitHub
by forking the repository and sending a pull request.

When submitting code, please make every effort to follow existing conventions
and style in order to keep the code as readable as possible. Please also make
sure all tests pass.

Before your code can be accepted into the project you must also sign the
[Individual Contributor License Agreement (CLA)][1].

Pull requests need to be approved by two members of Square's security engineering team.

Commits are signed by Square's security engineers. Merges are signed by GitHub. Contributors
are not required to sign their commits.

 [1]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1


================================================
FILE: LICENSE
================================================

                                 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.


================================================
FILE: README.md
================================================
Beancounter
==========

[![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/square/beancounter/master/LICENSE) [![travis](https://img.shields.io/travis/com/square/beancounter.svg?maxAge=3600&logo=travis&label=travis)](https://travis-ci.com/square/beancounter)
[![coverage](https://coveralls.io/repos/github/square/beancounter/badge.svg?branch=master)](https://coveralls.io/r/square/beancounter) [![report](https://goreportcard.com/badge/github.com/square/beancounter)](https://goreportcard.com/report/github.com/square/beancounter)

Beancounter is a command line utility to audit the balance of [Hierarchical Deterministic (HD)][bip32] wallets at a given point in time (or block height). The tool is designed to scale and work for wallets with a large number of addresses or a large number of transactions, with support ranging from simple watch wallets to more complicated multisig + segwit. If you're curious, [here's why we decided to write Beancounter](WHY.md) in the first place.

Beancounter currently supports two types of backends to query the blockchain:
1. Electrum public servers. When using these servers, Beancounter behaves in a similar fashion to an Electrum client wallet. The servers are queried for transaction history for specific addresses. Using Electrum servers is easiest but requires trusting public servers to return accurate information. There is also potential privacy exposure.

2. Private Btcd node. Btcd is a Bitcoin full node which implements transaction indexes. Setting up a Btcd node can take some time (the initial sync takes ~7 days) and requires maintaining the node up-to-date. The benefit is however a higher level of guarantee that the transaction history is accurate.

![logo](https://raw.githubusercontent.com/square/beancounter/master/coffee.jpg)

[bip32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

Getting Started
===============

Installing
----------
Requires Go 1.11 or higher.

```
$ git clone https://github.com/square/beancounter/
$ cd beancounter
$ go build -mod=vendor
```

Deriving the child pubkey
-------------------------
Let's imagine we want to track the balance of `tpubD8L6UhrL8ML9...` and the derivation being used is `m/1'/1234/change/index`.

We need to manually perform the `1234` derivation:

```
$ ./beancounter keytree 1234
Enter pubkey #1 out of #1:
tpubD8L6UhrL8ML9Ao47k4pmdvUoiA6QUJVzrJ9BXLgU9idRKnvdRFGgjcxmVxojWGvCcjMi6QWCp8uMpCwWdSFRDNJ7utizxLy27sVWXQT4Jz7
Child pubkey #1: tpubDBrCAXucLxvjC9n9nZGGcYS8pk4X1N97YJmUgdDSwG2p36gbSqeRuytHYCHe2dHxLsV2EchX9ePaFdRwp7cNLrSpnr3PsoPLUQqbvLBDWvh
```

We can then use `tpubDBrCAXucLxvj...` to compute the balance.

Compute balance of a HD wallet (using Electrum)
-----------------------------------------------
```
$ ./beancounter compute-balance --type multisig --block-height 1438791
Enter pubkey #1 out of #1:
tpubDBrCAXucLxvjC9n9nZGGcYS8pk4X1N97YJmUgdDSwG2p36gbSqeRuytHYCHe2dHxLsV2EchX9ePaFdRwp7cNLrSpnr3PsoPLUQqbvLBDWvh
...
Balance: 267893477
```

Compute balance of a single address (using Electrum)
----------------------------------------------------
```
$ ./beancounter compute-balance --type single-address --lookahead 1 --block-height 1438791
Enter single address:
mzoeuyGqMudyvKbkNx5dtNBNN59oKEAsPn
...
Balance: 111168038
```

Compute balance of a HD wallet (using Btcd)
-------------------------------------------

[https://github.com/btcsuite/btcd](https://github.com/btcsuite/btcd) contains information on how to setup a node.

Beancounter requires `addrindex=1`, `txindex=1`, and `notls=1`. If your node is on a remote server,
we recommend tunneling the RPC traffic over ssh or some other secure tunnel.

```
rpcuser=mia
rpcpass=ilovebrownies
rpclisten=127.0.0.1:8334
notls=1

blocksonly=1
addrindex=1
txindex=1
```

Once the Btcd is up and running, you can do:
```
$ ./beancounter compute-balance --type multisig --block-height 1438791 --backend btcd --addr localhost:8334 --rpcuser mia --rpcpass ilovebrownies
Enter pubkey #1 out of #1:
tpubDBrCAXucLxvjC9n9nZGGcYS8pk4X1N97YJmUgdDSwG2p36gbSqeRuytHYCHe2dHxLsV2EchX9ePaFdRwp7cNLrSpnr3PsoPLUQqbvLBDWvh
...
Balance: 267893477
```

Details
=======

Beancounter is implemented in Go. We picked Go because we wanted an easy build and distribution process. We appreciate the ability to cross-compile and distribute static binaries which don't have external dependencies.

We use the following process to determine a deterministic wallet's balance at a given block height:

1. Derive external (receive) and internal (change) addresses.
2. For each address, query the backend for a list of transactions. We keep deriving additional addresses until we find a large number of unused addresses.
3. Prune the transaction list to remove transactions newer than the block height.
4. For each transaction, query the backend for the raw transaction.
5. For each transaction, track whether the output belongs to the wallet and whether
   it got spent.
6. Iterate over the transactions and compute the final balance.

Contributing
============

We appreciate any pull request which fixes bugs or adds features!

If you need ideas on how to contribute, we would enjoy a 3rd backend (Bitcoin-core based, processing
each block by streaming the entire blockchain) as well as additional wallet types (e.g. multisig non-segwit).

Additional unittests and improvements to comments/docs are also always welcome.

License
=======

    Copyright 2018 Square, Inc.

    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.


================================================
FILE: WHY.md
================================================
# Why we wrote Beancounter
### _and why it wasn't trivial_
Intuitively, computing the balance for a Bitcoin wallet should be easy. This document explains the issues we ran into with both, our hot and cold wallets. We solved these issues by implementing Beancounter, a tool we then open-sourced.

# How is the blockchain structured?
A simplified explanation: Bitcoin stores transactions on a blockchain. A blockchain is a list of blocks. Each block contains transactions.

A transaction consumes previous transaction:index pairs (debits) and creates new outputs (credits). The outputs are address:amount pairs and are called unspent transactions (UTXO) until they get consumed in a subsequent transaction.

```
            [...] -> [block dc52a] -> [...]
                           |
                           +-- transaction d1e6d
                           | +-- debit: prevtx 068aa:1
                           | +-- debit: prevtx bfa74:4
                           | +-- credit: some address:amount
                           | +-- credit: another address:amount
                           | ...
                           |
                           +- transaction 1c867
                           | ...
                           |
                           ...
```

The important point for our discussion is that the funds are the UTXOs and there’s no per-address state. Each Bitcoin client needs to compute the per-address balance for the wallets they care about.

_Note: not all cryptocurrencies are implemented in this way. For instance, Ethereum maintains contract state._

https://github.com/bitcoinbook/bitcoinbook (or the paper version of the book) is a good place to learn more about the underlying structures.

# What is a Bitcoin wallet?
A wallet is a collection of addresses. For [Hierarchical Deterministic wallets][bip32] (which is what we use), each wallet has a huge number of addresses (typically 2^31 * 2). To figure out the balance, we need to find each addresses’ balance and sum things up. Doing the following would however be extremely slow:

```
balance = 0;
for (int i=0; i<2^31; i++) {
  address = wallet.get(i)
  balance += lookup(address)
}

```

[bip32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

# How does [insert favorite wallet software] do it?
Most Bitcoin software defines a gap window (called lookahead in [BitcoinJ][btcj]). The software initially has a small set of addresses (the size of the gap, say 20) and watches for transactions which include addresses from this set. As the software sees transactions, it computes the 20 following addresses and adds them to the set.

Note: the gap heuristic does not always work well in practice (there have been cases where the default was too small).

[btcj]: https://bitcoinj.github.io/

# What happened when we tried using Electrum
- Our hot wallets have a large number of transactions at a high velocity (multiple transactions per block).
  - We could potentially fix Electrum. Would require learning the code base and contributing patches (or filing bugs and hoping maintainers will be interested to address them).
- Our cold wallet were initially using a custom derivation scheme, not compatible with Electrum.
  - This is no longer true, we eventually switched to using the same scheme as our hot wallets.


# Why we can’t simply use our core Bitcoin nodes
- Square runs a few Bitcoin nodes. We explored using them (although we would need to figure out a way to safely expose the RPC protocol only to specific people).
- The standard Bitcoin node however does not maintain an index of address => balance. It also does not maintain an index of address => transaction. The only index the core nodes maintain is transaction => block (for all transaction or only for unspent transaction depending whether prunning is enabled or not).
  - ([there][pr1] [were][pr2] [some][pr3] PRs to address this, but none of them were ready).
  - We could query the entire history, pick out the addresses we care about and compute the balance. But it requires writing a fair amount of code.

[pr1]: https://github.com/bitcoin/bitcoin/pull/5048
[pr2]: https://github.com/bitcoin/bitcoin/pull/8660
[pr3]: https://github.com/bitcoin/bitcoin/pull/9806


# What about alternative Bitcoin nodes?
- There are multiple alternative implementations which maintain an address => transactions index (and also an address => balance):
  - Electrum servers ([original unmaintained implementation][elect] and [ElectrumX][electx])
  - [btcd][btcd] (Alternative Bitcoin implementation in Go)
  - [Bitcoin fork][btcfork] with an index patch (the author tried to upstream the changes).
  - [indexd-server][btcidx] which sits on top of a core node.
- The simplest API (address => balance) however does not take a max block height as a parameter (at least neither Electrum nor btcd’s APIs). A new block is mined every ~10 min, but it takes much longer to iterate over all the addresses in our large hot wallets. We are thus unable to determine the wallet balance.
- We had to use two indexes, the address => transactions index combined with the transactions => block index to compute the balance. This turns out to be quite a bit of engineering effort!

[btcd]:    https://github.com/btcsuite/btcd
[btcfork]: https://github.com/btcdrak/bitcoin
[btcidx]:  https://github.com/CounterpartyXCP/indexd-server
[elect]:   https://github.com/spesmilo/electrum-server
[electx]:  https://github.com/kyuupichan/electrumx

# What about trust. Can we trust Electrum nodes?
- Beancounter allows us to connect to our own Electrum node, our own btcd node, or public Electrum nodes. This allows us to pick the trust model we care about.
- Engineers can connect to their own nodes (e.g. when debugging).
non-technical people can still use Beancounter without having to worry about getting access to a full node.

# Converting human dates to block height.
- The tool we built works with blocks. Auditors want to know the wallet’s balance on a specific date (e.g. 3/31/18 at 00:00:00 GMT)
- Each block on the blockchain carries a timestamp, but the timestamps are not monotonic!
- However, the median of any [11][blk_height] consecutive blocks is guaranteed to be monotonic.
- We can therefore map a block to a monotonic time (by defining the block’s time as being the median of its timestamp, its previous 5 blocks and its next 5 blocks) and perform a binary search to map a human date (e.g. 3/31/18 at 00:00:00 GMT) to the (closest) specific block.

[blk_height]: https://github.com/bitcoin/bitcoin/blob/e8ad580f51532f6bfa6cb55688bffcc12196c0ac/src/chain.h#L324


# Random other issues/thoughts
- Electrum API is a little painful to use. E.g. some methods return a stream of results, but we only want one result. No way to unsubscribe from the stream.
- Electrum’s API versioning is a little messy—not 100% backwards compatible and the initial client library we picked wasn’t very well implemented.
- Running a node (for development purpose) takes a long time to sync and requires a large SSD (at least 250GB ~ Oct ‘18). For some reason, the btcd node takes ~7 days for its initial sync (what is it doing?).
- We cannot easily give random people (e.g. external auditors) access to our private Bitcoin or btcd node. The RPC mechanism does not support fine grained permissions / read-only access.
- We had to deal with potential race conditions when generating additional addresses to watch while synchronously scanning the blockchain. Our hands were tied when it came to parallelism. Talking to Electrum servers can be slow and needs to be multiplexed.
- Many other random issues (see github commit history for a full list).
Perhaps we could have leveraged some other tool? Some kind of Hadoop map-reduce over the blockchain.


================================================
FILE: accounter/accounter.go
================================================
package accounter

import (
	"encoding/hex"
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/btcsuite/btcutil"
	"github.com/square/beancounter/reporter"

	"github.com/square/beancounter/backend"
	"github.com/square/beancounter/deriver"
	. "github.com/square/beancounter/utils"
)

// Accounter is the main struct that can tally the balance for a given wallet.
// The main elements of Accounter are backend and deriver. Deriver is used to
// derive new addresses for a given config, and backend fetches transactions for each address.
//
// Note:
// - We don't track fees. I.e. we don't answer the question: how much have we spent in fees. It
//   shouldn't be hard to answer that question.
type Accounter struct {
	account     string
	net         Network
	xpubs       []string
	blockHeight uint32 // height at which we want to compute the balance

	addresses    map[string]address     // map of address script => (Address, txHashes)
	transactions map[string]transaction // map of txhash => transaction

	backend   backend.Backend
	deriver   *deriver.AddressDeriver
	lookahead uint32

	countMu            sync.Mutex // protects lastAddresses, derivedAddrCount and processedAddrCount
	lastAddresses      [2]uint32
	derivedAddrCount   uint32
	processedAddrCount uint32
	seenTxCount        uint32
	processedTxCount   uint32

	addrResponses <-chan *backend.AddrResponse
	txResponses   <-chan *backend.TxResponse
}

type address struct {
	path     *deriver.Address
	txHashes []string
}

type transaction struct {
	height int64
	hex    string
	vin    []vin
	vout   []vout
}

type vin struct {
	prevHash string // hash of previous transaction
	index    uint32 // offset. 0-indexed.
}

type vout struct {
	value   int64 // in Satoshi. We use signed int64 so we don't have to worry about underflow.
	address string
	ours    bool
	spentBy *string // txhash of spending transaction; nil for unspent transactions.
}

// New instantiates a new Accounter.
// TODO: find a better way to pass options to the NewCounter. Maybe thru a config or functional option params?
func New(b backend.Backend, addressDeriver *deriver.AddressDeriver, lookahead uint32, blockHeight uint32) *Accounter {
	a := &Accounter{
		blockHeight:   blockHeight,
		backend:       b,
		deriver:       addressDeriver,
		lookahead:     lookahead,
		lastAddresses: [2]uint32{lookahead, lookahead},
	}
	a.addresses = make(map[string]address)
	a.transactions = make(map[string]transaction)
	a.addrResponses = b.AddrResponses()
	a.txResponses = b.TxResponses()
	return a
}

func (a *Accounter) ComputeBalance() uint64 {
	// Fetch all the transactions
	a.fetchTransactions()

	// Process the data
	a.processTransactions()

	// Compute the balance
	return a.balance()
}

// Fetch all the transactions related to our wallet. We tally the balance after we have fetched
// all the transactions so that we don't need to worry about receiving transactions out-of-order.
func (a *Accounter) fetchTransactions() {
	// send work runs forever
	go a.sendWork()

	a.recvWork()

	reporter.GetInstance().Log("done fetching addresses; waiting to finish...")
	a.backend.Finish()
	reporter.GetInstance().Log("done fetching transactions")
}

func (a *Accounter) processTransactions() {
	for hash, tx := range a.transactions {
		// remove transactions which are too recent
		if tx.height > int64(a.blockHeight) {
			reporter.GetInstance().Logf("transaction %s has height %d > BLOCK HEIGHT (%d)", hash, tx.height, a.blockHeight)
			delete(a.transactions, hash)
		}
		// remove transactions which haven't been mined
		if tx.height <= 0 {
			reporter.GetInstance().Logf("transaction %s has not been mined, yet (height=%d)", hash, tx.height)
			delete(a.transactions, hash)
		}
	}
	reporter.GetInstance().SetTxAfterFilter(int32(len(a.transactions)))
	reporter.GetInstance().Log("done filtering")

	// TODO: we could check that scheduled == fetched in the metrics we track in reporter.

	// parse the transaction hex
	for hash, tx := range a.transactions {
		b, err := hex.DecodeString(tx.hex)
		if err != nil {
			fmt.Printf("failed to unhex transaction %s: %s", hash, tx.hex)
		}
		parsedTx, err := btcutil.NewTxFromBytes(b)
		if err != nil {
			fmt.Printf("failed to parse transaction %s: %s", hash, tx.hex)
			continue
		}
		for _, txin := range parsedTx.MsgTx().TxIn {
			tx.vin = append(tx.vin, vin{
				prevHash: txin.PreviousOutPoint.Hash.String(),
				index:    txin.PreviousOutPoint.Index,
			})
		}

		for _, txout := range parsedTx.MsgTx().TxOut {
			addr := hex.EncodeToString(txout.PkScript)
			_, exists := a.addresses[addr]
			tx.vout = append(tx.vout, vout{
				value:   txout.Value,
				address: addr,
				ours:    exists,
				spentBy: nil,
			})
		}

		// ugly...
		a.transactions[hash] = tx
	}
}

func (a *Accounter) balance() uint64 {
	balance := int64(0)

	// TODO: we could check that every transaction either has an input which belongs to us or an
	// output. Otherwise, it would not have appeared in the list. It's also a good check, given
	// that we filter some transactions out.

	// compute all credits
	for _, tx := range a.transactions {
		for _, txout := range tx.vout {
			if txout.ours {
				balance += txout.value
			}
		}
	}

	// TODO: log a warning if an address is being used multiple times. Ideally, a given address
	// should only have one incoming and one outgoing transaction.

	// TODO: log a warning if a receive address is getting change.

	// TODO: log a warning if a change address is receiving funds from an address we don't own.

	// compute all debits
	for hash, tx := range a.transactions {
		for _, txin := range tx.vin {
			prev, exists := a.transactions[txin.prevHash]
			if !exists {
				continue
			}
			if int(txin.index) >= len(prev.vout) {
				panic("prev index > vouts")
			}
			if prev.vout[txin.index].ours {
				balance -= prev.vout[txin.index].value
				if prev.vout[txin.index].spentBy != nil {
					// sanity check: an output can only be spent by one transaction.
					log.Panicf("%s and %s, both spending %s", hash, *prev.vout[txin.index].spentBy, txin.prevHash)
				}
				prev.vout[txin.index].spentBy = &hash
			}
		}
	}

	if balance < 0 {
		panic("balance is negative")
	}
	return uint64(balance)
}

// sendWork starts the send loop that derives new addresses and sends them to a
// a backend.
// Addresses are derived in batches (up to a `lookahead` index) and the range can
// be extended if a transaction for a given address is found. E.g.:
// only addresses 0-99 are initially checked, but there was a transaction at
// index 43, so now all addresses up to 142 are checked.
func (a *Accounter) sendWork() {
	indexes := []uint32{0, 0}
	for {
		for _, change := range []uint32{0, 1} {
			lastAddr := a.getLastAddress(change)
			for indexes[change] < lastAddr {
				// increment the number of addresses which have been derived
				addr := a.deriver.Derive(change, indexes[change])
				a.countMu.Lock()
				a.derivedAddrCount++
				a.countMu.Unlock()
				a.backend.AddrRequest(addr)
				indexes[change]++
			}
		}
		// apparently no more work for us, so we can sleep a bit
		time.Sleep(time.Millisecond * 100)
	}
}

func (a *Accounter) recvWork() {
	addrResponses := a.addrResponses
	txResponses := a.txResponses
	for {
		select {
		case resp, ok := <-addrResponses:
			// channel is closed now, so ignore this case by blocking forever
			if !ok {
				addrResponses = nil
				continue
			}
			reporter.GetInstance().IncAddressesFetched()

			a.countMu.Lock()
			a.processedAddrCount++
			a.countMu.Unlock()

			a.addresses[resp.Address.Script()] = address{
				path:     resp.Address,
				txHashes: resp.TxHashes,
			}

			a.countMu.Lock()
			for _, txHash := range resp.TxHashes {
				if _, exists := a.transactions[txHash]; !exists {
					a.backend.TxRequest(txHash)
					a.seenTxCount++
				}
			}
			a.countMu.Unlock()

			reporter.GetInstance().Logf("address %s has %d transactions", resp.Address, len(resp.TxHashes))

			if resp.HasTransactions() {
				a.countMu.Lock()
				a.lastAddresses[resp.Address.Change()] = Max(a.lastAddresses[resp.Address.Change()], resp.Address.Index()+a.lookahead)
				a.countMu.Unlock()
			}
		case resp, ok := <-txResponses:
			// channel is closed now, so ignore this case by blocking forever
			if !ok {
				txResponses = nil
				continue
			}

			reporter.GetInstance().IncTxFetched()

			a.countMu.Lock()
			a.processedTxCount++
			a.countMu.Unlock()

			tx := transaction{
				height: resp.Height,
				hex:    resp.Hex,
				vin:    []vin{},
				vout:   []vout{},
			}
			a.transactions[resp.Hash] = tx
		case <-time.Tick(1 * time.Second):
			if a.complete() {
				return
			}
		}
	}
}

// getLastAddress synchronizes access to lastAddresses array
func (a *Accounter) getLastAddress(change uint32) uint32 {
	a.countMu.Lock()
	defer a.countMu.Unlock()

	return a.lastAddresses[change]
}

// complete checks if all addresses have been derived and checked.
// Since most of the work happens asynchronuously, there needs to be a termination
// condition.
func (a *Accounter) complete() bool {
	a.countMu.Lock()
	defer a.countMu.Unlock()

	// We are done when the right number of addresses were scheduled, fetched and processed
	// *and* all the transactions that were seen have been scheduled, fetched and processed.
	indexes := a.lastAddresses[0] + a.lastAddresses[1]
	addrsDone := a.derivedAddrCount == indexes && a.processedAddrCount == indexes
	txsDone := a.seenTxCount == a.processedTxCount

	return addrsDone && txsDone
}


================================================
FILE: accounter/accounter_test.go
================================================
package accounter

import (
	"testing"

	"github.com/square/beancounter/backend"
	"github.com/square/beancounter/deriver"
	. "github.com/square/beancounter/utils"
	"github.com/stretchr/testify/assert"
)

func TestProcessTransactions(t *testing.T) {
	a := Accounter{
		blockHeight:  100,
		transactions: make(map[string]transaction),
	}
	// https://api.blockcypher.com/v1/btc/main/txs/38f6366700f12dc902718ab5222c8ae67a4514ed07ee8aea364feec22bf6424f?limit=50&includeHex=true
	a.transactions["1"] = transaction{
		height: 10,
		hex:    "020000000001012afcb974e6a5404d4a93d051746a2fe419d92f5c04a2f8cd19c80fc0068defa8010000001716001423819adc0d76e951ba8b0568d8e05b141d4ba5adfeffffff025b2297080000000017a9149ae902bcdf8859abc54a1baf253ea294336a212e87283463660000000017a9140662710b351b7834914b0303cf32c08f3e937c6d87024830450221008a52e1944137e724bebb477b9bf545b62b83d14e435ce9fb25b05bb9857a038202204b79214c7f90b76372d3ce11d9d645b159abcd1038fa20201c4168b09b103192012102f3ccaceecb31987e00e0d159459dcafea4c9bcd64f36b0dee034279bab96d1985c510800",
		vin:    []vin{},
		vout:   []vout{},
	}

	// https://api.blockcypher.com/v1/btc/main/txs/8e6c5effcc2d31b55bb7964747338db3a273b62c9b2385de50117ea09baefcb4?limit=50&includeHex=true
	a.transactions["2"] = transaction{
		height: 100,
		hex:    "0100000001c75e0c4591ca1a9a2b0d899b4312407fe4b220e6ad5cdee9c3e02be4bc99f321cd0300008b483045022100d0d49ae3f43a3a7799faa2c951dec497a867f6b904b7edba9f87755be15fd67e02200a454de50d7b582d0ed033403fac99d9e41536c018bf0b68058a79f85ef060a6014104fcf07bb1222f7925f2b7cc15183a40443c578e62ea17100aa3b44ba66905c95d4980aec4cd2f6eb426d1b1ec45d76724f26901099416b9265b76ba67c8b0b73dffffffff0388080000000000001976a914fa0692278afe508514b5ffee8fe5e97732ce066988ac0000000000000000166a146f6d6e69000000000000002700000022abdcac9622020000000000001976a9146d17f31f8cef7831b87896402bf2986d4361afb988ac00000000",
		vin:    []vin{},
		vout:   []vout{},
	}

	// https://api.blockcypher.com/v1/btc/main/txs/72abc310daf35dd21d3ba92e72bc39c47f245ba99441db7d8b05642842dbd62c?limit=50&includeHex=true
	a.transactions["3"] = transaction{
		height: 120,
		hex:    "020000000126a2fd32e2a97ce4d1ef244247edb1fa986b20f5e1d4b2a9f4279ac3f8c97fee020000006a473044022079d203284b5d656d229500451c03bf9f9242e865e205a883c2a3f847a598e579022008e7912074faaa343b0fbe8107f773ec19dcd2371a592c28f38d3ce68ab5bb3201210267759b65b67634ce5fb3114b3c9547f7efcd5a095fa6fc2bb8c532ec5df9d479feffffff0294cb43000000000017a914d237f4c583a567ab7e3ba091ee14953774b1ceda87198025000000000017a914bd706cbfc32ffaff0d2604f4bfbe490e0b36e211875d510800",
		vin:    []vin{},
		vout:   []vout{},
	}

	// https://api.blockcypher.com/v1/btc/main/txs/da47ec573c7639e61ca1bc77ab866f17fe0f1c55ee4aeb6c6daa8d35e3df950c?limit=50&includeHex=true
	a.transactions["4"] = transaction{
		height: 0,
		hex:    "02000000000105201000e0ad28b2c06cc333f9325f49b6e1532dc47b071a0b0e9039a2eecc2f3f000000001716001403ff881365a8c3318c645b2db7de3d0e9bb01e32feffffff2cd6db422864058b7ddb4194a95b247fc439bc722ea93b1dd25df3da10c3ab720100000017160014d970197441c15e71fa5926dcf494ecca0540de39feffffff68e8dcb6ac8e0edba261b953059839390738eca19139b7bbe97658c5f9866cc90000000000feffffffb3fe4a69cc708263cf3281e0a876c657ea6a424065d5d92f251802c28c7b422f00000000171600148a3e01c8043955c6d2cd754fbc9e0c063a69fcf1feffffffdbce7c09a67bfa1a2737a04205e5d145b689f98c634326a8be92d3aadd2787450000000017160014e0ae2e0c87f5ec2a885457af322550652265141cfeffffff02e00f9700000000001976a914c8bfd11d19fbdab3a0a0b525c8040b96ccac183f88ac02880c000000000017a9141c0aab9855abc6d9564714dbbfc0b8da5a8f2aca870247304402202f750e6b1e5b6759a784178ab9ce4162f2812c597690202655ad569e90a7f30802204cdb33c66c31da483e4c4bfac7d85bc9f1552fc2aa7b0eb060311cfc8db0c623012102d007f6f2ce40cc13c295598bb447faa5cb0a42cdacd39fbcb15d1152d87dc898024730440220561b78a66d16ab1f741a1f4c6cc42ad7257cfac9238f14bb10f9e351f2535c9002202383c70c4daa3b69229081b00a69732023b1dd1474eb0b9e32a7c08e112f642b012102c3bc868e47418bdef127d702af9593ce42790038a27f019ec467b0cd3802fbc802473044022076c69f83accbe0a5a42bbc8b03e4c77205a2bbb64da03ed0a8ece9bd9248e5b902204694c3ac5ec87ba4d93da30e9871a1e5581555722d60a534c79e92f55012d1080121037cd588476186076662d993913a9450ee12816efa5dbfbf1a41208694966c7c6c02483045022100b182661da8afbb51b6528e63a566b06d915e8d6cb3375bf7c26e825c9c89cb54022065bb0af673614611a5c9574dd2d47cf941afc6752dba7c6456f9a3e3beab74e30121029f0e39491bcebac56a52ce46c0bf0a782563698108bba3f290fdf232cb0c0635024830450221008a7d81574993ad3944102aac990e584ec09aa1071f31b0fdefa4adde21da613c022009d7ed96ddebe52ac760e5799dab659f53a961a79dda4929d18e1eb525372bfe012102f2eafee2c4ab2197c5394fb388128cd986b6c880eb0ba27e025ed74c64e7e6a75d510800",
		vin:    []vin{},
		vout:   []vout{},
	}

	a.processTransactions()

	assert.Equal(t, len(a.transactions), 2)
	assert.Equal(t, len(a.transactions["1"].vin), 1)
	assert.Equal(t, a.transactions["1"].vin[0], vin{
		prevHash: "a8ef8d06c00fc819cdf8a2045c2fd919e42f6a7451d0934a4d40a5e674b9fc2a",
		index:    1,
	})
	assert.Equal(t, len(a.transactions["1"].vout), 2)
	assert.Equal(t, a.transactions["1"].vout[0], vout{
		value:   144122459,
		address: "a9149ae902bcdf8859abc54a1baf253ea294336a212e87",
		ours:    false,
	})
	assert.Equal(t, a.transactions["1"].vout[1], vout{
		value:   1717777448,
		address: "a9140662710b351b7834914b0303cf32c08f3e937c6d87",
		ours:    false,
	})

	assert.Equal(t, len(a.transactions["2"].vin), 1)
	assert.Equal(t, a.transactions["2"].vin[0], vin{
		prevHash: "21f399bce42be0c3e9de5cade620b2e47f4012439b890d2b9a1aca91450c5ec7",
		index:    973,
	})
	assert.Equal(t, len(a.transactions["2"].vout), 3)
	assert.Equal(t, a.transactions["2"].vout[0], vout{
		value:   2184,
		address: "76a914fa0692278afe508514b5ffee8fe5e97732ce066988ac",
		ours:    false,
	})
	assert.Equal(t, a.transactions["2"].vout[1], vout{
		value:   0,
		address: "6a146f6d6e69000000000000002700000022abdcac96",
		ours:    false,
	})
	assert.Equal(t, a.transactions["2"].vout[2], vout{
		value:   546,
		address: "76a9146d17f31f8cef7831b87896402bf2986d4361afb988ac",
		ours:    false,
	})
}

func TestComputeBalanceTestnet(t *testing.T) {
	pubs := []string{"tpubDBrCAXucLxvjC9n9nZGGcYS8pk4X1N97YJmUgdDSwG2p36gbSqeRuytHYCHe2dHxLsV2EchX9ePaFdRwp7cNLrSpnr3PsoPLUQqbvLBDWvh"}
	deriver := deriver.NewAddressDeriver(Testnet, pubs, 1, "")
	b, err := backend.NewFixtureBackend("testdata/tpub_data.json")
	assert.NoError(t, err)
	a := New(b, deriver, 100, 1435169)

	assert.Equal(t, uint64(267893477), a.ComputeBalance())
}


================================================
FILE: accounter/testdata/tpub_data.json
================================================
{
    "addresses": [
        {
            "address": "mfsNoNz57ANkYrCzHaLZDLoMGujBW8u3zv",
            "path": "m/1'/1234/0/61",
            "network": "testnet",
            "change": 0,
            "addr_index": 61,
            "tx_hashes": []
        },
        {
            "address": "mftB8c4Uikunhk6McopZGsX4C2sDiejCDr",
            "path": "m/1'/1234/1/100",
            "network": "testnet",
            "change": 1,
            "addr_index": 100,
            "tx_hashes": []
        },
        {
            "address": "mg5YBWZKm5H6uoLmHZNxTJ27uzXwmea8H8",
            "path": "m/1'/1234/1/22",
            "network": "testnet",
            "change": 1,
            "addr_index": 22,
            "tx_hashes": []
        },
        {
            "address": "mgQQthmwgZJYs4FbeLhNCfoZY3smveNGpu",
            "path": "m/1'/1234/0/106",
            "network": "testnet",
            "change": 0,
            "addr_index": 106,
            "tx_hashes": []
        },
        {
            "address": "mgRj5bH333zCWdmprd5L4ta9xQUhwm9hTd",
            "path": "m/1'/1234/0/115",
            "network": "testnet",
            "change": 0,
            "addr_index": 115,
            "tx_hashes": []
        },
        {
            "address": "mgTMRBbe9owZQQs5BmaD1nJj6ZF3A619UC",
            "path": "m/1'/1234/1/43",
            "network": "testnet",
            "change": 1,
            "addr_index": 43,
            "tx_hashes": []
        },
        {
            "address": "mgXB4w1t3c4usHNx5iEWEJf7CBmqKNnbVB",
            "path": "m/1'/1234/0/82",
            "network": "testnet",
            "change": 0,
            "addr_index": 82,
            "tx_hashes": []
        },
        {
            "address": "mgc1u2A5NkkX8zUiFzZgKYCfXD4dCmnoB6",
            "path": "m/1'/1234/1/70",
            "network": "testnet",
            "change": 1,
            "addr_index": 70,
            "tx_hashes": []
        },
        {
            "address": "mgpkrTCfA3t9CegigXhURUDVqCdAKhYEB2",
            "path": "m/1'/1234/1/73",
            "network": "testnet",
            "change": 1,
            "addr_index": 73,
            "tx_hashes": []
        },
        {
            "address": "mgtnmFbtmKKmhqjD8rQkXdoTczUxGdcXmG",
            "path": "m/1'/1234/1/95",
            "network": "testnet",
            "change": 1,
            "addr_index": 95,
            "tx_hashes": []
        },
        {
            "address": "mh972ndpUc46sa81vqDNz31U9QvdRpYgUB",
            "path": "m/1'/1234/0/28",
            "network": "testnet",
            "change": 0,
            "addr_index": 28,
            "tx_hashes": []
        },
        {
            "address": "mhShbkWNfpUysxi41vRSXZYRh9pJ3oDumF",
            "path": "m/1'/1234/1/33",
            "network": "testnet",
            "change": 1,
            "addr_index": 33,
            "tx_hashes": []
        },
        {
            "address": "mhdPpFJ2GKWyXab3zWsPFxifraRcrfRueb",
            "path": "m/1'/1234/0/74",
            "network": "testnet",
            "change": 0,
            "addr_index": 74,
            "tx_hashes": []
        },
        {
            "address": "mhkVpsFWMMnrVaL2SQ2EBn28ZTYSssdZ8Y",
            "path": "m/1'/1234/0/110",
            "network": "testnet",
            "change": 0,
            "addr_index": 110,
            "tx_hashes": []
        },
        {
            "address": "mhsYkK2ZdHjCWVYYiZ93k3mzez1eCZcJ6H",
            "path": "m/1'/1234/0/71",
            "network": "testnet",
            "change": 0,
            "addr_index": 71,
            "tx_hashes": []
        },
        {
            "address": "mhx1M6yV58z9LAyEKemU6dcn5vNSdHU6rN",
            "path": "m/1'/1234/1/4",
            "network": "testnet",
            "change": 1,
            "addr_index": 4,
            "tx_hashes": []
        },
        {
            "address": "mhx3rJ9UwPHWcUkPzWNkJYaD8tpdHSt93e",
            "path": "m/1'/1234/0/37",
            "network": "testnet",
            "change": 0,
            "addr_index": 37,
            "tx_hashes": []
        },
        {
            "address": "mhzVmvofakaS8W1sQ1jW2JVhq8971qh52X",
            "path": "m/1'/1234/0/63",
            "network": "testnet",
            "change": 0,
            "addr_index": 63,
            "tx_hashes": []
        },
        {
            "address": "mhzcM1Uy2ZVvmf8U2WxUhwipzo3QtF7xyy",
            "path": "m/1'/1234/0/38",
            "network": "testnet",
            "change": 0,
            "addr_index": 38,
            "tx_hashes": []
        },
        {
            "address": "mi2udMvJHeeJJNp5wWKToa86L2cJUKzrby",
            "path": "m/1'/1234/0/7",
            "network": "testnet",
            "change": 0,
            "addr_index": 7,
            "tx_hashes": [
                "5554c15d13002786a70a7151aad4eddce76633c60bc7f90e3dc70eb4f9c4b2b0",
                "bd09a74381ffad78c162976ec27fc9c1dceda3c2bfe367541a7140b8dd6e1f4c"
            ]
        },
        {
            "address": "miNGFhhzfoaWQ23DZNLXsSFwJbmHLgFrMt",
            "path": "m/1'/1234/1/82",
            "network": "testnet",
            "change": 1,
            "addr_index": 82,
            "tx_hashes": []
        },
        {
            "address": "miNHQsiKCGSYmvx8jwQ1RP1nKAryepop65",
            "path": "m/1'/1234/1/89",
            "network": "testnet",
            "change": 1,
            "addr_index": 89,
            "tx_hashes": []
        },
        {
            "address": "miPXS6eR2nV3MyF8WGueWe7Xc6P1jWwV6E",
            "path": "m/1'/1234/1/45",
            "network": "testnet",
            "change": 1,
            "addr_index": 45,
            "tx_hashes": []
        },
        {
            "address": "minf4VcGeR18sAp7DscjH8hLrvNbL8LgZ1",
            "path": "m/1'/1234/1/59",
            "network": "testnet",
            "change": 1,
            "addr_index": 59,
            "tx_hashes": []
        },
        {
            "address": "mj8NcycxuyDcSUwenLpEFST9d1zX3QWV8x",
            "path": "m/1'/1234/1/57",
            "network": "testnet",
            "change": 1,
            "addr_index": 57,
            "tx_hashes": []
        },
        {
            "address": "mjAdhYPB2bTNvxWjSicMqHamAo7zNUCVy5",
            "path": "m/1'/1234/0/67",
            "network": "testnet",
            "change": 0,
            "addr_index": 67,
            "tx_hashes": []
        },
        {
            "address": "mjUrtMvK9GZMzPSgzzBfTWmrtREVecZhAf",
            "path": "m/1'/1234/1/17",
            "network": "testnet",
            "change": 1,
            "addr_index": 17,
            "tx_hashes": []
        },
        {
            "address": "mjYhm1Fr7CFXHmfBGYC6UwBAg7nmeMMKRw",
            "path": "m/1'/1234/1/47",
            "network": "testnet",
            "change": 1,
            "addr_index": 47,
            "tx_hashes": []
        },
        {
            "address": "mjghdrqA6sK34ve5M3dd3UbL4LNssqe8Ry",
            "path": "m/1'/1234/1/58",
            "network": "testnet",
            "change": 1,
            "addr_index": 58,
            "tx_hashes": []
        },
        {
            "address": "mjymM61vCSK2huPkvxFKRD5cKn1eaJv6ZR",
            "path": "m/1'/1234/0/33",
            "network": "testnet",
            "change": 0,
            "addr_index": 33,
            "tx_hashes": []
        },
        {
            "address": "mk6VcQnRsPcS97VptsyFvLRqjY2MeN41wL",
            "path": "m/1'/1234/1/91",
            "network": "testnet",
            "change": 1,
            "addr_index": 91,
            "tx_hashes": []
        },
        {
            "address": "mk9UXXdGJxKRn9k1YwsdxaHtur8J9x14p1",
            "path": "m/1'/1234/1/66",
            "network": "testnet",
            "change": 1,
            "addr_index": 66,
            "tx_hashes": []
        },
        {
            "address": "mkKF25gBCNLwWZkU9f9sRb7sbHGru6YnXD",
            "path": "m/1'/1234/1/83",
            "network": "testnet",
            "change": 1,
            "addr_index": 83,
            "tx_hashes": []
        },
        {
            "address": "mkU6sFjs3LPVKQw8yKNKJuwvMPeLCfCEiP",
            "path": "m/1'/1234/1/39",
            "network": "testnet",
            "change": 1,
            "addr_index": 39,
            "tx_hashes": []
        },
        {
            "address": "mkUgGrxWHKM7AYGUQov7GHgFBSHsaDxpVx",
            "path": "m/1'/1234/1/94",
            "network": "testnet",
            "change": 1,
            "addr_index": 94,
            "tx_hashes": []
        },
        {
            "address": "mkcUjuzzs8TaZkTtkeWeHstnpLNs9Vh9oB",
            "path": "m/1'/1234/1/15",
            "network": "testnet",
            "change": 1,
            "addr_index": 15,
            "tx_hashes": []
        },
        {
            "address": "mkkvscKE8dpNPzcpJutaLXvMzKBXCdevK1",
            "path": "m/1'/1234/0/55",
            "network": "testnet",
            "change": 0,
            "addr_index": 55,
            "tx_hashes": []
        },
        {
            "address": "mkm2Y4d4ymoFaVmY2sZ3UtqCaVWnfwM5FF",
            "path": "m/1'/1234/1/93",
            "network": "testnet",
            "change": 1,
            "addr_index": 93,
            "tx_hashes": []
        },
        {
            "address": "mkpqj3g9tG7NR4WAd35r5Uuaj6UDQ3hmnt",
            "path": "m/1'/1234/1/21",
            "network": "testnet",
            "change": 1,
            "addr_index": 21,
            "tx_hashes": []
        },
        {
            "address": "mm51Xdq9NhGcWXrL8ckQiXBWK2t1ryV8Qq",
            "path": "m/1'/1234/0/109",
            "network": "testnet",
            "change": 0,
            "addr_index": 109,
            "tx_hashes": []
        },
        {
            "address": "mmNXWy7aXQoiKfqyYpX2yfDvqUKjMEp9SL",
            "path": "m/1'/1234/0/26",
            "network": "testnet",
            "change": 0,
            "addr_index": 26,
            "tx_hashes": []
        },
        {
            "address": "mmSYwPHjdmdYtkceBkivQo2xLPj7hPQd4F",
            "path": "m/1'/1234/0/68",
            "network": "testnet",
            "change": 0,
            "addr_index": 68,
            "tx_hashes": []
        },
        {
            "address": "mmV4mpV1MyhzUnESU2XLTyg2wSyy8CjieH",
            "path": "m/1'/1234/1/68",
            "network": "testnet",
            "change": 1,
            "addr_index": 68,
            "tx_hashes": []
        },
        {
            "address": "mmcRhTrHnA1vXgpxQKdmFWFqxTg3QBCjoJ",
            "path": "m/1'/1234/0/86",
            "network": "testnet",
            "change": 0,
            "addr_index": 86,
            "tx_hashes": []
        },
        {
            "address": "mmfFY4UJHJBSjz3ve7tvaSrxNwCReVtifC",
            "path": "m/1'/1234/0/14",
            "network": "testnet",
            "change": 0,
            "addr_index": 14,
            "tx_hashes": [
                "c499c223f401175b14c8cb28893219dcd8b49563e59b9b4865dd4407c2de27c8",
                "df47e4bf599ecf27d8f3b34e85fcd7384d753823208d06171ff16899bc1709ce"
            ]
        },
        {
            "address": "mmk4YsZTafv7hvuiv2zCb9dEdHrgZoEi69",
            "path": "m/1'/1234/1/16",
            "network": "testnet",
            "change": 1,
            "addr_index": 16,
            "tx_hashes": []
        },
        {
            "address": "mmruYbefQY3FAco7ArQwYWgBDKwL8bY4xq",
            "path": "m/1'/1234/0/48",
            "network": "testnet",
            "change": 0,
            "addr_index": 48,
            "tx_hashes": []
        },
        {
            "address": "mmxTm1AKp6ffRHf2W4hdh2vrSbfCFFQV94",
            "path": "m/1'/1234/0/111",
            "network": "testnet",
            "change": 0,
            "addr_index": 111,
            "tx_hashes": []
        },
        {
            "address": "mn4pqFru248g51ZzHU5GCqsy4Jk35SRN3W",
            "path": "m/1'/1234/1/53",
            "network": "testnet",
            "change": 1,
            "addr_index": 53,
            "tx_hashes": []
        },
        {
            "address": "mnJBZg297ETSQZrJKGHDLLfuQwTMmK5U9h",
            "path": "m/1'/1234/1/8",
            "network": "testnet",
            "change": 1,
            "addr_index": 8,
            "tx_hashes": []
        },
        {
            "address": "mnLdhS2ACwRRMcBtfTNz6yH1R2QZ9hr7PJ",
            "path": "m/1'/1234/0/103",
            "network": "testnet",
            "change": 0,
            "addr_index": 103,
            "tx_hashes": []
        },
        {
            "address": "mndsBLfSpvirT9e7wvXt9oNQUNTkpaAGth",
            "path": "m/1'/1234/1/27",
            "network": "testnet",
            "change": 1,
            "addr_index": 27,
            "tx_hashes": []
        },
        {
            "address": "mnwUsRHDVUjfPJbRye9yhXgctCyJdjbKXU",
            "path": "m/1'/1234/0/92",
            "network": "testnet",
            "change": 0,
            "addr_index": 92,
            "tx_hashes": []
        },
        {
            "address": "mnxS7AKE3PE2MGdKMnu4ZUVAR3dCcvRWCs",
            "path": "m/1'/1234/0/114",
            "network": "testnet",
            "change": 0,
            "addr_index": 114,
            "tx_hashes": []
        },
        {
            "address": "moHN13u4RoMxujdaPxvuaTaawgWZ3LaGyo",
            "path": "m/1'/1234/1/0",
            "network": "testnet",
            "change": 1,
            "addr_index": 0,
            "tx_hashes": [
                "f2e6bc46d8bf08d19854bc8dfde1a3d4968fa8d09f2185ea6e2711ec0ce449ec"
            ]
        },
        {
            "address": "moYk4SHFJQXeyH1N6SMZfcJy3jst1JgPXv",
            "path": "m/1'/1234/0/88",
            "network": "testnet",
            "change": 0,
            "addr_index": 88,
            "tx_hashes": []
        },
        {
            "address": "mofjpvyi5Hn5veLnU6xvWiFvuuN9ABMiez",
            "path": "m/1'/1234/0/10",
            "network": "testnet",
            "change": 0,
            "addr_index": 10,
            "tx_hashes": []
        },
        {
            "address": "moo5ASJxjmYomHXFRsqV9DFdbd9j5Knk2w",
            "path": "m/1'/1234/0/23",
            "network": "testnet",
            "change": 0,
            "addr_index": 23,
            "tx_hashes": []
        },
        {
            "address": "mosHkEQ17EzDbBotFeZdUdw9JymCB6ygdD",
            "path": "m/1'/1234/0/11",
            "network": "testnet",
            "change": 0,
            "addr_index": 11,
            "tx_hashes": []
        },
        {
            "address": "motvDs4CXSEtfqZAig6AiYmQQSSx6tpUs7",
            "path": "m/1'/1234/0/52",
            "network": "testnet",
            "change": 0,
            "addr_index": 52,
            "tx_hashes": []
        },
        {
            "address": "mp1eTBsFMfE1akuhEad4z2GaYLXRxnQ5wR",
            "path": "m/1'/1234/0/16",
            "network": "testnet",
            "change": 0,
            "addr_index": 16,
            "tx_hashes": []
        },
        {
            "address": "mp4jnJRU6JtUFjpdxNKGf5LdG8ZBLyuDnX",
            "path": "m/1'/1234/1/85",
            "network": "testnet",
            "change": 1,
            "addr_index": 85,
            "tx_hashes": []
        },
        {
            "address": "mp7MjuSGBuV4sz7YWdKN65za6ahMvRXvbV",
            "path": "m/1'/1234/0/70",
            "network": "testnet",
            "change": 0,
            "addr_index": 70,
            "tx_hashes": []
        },
        {
            "address": "mp9MMATLEzuJgmCVodLeN385zcB7J4crRR",
            "path": "m/1'/1234/1/5",
            "network": "testnet",
            "change": 1,
            "addr_index": 5,
            "tx_hashes": []
        },
        {
            "address": "mp9QjnKCNZ2QeyePGssYpCZ3cVagCAW6G9",
            "path": "m/1'/1234/1/92",
            "network": "testnet",
            "change": 1,
            "addr_index": 92,
            "tx_hashes": []
        },
        {
            "address": "mp9T4m9veiFRkaB6mqu2JBpRTgF4RnJbBv",
            "path": "m/1'/1234/1/30",
            "network": "testnet",
            "change": 1,
            "addr_index": 30,
            "tx_hashes": []
        },
        {
            "address": "mpMrwsAcYpNV5DsDq3HBv4F45TzZwvFCNo",
            "path": "m/1'/1234/0/20",
            "network": "testnet",
            "change": 0,
            "addr_index": 20,
            "tx_hashes": []
        },
        {
            "address": "mpPHEz5X6mfkGhuGwhEK51Wv6nHM2TjPED",
            "path": "m/1'/1234/1/52",
            "network": "testnet",
            "change": 1,
            "addr_index": 52,
            "tx_hashes": []
        },
        {
            "address": "mpU6xAiBzXYHymccHYjfJjQ8VUsPDZanC8",
            "path": "m/1'/1234/0/80",
            "network": "testnet",
            "change": 0,
            "addr_index": 80,
            "tx_hashes": []
        },
        {
            "address": "mpY7Miopd7hsTfpLzUFssYHjLJdERPHBFv",
            "path": "m/1'/1234/0/51",
            "network": "testnet",
            "change": 0,
            "addr_index": 51,
            "tx_hashes": []
        },
        {
            "address": "mpk446eNYsryipfyK9AxdKBC28pSGC23Pn",
            "path": "m/1'/1234/0/57",
            "network": "testnet",
            "change": 0,
            "addr_index": 57,
            "tx_hashes": []
        },
        {
            "address": "mpkyCtaEhuL9w9HbCdA9MwDyo8rC6VyBBJ",
            "path": "m/1'/1234/1/24",
            "network": "testnet",
            "change": 1,
            "addr_index": 24,
            "tx_hashes": []
        },
        {
            "address": "mpnVuRaDw6K65g5n1kJtPEBJtLhF4gsf8F",
            "path": "m/1'/1234/0/93",
            "network": "testnet",
            "change": 0,
            "addr_index": 93,
            "tx_hashes": []
        },
        {
            "address": "mppV3tmErBc6cfchvrGxVTurpWQMTba72M",
            "path": "m/1'/1234/0/87",
            "network": "testnet",
            "change": 0,
            "addr_index": 87,
            "tx_hashes": []
        },
        {
            "address": "mpt3dnSox3y2B6GcvmqzEhq9thXbpFTN3w",
            "path": "m/1'/1234/1/79",
            "network": "testnet",
            "change": 1,
            "addr_index": 79,
            "tx_hashes": []
        },
        {
            "address": "mpxinSSCvMj4kSQb3HLCWDkw4q3tiQs3u4",
            "path": "m/1'/1234/0/56",
            "network": "testnet",
            "change": 0,
            "addr_index": 56,
            "tx_hashes": []
        },
        {
            "address": "mq9Thu4q58hC9mPmHjcr88FPwN742vteEe",
            "path": "m/1'/1234/0/104",
            "network": "testnet",
            "change": 0,
            "addr_index": 104,
            "tx_hashes": []
        },
        {
            "address": "mq9UNt51a59ak957F954bJLdyvZTNyS6nU",
            "path": "m/1'/1234/0/29",
            "network": "testnet",
            "change": 0,
            "addr_index": 29,
            "tx_hashes": []
        },
        {
            "address": "mqDx2C9mt3aG45LFxwGDs2g1J7HL1v6Noc",
            "path": "m/1'/1234/1/29",
            "network": "testnet",
            "change": 1,
            "addr_index": 29,
            "tx_hashes": []
        },
        {
            "address": "mqFdzF3V3MYg7PSqcexqJsRUHWEDradAHp",
            "path": "m/1'/1234/0/98",
            "network": "testnet",
            "change": 0,
            "addr_index": 98,
            "tx_hashes": []
        },
        {
            "address": "mqRHRhMwGv1eARSicG4Jr2PGjnNomTJvU1",
            "path": "m/1'/1234/0/18",
            "network": "testnet",
            "change": 0,
            "addr_index": 18,
            "tx_hashes": []
        },
        {
            "address": "mqTyj6kBhsSnRoHQrDdX5GkYiAJ8Z2JtYT",
            "path": "m/1'/1234/0/49",
            "network": "testnet",
            "change": 0,
            "addr_index": 49,
            "tx_hashes": []
        },
        {
            "address": "mqXA3V26DQ7V5nMxGXnHYbYX4TTipP853H",
            "path": "m/1'/1234/0/85",
            "network": "testnet",
            "change": 0,
            "addr_index": 85,
            "tx_hashes": []
        },
        {
            "address": "mqbdgR8pkovntrVag3DbqGsMLzQU2as3iR",
            "path": "m/1'/1234/0/46",
            "network": "testnet",
            "change": 0,
            "addr_index": 46,
            "tx_hashes": []
        },
        {
            "address": "mqeXweck99WEnF9uhzymmk8mijE5LrYW9G",
            "path": "m/1'/1234/0/95",
            "network": "testnet",
            "change": 0,
            "addr_index": 95,
            "tx_hashes": []
        },
        {
            "address": "mqvMS1eVvwLuDBu9KJmMTu9NK7kvtGqxro",
            "path": "m/1'/1234/0/45",
            "network": "testnet",
            "change": 0,
            "addr_index": 45,
            "tx_hashes": []
        },
        {
            "address": "mqyEEeArE2VdWcvkRCE14kKPxngJn5vrw3",
            "path": "m/1'/1234/0/17",
            "network": "testnet",
            "change": 0,
            "addr_index": 17,
            "tx_hashes": []
        },
        {
            "address": "mqzRYTKFnWvt39Hu4m5b78ZHnAK2FHn6gb",
            "path": "m/1'/1234/1/25",
            "network": "testnet",
            "change": 1,
            "addr_index": 25,
            "tx_hashes": []
        },
        {
            "address": "mr6ovHpa4XsYiNt8bw3XtcApH7jdXW7eW9",
            "path": "m/1'/1234/0/62",
            "network": "testnet",
            "change": 0,
            "addr_index": 62,
            "tx_hashes": []
        },
        {
            "address": "mr7aZaSHxAtuznkkRUdYo712CstgXqrKCe",
            "path": "m/1'/1234/0/89",
            "network": "testnet",
            "change": 0,
            "addr_index": 89,
            "tx_hashes": []
        },
        {
            "address": "mr8eizdRF395r1fUZMwW8zNeVif7Q98amB",
            "path": "m/1'/1234/0/79",
            "network": "testnet",
            "change": 0,
            "addr_index": 79,
            "tx_hashes": []
        },
        {
            "address": "mrE1BYykjMsuYgD7HVkfZTRx3aGGFx5SR8",
            "path": "m/1'/1234/0/44",
            "network": "testnet",
            "change": 0,
            "addr_index": 44,
            "tx_hashes": []
        },
        {
            "address": "mrJmZ4dnyitSHgY3vyFWNVwyqkSUGFBGTP",
            "path": "m/1'/1234/1/49",
            "network": "testnet",
            "change": 1,
            "addr_index": 49,
            "tx_hashes": []
        },
        {
            "address": "mrKnN6aRKm5YAYX8p2XybawiMLskZJrMXR",
            "path": "m/1'/1234/0/30",
            "network": "testnet",
            "change": 0,
            "addr_index": 30,
            "tx_hashes": []
        },
        {
            "address": "mrPU48eWP35wVcAWHf63eDKW9giqFiWVxC",
            "path": "m/1'/1234/1/34",
            "network": "testnet",
            "change": 1,
            "addr_index": 34,
            "tx_hashes": []
        },
        {
            "address": "mriYno5gzqN8ywsM1tcwpT1oGcZVQjVKSo",
            "path": "m/1'/1234/1/81",
            "network": "testnet",
            "change": 1,
            "addr_index": 81,
            "tx_hashes": []
        },
        {
            "address": "mrkzRJCSmtxXXxxmYnKTDHwkDVSeuuk7kC",
            "path": "m/1'/1234/1/88",
            "network": "testnet",
            "change": 1,
            "addr_index": 88,
            "tx_hashes": []
        },
        {
            "address": "mrofucNwQJsu8hdvFLYtrxbxeLK4MaHd86",
            "path": "m/1'/1234/0/91",
            "network": "testnet",
            "change": 0,
            "addr_index": 91,
            "tx_hashes": []
        },
        {
            "address": "mrqAS4K81RftZ1n6TJPDMMJUzThNZh1SVV",
            "path": "m/1'/1234/1/10",
            "network": "testnet",
            "change": 1,
            "addr_index": 10,
            "tx_hashes": []
        },
        {
            "address": "mrsoYh5mrwXJj9KfoP8DCBZStzPZyV3yxF",
            "path": "m/1'/1234/1/55",
            "network": "testnet",
            "change": 1,
            "addr_index": 55,
            "tx_hashes": []
        },
        {
            "address": "mruXWptxXo5z6UZUZKKJjaRURzHJ5VUftF",
            "path": "m/1'/1234/0/83",
            "network": "testnet",
            "change": 0,
            "addr_index": 83,
            "tx_hashes": []
        },
        {
            "address": "mrwXnJR97ZNpshJ29DVv4eFBMMCRKu1RyF",
            "path": "m/1'/1234/0/72",
            "network": "testnet",
            "change": 0,
            "addr_index": 72,
            "tx_hashes": []
        },
        {
            "address": "mrzFvDuYEs5k4N8xzEPBoWT1gTWFN7ZbuB",
            "path": "m/1'/1234/1/87",
            "network": "testnet",
            "change": 1,
            "addr_index": 87,
            "tx_hashes": []
        },
        {
            "address": "mrzk5FmMx45GMpGQCHN9sLcu4KkBJ3SQoA",
            "path": "m/1'/1234/0/65",
            "network": "testnet",
            "change": 0,
            "addr_index": 65,
            "tx_hashes": []
        },
        {
            "address": "mrzkhstGYAJqXH7e7LfADSwp5fHnUNm7yN",
            "path": "m/1'/1234/1/80",
            "network": "testnet",
            "change": 1,
            "addr_index": 80,
            "tx_hashes": []
        },
        {
            "address": "ms2f9UsMBE1n71kDZrH2yiUTSCoaS3C1sX",
            "path": "m/1'/1234/0/22",
            "network": "testnet",
            "change": 0,
            "addr_index": 22,
            "tx_hashes": []
        },
        {
            "address": "ms5JDaW3P7WDxXmBiMcj7ZH8Xevq3ZAJFa",
            "path": "m/1'/1234/0/118",
            "network": "testnet",
            "change": 0,
            "addr_index": 118,
            "tx_hashes": []
        },
        {
            "address": "msESZ1NKuCBMpk5aF5ExK5spiPvLjjbPgw",
            "path": "m/1'/1234/0/54",
            "network": "testnet",
            "change": 0,
            "addr_index": 54,
            "tx_hashes": []
        },
        {
            "address": "msFYTUMb4WqwWXUDBXkYzWkxcMsjqS2xCn",
            "path": "m/1'/1234/1/42",
            "network": "testnet",
            "change": 1,
            "addr_index": 42,
            "tx_hashes": []
        },
        {
            "address": "msTVNykCYKL3ipCnPkUWD1RepW3zQD1nDf",
            "path": "m/1'/1234/0/75",
            "network": "testnet",
            "change": 0,
            "addr_index": 75,
            "tx_hashes": []
        },
        {
            "address": "mscgVLhdDXKBc6dtKfNoPXfTmDqkeu5ysv",
            "path": "m/1'/1234/1/97",
            "network": "testnet",
            "change": 1,
            "addr_index": 97,
            "tx_hashes": []
        },
        {
            "address": "msiEtXVMb5vt83zMYPaBosnKzvQ1i8Nycj",
            "path": "m/1'/1234/1/75",
            "network": "testnet",
            "change": 1,
            "addr_index": 75,
            "tx_hashes": []
        },
        {
            "address": "mskQduVL7QBZCEWJUit8u9N8Cj4CFouPWX",
            "path": "m/1'/1234/0/19",
            "network": "testnet",
            "change": 0,
            "addr_index": 19,
            "tx_hashes": [
                "77bddf5ea1feef8eaf52375fdda8e08a5df6a581d0f34f5b3a849448f54c8d83"
            ]
        },
        {
            "address": "msvuWQLQw9wyEFg4kEFMYyrinaurPPqta9",
            "path": "m/1'/1234/1/44",
            "network": "testnet",
            "change": 1,
            "addr_index": 44,
            "tx_hashes": []
        },
        {
            "address": "mt1erM5cCp66z9YtRd8cHvSdQywM5ad1ab",
            "path": "m/1'/1234/1/41",
            "network": "testnet",
            "change": 1,
            "addr_index": 41,
            "tx_hashes": []
        },
        {
            "address": "mt2ZjRQfAQKF1f2Gte82ABGYR5KCqeqcmz",
            "path": "m/1'/1234/0/113",
            "network": "testnet",
            "change": 0,
            "addr_index": 113,
            "tx_hashes": []
        },
        {
            "address": "mt5k6nJnZFNLsZaoDuTcxf1kz1DGpj2xBQ",
            "path": "m/1'/1234/0/31",
            "network": "testnet",
            "change": 0,
            "addr_index": 31,
            "tx_hashes": []
        },
        {
            "address": "mtDYtVtSYRvgakwgf6Upawq3ijKCe8HE4F",
            "path": "m/1'/1234/1/18",
            "network": "testnet",
            "change": 1,
            "addr_index": 18,
            "tx_hashes": []
        },
        {
            "address": "mtNKHAT3fKCT9zSe69szyUbFqEWH7YtyPT",
            "path": "m/1'/1234/1/72",
            "network": "testnet",
            "change": 1,
            "addr_index": 72,
            "tx_hashes": []
        },
        {
            "address": "mtTDS4ifBzEVqwYj1mD26mrrsod7bSzijA",
            "path": "m/1'/1234/1/40",
            "network": "testnet",
            "change": 1,
            "addr_index": 40,
            "tx_hashes": []
        },
        {
            "address": "mth1ebF5qiGeQdxAyAmQgk3yNf7FLTQ54f",
            "path": "m/1'/1234/0/43",
            "network": "testnet",
            "change": 0,
            "addr_index": 43,
            "tx_hashes": []
        },
        {
            "address": "mth6eDXa7Yx6Bccci6j2PfgWgGVPZYw8qo",
            "path": "m/1'/1234/1/3",
            "network": "testnet",
            "change": 1,
            "addr_index": 3,
            "tx_hashes": []
        },
        {
            "address": "mtkqSGHacariaSmCYXjcb4nLHVJ58mWFQa",
            "path": "m/1'/1234/1/78",
            "network": "testnet",
            "change": 1,
            "addr_index": 78,
            "tx_hashes": []
        },
        {
            "address": "mtrbVX1MLVwjJwhLgMP2hLPUkdduUR9Kty",
            "path": "m/1'/1234/0/53",
            "network": "testnet",
            "change": 0,
            "addr_index": 53,
            "tx_hashes": []
        },
        {
            "address": "mtwTkqd8KX2xLhcrrDcTvkaoFAWgPEo5Cj",
            "path": "m/1'/1234/0/116",
            "network": "testnet",
            "change": 0,
            "addr_index": 116,
            "tx_hashes": []
        },
        {
            "address": "mtwTrVKh4E1Xancvxx59xaJsV5Kn7zVVSA",
            "path": "m/1'/1234/1/19",
            "network": "testnet",
            "change": 1,
            "addr_index": 19,
            "tx_hashes": []
        },
        {
            "address": "mtyw6R4vXcnHNj4DPLaz5UcXa8hhMfXEpP",
            "path": "m/1'/1234/0/41",
            "network": "testnet",
            "change": 0,
            "addr_index": 41,
            "tx_hashes": []
        },
        {
            "address": "muGDdgcwgj1oVmMX6vR1FqTMeeKb5JhgQX",
            "path": "m/1'/1234/1/74",
            "network": "testnet",
            "change": 1,
            "addr_index": 74,
            "tx_hashes": []
        },
        {
            "address": "muRPtvEdEiHU5K9V2TiTrkVCK1fR8SgPYC",
            "path": "m/1'/1234/1/77",
            "network": "testnet",
            "change": 1,
            "addr_index": 77,
            "tx_hashes": []
        },
        {
            "address": "murQifvdqKxaWZoLNdZ72XkJeqB55oWS6j",
            "path": "m/1'/1234/0/42",
            "network": "testnet",
            "change": 0,
            "addr_index": 42,
            "tx_hashes": []
        },
        {
            "address": "muvmkzDG6UmLX2MsfrhZ4pksk1KEawyZ1B",
            "path": "m/1'/1234/1/12",
            "network": "testnet",
            "change": 1,
            "addr_index": 12,
            "tx_hashes": []
        },
        {
            "address": "muxFaecKfqKt98G4VNUyqEVwVvqoPAtspj",
            "path": "m/1'/1234/1/11",
            "network": "testnet",
            "change": 1,
            "addr_index": 11,
            "tx_hashes": []
        },
        {
            "address": "muzujo9NwJYE1tACwzSRZiDgCkumsA1DEh",
            "path": "m/1'/1234/1/98",
            "network": "testnet",
            "change": 1,
            "addr_index": 98,
            "tx_hashes": []
        },
        {
            "address": "mv5dfNyTKMwED5g26LMZJYwN5QckEXrqe2",
            "path": "m/1'/1234/1/2",
            "network": "testnet",
            "change": 1,
            "addr_index": 2,
            "tx_hashes": [
                "df47e4bf599ecf27d8f3b34e85fcd7384d753823208d06171ff16899bc1709ce"
            ]
        },
        {
            "address": "mv6HgQTYwfNYsZmr9jcxK2wA9cfQunVuV8",
            "path": "m/1'/1234/1/14",
            "network": "testnet",
            "change": 1,
            "addr_index": 14,
            "tx_hashes": []
        },
        {
            "address": "mvAbNajPbcHp4qJ41TnW2rnAhrXwabt6Br",
            "path": "m/1'/1234/1/63",
            "network": "testnet",
            "change": 1,
            "addr_index": 63,
            "tx_hashes": []
        },
        {
            "address": "mvEno3oRvHpJQRVdJ67QFsWQZcXnqBXd8A",
            "path": "m/1'/1234/0/107",
            "network": "testnet",
            "change": 0,
            "addr_index": 107,
            "tx_hashes": []
        },
        {
            "address": "mvNTkMyRAFDtWZeCg48y5NUqjKovkVHd3v",
            "path": "m/1'/1234/1/61",
            "network": "testnet",
            "change": 1,
            "addr_index": 61,
            "tx_hashes": []
        },
        {
            "address": "mvaqsto6jVBUTX7Fxgzx6GW3un94xuGW3D",
            "path": "m/1'/1234/1/9",
            "network": "testnet",
            "change": 1,
            "addr_index": 9,
            "tx_hashes": []
        },
        {
            "address": "mveavhcorRjFUnnBoi6AY13U7hdjA7ucPA",
            "path": "m/1'/1234/0/69",
            "network": "testnet",
            "change": 0,
            "addr_index": 69,
            "tx_hashes": []
        },
        {
            "address": "mvwZE9bqfoy1gzE3s2whuw5kiJWuArvajN",
            "path": "m/1'/1234/1/64",
            "network": "testnet",
            "change": 1,
            "addr_index": 64,
            "tx_hashes": []
        },
        {
            "address": "mw1k8k5yRiVbE8cGpGoxwyxEfZPt8Vh8T1",
            "path": "m/1'/1234/1/60",
            "network": "testnet",
            "change": 1,
            "addr_index": 60,
            "tx_hashes": []
        },
        {
            "address": "mwA4LShWwYsLWtN24qPMNLuzUBEUCy1SUV",
            "path": "m/1'/1234/1/13",
            "network": "testnet",
            "change": 1,
            "addr_index": 13,
            "tx_hashes": []
        },
        {
            "address": "mwCGFyMPHYzYsXFCXEZKncTy7VTDMzemC8",
            "path": "m/1'/1234/0/101",
            "network": "testnet",
            "change": 0,
            "addr_index": 101,
            "tx_hashes": []
        },
        {
            "address": "mwEAAdykUVGQU51X9H4yk6KLcBhCHFbpj9",
            "path": "m/1'/1234/0/108",
            "network": "testnet",
            "change": 0,
            "addr_index": 108,
            "tx_hashes": []
        },
        {
            "address": "mwWcaS79Gnx93nwtsPV6vs559wzN2moxCo",
            "path": "m/1'/1234/1/26",
            "network": "testnet",
            "change": 1,
            "addr_index": 26,
            "tx_hashes": []
        },
        {
            "address": "mwZZvqyWkhjq7o399R7K4Rr5Hk674DTryA",
            "path": "m/1'/1234/0/73",
            "network": "testnet",
            "change": 0,
            "addr_index": 73,
            "tx_hashes": []
        },
        {
            "address": "mwfNyfjegvwoPvygYpAKugbHozUttjanvT",
            "path": "m/1'/1234/0/105",
            "network": "testnet",
            "change": 0,
            "addr_index": 105,
            "tx_hashes": []
        },
        {
            "address": "mwgXcj5Pz96UwD37enQ5GyiWmLUfMyH7mF",
            "path": "m/1'/1234/0/102",
            "network": "testnet",
            "change": 0,
            "addr_index": 102,
            "tx_hashes": []
        },
        {
            "address": "mwiGFquFDNhCE7z66xU1GPZxr3Vr838ayJ",
            "path": "m/1'/1234/0/8",
            "network": "testnet",
            "change": 0,
            "addr_index": 8,
            "tx_hashes": []
        },
        {
            "address": "mwwE6di2VoZuoespVUAkcWMkchuC3ouukv",
            "path": "m/1'/1234/0/112",
            "network": "testnet",
            "change": 0,
            "addr_index": 112,
            "tx_hashes": []
        },
        {
            "address": "mwyxsPfSrWEsbtnAqn82FY8rL7hNdL3VmQ",
            "path": "m/1'/1234/0/39",
            "network": "testnet",
            "change": 0,
            "addr_index": 39,
            "tx_hashes": []
        },
        {
            "address": "mxBqGqtGwqqLvaNJ1AcLcfMiCruXu8GCkX",
            "path": "m/1'/1234/1/101",
            "network": "testnet",
            "change": 1,
            "addr_index": 101,
            "tx_hashes": []
        },
        {
            "address": "mxFCGy4UGM7U32UNQs2ZC3h1vBfb8rUUgq",
            "path": "m/1'/1234/1/48",
            "network": "testnet",
            "change": 1,
            "addr_index": 48,
            "tx_hashes": []
        },
        {
            "address": "mxPDcrdY7vTC7GBiu31g5xNtWVyiuVgF6A",
            "path": "m/1'/1234/1/20",
            "network": "testnet",
            "change": 1,
            "addr_index": 20,
            "tx_hashes": []
        },
        {
            "address": "mxcJppiQL2NSYmLJUWmqKjAVQ5ryBfK8M4",
            "path": "m/1'/1234/1/32",
            "network": "testnet",
            "change": 1,
            "addr_index": 32,
            "tx_hashes": []
        },
        {
            "address": "mxmWr8evxoXVUVSg9tCjdc4Uxv5oompHyv",
            "path": "m/1'/1234/0/60",
            "network": "testnet",
            "change": 0,
            "addr_index": 60,
            "tx_hashes": []
        },
        {
            "address": "mxvsvBsrVW8tPLfcUZUVEwdbkRXaEetXzX",
            "path": "m/1'/1234/0/84",
            "network": "testnet",
            "change": 0,
            "addr_index": 84,
            "tx_hashes": []
        },
        {
            "address": "mxzp9QJkS6c8Roc1WxXMRbwHKjN3hzozWv",
            "path": "m/1'/1234/0/59",
            "network": "testnet",
            "change": 0,
            "addr_index": 59,
            "tx_hashes": []
        },
        {
            "address": "my1FMCXyo84tC1LkFXX8LctbtpycUmUnPx",
            "path": "m/1'/1234/0/3",
            "network": "testnet",
            "change": 0,
            "addr_index": 3,
            "tx_hashes": [
                "7d9abe7323077358acfb80ef2ec0374a37c07bc097609c48da486d6a9266581e",
                "f2e6bc46d8bf08d19854bc8dfde1a3d4968fa8d09f2185ea6e2711ec0ce449ec"
            ]
        },
        {
            "address": "my3U16MBzNVyUaEzibEdoUdYkLcubNgi8s",
            "path": "m/1'/1234/1/67",
            "network": "testnet",
            "change": 1,
            "addr_index": 67,
            "tx_hashes": []
        },
        {
            "address": "myDwY4oQ6HLz3u2tW1b23sg2T7QYqDw5dV",
            "path": "m/1'/1234/1/23",
            "network": "testnet",
            "change": 1,
            "addr_index": 23,
            "tx_hashes": []
        },
        {
            "address": "myEyz9WPaZmXqnhtN86xM8S66wVysBRNtN",
            "path": "m/1'/1234/0/15",
            "network": "testnet",
            "change": 0,
            "addr_index": 15,
            "tx_hashes": [
                "acffdca982d1ce6fcd1f51dbb9dda686441058f93686008a2c446c42a94a66a7",
                "df47e4bf599ecf27d8f3b34e85fcd7384d753823208d06171ff16899bc1709ce"
            ]
        },
        {
            "address": "myQVApRvQgKm4snLmMPeheni6K2KmESAgu",
            "path": "m/1'/1234/1/28",
            "network": "testnet",
            "change": 1,
            "addr_index": 28,
            "tx_hashes": []
        },
        {
            "address": "myXa6suFx4dqSyRKwMHqkkrpPFqhEHgvhB",
            "path": "m/1'/1234/0/117",
            "network": "testnet",
            "change": 0,
            "addr_index": 117,
            "tx_hashes": []
        },
        {
            "address": "myZRdPAtn9mkR6iGe41wbPbQ6pEKGEd7DR",
            "path": "m/1'/1234/0/97",
            "network": "testnet",
            "change": 0,
            "addr_index": 97,
            "tx_hashes": []
        },
        {
            "address": "mybf8GEdfxqBRhzwPMfxu1LNnCWoR2oSro",
            "path": "m/1'/1234/0/13",
            "network": "testnet",
            "change": 0,
            "addr_index": 13,
            "tx_hashes": []
        },
        {
            "address": "myfv2zdA8Fe7PaGACv5yXn3Bm2JpLBAdfE",
            "path": "m/1'/1234/0/96",
            "network": "testnet",
            "change": 0,
            "addr_index": 96,
            "tx_hashes": []
        },
        {
            "address": "mymP5DUfubfRzNfhGyguTrqb93VYvX13NY",
            "path": "m/1'/1234/0/99",
            "network": "testnet",
            "change": 0,
            "addr_index": 99,
            "tx_hashes": []
        },
        {
            "address": "mz37noAanMGMW1BMGvyhNnY1fqfTg726Ka",
            "path": "m/1'/1234/0/1",
            "network": "testnet",
            "change": 0,
            "addr_index": 1,
            "tx_hashes": [
                "820198df9af70251fdfcc3cae3f2995f09093a1677e6ac7800f6417d6679e929"
            ]
        },
        {
            "address": "mzLPXBnBRszfNRagBhPkn3fruUbfAMR7SZ",
            "path": "m/1'/1234/1/31",
            "network": "testnet",
            "change": 1,
            "addr_index": 31,
            "tx_hashes": []
        },
        {
            "address": "mzM6TL37rneU98z7CMuw9r9t6d5MPjeqVm",
            "path": "m/1'/1234/0/40",
            "network": "testnet",
            "change": 0,
            "addr_index": 40,
            "tx_hashes": []
        },
        {
            "address": "mzMF12VsXCL23ov7RwSbZdVnLzJ1MnxEzT",
            "path": "m/1'/1234/0/5",
            "network": "testnet",
            "change": 0,
            "addr_index": 5,
            "tx_hashes": []
        },
        {
            "address": "mzMu7Rd3StZhMQYxX2QR5MrjmPAQeLE6xY",
            "path": "m/1'/1234/1/86",
            "network": "testnet",
            "change": 1,
            "addr_index": 86,
            "tx_hashes": []
        },
        {
            "address": "mzP6VxjWxnfNSXerXXz8Hpr76rytF3EkmU",
            "path": "m/1'/1234/1/90",
            "network": "testnet",
            "change": 1,
            "addr_index": 90,
            "tx_hashes": []
        },
        {
            "address": "mzPCbXLqiHLNhVj6reah8VWXVT8X69Ssuf",
            "path": "m/1'/1234/0/2",
            "network": "testnet",
            "change": 0,
            "addr_index": 2,
            "tx_hashes": [
                "60014a64f5c808ce7af726ae28e60ad986dff519a5d8014528df39976b10d705"
            ]
        },
        {
            "address": "mzQinQemMnnfKtJmqvnwC4PcvmJrKxnSMi",
            "path": "m/1'/1234/0/9",
            "network": "testnet",
            "change": 0,
            "addr_index": 9,
            "tx_hashes": []
        },
        {
            "address": "mzgzBJxEZATE9npaMi1yXYsGxRHqTq8cWL",
            "path": "m/1'/1234/0/66",
            "network": "testnet",
            "change": 0,
            "addr_index": 66,
            "tx_hashes": []
        },
        {
            "address": "mzi6HLho5eRptPscGUWnqndv4Wddcaw5vT",
            "path": "m/1'/1234/0/50",
            "network": "testnet",
            "change": 0,
            "addr_index": 50,
            "tx_hashes": []
        },
        {
            "address": "mzoeuyGqMudyvKbkNx5dtNBNN59oKEAsPn",
            "path": "m/1'/1234/0/0",
            "network": "testnet",
            "change": 0,
            "addr_index": 0,
            "tx_hashes": [
                "ac3b83a9f90f73c7cac1e07b017d5c78ce6c79e74a0d72a6c80e84fb0adeb6ba",
                "d2ccea06bad8711a1c95e66f1b3a8d658c447a061c856cf284075f7a152d45fb"
            ]
        },
        {
            "address": "n14trLkKhqU53tvR8f6kohGTH128EiVaXk",
            "path": "m/1'/1234/0/35",
            "network": "testnet",
            "change": 0,
            "addr_index": 35,
            "tx_hashes": []
        },
        {
            "address": "n1Bw5SsvMHpfhTz8NghK4t7qcQ2rwLbpga",
            "path": "m/1'/1234/1/51",
            "network": "testnet",
            "change": 1,
            "addr_index": 51,
            "tx_hashes": []
        },
        {
            "address": "n1Bz6vRenfopHFKHY8EBwUxxxWiY2E5hwV",
            "path": "m/1'/1234/0/58",
            "network": "testnet",
            "change": 0,
            "addr_index": 58,
            "tx_hashes": []
        },
        {
            "address": "n1EstV7h4Jyx1XKLY7fdx6ufFRMxBVdieN",
            "path": "m/1'/1234/0/6",
            "network": "testnet",
            "change": 0,
            "addr_index": 6,
            "tx_hashes": [
                "f49001a572942a506bd414c51f5a0e9cd349899d05c868b1de2fa6742a66d5aa"
            ]
        },
        {
            "address": "n1GohMiYdx8Q8PSBynH34vdgZXH1tid7cW",
            "path": "m/1'/1234/0/4",
            "network": "testnet",
            "change": 0,
            "addr_index": 4,
            "tx_hashes": [
                "6b344d0823c3f3ff1e084232674320e1409a12d2af50a6320063cd8cf5797e9a",
                "75b465e8785b87fe11b625f5fd030e4f314c028c25b3ea84ae96bb1a3d369796"
            ]
        },
        {
            "address": "n1iKWWj6cH9UXSxpXBgn9XYx5rTv45NFB1",
            "path": "m/1'/1234/0/32",
            "network": "testnet",
            "change": 0,
            "addr_index": 32,
            "tx_hashes": []
        },
        {
            "address": "n1rH2G1VjPNgTD24h5tZXgo8pqvuCdyEUs",
            "path": "m/1'/1234/0/34",
            "network": "testnet",
            "change": 0,
            "addr_index": 34,
            "tx_hashes": []
        },
        {
            "address": "n1rvn6484NvPXtfwQyQoGicXKSWxnJY5oh",
            "path": "m/1'/1234/1/50",
            "network": "testnet",
            "change": 1,
            "addr_index": 50,
            "tx_hashes": []
        },
        {
            "address": "n1sFJNToHZojWVnkz65H1ZjUbWJBs5Fdy2",
            "path": "m/1'/1234/0/100",
            "network": "testnet",
            "change": 0,
            "addr_index": 100,
            "tx_hashes": []
        },
        {
            "address": "n1y9yLpqQk68R34CW6xGnssiRjWbsrsjNB",
            "path": "m/1'/1234/1/96",
            "network": "testnet",
            "change": 1,
            "addr_index": 96,
            "tx_hashes": []
        },
        {
            "address": "n1zC5hkhcYdNVSx8pztiqZSNbFrGjbKun2",
            "path": "m/1'/1234/1/36",
            "network": "testnet",
            "change": 1,
            "addr_index": 36,
            "tx_hashes": []
        },
        {
            "address": "n234ZK9Kt3fzjpntiTepFQP8m1WUj1kV3i",
            "path": "m/1'/1234/1/46",
            "network": "testnet",
            "change": 1,
            "addr_index": 46,
            "tx_hashes": []
        },
        {
            "address": "n23P5CnY3dwZuGx1u5tEYLK3an2XsAE9GL",
            "path": "m/1'/1234/0/78",
            "network": "testnet",
            "change": 0,
            "addr_index": 78,
            "tx_hashes": []
        },
        {
            "address": "n2AYb9qVFmBtyBQSUonFMcaqo1pXDwhHKC",
            "path": "m/1'/1234/0/24",
            "network": "testnet",
            "change": 0,
            "addr_index": 24,
            "tx_hashes": []
        },
        {
            "address": "n2JQXfzuVyFygt2aK6MG5XXMGegVMMzbFW",
            "path": "m/1'/1234/0/47",
            "network": "testnet",
            "change": 0,
            "addr_index": 47,
            "tx_hashes": []
        },
        {
            "address": "n2NEWUDyKTDpSZa9jzP2TWywRUAFuU3aVF",
            "path": "m/1'/1234/0/90",
            "network": "testnet",
            "change": 0,
            "addr_index": 90,
            "tx_hashes": []
        },
        {
            "address": "n2QtR7UYnNvPZPJCXxsXm4xELfWmdS9KC4",
            "path": "m/1'/1234/1/99",
            "network": "testnet",
            "change": 1,
            "addr_index": 99,
            "tx_hashes": []
        },
        {
            "address": "n2TuRXSL1yTxs9PaB5sueEwcrPkd2Q2P6B",
            "path": "m/1'/1234/0/94",
            "network": "testnet",
            "change": 0,
            "addr_index": 94,
            "tx_hashes": []
        },
        {
            "address": "n2X8igCsDFvqRXBYuBdYnTG6L7ZqWaUpWc",
            "path": "m/1'/1234/1/38",
            "network": "testnet",
            "change": 1,
            "addr_index": 38,
            "tx_hashes": []
        },
        {
            "address": "n2aNi43rgX8YD5NMJK55dgHp7n7rdGzbYj",
            "path": "m/1'/1234/1/1",
            "network": "testnet",
            "change": 1,
            "addr_index": 1,
            "tx_hashes": [
                "bd09a74381ffad78c162976ec27fc9c1dceda3c2bfe367541a7140b8dd6e1f4c"
            ]
        },
        {
            "address": "n2eB9gA1ywoUh1tszRSwBHTW4kunQqCPJm",
            "path": "m/1'/1234/1/6",
            "network": "testnet",
            "change": 1,
            "addr_index": 6,
            "tx_hashes": []
        },
        {
            "address": "n2fo4VZADUoboCbGhyw3Rrp5s9HtdeiS1L",
            "path": "m/1'/1234/0/12",
            "network": "testnet",
            "change": 0,
            "addr_index": 12,
            "tx_hashes": []
        },
        {
            "address": "n2krZjLK1msP3m9iNCHYAVRkW8enVX3KqK",
            "path": "m/1'/1234/0/81",
            "network": "testnet",
            "change": 0,
            "addr_index": 81,
            "tx_hashes": []
        },
        {
            "address": "n2v2BmxR3exxQFGuYXnsBqJWmpv5yfBZch",
            "path": "m/1'/1234/1/37",
            "network": "testnet",
            "change": 1,
            "addr_index": 37,
            "tx_hashes": []
        },
        {
            "address": "n2wNGGF9mm4Dfc1YoPUaMYwMjPmxkcXvB7",
            "path": "m/1'/1234/1/84",
            "network": "testnet",
            "change": 1,
            "addr_index": 84,
            "tx_hashes": []
        },
        {
            "address": "n34T3oB2u9BEWwSCMujSyr13umHGtRAnYa",
            "path": "m/1'/1234/0/36",
            "network": "testnet",
            "change": 0,
            "addr_index": 36,
            "tx_hashes": []
        },
        {
            "address": "n3Ps57oVeysLKB1bzDVLSKEMHmUoVhL2xC",
            "path": "m/1'/1234/1/65",
            "network": "testnet",
            "change": 1,
            "addr_index": 65,
            "tx_hashes": []
        },
        {
            "address": "n3c52Bp8nperb72Ub9mi7pWgtiGm1SKVE9",
            "path": "m/1'/1234/0/76",
            "network": "testnet",
            "change": 0,
            "addr_index": 76,
            "tx_hashes": []
        },
        {
            "address": "n3dXhVju9R2kJPjhnZME2E1yiQm1Scq6yn",
            "path": "m/1'/1234/0/21",
            "network": "testnet",
            "change": 0,
            "addr_index": 21,
            "tx_hashes": []
        },
        {
            "address": "n3dsSCmWNsg3Xb3yD4zKqMor2F6c1JHjJu",
            "path": "m/1'/1234/1/54",
            "network": "testnet",
            "change": 1,
            "addr_index": 54,
            "tx_hashes": []
        },
        {
            "address": "n3kUJbGHZKm5oCU4XWS4tUaAf7XqpGtLxQ",
            "path": "m/1'/1234/1/76",
            "network": "testnet",
            "change": 1,
            "addr_index": 76,
            "tx_hashes": []
        },
        {
            "address": "n3xqY2WwtZ64kJ7y7MWJDAZEt6KotqLyqe",
            "path": "m/1'/1234/1/69",
            "network": "testnet",
            "change": 1,
            "addr_index": 69,
            "tx_hashes": []
        },
        {
            "address": "n46v3LvVf5q8ytgJYEYWfPbNrHJjg78Fp1",
            "path": "m/1'/1234/1/56",
            "network": "testnet",
            "change": 1,
            "addr_index": 56,
            "tx_hashes": []
        },
        {
            "address": "n47c8ma14yQAhjCCrLmHxTSKuLgEEjFDsK",
            "path": "m/1'/1234/1/35",
            "network": "testnet",
            "change": 1,
            "addr_index": 35,
            "tx_hashes": []
        },
        {
            "address": "n47vcpTx38g4hKbfFximHnxrSkDs9G6xb2",
            "path": "m/1'/1234/0/64",
            "network": "testnet",
            "change": 0,
            "addr_index": 64,
            "tx_hashes": []
        },
        {
            "address": "n4FWvGyuimxGjQJd7ZWht56vF3nudxYVeo",
            "path": "m/1'/1234/0/25",
            "network": "testnet",
            "change": 0,
            "addr_index": 25,
            "tx_hashes": []
        },
        {
            "address": "n4JwUCCNtmpTjgcpALtVsZRT8zmqNuKRuV",
            "path": "m/1'/1234/0/77",
            "network": "testnet",
            "change": 0,
            "addr_index": 77,
            "tx_hashes": []
        },
        {
            "address": "n4X23dNHutdq9ANMzfbr4Dt6c8FCU2V6kg",
            "path": "m/1'/1234/1/71",
            "network": "testnet",
            "change": 1,
            "addr_index": 71,
            "tx_hashes": []
        },
        {
            "address": "n4Yt3Wng8waeykRC8Tgr1JQ6Gz5SQFZaYD",
            "path": "m/1'/1234/1/7",
            "network": "testnet",
            "change": 1,
            "addr_index": 7,
            "tx_hashes": []
        },
        {
            "address": "n4Z9HtF2YWZQgHuoWCTrm5cjNjEaoYZ3nU",
            "path": "m/1'/1234/1/62",
            "network": "testnet",
            "change": 1,
            "addr_index": 62,
            "tx_hashes": []
        },
        {
            "address": "n4rT8fSspf7WRSE46drbdEPjyYvncbrdgz",
            "path": "m/1'/1234/0/27",
            "network": "testnet",
            "change": 0,
            "addr_index": 27,
            "tx_hashes": []
        }
    ],
    "transactions": [
        {
            "hash": "5554c15d13002786a70a7151aad4eddce76633c60bc7f90e3dc70eb4f9c4b2b0",
            "height": 1414324,
            "hex": "0100000001c83c4eaf22da0d76cde59dac7a9938a8e08d3dceadd8ca7d89cdedb6c05393f5000000006b4830450221009919e035d23b9766b0042c3edf2f6215d2286ed37ab7dff4e9e82322de14eafe0220207ed9d98f8fc1e845b1e499e34dfb57b98df0f8928ef394b6b1b5cce780b3dc0121029f60b3dc24028d9691d66332aef968c3c2c253a7a296f5d520b6e547f0ef44eefeffffff0380969800000000001976a9141b9a8107f5f50cc8e23696463bf53c4350ab4b2f88ac002d3101000000001976a9141b9a8107f5f50cc8e23696463bf53c4350ab4b2f88accc064f01000000001976a914c1f9b2c439390d03e31af23fc644dc2c328cf00f88acb3941500"
        },
        {
            "hash": "60014a64f5c808ce7af726ae28e60ad986dff519a5d8014528df39976b10d705",
            "height": 1414323,
            "hex": "010000000167f30ff3b6b69cc720aabcf82c3e393d748d416edd449d4e90bf23836beb2fb2000000006b483045022100fcf379dbebdd4454e008f185cb7495fd0ed121c77a3bd0bf440e638a0bac1f040220021c649aea9b327265c639fb2441bdf029e7271b0306d7c03a3b82ee689446390121024fb6ed463d79ec0054754c0f83daeab09b486ae402c76235c2e38bd36e92fb99feffffff0380969800000000001976a914cef3000fea380079b0f0f9ac42a0d02865f969d588ac002d3101000000001976a914cef3000fea380079b0f0f9ac42a0d02865f969d588ac74714101000000001976a9147b095685f1d510541d85e4dff8522492b92155b688acb2941500"
        },
        {
            "hash": "6b344d0823c3f3ff1e084232674320e1409a12d2af50a6320063cd8cf5797e9a",
            "height": 1414324,
            "hex": "01000000011261d81baeda09130ac8335670dcd09cfcc79ec7b694908d99d8db0f9c3ff538000000006a473044022009ea4b27feb568599ecedfab05e500c1a5e606d0e2b377e2172a84d4c951145d022004e30f4e79dd821ad87bba5f51b65ba2409ee90137a366fa705646262c7c3ef3012103fc65f6bb061aa539fd3d77605d19a645fedb4f5b9cd55c793930f6b47eca3bb1feffffff0240420f00000000001976a914d8b583c92d10515efe9fe2207ec2add7efd004f588ac105b8500000000001976a91485db998e1b0efb278cbf8836918a6d7bb87723f688acb3941500"
        },
        {
            "hash": "75b465e8785b87fe11b625f5fd030e4f314c028c25b3ea84ae96bb1a3d369796",
            "height": 1414324,
            "hex": "01000000019a7e79f58ccd630032a650afd2129a40e12043673242081efff3c323084d346b000000006a473044022023d0afcb1189ce37db32e9a6b34e614112475a2215087ca73ba00b803da4fa1702206017ac791bf31003a0fc2fa158e3064eaf09e23c1ed7ee817d32c41c458172dc0121028f95f33011dd9c58e21b9d0fdae9e5fb191ea359d5a88d7b112f57d61061e912feffffff0100350c00000000001976a9143b16eb02e1a6bd4d7acd422981b627467de27bf988acb3941500"
        },
        {
            "hash": "77bddf5ea1feef8eaf52375fdda8e08a5df6a581d0f34f5b3a849448f54c8d83",
            "height": 1414325,
            "hex": "01000000010d6d83612869cb1e9c9c5eedc562051a31e62dff2e891cf76fb2145500098561010000006b483045022100a2d8a549f332c26f88c80946b8b7ca41b005c9b309f38efd63f76601fb57aaba022063563fce96f575a70cb24433faa77c321a85539411b7cb2b489fadff13b613c60121024c7300c2c72f1c093ddfeb804e100c6829ab808df4d424c5dad5d217ea35f51ffeffffff0240420f00000000001976a914862ce8053a5fe68982bd024d1056672a07f40c1588ac84ec1a01000000001976a914862f9e457fa471d9869bebb0da6f796c4d19c50288acb4941500"
        },
        {
            "hash": "7d9abe7323077358acfb80ef2ec0374a37c07bc097609c48da486d6a9266581e",
            "height": 1414324,
            "hex": "0100000001d1cf29d4fcfff1715da9923d845c609a59b21fc90aba8c2ce87021bb14156ff6000000006a473044022000fd83bda85b19a05d58ee622843e6ffecd980071bde1ed94f64bc399c7363a102204dc17ee9c013d4d908dda03a542ae096141d941c8b85d13be9daa26a8a109e960121025c7aca87b69cf7e218304870aa2a6e7728bf02c27ad260eb701218d17bc078fbfeffffff0240420f00000000001976a914bfd4057b55dc53aee566594fc3a75e32e726f2ae88acfc031e00000000001976a914f855559d7dc8ebef46040c2267ce16edc70bc50688acb3941500"
        },
        {
            "hash": "820198df9af70251fdfcc3cae3f2995f09093a1677e6ac7800f6417d6679e929",
            "height": 1414323,
            "hex": "0200000001a074c52fe346ea647e375b3c4022c29602d3f65170535ef208c55d0e9b3e066b0100000017160014a908377801306d6ebe1e01561dae031114788571feffffff02472cef00000000001976a914cb26ab61b853a553c7adeaa01bc2686c0a76759a88ac5cb215f57100000017a914d3da18055b22d2f9283f643d14cc257ba3b4380e87b2941500"
        },
        {
            "hash": "ac3b83a9f90f73c7cac1e07b017d5c78ce6c79e74a0d72a6c80e84fb0adeb6ba",
            "height": 1414323,
            "hex": "01000000013a58f1fad756f5dc31eb0dee4c8667dad67f88fe31e72468876a2c55fa9cc2c7010000006a47304402203c15565344616ddee3c8b29c6f7dfe8328604fb0af99d75b96e8114589c7230902202996abf233e86ed4d46bdf002c118851ae9456c3458bb2b996f68cea5f66c4fb0121034648933562681ff2b8f8e31a1ccb4fd3c902304c2754ac33f96fa2206f420341feffffff0200e1f505000000001976a914d392f3d90559efbf0a53e091ea86aba41324a53a88aca0870ef3030000001976a9144107eaf57b36f840ce06c0326953a6d9de7250c588acb2941500"
        },
        {
            "hash": "acffdca982d1ce6fcd1f51dbb9dda686441058f93686008a2c446c42a94a66a7",
            "height": 1414324,
            "hex": "01000000016b26fd5fcad7389079c468dab95fbf12a4ae6646b31a9c3fd9c449c8874ea37a000000006b483045022100d27e0104c86f295821ac5b032a3b4661fb7a65bc1df447f0955ed9f63295a0430220511699e2455fb6094a46c0646667f1d5b43a479cc90334b6630d97c24ef626b6012103e0a55b7d32efb3dbc9ba698f192ef161a4851572817cfb0685a48e27c0420fbffeffffff0280841e00000000001976a914c26d0540a4c20b867c83cb303c8ea1fa8cdf2b8b88ac28e83a05000000001976a914c1f9b2c439390d03e31af23fc644dc2c328cf00f88acb3941500"
        },
        {
            "hash": "bd09a74381ffad78c162976ec27fc9c1dceda3c2bfe367541a7140b8dd6e1f4c",
            "height": 1414324,
            "hex": "0100000002b0b2c4f9b40ec73d0ef9c70bc63366e7dcedd4aa51710aa7862700135dc15455000000006a47304402202a2ecc628a92560bc1382bf8867424f2aec59b1b9b8d7217e8e19126fb562027022031f8b15de547ba75f2a84513178c5a2744f7573c62c2c4af4dd48e7793b54a530121033334a7401df9930e726905963c9f535fdeff975a84cdc85067217c2ee403db8afeffffffb0b2c4f9b40ec73d0ef9c70bc63366e7dcedd4aa51710aa7862700135dc15455010000006a4730440220286db3a120b29c448fb6fdc93d472cf41caa14b3c2ae37717d0beee72c1754a0022079e849ce5a3e9ead451c02ee2271bf637b8714dfcf77e96f3574f7d48d35f3240121033334a7401df9930e726905963c9f535fdeff975a84cdc85067217c2ee403db8afeffffff0440420f00000000001976a9141b9a8107f5f50cc8e23696463bf53c4350ab4b2f88ac80841e00000000001976a9141b9a8107f5f50cc8e23696463bf53c4350ab4b2f88acd03f6300000000001976a914e70044d98006524a1a032f507d10427dca87f5fb88ac002d3101000000001976a9143b16eb02e1a6bd4d7acd422981b627467de27bf988acb3941500"
        },
        {
            "hash": "c499c223f401175b14c8cb28893219dcd8b49563e59b9b4865dd4407c2de27c8",
            "height": 1414324,
            "hex": "01000000016720cbbd13dd812d1c92abf21767aeae8c0f74762c555e1d51920c3b0f58e5ee000000006a47304402204b1ad610a6f803780406e863907df748ecc36ae08af18a70d6a868be91c43e19022071f27d527bebdc54bea2955d63778582533c3e23f46b50d008fd3125b2a78aac01210251925ad4fee452bdec4000ac008264127f967171a0c629cbe5204d1a86d39d5bfeffffff0240420f00000000001976a914436279912756fcf86f046911c465e07c3015726388acc48ee800000000001976a9144107eaf57b36f840ce06c0326953a6d9de7250c588acb3941500"
        },
        {
            "hash": "d2ccea06bad8711a1c95e66f1b3a8d658c447a061c856cf284075f7a152d45fb",
            "height": 1414995,
            "hex": "02000000000101c75d20b25fc8d9330ebd5b898200dec2e4006283ed0921b2febe992431a591fc000000001716001447519c784d680319752e25c11f40f55f511fafc7feffffff02400fb7066c00000017a914839852e194269cf3e71179b49712974b858d2d06872669aa00000000001976a914d392f3d90559efbf0a53e091ea86aba41324a53a88ac02483045022100d75c69fd521bcb21285fb289b3b999d623ea9496fb561f60fb92d07dfba079400220667e2b2ebc970c17e19c88cc2ced316144c85ad493eabaad919d79c76fddb3f70121021d6110c5773cd692b46cbfe39539343e576a69d5df95c8ec92210ca892a7a89b4d971500"
        },
        {
            "hash": "df47e4bf599ecf27d8f3b34e85fcd7384d753823208d06171ff16899bc1709ce",
            "height": 1414324,
            "hex": "0100000002a7664aa9426c442c8a008636f958104486a6ddb9db511fcd6fced182a9dcffac000000006b483045022100de8365c8a9f4364a97f540d96acdedd6b64231607016d3bec2e673ab65c4f2dc02205cf22e2f0e382dea3e46dabec821a4d3d6dfeebc46e117df01d72ebdda2720fe0121027f8d509060eac49ec1459a6026de7bd126e8c64d0f67a11cb55e1d34553b1085fdffffffc827dec20744dd65489b9be56395b4d8dc19328928cbc8145b1701f423c299c4000000006a47304402202c776d8a1a84d8eded4208f302768be2985eb4c5f1dd7c9b509fcd24f78650fd022060d6f8e1dcdeeb16901ec2d33015d84cef72fd4792935c7b5b3abba2cc7e1fd90121021497743c1fa69e9c4961cf0cc8e2d55790087e918d5ba92eb166aa0da2a3a8a9fdffffff02e0930400000000001976a9149fbfef2a2f386818a33b5e2e94b5c753f741846888aca0252600000000001976a9143b16eb02e1a6bd4d7acd422981b627467de27bf988acb3941500"
        },
        {
            "hash": "f2e6bc46d8bf08d19854bc8dfde1a3d4968fa8d09f2185ea6e2711ec0ce449ec",
            "height": 1414324,
            "hex": "01000000011e5866926a6d48da489c6097c07bc0374a37c02eef80fbac5873072373be9a7d000000006b483045022100caac9a30da1805898c2cb1b7e1a666174175776711e029a95533e7c1b94fe646022002452c0a3f983ce7b4784e149f0e1264b83c3c5745a7db61aa22197326f998610121035fd185ba86d1a69809a6a4906c6229022748125d8eb56b0bc6fb8e1074b47ff9feffffff0248c30300000000001976a914552ef8e748705cbcf09820f398084d54a488593a88ac20a10700000000001976a9143b16eb02e1a6bd4d7acd422981b627467de27bf988acb3941500"
        },
        {
            "hash": "f49001a572942a506bd414c51f5a0e9cd349899d05c868b1de2fa6742a66d5aa",
            "height": 1414324,
            "hex": "010000000162a80d2afb2d687c5b3924c22a36ad0e1bc6b621cde7b5484acb2c874a521b33000000006a473044022056ec2e7ed4197a8bb9ee47ed083aee4318b108055b61c4cb6f38b722af20f45b022022d1887d4bb9a648109b5591e2beaba72da28dc77b25b37490cb1bae032e44200121025456608e1c1912d18ef2b09e5280d1117d1a02c6efc90393801b5586ed0e4de0feffffff0200e1f505000000001976a914d8582e9ac212e9be0e364e764e97977f2f5791c688ac4405d329000000001976a914862f9e457fa471d9869bebb0da6f796c4d19c50288acb3941500"
        }
    ]
}


================================================
FILE: backend/backend.go
================================================
package backend

import (
	"github.com/square/beancounter/deriver"
	time "time"
)

// Backend is an interface which abstracts different types of backends.
//
// The Backends are responsible for fetching all the transactions related to an address.
// For each transaction, the Backend must grab:
// - the height
// - the raw transaction bytes
//
// In addition, the backend must know the chain height. The backend is allowed to fetch this value
// once (at startup) and cache it.
//
// In general, we tried to keep the backends minimal and move as much (common) logic as possible
// into the accounter.
//
// There are a few differences between Electrum and Btcd (and potentially any other Backend we
// decide to add in the future). For instance, Electrum returns the block height when fetching all
// the transactions for a given address, but Btcd doesn't. On the other hand, Btcd returns the raw
// transaction information right away but Electrum requires additional requests.
//
// Because of these differences, the Backend exposes a Finish() method. This method allows the
// Accounter to wait until the Backend is done with any additional requests. In theory, we could
// forgo the Finish() method and have the Accounter read from the TxResponses channel until it has
// all the data it needs. This would require the Accounter to maintain its own set of transactions.
type Backend interface {
	ChainHeight() uint32

	AddrRequest(addr *deriver.Address)
	AddrResponses() <-chan *AddrResponse
	TxRequest(txHash string)
	TxResponses() <-chan *TxResponse
	BlockRequest(height uint32)
	BlockResponses() <-chan *BlockResponse

	Finish()
}

// AddrResponse lists transaction hashes for a given address
type AddrResponse struct {
	Address  *deriver.Address
	TxHashes []string
}

// TxResponse contains raw transaction, transaction hash and a block height in which
// it was confirmed.
type TxResponse struct {
	Hash   string
	Height int64
	Hex    string
}

type BlockResponse struct {
	Height    uint32
	Timestamp time.Time
}

// HasTransactions returns true if the Response contains any transactions
func (r *AddrResponse) HasTransactions() bool {
	return len(r.TxHashes) > 0
}


================================================
FILE: backend/btcd_backend.go
================================================
package backend

import (
	"fmt"
	"log"
	"sync"

	"github.com/btcsuite/btcd/btcjson"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/rpcclient"
	"github.com/pkg/errors"
	"github.com/square/beancounter/deriver"
	"github.com/square/beancounter/reporter"
	. "github.com/square/beancounter/utils"
)

// BtcdBackend wraps Btcd node and its API to provide a simple
// balance and transaction history information for a given address.
// BtcdBackend implements Backend interface.
type BtcdBackend struct {
	chainHeight uint32

	client            *rpcclient.Client
	network           Network
	blockHeightMu     sync.Mutex // mutex to guard read/writes to blockHeightLookup map
	blockHeightLookup map[string]int64

	// channels used to communicate with the Accounter
	addrRequests  chan *deriver.Address
	addrResponses chan *AddrResponse
	txRequests    chan string
	txResponses   chan *TxResponse

	// channels used to communicate with the Blockfinder
	blockRequests  chan uint32
	blockResponses chan *BlockResponse

	// internal channels
	transactionsMu     sync.Mutex // mutex to guard read/writes to transactions map
	cachedTransactions map[string]*TxResponse
	doneCh             chan bool
}

const (
	// For now assume that there cannot be more than maxTxsPerAddr.
	// Ideally, if maxTxsPerAddr is reached then we should paginate and retrieve
	// all the transactions.
	maxTxsPerAddr = 1000

	addrRequestsChanSize = 100
	blockRequestChanSize = 100

	concurrency = 100
)

// NewBtcdBackend returns a new BtcdBackend structs or errors.
//
// BtcdBackend is meants to connect to a personal Btcd node (because public nodes don't expose the
// API we need). There's no TLS support. If your node is not co-located with Beancounter, we
// recommend wrapping your connection in a ssh or other secure tunnel.
func NewBtcdBackend(host, port, user, pass string, network Network) (*BtcdBackend, error) {
	connCfg := &rpcclient.ConnConfig{
		Host:         fmt.Sprintf("%s:%s", host, port),
		User:         user,
		Pass:         pass,
		HTTPPostMode: true, // Bitcoin core only supports HTTP POST mode
		DisableTLS:   true, // Since we're assuming a personal bitcoin node for now, skip TLS
	}
	client, err := rpcclient.New(connCfg, nil)
	if err != nil {
		return nil, errors.Wrap(err, "could not create a Btcd RPC client")
	}

	// Check that we are talking to the right chain
	genesis, err := client.GetBlockHash(0)
	if err != nil {
		return nil, errors.Wrap(err, "GetBlockHash(0) failed")
	}
	if genesis.String() != GenesisBlock(network) {
		return nil, errors.Errorf("Unexpected genesis block %s != %s", genesis.String(), GenesisBlock(network))
	}

	height, err := client.GetBlockCount()
	if err != nil {
		return nil, errors.Wrap(err, "could not connect to the Btcd server")
	}

	b := &BtcdBackend{
		client:         client,
		network:        network,
		chainHeight:    uint32(height),
		addrRequests:   make(chan *deriver.Address, addrRequestsChanSize),
		addrResponses:  make(chan *AddrResponse, addrRequestsChanSize),
		txRequests:     make(chan string, 2*maxTxsPerAddr),
		txResponses:    make(chan *TxResponse, 2*maxTxsPerAddr),
		blockRequests:  make(chan uint32, 2*blockRequestChanSize),
		blockResponses: make(chan *BlockResponse, 2*blockRequestChanSize),

		blockHeightLookup:  make(map[string]int64),
		cachedTransactions: make(map[string]*TxResponse),
		doneCh:             make(chan bool),
	}

	// launch
	for i := 0; i < concurrency; i++ {
		go b.processRequests()
	}
	return b, nil
}

// AddrRequest schedules a request to the backend to lookup information related
// to the given address.
func (b *BtcdBackend) AddrRequest(addr *deriver.Address) {
	reporter.GetInstance().IncAddressesScheduled()
	reporter.GetInstance().Logf("scheduling address: %s", addr)
	b.addrRequests <- addr
}

// AddrResponses exposes a channel that allows to consume backend's responses to
// address requests created with AddrRequest()
func (b *BtcdBackend) AddrResponses() <-chan *AddrResponse {
	return b.addrResponses
}

// TxRequest schedules a request to the backend to lookup information related
// to the given transaction hash.
func (b *BtcdBackend) TxRequest(txHash string) {
	reporter.GetInstance().IncTxScheduled()
	reporter.GetInstance().Logf("scheduling tx: %s", txHash)
	b.txRequests <- txHash
}

// TxResponses exposes a channel that allows to consume backend's responses to
// address requests created with addrrequest().
// if an address has any transactions then they will be sent to this channel by the
// backend.
func (b *BtcdBackend) TxResponses() <-chan *TxResponse {
	return b.txResponses
}

func (b *BtcdBackend) BlockRequest(height uint32) {
	b.blockRequests <- height
}

func (b *BtcdBackend) BlockResponses() <-chan *BlockResponse {
	return b.blockResponses
}

// Finish informs the backend to stop doing its work.
func (b *BtcdBackend) Finish() {
	close(b.doneCh)
	b.client.Disconnect()
}

func (b *BtcdBackend) ChainHeight() uint32 {
	return b.chainHeight
}

func (b *BtcdBackend) processRequests() {
	for {
		select {
		case addr := <-b.addrRequests:
			err := b.processAddrRequest(addr)
			if err != nil {
				log.Panicf("processAddrRequest failed: %+v", err)
			}
		case tx := <-b.txRequests:
			err := b.processTxRequest(tx)
			if err != nil {
				log.Panicf("processTxRequest failed: %+v", err)
			}
		case block := <-b.blockRequests:
			err := b.processBlockRequest(block)
			if err != nil {
				log.Panicf("processBlockRequest failed: %+v", err)
			}
		case <-b.doneCh:
			break
		}
	}
}

func (b *BtcdBackend) processAddrRequest(address *deriver.Address) error {
	addr := address.Script()
	txs, err := b.client.SearchRawTransactionsVerbose(address.Address(), 0, maxTxsPerAddr+1, true, false, nil)
	if err != nil {
		if jerr, ok := err.(*btcjson.RPCError); ok {
			switch jerr.Code {
			case btcjson.ErrRPCInvalidAddressOrKey:
				// the address doesn't exist in the blockchain - either because it was not used
				// or given backend doesn't have a complete blockchain
				b.addrResponses <- &AddrResponse{
					Address:  address,
					TxHashes: []string{},
				}
				return nil
			}
		}
		return errors.Wrap(err, "could not fetch transactions for "+addr)
	}

	if len(txs) > maxTxsPerAddr {
		return fmt.Errorf("address %s has more than max allowed transactions of %d", addr, maxTxsPerAddr)
	}

	txHashes := make([]string, 0, len(txs))
	for _, tx := range txs {
		txHashes = append(txHashes, tx.Txid)
	}

	b.cacheTxs(txs)

	b.addrResponses <- &AddrResponse{
		Address:  address,
		TxHashes: txHashes,
	}

	return nil
}

func (b *BtcdBackend) processTxRequest(txHash string) error {
	b.transactionsMu.Lock()
	tx, exists := b.cachedTransactions[txHash]
	b.transactionsMu.Unlock()

	if exists {
		b.txResponses <- tx

		return nil
	}

	hash, err := chainhash.NewHashFromStr(txHash)
	if err != nil {
		return err
	}
	txResp, err := b.client.GetRawTransactionVerbose(hash)
	if err != nil {
		if jerr, ok := err.(*btcjson.RPCError); ok {
			switch jerr.Code {
			case btcjson.ErrRPCInvalidAddressOrKey:
				return errors.Wrap(err, "blockchain doesn't have transaction "+txHash)
			}
		}
		return errors.Wrap(err, "could not fetch transaction "+txHash)
	}
	height, err := b.getBlockHeight(txResp.BlockHash)
	if err != nil {
		return err
	}

	b.txResponses <- &TxResponse{
		Hash:   txHash,
		Height: height,
		Hex:    txResp.Hex,
	}
	return nil
}

func (b *BtcdBackend) processBlockRequest(height uint32) error {
	hash, err := b.client.GetBlockHash(int64(height))
	if err != nil {
		if jerr, ok := err.(*btcjson.RPCError); ok {
			switch jerr.Code {
			case btcjson.ErrRPCInvalidAddressOrKey:
				return errors.Wrapf(err, "blockchain doesn't have block %d", height)
			}
		}
		return errors.Wrapf(err, "could not fetch block %d", height)
	}

	header, err := b.client.GetBlockHeader(hash)
	if err != nil {
		if jerr, ok := err.(*btcjson.RPCError); ok {
			switch jerr.Code {
			case btcjson.ErrRPCInvalidAddressOrKey:
				return errors.Wrapf(err, "blockchain doesn't have block %d", height)
			}
		}
		return errors.Wrapf(err, "could not fetch block %d", height)
	}

	b.blockResponses <- &BlockResponse{
		Height:    height,
		Timestamp: header.Timestamp,
	}
	return nil
}

func (b *BtcdBackend) cacheTxs(txs []*btcjson.SearchRawTransactionsResult) {
	for _, tx := range txs {
		b.transactionsMu.Lock()
		_, exists := b.cachedTransactions[tx.Txid]
		b.transactionsMu.Unlock()

		if exists {
			return
		}

		height, err := b.getBlockHeight(tx.BlockHash)
		if err != nil {
			log.Panicf("error getting block height for hash %s: %s", tx.BlockHash, err.Error())
		}

		b.transactionsMu.Lock()
		b.cachedTransactions[tx.Txid] = &TxResponse{
			Hash:   tx.Txid,
			Height: height,
			Hex:    tx.Hex,
		}
		b.transactionsMu.Unlock()
	}
}

// getBlockHeight returns a block height for a given block hash or returns an error
func (b *BtcdBackend) getBlockHeight(hash string) (int64, error) {
	b.blockHeightMu.Lock()
	height, exists := b.blockHeightLookup[hash]
	b.blockHeightMu.Unlock()
	if exists {
		return height, nil
	}

	h, err := chainhash.NewHashFromStr(hash)
	if err != nil {
		return -1, err
	}
	resp, err := b.client.GetBlockVerbose(h)
	if err != nil {
		if jerr, ok := err.(*btcjson.RPCError); ok {
			switch jerr.Code {
			case btcjson.ErrRPCInvalidAddressOrKey:
				return -1, errors.Wrap(err, "blockchain doesn't have block "+hash)
			}
		}
		return -1, errors.Wrap(err, "could not fetch block "+hash)
	}

	b.blockHeightMu.Lock()
	b.blockHeightLookup[hash] = resp.Height
	b.blockHeightMu.Unlock()

	return resp.Height, nil
}


================================================
FILE: backend/common.go
================================================
package backend

import (
	. "github.com/square/beancounter/utils"
	"time"
)

// index, address and transaction and helper structs used by recorder and fixture
// backends marshal/unmarshal address and transaction data

type index struct {
	Metadata     metadata      `json:"metadata"`
	Addresses    []address     `json:"addresses"`
	Transactions []transaction `json:"transactions"`
	Blocks       []block       `json:"blocks"`
}

type metadata struct {
	Height uint32 `json:"height"`
}

type address struct {
	Address      string   `json:"address"`
	Path         string   `json:"path"`
	Network      Network  `json:"network"`
	Change       uint32   `json:"change"`
	AddressIndex uint32   `json:"addr_index"`
	TxHashes     []string `json:"tx_hashes"`
}

type byAddress []address

func (a byAddress) Len() int           { return len(a) }
func (a byAddress) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byAddress) Less(i, j int) bool { return a[i].Address < a[j].Address }

type transaction struct {
	Hash   string `json:"hash"`
	Height int64  `json:"height"`
	Hex    string `json:"hex"`
}

type byTransactionID []transaction

func (a byTransactionID) Len() int           { return len(a) }
func (a byTransactionID) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a byTransactionID) Less(i, j int) bool { return a[i].Hash < a[j].Hash }

type block struct {
	Height    uint32    `json:"height"`
	Timestamp time.Time `json:"timestamp"`
}


================================================
FILE: backend/electrum/LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015 Tristan Rice

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.



================================================
FILE: backend/electrum/README.md
================================================
This code was imported from github.com/mbyczkowski/go-electrum, a fork of
github.com/qshuai/go-electrum, a fork of github.com/d4l3k/go-electrum.


================================================
FILE: backend/electrum/blockchain.go
================================================
package electrum

import (
	"encoding/json"
	"fmt"
	"log"
	"strings"
	"sync/atomic"
	"time"

	"github.com/bcext/cashutil"
	. "github.com/square/beancounter/utils"
)

const (
	sleep = 200 * time.Millisecond // Be nice to the Electrum nodes
)

type Node struct {
	// Ident is a an identifier of the form 127.0.0.1|s1234 or ::1|t5432.
	Ident   string
	Network Network

	transport Transport

	// Next ID for request. Store/load this via sync/atomic.
	nextId uint64
}

type Feature struct {
	Prunning string `json:"prunning"`
	Protocol string `json:"protocol_max"`
	Genesis  string `json:"genesis_hash"`
}

type BlockchainHeader struct {
	Nonce         uint32 `json:"nonce"`
	PrevBlockHash string `json:"prev_block_hash"`
	Timestamp     int64  `json:"timestamp"`
	MerkleRoot    string `json:"merkle_root"`
	BlockHeight   int32  `json:"block_height"`
	UtxoRoot      string `json:"utxo_root"`
	Version       int32  `json:"version"`
	Bits          int64  `json:"bits"`
}

type Balance struct {
	// Address field is unnecessary for Electrumx server protocol,
	// but is required for user of this library.
	Address string `json:"address"`

	Confirmed   cashutil.Amount `json:"confirmed"`
	Unconfirmed cashutil.Amount `json:"unconfirmed"`
}

type Transaction struct {
	Hash   string `json:"tx_hash"`
	Height uint32 `json:"height"`
	Value  int64  `json:"value"`
	Pos    uint32 `json:"tx_pos"`
}

type GetTransaction struct {
	Hex           string `json:"hex"`
	Txid          string `json:"txid"`
	Version       int32  `json:"version"`
	Locktime      uint32 `json:"locktime"`
	Vin           []Vin  `json:"vin"`
	Vout          []Vout `json:"vout"`
	BlockHash     string `json:"blockhash"`
	Confirmations int32  `json:"confirmations"`
	Time          int64  `json:"time"`
	Blocktime     int64  `json:"blocktime"`
}

// Vin models parts of the tx data.
type Vin struct {
	Coinbase  string     `json:"coinbase"`
	Txid      string     `json:"txid"`
	Vout      uint32     `json:"vout"`
	ScriptSig *ScriptSig `json:"scriptSig"`
	Sequence  uint32     `json:"sequence"`
}

// ScriptPubKeyResult models the scriptPubKey data of a tx script.  It is
// defined separately since it is used by multiple commands.
type ScriptPubKeyResult struct {
	Asm       string   `json:"asm"`
	Hex       string   `json:"hex,omitempty"`
	ReqSigs   int32    `json:"reqSigs,omitempty"`
	Type      string   `json:"type"`
	Addresses []string `json:"addresses,omitempty"`
}

// Vout models parts of the tx data.
type Vout struct {
	Value        float64            `json:"value"`
	N            uint32             `json:"n"`
	ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
}

// ScriptSig models a signature script.  It is defined separately since it only
// applies to non-coinbase.  Therefore the field in the Vin structure needs
// to be a pointer.
type ScriptSig struct {
	Asm string `json:"asm"`
	Hex string `json:"hex"`
}

type Peer struct {
	IP       string
	Host     string
	Version  string
	Features []string
}

type Header struct {
	Height uint32 `json:"height"`
	Hex    string `json:"hex"`
}

type Block struct {
	Count uint   `json:"count"`
	Hex   string `json:"hex"`
	Max   uint   `json:"max"`
}

func NewNode(addr, port string, network Network) (*Node, error) {
	n := &Node{}
	var a string
	var t Transport
	var err error

	defaultTCP, defaultSSL := defaultPorts(network)

	if strings.Contains(addr, ":") {
		a = fmt.Sprintf("[%s]", addr)
	} else {
		a = addr
	}

	if port[0] == 't' {
		// TCP
		var p string
		if len(port) == 1 {
			p = defaultTCP
		} else {
			p = port[1:]
		}
		t, err = NewTCPTransport(fmt.Sprintf("%s:%s", a, p))
	} else if port[0] == 's' {
		// TLS
		var p string
		if len(port) == 1 {
			p = defaultSSL
		} else {
			p = port[1:]
		}
		t, err = NewSSLTransport(fmt.Sprintf("%s:%s", a, p))
	} else {
		log.Panicf("port (%s) must start with t or s", port)
	}

	if err != nil {
		return nil, err
	}

	n.transport = t
	n.Network = network
	n.Ident = NodeIdent(addr, port)
	return n, nil
}

func (n *Node) Disconnect() error {
	return n.transport.Shutdown()
}

func NodeIdent(addr, port string) string {
	return fmt.Sprintf("%s|%s", addr, port)
}

// IsCoinBase returns a bool to show if a Vin is a Coinbase one or not.
func (v *Vin) IsCoinBase() bool {
	return len(v.Coinbase) > 0
}

// ServerFeatures returns the server features dictionary.
// method: "server.features"
//
// version 1.1
// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-features
func (n *Node) ServerFeatures() (*Feature, error) {
	var result Feature
	err := n.request("server.features", []interface{}{}, &result)
	if err != nil {
		return nil, err
	}
	return &result, nil
}

// ServerVersion allows negotiating a min protocol version. This is required, as various methods
// appeared (or were removed) in various versions.
//
// version 1.1
// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-version
func (n *Node) ServerVersion(ver string) error {
	var ignored []string
	return n.request("server.version", []interface{}{"beancounter", ver}, &ignored)
}

// BlockchainAddressGetHistory returns the history of an address.
//
// version 1.1 and version 1.2 only
// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-scripthash-get_history
func (n *Node) BlockchainAddressGetHistory(address string) ([]*Transaction, error) {
	var result []*Transaction
	err := n.request("blockchain.address.get_history", []interface{}{address}, &result)
	if err != nil {
		return nil, err
	}
	return result, nil
}

// BlockchainTransactionGet returns a raw transaction.
//
// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-transaction-get
func (n *Node) BlockchainTransactionGet(txid string) (string, error) {
	var hex string
	err := n.request("blockchain.transaction.get", []interface{}{txid, false}, &hex)
	return hex, err
}

// Subscribe to receive block headers when a new block is found.
//
// Note: there's no way to unsubscribe, and the rest of this code doesn't know how to deal with
// notifications. It is advisable to only call this method once and disconnect/reconnect after
// getting the block height.
//
// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#blockchain-headers-subscribe
func (n *Node) BlockchainHeadersSubscribe() (*Header, error) {
	var header Header
	err := n.request("blockchain.headers.subscribe", []interface{}{true}, &header)
	return &header, err
}

// ServerPeersSubscribe requests peers from a server.
//
// https://electrumx.readthedocs.io/en/latest/protocol-methods.html#server-peers-subscribe
func (n *Node) ServerPeersSubscribe() ([]Peer, error) {
	var peers [][]interface{}
	err := n.request("server.peers.subscribe", []interface{}{}, &peers)
	if err != nil {
		return nil, err
	}

	out := []Peer{}
	for _, peer := range peers {
		features := make([]string, 0, len(peer[2].([]interface{})))
		for _, feature := range peer[2].([]interface{}) {
			features = append(features, feature.(string))
		}

		p := Peer{
			IP:       peer[0].(string),
			Host:     peer[1].(string),
			Version:  features[0],
			Features: features[1:],
		}
		out = append(out, p)
	}

	return out, nil
}

// BlockchainBlockHeaders returns a block header (160 hex).
func (n *Node) BlockchainBlockHeaders(height uint32, count uint) (Block, error) {
	var block Block
	err := n.request("blockchain.block.headers", []interface{}{height, count}, &block)
	return block, err
}

func (n *Node) request(method string, params []interface{}, result interface{}) error {
	msg := RequestMessage{
		Id:     atomic.AddUint64(&n.nextId, 1),
		Method: method,
		Params: params,
	}

	resp, err := n.transport.SendMessage(msg)
	if err != nil {
		return err
	}

	r, err := json.Marshal(resp.Result)
	if err != nil {
		return err
	}
	json.Unmarshal(r, result)
	time.Sleep(sleep)
	return nil
}

func defaultPorts(network Network) (string, string) {
	switch network {
	case Mainnet:
		return "50001", "50002"
	case Testnet:
		return "50101", "50102"
	default:
		panic("unreachable")
	}
}


================================================
FILE: backend/electrum/tcp.go
================================================
package electrum

import (
	"bufio"
	"crypto/tls"
	"encoding/json"
	"errors"
	"log"
	"net"
	"time"
)

var DebugMode bool

const (
	connTimeout  = 2 * time.Second
	writeTimeout = 10 * time.Second
	readTimeout  = 10 * time.Second
	messageDelim = byte('\n')
)

var (
	ErrNotImplemented = errors.New("not implemented")
	ErrNodeConnected  = errors.New("node already connected")
	ErrNodeShutdown   = errors.New("node has shutdown")
	ErrIdMismatch     = errors.New("response id mismatch")
	ErrUnknown        = errors.New("unknown error")
	ErrNetwork        = errors.New("network error")
	ErrAPI            = errors.New("received API error")
)

type ErrorResponse struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

type RequestMessage struct {
	Id     uint64        `json:"id"`
	Method string        `json:"method"`
	Params []interface{} `json:"params"`
}

type ResponseMessage struct {
	Id      uint64         `json:"id"`
	JsonRpc string         `json:"jsonrpc"`
	Result  interface{}    `json:"result"`
	Error   *ErrorResponse `json:"error"`
}

type Transport interface {
	SendMessage(RequestMessage) (*ResponseMessage, error)
	Shutdown() error
}

type TCPTransport struct {
	conn net.Conn
}

func NewTCPTransport(addr string) (Transport, error) {
	conn, err := net.DialTimeout("tcp", addr, connTimeout)
	if err != nil {
		return nil, err
	}

	t := &TCPTransport{conn: conn}

	return t, nil
}

func NewSSLTransport(addr string) (Transport, error) {
	d := &net.Dialer{
		Timeout: connTimeout,
	}

	conn, err := tls.DialWithDialer(d, "tcp", addr, &tls.Config{InsecureSkipVerify: true})
	if err != nil {
		return nil, err
	}

	t := &TCPTransport{conn: conn}

	return t, nil
}

func (t *TCPTransport) SendMessage(request RequestMessage) (*ResponseMessage, error) {
	if t.conn == nil {
		return nil, ErrNodeShutdown
	}

	body, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}
	body = append(body, messageDelim)

	// Set write deadline
	_ = t.conn.SetWriteDeadline(time.Now().Add(writeTimeout))

	// Send message
	n, err := t.conn.Write(body)
	if err != nil {
		_ = t.Shutdown()
		if DebugMode {
			log.Printf("error on send to %s: %s", t.conn.RemoteAddr(), err)
		}
		return nil, ErrNetwork
	}
	if n != len(body) {
		_ = t.Shutdown()
		if DebugMode {
			log.Printf("error on send to %s: short write (%d < %d)", t.conn.RemoteAddr(), n, len(body))
		}
		return nil, ErrNetwork
	}

	if DebugMode {
		log.Printf("%s <- %s", t.conn.RemoteAddr(), body)
	}

	// Clear write deadline, set read deadline
	_ = t.conn.SetWriteDeadline(time.Time{})
	_ = t.conn.SetReadDeadline(time.Now().Add(readTimeout))

	// Wait for response
	reader := bufio.NewReader(t.conn)

	line, err := reader.ReadBytes(messageDelim)
	if err != nil {
		_ = t.Shutdown()
		if DebugMode {
			log.Printf("error on recv from %s: %s", t.conn.RemoteAddr(), err)
		}
		return nil, ErrNetwork
	}

	// Clear deadline
	_ = t.conn.SetReadDeadline(time.Time{})

	if DebugMode {
		log.Printf("%s -> %s", t.conn.RemoteAddr(), line)
	}

	// Parse & process message
	resp := ResponseMessage{}
	err = json.Unmarshal(line, &resp)
	if err != nil {
		_ = t.Shutdown()
		if DebugMode {
			log.Printf("error on recv from %s: %s", t.conn.RemoteAddr(), err)
		}
		return nil, ErrUnknown
	}

	if resp.Id != request.Id {
		_ = t.Shutdown()
		if DebugMode {
			log.Printf("error on recv from %s: id mismatch (%d != %d)", t.conn.RemoteAddr(), request.Id, resp.Id)
		}
		return nil, ErrIdMismatch
	}

	if resp.Error != nil {
		if DebugMode {
			log.Printf("error on recv from %s: server error (%d: %s)", t.conn.RemoteAddr(), resp.Error.Code, resp.Error.Message)
		}
		return nil, ErrAPI
	}

	return &resp, nil
}

func (t *TCPTransport) Shutdown() error {
	return t.conn.Close()
}


================================================
FILE: backend/electrum_backend.go
================================================
package backend

import (
	"bytes"
	"encoding/hex"
	"errors"
	"fmt"
	"log"
	"strings"
	"sync"
	"time"

	"github.com/btcsuite/btcd/wire"

	"github.com/Masterminds/semver"
	"github.com/square/beancounter/backend/electrum"
	"github.com/square/beancounter/deriver"
	"github.com/square/beancounter/reporter"
	. "github.com/square/beancounter/utils"
)

// Fetches transaction information from Electrum servers.
// Electrum protocol docs: https://electrumx.readthedocs.io/en/latest/protocol.html
//
// When we connect to an Electrum server, we:
// - ensure the server talks v1.2
// - has the right genesis block
// - has crossed the height we are interested in.
// - we then negotiate protocol v1.2
//
// A background goroutine continuously connects to peers.

// ElectrumBackend wraps Electrum node and its API to provide a simple
// balance and transaction history information for a given address.
// ElectrumBackend implements Backend interface.
type ElectrumBackend struct {
	chainHeight uint32

	// peer management
	nodeMu sync.RWMutex // mutex to guard reads/writes to nodes map
	nodes  map[string]*electrum.Node
	// todo: blacklistedNodes should be a timestamp and we should re-try after a certain amount of
	// time has elapsed.
	blacklistedNodes map[string]struct{}
	network          Network

	// channels used to communicate with the Accounter
	addrRequests  chan *deriver.Address
	addrResponses chan *AddrResponse
	txResponses   chan *TxResponse
	txRequests    chan string

	// channels used to communicate with the Blockfinder
	blockRequests  chan uint32
	blockResponses chan *BlockResponse

	// internal channels
	peersRequests  chan struct{}
	transactionsMu sync.Mutex // mutex to guard read/writes to transactions map
	transactions   map[string]int64
	doneCh         chan bool
}

const (
	maxPeers          = 100
	peerFetchInterval = 30 * time.Second // How often to fetch additional peers?
)

var (
	// ErrIncorrectGenesisBlock means electrum is set-up to for wrong currency
	ErrIncorrectGenesisBlock = errors.New("Incorrect genesis block")
	// ErrIncompatibleVersion means electrum server version is not compatible with electrum client lib
	ErrIncompatibleVersion = errors.New("Incompatible version")
	// ErrFailedNegotiateVersion means electrum server doesn't support version(s) used by the electrum client lib
	ErrFailedNegotiateVersion = errors.New("Failed negotiate version")
)

// NewElectrumBackend returns a new ElectrumBackend structs or errors.
// Initially connects to 1 node. A background job handles connecting to
// additional peers. The background job fails if there are no peers left.
func NewElectrumBackend(addr, port string, network Network) (*ElectrumBackend, error) {

	// TODO: should the channels have k * maxPeers buffers? Each node needs to enqueue a
	// potentially large number of transactions. If all nodes are doing that at the same time,
	// there's a deadlock risk?
	eb := &ElectrumBackend{
		nodes:            make(map[string]*electrum.Node),
		blacklistedNodes: make(map[string]struct{}),
		network:          network,
		addrRequests:     make(chan *deriver.Address, 2*maxPeers),
		addrResponses:    make(chan *AddrResponse, 2*maxPeers),
		txRequests:       make(chan string, 2*maxPeers),
		txResponses:      make(chan *TxResponse, 2*maxPeers),
		blockRequests:    make(chan uint32, 2*maxPeers),
		blockResponses:   make(chan *BlockResponse, 2*maxPeers),

		peersRequests: make(chan struct{}),
		transactions:  make(map[string]int64),
		doneCh:        make(chan bool),
	}

	// Connect to a node to fetch the height
	height, err := eb.getHeight(addr, port, network)
	if err != nil {
		return nil, err
	}
	eb.chainHeight = height

	// Connect to a node and handle requests
	if err := eb.addNode(addr, port, network); err != nil {
		fmt.Printf("failed to connect to initial node: %+v", err)
		return nil, err
	}

	// goroutine to continuously fetch additional peers
	go func() {
		eb.findPeers()
		for {
			select {
			case <-time.Tick(peerFetchInterval):
				eb.findPeers()
			case <-eb.doneCh:
				return
			}
		}
	}()

	return eb, nil
}

// AddrRequest schedules a request to the backend to lookup information related
// to the given address.
func (eb *ElectrumBackend) AddrRequest(addr *deriver.Address) {
	reporter.GetInstance().IncAddressesScheduled()
	reporter.GetInstance().Logf("scheduling address: %s", addr)
	eb.addrRequests <- addr
}

// AddrResponses exposes a channel that allows to consume backend's responses to
// address requests created with AddrRequest()
func (eb *ElectrumBackend) AddrResponses() <-chan *AddrResponse {
	return eb.addrResponses
}

// TxRequest schedules a request to the backend to lookup information related
// to the given transaction hash.
func (eb *ElectrumBackend) TxRequest(txHash string) {
	reporter.GetInstance().IncTxScheduled()
	reporter.GetInstance().Logf("scheduling tx: %s", txHash)
	eb.txRequests <- txHash
}

// TxResponses exposes a channel that allows to consume backend's responses to
// address requests created with AddrRequest().
// If an address has any transactions then they will be sent to this channel by the
// backend.
func (eb *ElectrumBackend) TxResponses() <-chan *TxResponse {
	return eb.txResponses
}

func (eb *ElectrumBackend) BlockRequest(height uint32) {
	eb.blockRequests <- height
}

func (eb *ElectrumBackend) BlockResponses() <-chan *BlockResponse {
	return eb.blockResponses
}

// Finish informs the backend to stop doing its work.
func (eb *ElectrumBackend) Finish() {
	close(eb.doneCh)
	eb.removeAllNodes()
	// TODO: we could gracefully disconnect from all the nodes. We currently don't, because the
	// program is going to terminate soon anyways.
}

func (eb *ElectrumBackend) ChainHeight() uint32 {
	return eb.chainHeight
}

// Connect to a node and add it to the map of nodes
func (eb *ElectrumBackend) addNode(addr, port string, network Network) error {
	ident := electrum.NodeIdent(addr, port)

	eb.nodeMu.RLock()
	_, existsGood := eb.nodes[ident]
	_, existsBad := eb.blacklistedNodes[ident]
	eb.nodeMu.RUnlock()
	if existsGood {
		return fmt.Errorf("already connected to %s", addr)
	}
	if existsBad {
		// TODO: if we can't connect to a node over TCP, we should try the TLS port?
		return fmt.Errorf("%s is known to be unreachable", addr)
	}

	log.Printf("connecting to %s", addr)
	node, err := electrum.NewNode(addr, port, network)
	if err != nil {
		eb.nodeMu.Lock()
		eb.blacklistedNodes[ident] = struct{}{}
		eb.nodeMu.Unlock()
		return err
	}

	// Get the server's features
	feature, err := node.ServerFeatures()
	if err != nil {
		eb.nodeMu.Lock()
		eb.blacklistedNodes[ident] = struct{}{}
		eb.nodeMu.Unlock()
		return err
	}
	// Check genesis block
	if feature.Genesis != GenesisBlock(network) {
		eb.nodeMu.Lock()
		eb.blacklistedNodes[ident] = struct{}{}
		eb.nodeMu.Unlock()
		return ErrIncorrectGenesisBlock
	}
	// TODO: check pruning. Currently, servers currently don't prune, so it's fine to skip for now.

	// Check version
	err = checkVersion(feature.Protocol)
	if err != nil {
		eb.nodeMu.Lock()
		eb.blacklistedNodes[ident] = struct{}{}
		eb.nodeMu.Unlock()
		return err
	}

	// Negotiate version
	err = node.ServerVersion("1.2")
	if err != nil {
		eb.nodeMu.Lock()
		eb.blacklistedNodes[ident] = struct{}{}
		eb.nodeMu.Unlock()
		return ErrFailedNegotiateVersion
	}

	// TODO: ask the server for info on the block height we care about. If the server doesn't have
	// that block, we'll automatically disconnect.

	eb.nodeMu.Lock()
	eb.nodes[ident] = node
	eb.nodeMu.Unlock()

	// We can process requests
	go eb.processRequests(node)

	return nil
}

// Connect to a node without registering it, fetch height and disconnect.
func (eb *ElectrumBackend) getHeight(addr, port string, network Network) (uint32, error) {
	log.Printf("connecting to %s", addr)
	node, err := electrum.NewNode(addr, port, network)
	if err != nil {
		return 0, err
	}
	defer node.Disconnect()

	// Get the server's features
	feature, err := node.ServerFeatures()
	if err != nil {
		return 0, err
	}
	// Check genesis block
	if feature.Genesis != GenesisBlock(network) {
		return 0, ErrIncorrectGenesisBlock
	}
	// TODO: check pruning. Currently, servers currently don't prune, so it's fine to skip for now.

	// Check version
	err = checkVersion(feature.Protocol)
	if err != nil {
		return 0, err
	}

	// Negotiate version
	err = node.ServerVersion("1.2")
	if err != nil {
		return 0, ErrFailedNegotiateVersion
	}

	header, err := node.BlockchainHeadersSubscribe()
	if err != nil {
		log.Printf("BlockchainHeadersSubscribe failed: %+v", err)
		return 0, err
	}

	return header.Height, nil
}

func (eb *ElectrumBackend) processRequests(node *electrum.Node) {
	for {
		select {
		case _ = <-eb.peersRequests:
			err := eb.processPeersRequest(node)
			if err != nil {
				return
			}
		case addr := <-eb.addrRequests:
			err := eb.processAddrRequest(node, addr)
			if err != nil {
				return
			}
		case tx := <-eb.txRequests:
			err := eb.processTxRequest(node, tx)
			if err != nil {
				return
			}
		case block := <-eb.blockRequests:
			err := eb.processBlockRequest(node, block)
			if err != nil {
				return
			}
		}
	}
}

func (eb *ElectrumBackend) processPeersRequest(node *electrum.Node) error {
	eb.nodeMu.Lock()
	numNodes := len(eb.nodes)
	eb.nodeMu.Unlock()

	if numNodes >= maxPeers {
		return nil
	}
	peers, err := node.ServerPeersSubscribe()
	if err != nil {
		log.Printf("ServerPeersSubscribe failed: %+v", err)
		return err
	}
	for _, peer := range peers {
		eb.addPeer(peer)
	}
	return nil
}

func (eb *ElectrumBackend) processTxRequest(node *electrum.Node, txHash string) error {
	hex, err := node.BlockchainTransactionGet(txHash)
	if err != nil {
		log.Printf("processTxRequest failed with: %s, %+v", node.Ident, err)
		eb.removeNode(node.Ident)

		// requeue request
		// TODO: we should have a retry counter and fail gracefully if a transaction fails
		//       too many times.
		eb.txRequests <- txHash
		return err
	}
	height := eb.getTxHeight(txHash)

	eb.txResponses <- &TxResponse{
		Hash:   txHash,
		Height: height,
		Hex:    hex,
	}

	return nil
}

func (eb *ElectrumBackend) getTxHeight(txHash string) int64 {
	eb.transactionsMu.Lock()
	defer eb.transactionsMu.Unlock()

	height, exists := eb.transactions[txHash]
	if !exists {
		log.Panicf("transactions cache miss for %s", txHash)
	}
	return height
}

// note: we could be more efficient and batch things up.
func (eb *ElectrumBackend) processBlockRequest(node *electrum.Node, height uint32) error {
	block, err := node.BlockchainBlockHeaders(height, 1)
	if err != nil {
		log.Printf("processBlockRequest failed with: %s, %+v", node.Ident, err)
		eb.removeNode(node.Ident)

		// requeue request
		// TODO: we should have a retry counter and fail gracefully if an address fails too
		// many times.
		eb.blockRequests <- height
		return err
	}

	// Decode hex to get Timestamp
	b, err := hex.DecodeString(block.Hex)
	if err != nil {
		fmt.Printf("failed to unhex block %d: %s\n", height, block.Hex)
		panic(err)
	}

	var blockHeader wire.BlockHeader
	err = blockHeader.Deserialize(bytes.NewReader(b))
	if err != nil {
		fmt.Printf("failed to parse block %d: %s\n", height, block.Hex)
		panic(err)
	}

	eb.blockResponses <- &BlockResponse{
		Height:    height,
		Timestamp: blockHeader.Timestamp,
	}

	return nil
}

func (eb *ElectrumBackend) processAddrRequest(node *electrum.Node, addr *deriver.Address) error {
	txs, err := node.BlockchainAddressGetHistory(addr.String())
	if err != nil {
		log.Printf("processAddrRequest failed with: %s, %+v", node.Ident, err)
		eb.removeNode(node.Ident)

		// requeue request
		// TODO: we should have a retry counter and fail gracefully if an address fails too
		// many times.
		eb.addrRequests <- addr
		return err
	}

	txHashes := make([]string, 0, len(txs))
	for _, tx := range txs {
		txHashes = append(txHashes, tx.Hash)
		// fetch additional data if needed
	}
	eb.cacheTxs(txs)

	// TODO: we assume there are no more transactions. We should check what the API returns for
	// addresses with very large number of transactions.
	eb.addrResponses <- &AddrResponse{
		Address:  addr,
		TxHashes: txHashes,
	}
	return nil
}

func (eb *ElectrumBackend) cacheTxs(txs []*electrum.Transaction) {
	eb.transactionsMu.Lock()
	defer eb.transactionsMu.Unlock()

	for _, tx := range txs {
		height, exists := eb.transactions[tx.Hash]
		if exists && (height != int64(tx.Height)) {
			log.Panicf("inconsistent cache: %s %d != %d", tx.Hash, height, tx.Height)
		}
		eb.transactions[tx.Hash] = int64(tx.Height)
	}
}

// Checks that Electrum server's version is 1.2 or higher
func checkVersion(ver string) error {
	if ver[0] == 'v' {
		ver = ver[1:]
	}
	v, err := semver.NewVersion(ver)
	if err != nil {
		return err
	}

	c, err := semver.NewConstraint(">= 1.2")
	if err != nil {
		return err
	}

	if !c.Check(v) {
		return ErrIncompatibleVersion
	}
	return nil
}

// remove a node from the map of nodes.
func (eb *ElectrumBackend) removeNode(ident string) {
	eb.nodeMu.Lock()
	defer eb.nodeMu.Unlock()
	node, exists := eb.nodes[ident]
	if exists {
		node.Disconnect()
		delete(eb.nodes, ident)
	}
}

func (eb *ElectrumBackend) removeAllNodes() {
	eb.nodeMu.Lock()
	defer eb.nodeMu.Unlock()

	for _, node := range eb.nodes {
		node.Disconnect()
	}

	eb.nodes = map[string]*electrum.Node{}
}

func (eb *ElectrumBackend) findPeers() {
	eb.peersRequests <- struct{}{}
	eb.nodeMu.Lock()
	reporter.GetInstance().SetPeers(int32(len(eb.nodes)))
	eb.nodeMu.Unlock()
}

func (eb *ElectrumBackend) addPeer(peer electrum.Peer) {
	if strings.HasSuffix(peer.Host, ".onion") {
		log.Printf("skipping %s because of .onion\n", peer.Host)
		return
	}
	err := checkVersion(peer.Version)
	if err != nil {
		log.Printf("skipping %s because of protocol version %s\n", peer.Host, peer.Version)
		return
	}
	for _, feature := range peer.Features {
		if strings.HasPrefix(feature, "t") {
			go func(addr, feature string, network Network) {
				if err := eb.addNode(addr, feature, network); err != nil {
					log.Printf("error on addNode: %+v\n", err)
				}
			}(peer.IP, feature, eb.network)
			return
		}
	}
	for _, feature := range peer.Features {
		if strings.HasPrefix(feature, "s") {
			go func(addr, feature string, network Network) {
				if err := eb.addNode(addr, feature, network); err != nil {
					log.Printf("error on addNode: %+v\n", err)
				}
			}(peer.IP, feature, eb.network)
			return
		}
	}
	log.Printf("skipping %s because of feature mismatch: %+v\n", peer, peer.Features)
}


================================================
FILE: backend/electrum_backend_test.go
================================================
package backend

import (
	"github.com/square/beancounter/backend/electrum"
	"github.com/square/beancounter/deriver"
	. "github.com/square/beancounter/utils"
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestTransactionCache(t *testing.T) {
	// TODO: refactor ElectrumBackend to make it easier to test

	eb := &ElectrumBackend{
		nodes:            make(map[string]*electrum.Node),
		blacklistedNodes: make(map[string]struct{}),
		network:          Testnet,
		addrRequests:     make(chan *deriver.Address, 2*maxPeers),
		addrResponses:    make(chan *AddrResponse, 2*maxPeers),
		txRequests:       make(chan string, 2*maxPeers),
		txResponses:      make(chan *TxResponse, 2*maxPeers),

		peersRequests: make(chan struct{}),
		transactions:  make(map[string]int64),
		doneCh:        make(chan bool),
	}

	tx1 := electrum.Transaction{Hash: "aaaaaa", Height: 100}
	tx2 := electrum.Transaction{Hash: "bbbbbb", Height: 100}
	tx3 := electrum.Transaction{Hash: "cccccc", Height: 101}
	badTx := electrum.Transaction{Hash: "aaaaaa", Height: 102}

	eb.cacheTxs([]*electrum.Transaction{&tx1, &tx2})

	assert.Equal(t, int64(tx1.Height), eb.getTxHeight(tx1.Hash))
	assert.Equal(t, int64(tx2.Height), eb.getTxHeight(tx2.Hash))
	assert.Panics(t, func() { eb.getTxHeight(tx3.Hash) })

	eb.cacheTxs([]*electrum.Transaction{&tx2, &tx3})

	assert.Equal(t, int64(tx1.Height), eb.getTxHeight(tx1.Hash))
	assert.Equal(t, int64(tx2.Height), eb.getTxHeight(tx2.Hash))
	assert.Equal(t, int64(tx3.Height), eb.getTxHeight(tx3.Hash))

	assert.Panics(t, func() { eb.cacheTxs([]*electrum.Transaction{&badTx}) })
}


================================================
FILE: backend/fixture_backend.go
================================================
package backend

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"os"
	"sync"

	pkgerr "github.com/pkg/errors"
	"github.com/square/beancounter/deriver"
	"github.com/square/beancounter/reporter"
)

// FixtureBackend loads data from a file that was previously recorded by
// RecorderBackend
type FixtureBackend struct {
	addrIndexMu  sync.Mutex
	addrIndex    map[string]AddrResponse
	txIndexMu    sync.Mutex
	txIndex      map[string]TxResponse
	blockIndexMu sync.Mutex
	blockIndex   map[uint32]BlockResponse

	// channels used to communicate with the Accounter
	addrRequests  chan *deriver.Address
	addrResponses chan *AddrResponse
	txRequests    chan string
	txResponses   chan *TxResponse

	// channels used to communicate with the Blockfinder
	blockRequests  chan uint32
	blockResponses chan *BlockResponse

	transactionsMu sync.Mutex // mutex to guard read/writes to transactions map
	transactions   map[string]int64

	// internal channels
	doneCh chan bool

	readOnly bool

	height uint32
}

// NewFixtureBackend returns a new FixtureBackend structs or errors.
func NewFixtureBackend(filepath string) (*FixtureBackend, error) {
	cb := &FixtureBackend{
		addrRequests:   make(chan *deriver.Address, 10),
		addrResponses:  make(chan *AddrResponse, 10),
		txRequests:     make(chan string, 1000),
		txResponses:    make(chan *TxResponse, 1000),
		blockRequests:  make(chan uint32, 10),
		blockResponses: make(chan *BlockResponse, 10),
		addrIndex:      make(map[string]AddrResponse),
		txIndex:        make(map[string]TxResponse),
		blockIndex:     make(map[uint32]BlockResponse),
		transactions:   make(map[string]int64),
		doneCh:         make(chan bool),
	}

	f, err := os.Open(filepath)
	if err != nil {
		return nil, pkgerr.Wrap(err, "cannot open a fixture file")
	}
	defer f.Close()

	if err := cb.loadFromFile(f); err != nil {
		return nil, pkgerr.Wrap(err, "cannot load data from a fixture file")
	}

	go cb.processRequests()
	return cb, nil
}

// AddrRequest schedules a request to the backend to lookup information related
// to the given address.
func (fb *FixtureBackend) AddrRequest(addr *deriver.Address) {
	reporter.GetInstance().IncAddressesScheduled()
	reporter.GetInstance().Logf("[fixture] scheduling address: %s", addr)
	fb.addrRequests <- addr
}

// TxRequest schedules a request to the backend to lookup information related
// to the given transaction hash.
func (fb *FixtureBackend) TxRequest(txHash string) {
	reporter.GetInstance().IncTxScheduled()
	reporter.GetInstance().Logf("[fixture] scheduling tx: %s", txHash)
	fb.txRequests <- txHash
}

func (fb *FixtureBackend) BlockRequest(height uint32) {
	fb.blockRequests <- height
}

// AddrResponses exposes a channel that allows to consume backend's responses to
// address requests created with AddrRequest()
func (fb *FixtureBackend) AddrResponses() <-chan *AddrResponse {
	return fb.addrResponses
}

// TxResponses exposes a channel that allows to consume backend's responses to
// address requests created with addrrequest().
// if an address has any transactions then they will be sent to this channel by the
// backend.
func (fb *FixtureBackend) TxResponses() <-chan *TxResponse {
	return fb.txResponses
}

func (fb *FixtureBackend) BlockResponses() <-chan *BlockResponse {
	return fb.blockResponses
}

// Finish informs the backend to stop doing its work.
func (fb *FixtureBackend) Finish() {
	close(fb.doneCh)
}

func (fb *FixtureBackend) ChainHeight() uint32 {
	return fb.height
}

func (fb *FixtureBackend) processRequests() {
	for {
		select {
		case addr := <-fb.addrRequests:
			fb.processAddrRequest(addr)
		case tx := <-fb.txRequests:
			fb.processTxRequest(tx)
		case addrResp, ok := <-fb.addrResponses:
			if !ok {
				fb.addrResponses = nil
				continue
			}
			fb.addrResponses <- addrResp
		case txResp, ok := <-fb.txResponses:
			if !ok {
				fb.txResponses = nil
				continue
			}
			fb.txResponses <- txResp
		case block := <-fb.blockRequests:
			fb.processBlockRequest(block)
		case <-fb.doneCh:
			return
		}
	}
}

func (fb *FixtureBackend) processAddrRequest(addr *deriver.Address) {
	fb.addrIndexMu.Lock()
	resp, exists := fb.addrIndex[addr.String()]
	fb.addrIndexMu.Unlock()

	if exists {
		fb.addrResponses <- &resp
		return
	}

	// assuming that address has not been used
	fb.addrResponses <- &AddrResponse{
		Address: addr,
	}
}

func (fb *FixtureBackend) processTxRequest(txHash string) {
	fb.txIndexMu.Lock()
	resp, exists := fb.txIndex[txHash]
	fb.txIndexMu.Unlock()

	if exists {
		fb.txResponses <- &resp
		return
	}

	// assuming that transaction does not exist in the fixture file
}

func (fb *FixtureBackend) processBlockRequest(height uint32) {
	fb.blockIndexMu.Lock()
	resp, exists := fb.blockIndex[height]
	fb.blockIndexMu.Unlock()

	if exists {
		fb.blockResponses <- &resp
		return
	}
	log.Panicf("fixture doesn't contain block %d", height)
}

func (fb *FixtureBackend) loadFromFile(f *os.File) error {
	var cachedData index

	byteValue, err := ioutil.ReadAll(f)
	if err != nil {
		return err
	}

	err = json.Unmarshal(byteValue, &cachedData)
	if err != nil {
		return err
	}

	fb.height = cachedData.Metadata.Height

	for _, addr := range cachedData.Addresses {
		a := AddrResponse{
			Address:  deriver.NewAddress(addr.Path, addr.Address, addr.Network, addr.Change, addr.AddressIndex),
			TxHashes: addr.TxHashes,
		}
		fb.addrIndex[addr.Address] = a
	}

	for _, tx := range cachedData.Transactions {
		fb.txIndex[tx.Hash] = TxResponse{
			Hash:   tx.Hash,
			Height: tx.Height,
			Hex:    tx.Hex,
		}

		fb.transactions[tx.Hash] = tx.Height
	}

	for _, b := range cachedData.Blocks {
		fb.blockIndex[b.Height] = BlockResponse{
			Height:    b.Height,
			Timestamp: b.Timestamp,
		}
	}

	return nil
}


================================================
FILE: backend/fixture_backend_test.go
================================================
package backend

import (
	"sync"
	"testing"
	"time"

	"github.com/square/beancounter/deriver"
	. "github.com/square/beancounter/utils"
	"github.com/stretchr/testify/assert"
)

func TestNonExistantFixtureFile(t *testing.T) {
	b, err := NewFixtureBackend("testdata/badpath")
	assert.Nil(t, b)
	assert.Error(t, err)
}

func TestBadFixtureFile(t *testing.T) {
	b, err := NewFixtureBackend("testdata/nonjsonfixture")
	assert.Nil(t, b)
	assert.Error(t, err)
}

func TestFinish(t *testing.T) {
	b, err := NewFixtureBackend("../accounter/testdata/tpub_data.json")
	assert.NoError(t, err)

	closed := make(chan bool)
	go func(ch chan bool) {
		b.processRequests()
		closed <- true
	}(closed)

	b.Finish()

	select {
	case <-closed:
		// processRequests() shut down as expected
		// PASS
	case <-time.Tick(100 * time.Millisecond):
		t.Errorf("expected a call to Finish() to cleanly shutdown the FixtureBackend")
	}
}

func TestNoAddress(t *testing.T) {
	b, err := NewFixtureBackend("../accounter/testdata/tpub_data.json")
	assert.NoError(t, err)

	b.AddrRequest(deriver.NewAddress("m/1'/1/0/1", "BAD_ADDRESS", Testnet, 0, 1))

	var addrs []*AddrResponse
	var txs []*TxResponse

	fetchResults(b, &addrs, &txs, 100*time.Millisecond)

	// we don't know if address is legit or not, we just know if the address shows up
	// in the blockchain. The default behavior is just to return the address with no transactions
	assert.Len(t, addrs, 1)
	assert.False(t, addrs[0].HasTransactions())
	assert.Equal(t, "BAD_ADDRESS", addrs[0].Address.String())
	assert.Len(t, txs, 0)
}

func TestAddressNoTransactions(t *testing.T) {
	b, err := NewFixtureBackend("../accounter/testdata/tpub_data.json")
	assert.NoError(t, err)

	b.AddrRequest(deriver.NewAddress("m/1'/1234/0/61", "mfsNoNz57ANkYrCzHaLZDLoMGujBW8u3zv", Testnet, 0, 61))

	var addrs []*AddrResponse
	var txs []*TxResponse

	fetchResults(b, &addrs, &txs, 100*time.Millisecond)

	assert.Len(t, addrs, 1)
	assert.False(t, addrs[0].HasTransactions())
	assert.Equal(t, "mfsNoNz57ANkYrCzHaLZDLoMGujBW8u3zv", addrs[0].Address.String())
	assert.Len(t, txs, 0)
}

func TestAddressWithTransactions(t *testing.T) {
	b, err := NewFixtureBackend("../accounter/testdata/tpub_data.json")
	assert.NoError(t, err)

	b.AddrRequest(deriver.NewAddress("m/1'/1234/0/7", "mi2udMvJHeeJJNp5wWKToa86L2cJUKzrby", Testnet, 0, 7))

	var addrs []*AddrResponse
	var txs []*TxResponse

	fetchResults(b, &addrs, &txs, 100*time.Millisecond)

	assert.Len(t, addrs, 1)
	assert.True(t, addrs[0].HasTransactions())
	assert.Len(t, addrs[0].TxHashes, 2)
	assert.Contains(t, addrs[0].TxHashes, "5554c15d13002786a70a7151aad4eddce76633c60bc7f90e3dc70eb4f9c4b2b0")
	assert.Contains(t, addrs[0].TxHashes, "bd09a74381ffad78c162976ec27fc9c1dceda3c2bfe367541a7140b8dd6e1f4c")
	assert.Len(t, txs, 0)

	for _, tx := range addrs[0].TxHashes {
		b.TxRequest(tx)
	}

	fetchResults(b, &addrs, &txs, 100*time.Millisecond)
	// ensure that txs contain the same transaction hashes as addrs[0].TxHashes
	var txHashes []string
	txHashes = append(txHashes, txs[0].Hash)
	txHashes = append(txHashes, txs[1].Hash)
	assert.Contains(t, txHashes, "5554c15d13002786a70a7151aad4eddce76633c60bc7f90e3dc70eb4f9c4b2b0")
	assert.Contains(t, txHashes, "bd09a74381ffad78c162976ec27fc9c1dceda3c2bfe367541a7140b8dd6e1f4c")
}

func fetchResults(b Backend, addrs *[]*AddrResponse, txs *[]*TxResponse, timeout time.Duration) {
	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		addrResponses := b.AddrResponses()
		txResponses := b.TxResponses()
		for {
			select {
			case addrResp, ok := <-addrResponses:
				if !ok {
					addrResponses = nil
					continue
				}
				*addrs = append(*addrs, addrResp)
			case txResp, ok := <-txResponses:
				if !ok {
					txResponses = nil
					continue
				}
				*txs = append(*txs, txResp)
			case <-time.Tick(timeout):

				wg.Done()
				return
			}
		}
	}()

	wg.Wait()
}


================================================
FILE: backend/recorder_backend.go
================================================
package backend

import (
	"encoding/json"
	"fmt"
	"os"
	"sort"
	"sync"

	"github.com/square/beancounter/deriver"
	"github.com/square/beancounter/reporter"
)

// RecorderBackend wraps Btcd node and its API to provide a simple
// balance and transaction history information for a given address.
// RecorderBackend implements Backend interface.
type RecorderBackend struct {
	backend      Backend
	addrIndexMu  sync.Mutex
	addrIndex    map[string]AddrResponse
	txIndexMu    sync.Mutex
	txIndex      map[string]TxResponse
	blockIndexMu sync.Mutex
	blockIndex   map[uint32]BlockResponse

	// channels used to communicate with the Accounter
	addrResponses chan *AddrResponse
	txResponses   chan *TxResponse

	// channels used to communicate with the Blockfinder
	blockResponses chan *BlockResponse

	// internal channels
	doneCh chan bool

	outputFilepath string
}

// NewRecorderBackend returns a new RecorderBackend structs or errors.
// RecorderBackend passes requests to another backend and ten records
// address and transaction responses to a file. The file can later be used by a
// FixtureBackend to reply those responses.
func NewRecorderBackend(b Backend, filepath string) (*RecorderBackend, error) {
	rb := &RecorderBackend{
		backend:        b,
		addrResponses:  make(chan *AddrResponse, addrRequestsChanSize),
		txResponses:    make(chan *TxResponse, 2*maxTxsPerAddr),
		blockResponses: make(chan *BlockResponse, blockRequestChanSize),
		addrIndex:      make(map[string]AddrResponse),
		txIndex:        make(map[string]TxResponse),
		blockIndex:     make(map[uint32]BlockResponse),
		doneCh:         make(chan bool),
		outputFilepath: filepath,
	}

	go rb.processRequests()
	return rb, nil
}

// AddrRequest schedules a request to the backend to lookup information related
// to the given address.
func (rb *RecorderBackend) AddrRequest(addr *deriver.Address) {
	rb.backend.AddrRequest(addr)
}

// AddrResponses exposes a channel that allows to consume backend's responses to
// address requests created with AddrRequest()
func (rb *RecorderBackend) AddrResponses() <-chan *AddrResponse {
	return rb.addrResponses
}

// TxRequest schedules a request to the backend to lookup information related
// to the given transaction hash.
func (rb *RecorderBackend) TxRequest(txHash string) {
	rb.backend.TxRequest(txHash)
}

// TxResponses exposes a channel that allows to consume backend's responses to
// address requests created with addrrequest().
// if an address has any transactions then they will be sent to this channel by the
// backend.
func (rb *RecorderBackend) TxResponses() <-chan *TxResponse {
	return rb.txResponses
}

func (rb *RecorderBackend) BlockRequest(height uint32) {
	rb.backend.BlockRequest(height)
}

func (rb *RecorderBackend) BlockResponses() <-chan *BlockResponse {
	return rb.blockResponses
}

// Finish informs the backend to stop doing its work.
func (rb *RecorderBackend) Finish() {
	rb.backend.Finish()
	close(rb.doneCh)

	if err := rb.writeToFile(); err != nil {
		fmt.Println(err)
	}
}

func (rb *RecorderBackend) ChainHeight() uint32 {
	return rb.backend.ChainHeight()
}

func (rb *RecorderBackend) processRequests() {
	backendAddrResponses := rb.backend.AddrResponses()
	backendTxResponses := rb.backend.TxResponses()
	backendBlockResponses := rb.backend.BlockResponses()

	for {
		select {
		case addrResp, ok := <-backendAddrResponses:
			if !ok {
				backendAddrResponses = nil
				continue
			}
			rb.addrIndexMu.Lock()
			rb.addrIndex[addrResp.Address.String()] = *addrResp
			rb.addrIndexMu.Unlock()
			rb.addrResponses <- addrResp
		case txResp, ok := <-backendTxResponses:
			if !ok {
				backendTxResponses = nil
				continue
			}
			rb.txIndexMu.Lock()
			rb.txIndex[txResp.Hash] = *txResp
			rb.txIndexMu.Unlock()
			rb.txResponses <- txResp
		case block, ok := <-backendBlockResponses:
			if !ok {
				backendBlockResponses = nil
				continue
			}
			rb.blockIndexMu.Lock()
			rb.blockIndex[block.Height] = *block
			rb.blockIndexMu.Unlock()
			rb.blockResponses <- block
		case <-rb.doneCh:
			return
		}
	}
}

func (rb *RecorderBackend) writeToFile() error {
	cachedData := index{
		Metadata: metadata{}, Addresses: []address{}, Transactions: []transaction{},
		Blocks: []block{},
	}

	reporter.GetInstance().Logf("writing data to %s\n ...", rb.outputFilepath)
	f, err := os.Create(rb.outputFilepath)
	if err != nil {
		return err
	}
	defer f.Close()

	cachedData.Metadata.Height = rb.ChainHeight()

	for addr, addrResp := range rb.addrIndex {
		a := address{
			Address:      addr,
			Path:         addrResp.Address.Path(),
			Network:      addrResp.Address.Network(),
			Change:       addrResp.Address.Change(),
			AddressIndex: addrResp.Address.Index(),
			TxHashes:     addrResp.TxHashes,
		}
		cachedData.Addresses = append(cachedData.Addresses, a)
	}

	sort.Sort(byAddress(cachedData.Addresses))

	for _, txResp := range rb.txIndex {
		tx := transaction{
			Hash:   txResp.Hash,
			Height: txResp.Height,
			Hex:    txResp.Hex,
		}
		cachedData.Transactions = append(cachedData.Transactions, tx)
	}
	sort.Sort(byTransactionID(cachedData.Transactions))

	for _, b := range rb.blockIndex {
		cachedData.Blocks = append(cachedData.Blocks, block{
			Height:    b.Height,
			Timestamp: b.Timestamp,
		})
	}

	cachedDataJSON, err := json.MarshalIndent(cachedData, "", "    ")
	if err != nil {
		return err
	}

	_, err = f.Write(cachedDataJSON)
	if err != nil {
		return err
	}

	return nil
}


================================================
FILE: backend/testdata/nonjsonfixture
================================================
SOME DATA THAT'S NOT VALID JSON


================================================
FILE: blockfinder/blockfinder.go
================================================
package blockfinder

import (
	"fmt"
	"github.com/square/beancounter/backend"
	"sort"
	"time"
)

// Blockfinder uses the backend to find the last block before a given timestamp.
// For each block, the block's time is computed by taking the median of the previous  11 blocks.
type Blockfinder struct {
	blocks         map[uint32]time.Time
	backend        backend.Backend
	blockResponses <-chan *backend.BlockResponse
}

// New instantiates a new Blockfinder
func New(b backend.Backend) *Blockfinder {
	bf := &Blockfinder{
		backend: b,
	}
	bf.blocks = make(map[uint32]time.Time)
	bf.blockResponses = b.BlockResponses()
	return bf
}

// Returns block height, block median, block timestamp
func (bf *Blockfinder) Search(timestamp time.Time) (uint32, time.Time, time.Time) {
	target := timestamp.Unix()

	min := uint32(10) // any small number above 5 works
	minMedian := bf.searchSync(min)

	// Use chainheight - 6 (because of min confirmations) - 5 (because of the way we compute median)
	max := bf.backend.ChainHeight() - 11
	maxMedian := bf.searchSync(max)

	for max-min > 1 {
		avg := (max + min) / 2
		avgTimestamp := bf.searchSync(avg)
		fmt.Printf("min: %d %d, avg: %d %d, max: %d %d, target: %d\n",
			min, minMedian, avg, avgTimestamp, max, maxMedian, target)

		if avgTimestamp < minMedian || avgTimestamp > maxMedian {
			panic("non-monotonic medians")
		}

		if target == avgTimestamp {
			min = avg
			minMedian = avgTimestamp
			break
		} else if target > avgTimestamp {
			min = avg
			minMedian = avgTimestamp
		} else {
			max = avg
			maxMedian = avgTimestamp
		}
	}

	bf.backend.BlockRequest(min)
	blockHeader := <-bf.blockResponses

	// Give recorder backend a chance to write the data
	bf.backend.Finish()

	return min, time.Unix(minMedian, 0), blockHeader.Timestamp
}

// TODO: cache requests
// around 283655 is a good test case for this function...
// We define the median time as the median of time timestamps from 5 blocks before and 5 blocks
// after. We have to pick a total of 11 blocks, because that's how the validation rule is defined.
// (https://en.bitcoin.it/wiki/Block_timestamp, https://github.com/bitcoin/bitcoin/blob/0.17/src/chain.h#L307)
// but we don't have to do the previous 11. Any consecutive 11 blocks has monotonic medians. By looking
// at the previous 5 and next 5, we reduce the delta between the block time displayed on a website
// such as live.blockcypher.com and the median we compute. It makes things less confusing for people
// who might not understand why we need to look at the median.
func (bf *Blockfinder) searchSync(height uint32) int64 {
	for i := height - 5; i <= (height + 5); i++ {
		bf.backend.BlockRequest(i)
	}
	timestamps := []int64{}
	for i := 0; i < 11; i++ {
		blockHeader := <-bf.blockResponses
		timestamps = append(timestamps, blockHeader.Timestamp.Unix())
	}
	sort.Slice(timestamps, func(i, j int) bool { return timestamps[i] < timestamps[j] })
	return timestamps[5]
}


================================================
FILE: blockfinder/blockfinder_test.go
================================================
package blockfinder

import (
	"github.com/square/beancounter/backend"
	"github.com/stretchr/testify/assert"
	"testing"
	"time"
)

func TestFindBLock(t *testing.T) {
	b, err := backend.NewFixtureBackend("../fixtures/blocks.json")
	assert.NoError(t, err)

	bf := New(b)
	height, median, timestamp := bf.Search(time.Unix(1533153600, 0))

	assert.Equal(t, height, uint32(534733))
	assert.Equal(t, median.Unix(), int64(1533152846))
	assert.Equal(t, timestamp.Unix(), int64(1533152846))
}


================================================
FILE: deriver/address_deriver.go
================================================
package deriver

import (
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"log"
	"sort"

	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcutil"
	"github.com/btcsuite/btcutil/hdkeychain"

	. "github.com/square/beancounter/utils"
)

// AddressDeriver is a struct that contains necessary information to derive
// an address from a given extended public key (or list of public keys).
// It follows the conventions as written in BIP32
// // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format
type AddressDeriver struct {
	network       Network
	xpubs         []string
	m             int
	singleAddress string
}

// Address wraps a simple wallet address.
// It contains information such as network type (e.g. mainnet or testnet), derivation
// path (e.g. m/0/0/123/50), change value and address index.
type Address struct {
	path      string
	addr      string
	net       Network
	change    uint32
	addrIndex uint32
}

// NewAddress creates a new instance of Address, given network, derivation path,
// change value and address index.
func NewAddress(path, addr string, net Network, change, addrIndex uint32) *Address {
	return &Address{path: path, addr: addr, net: net, change: change, addrIndex: addrIndex}
}

// Path returns derivation path
func (a *Address) Path() string {
	return a.path
}

// String returns the address as string
func (a *Address) String() string {
	return a.addr
}

// Change returns the change value (so 0 or 1)
func (a *Address) Change() uint32 {
	return a.change
}

// Index returns the address index
func (a *Address) Index() uint32 {
	return a.addrIndex
}

func (a *Address) Network() Network {
	return a.net
}

func (a *Address) Address() btcutil.Address {
	address, err := btcutil.DecodeAddress(a.addr, a.net.ChainConfig())
	if err != nil {
		panic("failed to decode address")
	}

	return address
}

// TODO: might be more efficient to store the script in the struct.
func (a *Address) Script() string {
	address := a.Address()
	script, err := txscript.PayToAddrScript(address)
	if err != nil {
		panic("failed to encode script")
	}
	return hex.EncodeToString(script)
}

// NewAddressDeriver returns a new instance of AddressDeriver
func NewAddressDeriver(network Network, xpubs []string, m int, singleAddress string) *AddressDeriver {
	return &AddressDeriver{
		network:       network,
		xpubs:         xpubs,
		m:             m,
		singleAddress: singleAddress,
	}
}

// Derive dervives an address for given change and address index.
// It supports derivation using single extended public key and multisig + segwit.
func (d *AddressDeriver) Derive(change uint32, addressIndex uint32) *Address {
	if d.singleAddress != "" {
		return &Address{
			path:      "n/a",
			addr:      d.singleAddress,
			net:       d.network,
			change:    0,
			addrIndex: 0,
		}
	}

	path := fmt.Sprintf("m/.../%d/%d", change, addressIndex)
	addr := &Address{path: path, net: d.network, change: change, addrIndex: addressIndex}
	if len(d.xpubs) == 1 {
		addr.addr = d.singleDerive(change, addressIndex)
		return addr
	}
	addr.addr = d.multiSigSegwitDerive(change, addressIndex)
	return addr
}

// singleDerive performs a derivation using a single extended public key
func (d *AddressDeriver) singleDerive(change uint32, addressIndex uint32) string {
	key, err := hdkeychain.NewKeyFromString(d.xpubs[0])
	PanicOnError(err)

	key, err = key.Child(change)
	PanicOnError(err)

	key, err = key.Child(addressIndex)
	PanicOnError(err)

	pubKey, err := key.Address(d.network.ChainConfig())
	PanicOnError(err)

	return pubKey.String()
}

// multiSigSegwitDerive performs a multisig + segwit derivation.
func (d *AddressDeriver) multiSigSegwitDerive(change uint32, addressIndex uint32) string {
	pubKeysBytes := make([][]byte, 0, len(d.xpubs))
	pubKeys := make([]*btcutil.AddressPubKey, 0, len(d.xpubs))

	for _, xpub := range d.xpubs {
		key, err := hdkeychain.NewKeyFromString(xpub)
		PanicOnError(err)

		key, err = key.Child(change)
		PanicOnError(err)

		key, err = key.Child(addressIndex)
		PanicOnError(err)

		pubKey, err := key.ECPubKey()
		PanicOnError(err)

		pubKeyBytes := pubKey.SerializeCompressed()
		if len(pubKeyBytes) != 33 {
			log.Panicf("expected pubkey length 33, got %d", len(pubKeyBytes))
		}

		pubKeysBytes = append(pubKeysBytes, pubKeyBytes)

		sortByteArrays(pubKeysBytes)
	}

	for _, pubKeyBytes := range pubKeysBytes {
		key, err := btcutil.NewAddressPubKey(pubKeyBytes, d.network.ChainConfig())
		PanicOnError(err)
		pubKeys = append(pubKeys, key)
	}

	multiSigScript, err := txscript.MultiSigScript(pubKeys, d.m)
	PanicOnError(err)

	sha := sha256.Sum256(multiSigScript)

	segWitScriptBuilder := txscript.NewScriptBuilder()
	segWitScriptBuilder.AddOp(txscript.OP_0)
	segWitScriptBuilder.AddData(sha[:])
	segWitScript, err := segWitScriptBuilder.Script()
	PanicOnError(err)

	addrScriptHash, err := btcutil.NewAddressScriptHash(segWitScript, d.network.ChainConfig())
	PanicOnError(err)

	return addrScriptHash.EncodeAddress()
}

// implement `Interface` in sort package.
type sortedByteArrays [][]byte

func (b sortedByteArrays) Len() int {
	return len(b)
}

func (b sortedByteArrays) Less(i, j int) bool {
	// bytes package already implements Comparable for []byte.
	switch bytes.Compare(b[i], b[j]) {
	case -1:
		return true
	case 0, 1:
		return false
	default:
		log.Panic("not fail-able with `bytes.Comparable` bounded [-1, 1].")
		return false
	}
}

func (b sortedByteArrays) Swap(i, j int) {
	b[j], b[i] = b[i], b[j]
}

func sortByteArrays(src [][]byte) [][]byte {
	sorted := sortedByteArrays(src)
	sort.Sort(sorted)
	return sorted
}


================================================
FILE: deriver/address_deriver_test.go
================================================
package deriver

import (
	"testing"

	. "github.com/square/beancounter/utils"
	"github.com/stretchr/testify/assert"
)

func TestAddress(t *testing.T) {
	deriver := NewAddressDeriver(Mainnet, []string{"xpub6CjzRxucHWJbmtuNTg6EjPax3V75AhsBRnFKn8MEkc8UFFEhrCoWcQN6oUBhfZWoFKqTyQ21iNVK8KMbC44ifW25uyXaMPWkRtpwcbAWXJx"}, 1, "")
	addr := deriver.Derive(0, 5)
	assert.Equal(t, addr.Path(), "m/.../0/5")
	assert.Equal(t, addr.String(), "1N4VBTZqwLkHEKX79kjJ1WaYvX4c3txioz")
	assert.Equal(t, addr.Change(), uint32(0))
	assert.Equal(t, addr.Index(), uint32(5))
	assert.Equal(t, addr.Network(), Mainnet)
	assert.Equal(t, addr.Script(), "76a914e70369bfda4ba9bdcbb96cfd269a768573d0624c88ac")
}

func TestDeriveMultiSigSegwit(t *testing.T) {
	xpubs := []string{
		"tpubDAiPiLZeUdwo9oJiE9GZnteXj2E2MEMUb4knc4yCD87bL9siDgYcvrZSHZQZcYTyraL3fxVBRCcMiyfr3oQfH1wNo8J5i8aRAN56dDXaZxC",
		"tpubDBYBpkSfvt9iVSfdX2ArZq1Q8bVSro3sotbJhdZCG9rgfjdr4aZp7g7AF1P9w95X5fzuJzdZAqYWWU7nb37c594wR22hPY5VpYziXUN2yez",
		"tpubDAaTEMnf9SPKJweLaptFdy3Vmyhim5DKQxXRbsCxmAaUp8F84YD5GhdfmABwLddjHTftSVvUPuSru6vJ3b5N2hBveiGmZNE5N5yvB6WZ96c",
		"tpubDAXKYCetkje8HRRhAvUbAyuC5iF3SgfFWCVXfmrGCw3H9ExCYZVTEoeg7TjtDhgkS7TNHDRZUQNzGACWVzZCAYXy79vqku5z1geYmnsNLaa",
	}
	deriver := NewAddressDeriver(Testnet, xpubs, 2, "")
	assert.Equal(t, "2N4TmnHspa8wqFEUfxfjzHoSUAgwoUwNWhr", deriver.Derive(0, 0).String())
}

func TestDeriveGateway(t *testing.T) {
	xpubs := []string{
		"tpubDBrCAXucLxvjC9n9nZGGcYS8pk4X1N97YJmUgdDSwG2p36gbSqeRuytHYCHe2dHxLsV2EchX9ePaFdRwp7cNLrSpnr3PsoPLUQqbvLBDWvh",
	}
	deriver := NewAddressDeriver(Testnet, xpubs, 1, "")
	assert.Equal(t, "mzoeuyGqMudyvKbkNx5dtNBNN59oKEAsPn", deriver.Derive(0, 0).String())
	assert.Equal(t, "moHN13u4RoMxujdaPxvuaTaawgWZ3LaGyo", deriver.Derive(1, 0).String())
}


================================================
FILE: fixtures/blocks.json
================================================
{
    "metadata": {
        "height": 546110
    },
    "addresses": [],
    "transactions": [],
    "blocks": [
        {
            "height": 533300,
            "timestamp": "2018-07-23T09:00:55-07:00"
        },
        {
            "height": 533296,
            "timestamp": "2018-07-23T08:42:44-07:00"
        },
        {
            "height": 534731,
            "timestamp": "2018-08-01T12:35:25-07:00"
        },
        {
            "height": 534728,
            "timestamp": "2018-08-01T11:59:43-07:00"
        },
        {
            "height": 546094,
            "timestamp": "2018-10-16T20:21:33-07:00"
        },
        {
            "height": 533295,
            "timestamp": "2018-07-23T08:42:08-07:00"
        },
        {
            "height": 535435,
            "timestamp": "2018-08-05T19:32:32-07:00"
        },
        {
            "height": 534700,
            "timestamp": "2018-08-01T07:03:39-07:00"
        },
        {
            "height": 534725,
            "timestamp": "2018-08-01T11:22:00-07:00"
        },
        {
            "height": 477837,
            "timestamp": "2017-07-27T11:31:50-07:00"
        },
        {
            "height": 537568,
            "timestamp": "2018-08-19T16:58:47-07:00"
        },
        {
            "height": 537570,
            "timestamp": "2018-08-19T17:06:00-07:00"
        },
        {
            "height": 533294,
            "timestamp": "2018-07-23T08:27:11-07:00"
        },
        {
            "height": 15,
            "timestamp": "2009-01-09T20:45:46-08:00"
        },
        {
            "height": 409575,
            "timestamp": "2016-04-30T06:44:47-07:00"
        },
        {
            "height": 477839,
            "timestamp": "2017-07-27T11:34:11-07:00"
        },
        {
            "height": 511966,
            "timestamp": "2018-03-04T05:44:23-08:00"
        },
        {
            "height": 529029,
            "timestamp": "2018-06-24T06:48:56-07:00"
        },
        {
            "height": 534367,
            "timestamp": "2018-07-30T01:02:11-07:00"
        },
        {
            "height": 534763,
            "timestamp": "2018-08-01T17:07:00-07:00"
        },
        {
            "height": 534635,
            "timestamp": "2018-07-31T20:13:52-07:00"
        },
        {
            "height": 477834,
            "timestamp": "2017-07-27T11:04:27-07:00"
        },
        {
            "height": 511973,
            "timestamp": "2018-03-04T06:26:10-08:00"
        },
        {
            "height": 511965,
            "timestamp": "2018-03-04T05:41:02-08:00"
        },
        {
            "height": 533301,
            "timestamp": "2018-07-23T09:07:43-07:00"
        },
        {
            "height": 533304,
            "timestamp": "2018-07-23T10:14:47-07:00"
        },
        {
            "height": 535436,
            "timestamp": "2018-08-05T20:18:18-07:00"
        },
        {
            "height": 534630,
            "timestamp": "2018-07-31T19:05:01-07:00"
        },
        {
            "height": 5,
            "timestamp": "2009-01-08T19:23:48-08:00"
        },
        {
            "height": 273054,
            "timestamp": "2013-12-04T09:16:15-08:00"
        },
        {
            "height": 529035,
            "timestamp": "2018-06-24T07:55:41-07:00"
        },
        {
            "height": 537563,
            "timestamp": "2018-08-19T16:00:28-07:00"
        },
        {
            "height": 534745,
            "timestamp": "2018-08-01T15:24:37-07:00"
        },
        {
            "height": 534736,
            "timestamp": "2018-08-01T13:20:08-07:00"
        },
        {
            "height": 477838,
            "timestamp": "2017-07-27T11:32:53-07:00"
        },
        {
            "height": 511971,
            "timestamp": "2018-03-04T06:19:56-08:00"
        },
        {
            "height": 535428,
            "timestamp": "2018-08-05T18:55:22-07:00"
        },
        {
            "height": 534896,
            "timestamp": "2018-08-02T13:07:07-07:00"
        },
        {
            "height": 534694,
            "timestamp": "2018-08-01T05:59:06-07:00"
        },
        {
            "height": 534730,
            "timestamp": "2018-08-01T12:25:35-07:00"
        },
        {
            "height": 534767,
            "timestamp": "2018-08-01T17:27:13-07:00"
        },
        {
            "height": 546096,
            "timestamp": "2018-10-16T20:51:12-07:00"
        },
        {
            "height": 546099,
            "timestamp": "2018-10-16T21:30:25-07:00"
        },
        {
            "height": 409581,
            "timestamp": "2016-04-30T07:30:26-07:00"
        },
        {
            "height": 529031,
            "timestamp": "2018-06-24T07:17:08-07:00"
        },
        {
            "height": 534370,
            "timestamp": "2018-07-30T01:14:58-07:00"
        },
        {
            "height": 534631,
            "timestamp": "2018-07-31T19:18:04-07:00"
        },
        {
            "height": 534632,
            "timestamp": "2018-07-31T19:36:14-07:00"
        },
        {
            "height": 534699,
            "timestamp": "2018-08-01T06:52:11-07:00"
        },
        {
            "height": 534749,
            "timestamp": "2018-08-01T15:44:22-07:00"
        },
        {
            "height": 6,
            "timestamp": "2009-01-08T19:29:49-08:00"
        },
        {
            "height": 409580,
            "timestamp": "2016-04-30T07:13:46-07:00"
        },
        {
            "height": 529033,
            "timestamp": "2018-06-24T07:35:37-07:00"
        },
        {
            "height": 534366,
            "timestamp": "2018-07-30T00:12:54-07:00"
        },
        {
            "height": 534744,
            "timestamp": "2018-08-01T15:20:00-07:00"
        },
        {
            "height": 546095,
            "timestamp": "2018-10-16T20:31:45-07:00"
        },
        {
            "height": 409574,
            "timestamp": "2016-04-30T06:43:18-07:00"
        },
        {
            "height": 273050,
            "timestamp": "2013-12-04T08:27:28-08:00"
        },
        {
            "height": 511964,
            "timestamp": "2018-03-04T05:36:00-08:00"
        },
        {
            "height": 533298,
            "timestamp": "2018-07-23T08:49:32-07:00"
        },
        {
            "height": 534368,
            "timestamp": "2018-07-30T01:02:53-07:00"
        },
        {
            "height": 534369,
            "timestamp": "2018-07-30T01:07:40-07:00"
        },
        {
            "height": 534693,
            "timestamp": "2018-08-01T05:47:26-07:00"
        },
        {
            "height": 534743,
            "timestamp": "2018-08-01T15:04:47-07:00"
        },
        {
            "height": 534894,
            "timestamp": "2018-08-02T12:51:43-07:00"
        },
        {
            "height": 10,
            "timestamp": "2009-01-08T20:05:52-08:00"
        },
        {
            "height": 546104,
            "timestamp": "2018-10-16T22:30:25-07:00"
        },
        {
            "height": 273058,
            "timestamp": "2013-12-04T09:55:46-08:00"
        },
        {
            "height": 511970,
            "timestamp": "2018-03-04T06:08:35-08:00"
        },
        {
            "height": 529030,
            "timestamp": "2018-06-24T07:16:42-07:00"
        },
        {
            "height": 535429,
            "timestamp": "2018-08-05T19:00:45-07:00"
        },
        {
            "height": 534365,
            "timestamp": "2018-07-30T00:09:57-07:00"
        },
        {
            "height": 534636,
            "timestamp": "2018-07-31T20:19:27-07:00"
        },
        {
            "height": 537569,
            "timestamp": "2018-08-19T17:04:08-07:00"
        },
        {
            "height": 535431,
            "timestamp": "2018-08-05T19:06:24-07:00"
        },
        {
            "height": 9,
            "timestamp": "2009-01-08T19:54:39-08:00"
        },
        {
            "height": 546098,
            "timestamp": "2018-10-16T21:10:28-07:00"
        },
        {
            "height": 546100,
            "timestamp": "2018-10-16T21:31:23-07:00"
        },
        {
            "height": 273051,
            "timestamp": "2013-12-04T08:24:52-08:00"
        },
        {
            "height": 535432,
            "timestamp": "2018-08-05T19:12:26-07:00"
        },
        {
            "height": 14,
            "timestamp": "2009-01-08T20:33:09-08:00"
        },
        {
            "height": 546103,
            "timestamp": "2018-10-16T22:04:23-07:00"
        },
        {
            "height": 534363,
            "timestamp": "2018-07-29T23:52:13-07:00"
        },
        {
            "height": 534903,
            "timestamp": "2018-08-02T14:48:04-07:00"
        },
        {
            "height": 534762,
            "timestamp": "2018-08-01T16:50:36-07:00"
        },
        {
            "height": 534761,
            "timestamp": "2018-08-01T16:47:23-07:00"
        },
        {
            "height": 529037,
            "timestamp": "2018-06-24T08:02:00-07:00"
        },
        {
            "height": 534627,
            "timestamp": "2018-07-31T18:39:49-07:00"
        },
        {
            "height": 534741,
            "timestamp": "2018-08-01T14:32:19-07:00"
        },
        {
            "height": 534752,
            "timestamp": "2018-08-01T16:09:06-07:00"
        },
        {
            "height": 12,
            "timestamp": "2009-01-08T20:21:28-08:00"
        },
        {
            "height": 409577,
            "timestamp": "2016-04-30T06:52:32-07:00"
        },
        {
            "height": 529034,
            "timestamp": "2018-06-24T07:37:17-07:00"
        },
        {
            "height": 535430,
            "timestamp": "2018-08-05T19:05:15-07:00"
        },
        {
            "height": 534897,
            "timestamp": "2018-08-02T13:10:34-07:00"
        },
        {
            "height": 534902,
            "timestamp": "2018-08-02T14:31:21-07:00"
        },
        {
            "height": 534629,
            "timestamp": "2018-07-31T19:04:21-07:00"
        },
        {
            "height": 534361,
            "timestamp": "2018-07-29T23:30:51-07:00"
        },
        {
            "height": 409571,
            "timestamp": "2016-04-30T06:35:06-07:00"
        },
        {
            "height": 409576,
            "timestamp": "2016-04-30T06:48:53-07:00"
        },
        {
            "height": 477835,
            "timestamp": "2017-07-27T11:10:14-07:00"
        },
        {
            "height": 529032,
            "timestamp": "2018-06-24T07:35:10-07:00"
        },
        {
            "height": 529036,
            "timestamp": "2018-06-24T08:00:07-07:00"
        },
        {
            "height": 535427,
            "timestamp": "2018-08-05T18:44:40-07:00"
        },
        {
            "height": 534362,
            "timestamp": "2018-07-29T23:47:30-07:00"
        },
        {
            "height": 534628,
            "timestamp": "2018-07-31T18:52:59-07:00"
        },
        {
            "height": 534733,
            "timestamp": "2018-08-01T12:47:26-07:00"
        },
        {
            "height": 273053,
            "timestamp": "2013-12-04T09:01:05-08:00"
        },
        {
            "height": 273055,
            "timestamp": "2013-12-04T09:20:58-08:00"
        },
        {
            "height": 409572,
            "timestamp": "2016-04-30T06:35:43-07:00"
        },
        {
            "height": 477832,
            "timestamp": "2017-07-27T10:23:10-07:00"
        },
        {
            "height": 534898,
            "timestamp": "2018-08-02T13:15:23-07:00"
        },
        {
            "height": 534747,
            "timestamp": "2018-08-01T15:37:52-07:00"
        },
        {
            "height": 273049,
            "timestamp": "2013-12-04T08:15:47-08:00"
        },
        {
            "height": 477833,
            "timestamp": "2017-07-27T10:27:18-07:00"
        },
        {
            "height": 477841,
            "timestamp": "2017-07-27T12:03:49-07:00"
        },
        {
            "height": 511972,
            "timestamp": "2018-03-04T06:25:39-08:00"
        },
        {
            "height": 533299,
            "timestamp": "2018-07-23T08:55:38-07:00"
        },
        {
            "height": 534901,
            "timestamp": "2018-08-02T14:29:22-07:00"
        },
        {
            "height": 534702,
            "timestamp": "2018-08-01T07:15:54-07:00"
        },
        {
            "height": 534739,
            "timestamp": "2018-08-01T14:10:26-07:00"
        },
        {
            "height": 546097,
            "timestamp": "2018-10-16T20:52:28-07:00"
        },
        {
            "height": 409578,
            "timestamp": "2016-04-30T06:55:24-07:00"
        },
        {
            "height": 534364,
            "timestamp": "2018-07-30T00:06:22-07:00"
        },
        {
            "height": 534698,
            "timestamp": "2018-08-01T06:37:12-07:00"
        },
        {
            "height": 534740,
            "timestamp": "2018-08-01T14:16:36-07:00"
        },
        {
            "height": 409579,
            "timestamp": "2016-04-30T07:08:07-07:00"
        },
        {
            "height": 511967,
            "timestamp": "2018-03-04T05:53:30-08:00"
        },
        {
            "height": 537564,
            "timestamp": "2018-08-19T16:27:17-07:00"
        },
        {
            "height": 534633,
            "timestamp": "2018-07-31T19:47:39-07:00"
        },
        {
            "height": 534759,
            "timestamp": "2018-08-01T16:42:56-07:00"
        },
        {
            "height": 534732,
            "timestamp": "2018-08-01T12:40:59-07:00"
        },
        {
            "height": 534742,
            "timestamp": "2018-08-01T14:42:33-07:00"
        },
        {
            "height": 534692,
            "timestamp": "2018-08-01T05:43:04-07:00"
        },
        {
            "height": 529038,
            "timestamp": "2018-06-24T08:02:19-07:00"
        },
        {
            "height": 537571,
            "timestamp": "2018-08-19T17:06:50-07:00"
        },
        {
            "height": 533303,
            "timestamp": "2018-07-23T09:51:22-07:00"
        },
        {
            "height": 533297,
            "timestamp": "2018-07-23T08:43:54-07:00"
        },
        {
            "height": 534626,
            "timestamp": "2018-07-31T18:35:58-07:00"
        },
        {
            "height": 534764,
            "timestamp": "2018-08-01T17:14:46-07:00"
        },
        {
            "height": 534760,
            "timestamp": "2018-08-01T16:45:41-07:00"
        },
        {
            "height": 534735,
            "timestamp": "2018-08-01T13:12:26-07:00"
        },
        {
            "height": 11,
            "timestamp": "2009-01-08T20:12:40-08:00"
        },
        {
            "height": 534748,
            "timestamp": "2018-08-01T15:39:54-07:00"
        },
        {
            "height": 537565,
            "timestamp": "2018-08-19T16:37:35-07:00"
        },
        {
            "height": 533302,
            "timestamp": "2018-07-23T09:50:01-07:00"
        },
        {
            "height": 534893,
            "timestamp": "2018-08-02T12:50:04-07:00"
        },
        {
            "height": 534738,
            "timestamp": "2018-08-01T13:45:07-07:00"
        },
        {
            "height": 535437,
            "timestamp": "2018-08-05T20:39:44-07:00"
        },
        {
            "height": 534634,
            "timestamp": "2018-07-31T20:13:39-07:00"
        },
        {
            "height": 534766,
            "timestamp": "2018-08-01T17:25:16-07:00"
        },
        {
            "height": 534696,
            "timestamp": "2018-08-01T06:21:54-07:00"
        },
        {
            "height": 534701,
            "timestamp": "2018-08-01T07:12:46-07:00"
        },
        {
            "height": 534695,
            "timestamp": "2018-08-01T06:10:36-07:00"
        },
        {
            "height": 534751,
            "timestamp": "2018-08-01T15:57:39-07:00"
        },
        {
            "height": 534697,
            "timestamp": "2018-08-01T06:31:33-07:00"
        },
        {
            "height": 546101,
            "timestamp": "2018-10-16T21:39:58-07:00"
        },
        {
            "height": 273059,
            "timestamp": "2013-12-04T10:11:46-08:00"
        },
        {
            "height": 477836,
            "timestamp": "2017-07-27T11:16:54-07:00"
        },
        {
            "height": 511969,
            "timestamp": "2018-03-04T05:57:00-08:00"
        },
        {
            "height": 537567,
            "timestamp": "2018-08-19T16:56:45-07:00"
        },
        {
            "height": 534895,
            "timestamp": "2018-08-02T13:04:53-07:00"
        },
        {
            "height": 534765,
            "timestamp": "2018-08-01T17:20:59-07:00"
        },
        {
            "height": 8,
            "timestamp": "2009-01-08T19:45:43-08:00"
        },
        {
            "height": 477840,
            "timestamp": "2017-07-27T11:51:16-07:00"
        },
        {
            "height": 534900,
            "timestamp": "2018-08-02T14:20:52-07:00"
        },
        {
            "height": 534729,
            "timestamp": "2018-08-01T12:00:36-07:00"
        },
        {
            "height": 534737,
            "timestamp": "2018-08-01T13:41:56-07:00"
        },
        {
            "height": 409573,
            "timestamp": "2016-04-30T06:37:41-07:00"
        },
        {
            "height": 535433,
            "timestamp": "2018-08-05T19:12:38-07:00"
        },
        {
            "height": 535434,
            "timestamp": "2018-08-05T19:24:21-07:00"
        },
        {
            "height": 534360,
            "timestamp": "2018-07-29T23:22:24-07:00"
        },
        {
            "height": 534734,
            "timestamp": "2018-08-01T13:10:35-07:00"
        },
        {
            "height": 534726,
            "timestamp": "2018-08-01T11:45:10-07:00"
        },
        {
            "height": 534750,
            "timestamp": "2018-08-01T15:55:44-07:00"
        },
        {
            "height": 534727,
            "timestamp": "2018-08-01T11:47:16-07:00"
        },
        {
            "height": 7,
            "timestamp": "2009-01-08T19:39:29-08:00"
        },
        {
            "height": 273057,
            "timestamp": "2013-12-04T09:53:04-08:00"
        },
        {
            "height": 477842,
            "timestamp": "2017-07-27T12:11:49-07:00"
        },
        {
            "height": 529028,
            "timestamp": "2018-06-24T06:47:19-07:00"
        },
        {
            "height": 537566,
            "timestamp": "2018-08-19T16:38:25-07:00"
        },
        {
            "height": 537562,
            "timestamp": "2018-08-19T15:58:05-07:00"
        },
        {
            "height": 534768,
            "timestamp": "2018-08-01T17:29:09-07:00"
        },
        {
            "height": 273052,
            "timestamp": "2013-12-04T08:54:08-08:00"
        },
        {
            "height": 273056,
            "timestamp": "2013-12-04T09:44:34-08:00"
        },
        {
            "height": 511963,
            "timestamp": "2018-03-04T05:32:35-08:00"
        },
        {
            "height": 511968,
            "timestamp": "2018-03-04T05:56:25-08:00"
        },
        {
            "height": 13,
            "timestamp": "2009-01-08T20:23:40-08:00"
        },
        {
            "height": 546102,
            "timestamp": "2018-10-16T21:50:43-07:00"
        },
        {
            "height": 537561,
            "timestamp": "2018-08-19T14:55:35-07:00"
        },
        {
            "height": 534899,
            "timestamp": "2018-08-02T13:42:25-07:00"
        },
        {
            "height": 534769,
            "timestamp": "2018-08-01T17:41:17-07:00"
        },
        {
            "height": 534746,
            "timestamp": "2018-08-01T15:37:21-07:00"
        }
    ]
}


================================================
FILE: go.mod
================================================
module github.com/square/beancounter

go 1.12

require (
	github.com/Masterminds/semver v1.5.0
	github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
	github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
	github.com/bcext/cashutil v0.0.0-20180827115045-9ba6cf292283
	github.com/bcext/gcash v0.0.0-20180921133405-3f4b56493047 // indirect
	github.com/btcsuite/btcd v0.0.0-20180924021209-2a560b2036be
	github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect
	github.com/btcsuite/btcutil v0.0.0-20180706230648-ab6388e0c60a
	github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect
	github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect
	github.com/davecgh/go-spew v1.1.1 // indirect
	github.com/pkg/errors v0.9.1
	github.com/stretchr/testify v1.7.0
	golang.org/x/crypto v0.0.0-20181001203147-e3636079e1a4 // indirect
Download .txt
gitextract_x09c0s2c/

├── .github/
│   └── dependabot.yml
├── .gitignore
├── .travis.yml
├── BUG-BOUNTY.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── WHY.md
├── accounter/
│   ├── accounter.go
│   ├── accounter_test.go
│   └── testdata/
│       └── tpub_data.json
├── backend/
│   ├── backend.go
│   ├── btcd_backend.go
│   ├── common.go
│   ├── electrum/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── blockchain.go
│   │   └── tcp.go
│   ├── electrum_backend.go
│   ├── electrum_backend_test.go
│   ├── fixture_backend.go
│   ├── fixture_backend_test.go
│   ├── recorder_backend.go
│   └── testdata/
│       └── nonjsonfixture
├── blockfinder/
│   ├── blockfinder.go
│   └── blockfinder_test.go
├── deriver/
│   ├── address_deriver.go
│   └── address_deriver_test.go
├── fixtures/
│   └── blocks.json
├── go.mod
├── go.sum
├── main.go
├── reporter/
│   └── reporter.go
├── utils/
│   ├── utils.go
│   └── utils_test.go
└── vendor/
    ├── github.com/
    │   ├── Masterminds/
    │   │   └── semver/
    │   │       ├── .travis.yml
    │   │       ├── CHANGELOG.md
    │   │       ├── LICENSE.txt
    │   │       ├── Makefile
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── collection.go
    │   │       ├── constraints.go
    │   │       ├── doc.go
    │   │       └── version.go
    │   ├── alecthomas/
    │   │   ├── template/
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── doc.go
    │   │   │   ├── exec.go
    │   │   │   ├── funcs.go
    │   │   │   ├── helper.go
    │   │   │   ├── parse/
    │   │   │   │   ├── lex.go
    │   │   │   │   ├── node.go
    │   │   │   │   └── parse.go
    │   │   │   └── template.go
    │   │   └── units/
    │   │       ├── COPYING
    │   │       ├── README.md
    │   │       ├── bytes.go
    │   │       ├── doc.go
    │   │       ├── si.go
    │   │       └── util.go
    │   ├── bcext/
    │   │   ├── cashutil/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── address.go
    │   │   │   ├── amount.go
    │   │   │   ├── appdata.go
    │   │   │   ├── base58/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── alphabet.go
    │   │   │   │   ├── base58.go
    │   │   │   │   ├── base58check.go
    │   │   │   │   ├── cov_report.sh
    │   │   │   │   ├── doc.go
    │   │   │   │   └── genalphabet.go
    │   │   │   ├── block.go
    │   │   │   ├── cashaddr.go
    │   │   │   ├── cashaddrconv.go
    │   │   │   ├── certgen.go
    │   │   │   ├── const.go
    │   │   │   ├── cov_report.sh
    │   │   │   ├── doc.go
    │   │   │   ├── glide.yaml
    │   │   │   ├── goclean.sh
    │   │   │   ├── hash160.go
    │   │   │   ├── net.go
    │   │   │   ├── net_noop.go
    │   │   │   ├── profile.cov
    │   │   │   ├── test_coverage.txt
    │   │   │   ├── tx.go
    │   │   │   └── wif.go
    │   │   └── gcash/
    │   │       ├── LICENSE
    │   │       ├── btcec/
    │   │       │   ├── README.md
    │   │       │   ├── btcec.go
    │   │       │   ├── ciphering.go
    │   │       │   ├── doc.go
    │   │       │   ├── field.go
    │   │       │   ├── genprecomps.go
    │   │       │   ├── gensecp256k1.go
    │   │       │   ├── precompute.go
    │   │       │   ├── privkey.go
    │   │       │   ├── pubkey.go
    │   │       │   ├── secp256k1.go
    │   │       │   └── signature.go
    │   │       ├── chaincfg/
    │   │       │   ├── README.md
    │   │       │   ├── chainhash/
    │   │       │   │   ├── README.md
    │   │       │   │   ├── doc.go
    │   │       │   │   ├── hash.go
    │   │       │   │   └── hashfuncs.go
    │   │       │   ├── doc.go
    │   │       │   ├── genesis.go
    │   │       │   └── params.go
    │   │       └── wire/
    │   │           ├── README.md
    │   │           ├── blockheader.go
    │   │           ├── common.go
    │   │           ├── doc.go
    │   │           ├── error.go
    │   │           ├── invvect.go
    │   │           ├── message.go
    │   │           ├── msgaddr.go
    │   │           ├── msgalert.go
    │   │           ├── msgblock.go
    │   │           ├── msgcfcheckpt.go
    │   │           ├── msgcfheaders.go
    │   │           ├── msgcfilter.go
    │   │           ├── msgfeefilter.go
    │   │           ├── msgfilteradd.go
    │   │           ├── msgfilterclear.go
    │   │           ├── msgfilterload.go
    │   │           ├── msggetaddr.go
    │   │           ├── msggetblocks.go
    │   │           ├── msggetcfcheckpt.go
    │   │           ├── msggetcfheaders.go
    │   │           ├── msggetcfilters.go
    │   │           ├── msggetdata.go
    │   │           ├── msggetheaders.go
    │   │           ├── msgheaders.go
    │   │           ├── msginv.go
    │   │           ├── msgmempool.go
    │   │           ├── msgmerkleblock.go
    │   │           ├── msgnotfound.go
    │   │           ├── msgping.go
    │   │           ├── msgpong.go
    │   │           ├── msgreject.go
    │   │           ├── msgsendheaders.go
    │   │           ├── msgtx.go
    │   │           ├── msgverack.go
    │   │           ├── msgversion.go
    │   │           ├── netaddress.go
    │   │           └── protocol.go
    │   ├── btcsuite/
    │   │   ├── btcd/
    │   │   │   ├── LICENSE
    │   │   │   ├── btcec/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── btcec.go
    │   │   │   │   ├── ciphering.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── field.go
    │   │   │   │   ├── genprecomps.go
    │   │   │   │   ├── gensecp256k1.go
    │   │   │   │   ├── precompute.go
    │   │   │   │   ├── privkey.go
    │   │   │   │   ├── pubkey.go
    │   │   │   │   ├── secp256k1.go
    │   │   │   │   └── signature.go
    │   │   │   ├── btcjson/
    │   │   │   │   ├── CONTRIBUTORS
    │   │   │   │   ├── README.md
    │   │   │   │   ├── btcdextcmds.go
    │   │   │   │   ├── btcdextresults.go
    │   │   │   │   ├── btcwalletextcmds.go
    │   │   │   │   ├── chainsvrcmds.go
    │   │   │   │   ├── chainsvrresults.go
    │   │   │   │   ├── chainsvrwscmds.go
    │   │   │   │   ├── chainsvrwsntfns.go
    │   │   │   │   ├── chainsvrwsresults.go
    │   │   │   │   ├── cmdinfo.go
    │   │   │   │   ├── cmdparse.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── error.go
    │   │   │   │   ├── help.go
    │   │   │   │   ├── helpers.go
    │   │   │   │   ├── jsonrpc.go
    │   │   │   │   ├── jsonrpcerr.go
    │   │   │   │   ├── register.go
    │   │   │   │   ├── walletsvrcmds.go
    │   │   │   │   ├── walletsvrresults.go
    │   │   │   │   ├── walletsvrwscmds.go
    │   │   │   │   └── walletsvrwsntfns.go
    │   │   │   ├── chaincfg/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── chainhash/
    │   │   │   │   │   ├── README.md
    │   │   │   │   │   ├── doc.go
    │   │   │   │   │   ├── hash.go
    │   │   │   │   │   └── hashfuncs.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── genesis.go
    │   │   │   │   └── params.go
    │   │   │   ├── rpcclient/
    │   │   │   │   ├── CONTRIBUTORS
    │   │   │   │   ├── README.md
    │   │   │   │   ├── chain.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── extensions.go
    │   │   │   │   ├── infrastructure.go
    │   │   │   │   ├── log.go
    │   │   │   │   ├── mining.go
    │   │   │   │   ├── net.go
    │   │   │   │   ├── notify.go
    │   │   │   │   ├── rawrequest.go
    │   │   │   │   ├── rawtransactions.go
    │   │   │   │   └── wallet.go
    │   │   │   ├── txscript/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── consensus.go
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── engine.go
    │   │   │   │   ├── error.go
    │   │   │   │   ├── hashcache.go
    │   │   │   │   ├── log.go
    │   │   │   │   ├── opcode.go
    │   │   │   │   ├── script.go
    │   │   │   │   ├── scriptbuilder.go
    │   │   │   │   ├── scriptnum.go
    │   │   │   │   ├── sigcache.go
    │   │   │   │   ├── sign.go
    │   │   │   │   ├── stack.go
    │   │   │   │   └── standard.go
    │   │   │   └── wire/
    │   │   │       ├── README.md
    │   │   │       ├── blockheader.go
    │   │   │       ├── common.go
    │   │   │       ├── doc.go
    │   │   │       ├── error.go
    │   │   │       ├── invvect.go
    │   │   │       ├── message.go
    │   │   │       ├── msgaddr.go
    │   │   │       ├── msgalert.go
    │   │   │       ├── msgblock.go
    │   │   │       ├── msgcfcheckpt.go
    │   │   │       ├── msgcfheaders.go
    │   │   │       ├── msgcfilter.go
    │   │   │       ├── msgfeefilter.go
    │   │   │       ├── msgfilteradd.go
    │   │   │       ├── msgfilterclear.go
    │   │   │       ├── msgfilterload.go
    │   │   │       ├── msggetaddr.go
    │   │   │       ├── msggetblocks.go
    │   │   │       ├── msggetcfcheckpt.go
    │   │   │       ├── msggetcfheaders.go
    │   │   │       ├── msggetcfilters.go
    │   │   │       ├── msggetdata.go
    │   │   │       ├── msggetheaders.go
    │   │   │       ├── msgheaders.go
    │   │   │       ├── msginv.go
    │   │   │       ├── msgmempool.go
    │   │   │       ├── msgmerkleblock.go
    │   │   │       ├── msgnotfound.go
    │   │   │       ├── msgping.go
    │   │   │       ├── msgpong.go
    │   │   │       ├── msgreject.go
    │   │   │       ├── msgsendheaders.go
    │   │   │       ├── msgtx.go
    │   │   │       ├── msgverack.go
    │   │   │       ├── msgversion.go
    │   │   │       ├── netaddress.go
    │   │   │       └── protocol.go
    │   │   ├── btclog/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── doc.go
    │   │   │   ├── goclean.sh
    │   │   │   ├── interface.go
    │   │   │   └── log.go
    │   │   ├── btcutil/
    │   │   │   ├── .gitignore
    │   │   │   ├── .travis.yml
    │   │   │   ├── LICENSE
    │   │   │   ├── README.md
    │   │   │   ├── address.go
    │   │   │   ├── amount.go
    │   │   │   ├── appdata.go
    │   │   │   ├── base58/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── alphabet.go
    │   │   │   │   ├── base58.go
    │   │   │   │   ├── base58check.go
    │   │   │   │   ├── cov_report.sh
    │   │   │   │   ├── doc.go
    │   │   │   │   └── genalphabet.go
    │   │   │   ├── bech32/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── bech32.go
    │   │   │   │   └── doc.go
    │   │   │   ├── block.go
    │   │   │   ├── certgen.go
    │   │   │   ├── const.go
    │   │   │   ├── cov_report.sh
    │   │   │   ├── doc.go
    │   │   │   ├── goclean.sh
    │   │   │   ├── hash160.go
    │   │   │   ├── hdkeychain/
    │   │   │   │   ├── README.md
    │   │   │   │   ├── cov_report.sh
    │   │   │   │   ├── doc.go
    │   │   │   │   ├── extendedkey.go
    │   │   │   │   └── test_coverage.txt
    │   │   │   ├── net.go
    │   │   │   ├── net_noop.go
    │   │   │   ├── test_coverage.txt
    │   │   │   ├── tx.go
    │   │   │   └── wif.go
    │   │   ├── go-socks/
    │   │   │   ├── LICENSE
    │   │   │   └── socks/
    │   │   │       ├── addr.go
    │   │   │       ├── conn.go
    │   │   │       └── dial.go
    │   │   └── websocket/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── AUTHORS
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── client.go
    │   │       ├── conn.go
    │   │       ├── doc.go
    │   │       ├── json.go
    │   │       ├── server.go
    │   │       └── util.go
    │   ├── davecgh/
    │   │   └── go-spew/
    │   │       ├── LICENSE
    │   │       └── spew/
    │   │           ├── bypass.go
    │   │           ├── bypasssafe.go
    │   │           ├── common.go
    │   │           ├── config.go
    │   │           ├── doc.go
    │   │           ├── dump.go
    │   │           ├── format.go
    │   │           └── spew.go
    │   ├── pkg/
    │   │   └── errors/
    │   │       ├── .gitignore
    │   │       ├── .travis.yml
    │   │       ├── LICENSE
    │   │       ├── README.md
    │   │       ├── appveyor.yml
    │   │       ├── errors.go
    │   │       └── stack.go
    │   ├── pmezard/
    │   │   └── go-difflib/
    │   │       ├── LICENSE
    │   │       └── difflib/
    │   │           └── difflib.go
    │   └── stretchr/
    │       └── testify/
    │           ├── LICENSE
    │           └── assert/
    │               ├── assertion_format.go
    │               ├── assertion_format.go.tmpl
    │               ├── assertion_forward.go
    │               ├── assertion_forward.go.tmpl
    │               ├── assertions.go
    │               ├── doc.go
    │               ├── errors.go
    │               ├── forward_assertions.go
    │               └── http_assertions.go
    ├── golang.org/
    │   └── x/
    │       └── crypto/
    │           ├── AUTHORS
    │           ├── CONTRIBUTORS
    │           ├── LICENSE
    │           ├── PATENTS
    │           └── ripemd160/
    │               ├── ripemd160.go
    │               └── ripemd160block.go
    ├── gopkg.in/
    │   └── alecthomas/
    │       └── kingpin.v2/
    │           ├── .travis.yml
    │           ├── COPYING
    │           ├── README.md
    │           ├── actions.go
    │           ├── app.go
    │           ├── args.go
    │           ├── cmd.go
    │           ├── completions.go
    │           ├── doc.go
    │           ├── envar.go
    │           ├── flags.go
    │           ├── global.go
    │           ├── guesswidth.go
    │           ├── guesswidth_unix.go
    │           ├── model.go
    │           ├── parser.go
    │           ├── parsers.go
    │           ├── templates.go
    │           ├── usage.go
    │           ├── values.go
    │           ├── values.json
    │           └── values_generated.go
    └── modules.txt
Download .txt
Showing preview only (414K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4827 symbols across 249 files)

FILE: accounter/accounter.go
  type Accounter (line 25) | type Accounter struct
    method ComputeBalance (line 90) | func (a *Accounter) ComputeBalance() uint64 {
    method fetchTransactions (line 103) | func (a *Accounter) fetchTransactions() {
    method processTransactions (line 114) | func (a *Accounter) processTransactions() {
    method balance (line 166) | func (a *Accounter) balance() uint64 {
    method sendWork (line 222) | func (a *Accounter) sendWork() {
    method recvWork (line 242) | func (a *Accounter) recvWork() {
    method getLastAddress (line 309) | func (a *Accounter) getLastAddress(change uint32) uint32 {
    method complete (line 319) | func (a *Accounter) complete() bool {
  type address (line 49) | type address struct
  type transaction (line 54) | type transaction struct
  type vin (line 61) | type vin struct
  type vout (line 66) | type vout struct
  function New (line 75) | func New(b backend.Backend, addressDeriver *deriver.AddressDeriver, look...

FILE: accounter/accounter_test.go
  function TestProcessTransactions (line 12) | func TestProcessTransactions(t *testing.T) {
  function TestComputeBalanceTestnet (line 92) | func TestComputeBalanceTestnet(t *testing.T) {

FILE: backend/backend.go
  type Backend (line 30) | type Backend interface
  type AddrResponse (line 44) | type AddrResponse struct
    method HasTransactions (line 63) | func (r *AddrResponse) HasTransactions() bool {
  type TxResponse (line 51) | type TxResponse struct
  type BlockResponse (line 57) | type BlockResponse struct

FILE: backend/btcd_backend.go
  type BtcdBackend (line 20) | type BtcdBackend struct
    method AddrRequest (line 113) | func (b *BtcdBackend) AddrRequest(addr *deriver.Address) {
    method AddrResponses (line 121) | func (b *BtcdBackend) AddrResponses() <-chan *AddrResponse {
    method TxRequest (line 127) | func (b *BtcdBackend) TxRequest(txHash string) {
    method TxResponses (line 137) | func (b *BtcdBackend) TxResponses() <-chan *TxResponse {
    method BlockRequest (line 141) | func (b *BtcdBackend) BlockRequest(height uint32) {
    method BlockResponses (line 145) | func (b *BtcdBackend) BlockResponses() <-chan *BlockResponse {
    method Finish (line 150) | func (b *BtcdBackend) Finish() {
    method ChainHeight (line 155) | func (b *BtcdBackend) ChainHeight() uint32 {
    method processRequests (line 159) | func (b *BtcdBackend) processRequests() {
    method processAddrRequest (line 183) | func (b *BtcdBackend) processAddrRequest(address *deriver.Address) err...
    method processTxRequest (line 221) | func (b *BtcdBackend) processTxRequest(txHash string) error {
    method processBlockRequest (line 259) | func (b *BtcdBackend) processBlockRequest(height uint32) error {
    method cacheTxs (line 289) | func (b *BtcdBackend) cacheTxs(txs []*btcjson.SearchRawTransactionsRes...
    method getBlockHeight (line 315) | func (b *BtcdBackend) getBlockHeight(hash string) (int64, error) {
  constant maxTxsPerAddr (line 48) | maxTxsPerAddr = 1000
  constant addrRequestsChanSize (line 50) | addrRequestsChanSize = 100
  constant blockRequestChanSize (line 51) | blockRequestChanSize = 100
  constant concurrency (line 53) | concurrency = 100
  function NewBtcdBackend (line 61) | func NewBtcdBackend(host, port, user, pass string, network Network) (*Bt...

FILE: backend/common.go
  type index (line 11) | type index struct
  type metadata (line 18) | type metadata struct
  type address (line 22) | type address struct
  type byAddress (line 31) | type byAddress
    method Len (line 33) | func (a byAddress) Len() int           { return len(a) }
    method Swap (line 34) | func (a byAddress) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    method Less (line 35) | func (a byAddress) Less(i, j int) bool { return a[i].Address < a[j].Ad...
  type transaction (line 37) | type transaction struct
  type byTransactionID (line 43) | type byTransactionID
    method Len (line 45) | func (a byTransactionID) Len() int           { return len(a) }
    method Swap (line 46) | func (a byTransactionID) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    method Less (line 47) | func (a byTransactionID) Less(i, j int) bool { return a[i].Hash < a[j]...
  type block (line 49) | type block struct

FILE: backend/electrum/blockchain.go
  constant sleep (line 16) | sleep = 200 * time.Millisecond
  type Node (line 19) | type Node struct
    method Disconnect (line 174) | func (n *Node) Disconnect() error {
    method ServerFeatures (line 192) | func (n *Node) ServerFeatures() (*Feature, error) {
    method ServerVersion (line 206) | func (n *Node) ServerVersion(ver string) error {
    method BlockchainAddressGetHistory (line 215) | func (n *Node) BlockchainAddressGetHistory(address string) ([]*Transac...
    method BlockchainTransactionGet (line 227) | func (n *Node) BlockchainTransactionGet(txid string) (string, error) {
    method BlockchainHeadersSubscribe (line 240) | func (n *Node) BlockchainHeadersSubscribe() (*Header, error) {
    method ServerPeersSubscribe (line 249) | func (n *Node) ServerPeersSubscribe() ([]Peer, error) {
    method BlockchainBlockHeaders (line 276) | func (n *Node) BlockchainBlockHeaders(height uint32, count uint) (Bloc...
    method request (line 282) | func (n *Node) request(method string, params []interface{}, result int...
  type Feature (line 30) | type Feature struct
  type BlockchainHeader (line 36) | type BlockchainHeader struct
  type Balance (line 47) | type Balance struct
  type Transaction (line 56) | type Transaction struct
  type GetTransaction (line 63) | type GetTransaction struct
  type Vin (line 77) | type Vin struct
    method IsCoinBase (line 183) | func (v *Vin) IsCoinBase() bool {
  type ScriptPubKeyResult (line 87) | type ScriptPubKeyResult struct
  type Vout (line 96) | type Vout struct
  type ScriptSig (line 105) | type ScriptSig struct
  type Peer (line 110) | type Peer struct
  type Header (line 117) | type Header struct
  type Block (line 122) | type Block struct
  function NewNode (line 128) | func NewNode(addr, port string, network Network) (*Node, error) {
  function NodeIdent (line 178) | func NodeIdent(addr, port string) string {
  function defaultPorts (line 303) | func defaultPorts(network Network) (string, string) {

FILE: backend/electrum/tcp.go
  constant connTimeout (line 16) | connTimeout  = 2 * time.Second
  constant writeTimeout (line 17) | writeTimeout = 10 * time.Second
  constant readTimeout (line 18) | readTimeout  = 10 * time.Second
  constant messageDelim (line 19) | messageDelim = byte('\n')
  type ErrorResponse (line 32) | type ErrorResponse struct
  type RequestMessage (line 37) | type RequestMessage struct
  type ResponseMessage (line 43) | type ResponseMessage struct
  type Transport (line 50) | type Transport interface
  type TCPTransport (line 55) | type TCPTransport struct
    method SendMessage (line 85) | func (t *TCPTransport) SendMessage(request RequestMessage) (*ResponseM...
    method Shutdown (line 172) | func (t *TCPTransport) Shutdown() error {
  function NewTCPTransport (line 59) | func NewTCPTransport(addr string) (Transport, error) {
  function NewSSLTransport (line 70) | func NewSSLTransport(addr string) (Transport, error) {

FILE: backend/electrum_backend.go
  type ElectrumBackend (line 36) | type ElectrumBackend struct
    method AddrRequest (line 133) | func (eb *ElectrumBackend) AddrRequest(addr *deriver.Address) {
    method AddrResponses (line 141) | func (eb *ElectrumBackend) AddrResponses() <-chan *AddrResponse {
    method TxRequest (line 147) | func (eb *ElectrumBackend) TxRequest(txHash string) {
    method TxResponses (line 157) | func (eb *ElectrumBackend) TxResponses() <-chan *TxResponse {
    method BlockRequest (line 161) | func (eb *ElectrumBackend) BlockRequest(height uint32) {
    method BlockResponses (line 165) | func (eb *ElectrumBackend) BlockResponses() <-chan *BlockResponse {
    method Finish (line 170) | func (eb *ElectrumBackend) Finish() {
    method ChainHeight (line 177) | func (eb *ElectrumBackend) ChainHeight() uint32 {
    method addNode (line 182) | func (eb *ElectrumBackend) addNode(addr, port string, network Network)...
    method getHeight (line 255) | func (eb *ElectrumBackend) getHeight(addr, port string, network Networ...
    method processRequests (line 295) | func (eb *ElectrumBackend) processRequests(node *electrum.Node) {
    method processPeersRequest (line 322) | func (eb *ElectrumBackend) processPeersRequest(node *electrum.Node) er...
    method processTxRequest (line 341) | func (eb *ElectrumBackend) processTxRequest(node *electrum.Node, txHas...
    method getTxHeight (line 364) | func (eb *ElectrumBackend) getTxHeight(txHash string) int64 {
    method processBlockRequest (line 376) | func (eb *ElectrumBackend) processBlockRequest(node *electrum.Node, he...
    method processAddrRequest (line 411) | func (eb *ElectrumBackend) processAddrRequest(node *electrum.Node, add...
    method cacheTxs (line 440) | func (eb *ElectrumBackend) cacheTxs(txs []*electrum.Transaction) {
    method removeNode (line 475) | func (eb *ElectrumBackend) removeNode(ident string) {
    method removeAllNodes (line 485) | func (eb *ElectrumBackend) removeAllNodes() {
    method findPeers (line 496) | func (eb *ElectrumBackend) findPeers() {
    method addPeer (line 503) | func (eb *ElectrumBackend) addPeer(peer electrum.Peer) {
  constant maxPeers (line 65) | maxPeers          = 100
  constant peerFetchInterval (line 66) | peerFetchInterval = 30 * time.Second
  function NewElectrumBackend (line 81) | func NewElectrumBackend(addr, port string, network Network) (*ElectrumBa...
  function checkVersion (line 454) | func checkVersion(ver string) error {

FILE: backend/electrum_backend_test.go
  function TestTransactionCache (line 11) | func TestTransactionCache(t *testing.T) {

FILE: backend/fixture_backend.go
  type FixtureBackend (line 17) | type FixtureBackend struct
    method AddrRequest (line 78) | func (fb *FixtureBackend) AddrRequest(addr *deriver.Address) {
    method TxRequest (line 86) | func (fb *FixtureBackend) TxRequest(txHash string) {
    method BlockRequest (line 92) | func (fb *FixtureBackend) BlockRequest(height uint32) {
    method AddrResponses (line 98) | func (fb *FixtureBackend) AddrResponses() <-chan *AddrResponse {
    method TxResponses (line 106) | func (fb *FixtureBackend) TxResponses() <-chan *TxResponse {
    method BlockResponses (line 110) | func (fb *FixtureBackend) BlockResponses() <-chan *BlockResponse {
    method Finish (line 115) | func (fb *FixtureBackend) Finish() {
    method ChainHeight (line 119) | func (fb *FixtureBackend) ChainHeight() uint32 {
    method processRequests (line 123) | func (fb *FixtureBackend) processRequests() {
    method processAddrRequest (line 150) | func (fb *FixtureBackend) processAddrRequest(addr *deriver.Address) {
    method processTxRequest (line 166) | func (fb *FixtureBackend) processTxRequest(txHash string) {
    method processBlockRequest (line 179) | func (fb *FixtureBackend) processBlockRequest(height uint32) {
    method loadFromFile (line 191) | func (fb *FixtureBackend) loadFromFile(f *os.File) error {
  function NewFixtureBackend (line 47) | func NewFixtureBackend(filepath string) (*FixtureBackend, error) {

FILE: backend/fixture_backend_test.go
  function TestNonExistantFixtureFile (line 13) | func TestNonExistantFixtureFile(t *testing.T) {
  function TestBadFixtureFile (line 19) | func TestBadFixtureFile(t *testing.T) {
  function TestFinish (line 25) | func TestFinish(t *testing.T) {
  function TestNoAddress (line 46) | func TestNoAddress(t *testing.T) {
  function TestAddressNoTransactions (line 65) | func TestAddressNoTransactions(t *testing.T) {
  function TestAddressWithTransactions (line 82) | func TestAddressWithTransactions(t *testing.T) {
  function fetchResults (line 113) | func fetchResults(b Backend, addrs *[]*AddrResponse, txs *[]*TxResponse,...

FILE: backend/recorder_backend.go
  type RecorderBackend (line 17) | type RecorderBackend struct
    method AddrRequest (line 62) | func (rb *RecorderBackend) AddrRequest(addr *deriver.Address) {
    method AddrResponses (line 68) | func (rb *RecorderBackend) AddrResponses() <-chan *AddrResponse {
    method TxRequest (line 74) | func (rb *RecorderBackend) TxRequest(txHash string) {
    method TxResponses (line 82) | func (rb *RecorderBackend) TxResponses() <-chan *TxResponse {
    method BlockRequest (line 86) | func (rb *RecorderBackend) BlockRequest(height uint32) {
    method BlockResponses (line 90) | func (rb *RecorderBackend) BlockResponses() <-chan *BlockResponse {
    method Finish (line 95) | func (rb *RecorderBackend) Finish() {
    method ChainHeight (line 104) | func (rb *RecorderBackend) ChainHeight() uint32 {
    method processRequests (line 108) | func (rb *RecorderBackend) processRequests() {
    method writeToFile (line 148) | func (rb *RecorderBackend) writeToFile() error {
  function NewRecorderBackend (line 43) | func NewRecorderBackend(b Backend, filepath string) (*RecorderBackend, e...

FILE: blockfinder/blockfinder.go
  type Blockfinder (line 12) | type Blockfinder struct
    method Search (line 29) | func (bf *Blockfinder) Search(timestamp time.Time) (uint32, time.Time,...
    method searchSync (line 80) | func (bf *Blockfinder) searchSync(height uint32) int64 {
  function New (line 19) | func New(b backend.Backend) *Blockfinder {

FILE: blockfinder/blockfinder_test.go
  function TestFindBLock (line 10) | func TestFindBLock(t *testing.T) {

FILE: deriver/address_deriver.go
  type AddressDeriver (line 22) | type AddressDeriver struct
    method Derive (line 101) | func (d *AddressDeriver) Derive(change uint32, addressIndex uint32) *A...
    method singleDerive (line 123) | func (d *AddressDeriver) singleDerive(change uint32, addressIndex uint...
    method multiSigSegwitDerive (line 140) | func (d *AddressDeriver) multiSigSegwitDerive(change uint32, addressIn...
  type Address (line 32) | type Address struct
    method Path (line 47) | func (a *Address) Path() string {
    method String (line 52) | func (a *Address) String() string {
    method Change (line 57) | func (a *Address) Change() uint32 {
    method Index (line 62) | func (a *Address) Index() uint32 {
    method Network (line 66) | func (a *Address) Network() Network {
    method Address (line 70) | func (a *Address) Address() btcutil.Address {
    method Script (line 80) | func (a *Address) Script() string {
  function NewAddress (line 42) | func NewAddress(path, addr string, net Network, change, addrIndex uint32...
  function NewAddressDeriver (line 90) | func NewAddressDeriver(network Network, xpubs []string, m int, singleAdd...
  type sortedByteArrays (line 191) | type sortedByteArrays
    method Len (line 193) | func (b sortedByteArrays) Len() int {
    method Less (line 197) | func (b sortedByteArrays) Less(i, j int) bool {
    method Swap (line 210) | func (b sortedByteArrays) Swap(i, j int) {
  function sortByteArrays (line 214) | func sortByteArrays(src [][]byte) [][]byte {

FILE: deriver/address_deriver_test.go
  function TestAddress (line 10) | func TestAddress(t *testing.T) {
  function TestDeriveMultiSigSegwit (line 21) | func TestDeriveMultiSigSegwit(t *testing.T) {
  function TestDeriveGateway (line 32) | func TestDeriveGateway(t *testing.T) {

FILE: main.go
  constant minConfirmations (line 58) | minConfirmations = 6
  function main (line 61) | func main() {
  function doKeytree (line 77) | func doKeytree() {
  function doFindAddr (line 119) | func doFindAddr() {
  function doFindBlock (line 169) | func doFindBlock() {
  function doComputeBalance (line 184) | func doComputeBalance() {
  function findBlockBuildBackend (line 248) | func findBlockBuildBackend(network Network) (backend.Backend, error) {
  function computeBalanceBuildBackend (line 299) | func computeBalanceBuildBackend(network Network) (backend.Backend, error) {

FILE: reporter/reporter.go
  type Reporter (line 12) | type Reporter struct
    method Log (line 31) | func (r *Reporter) Log(msg string) {
    method Logf (line 36) | func (r *Reporter) Logf(format string, args ...interface{}) {
    method IncAddressesFetched (line 40) | func (r *Reporter) IncAddressesFetched() {
    method GetAddressesFetched (line 44) | func (r *Reporter) GetAddressesFetched() uint32 {
    method SetAddressesFetched (line 48) | func (r *Reporter) SetAddressesFetched(n uint32) {
    method IncAddressesScheduled (line 52) | func (r *Reporter) IncAddressesScheduled() {
    method GetAddressesScheduled (line 56) | func (r *Reporter) GetAddressesScheduled() uint32 {
    method SetddressesScheduled (line 60) | func (r *Reporter) SetddressesScheduled(n uint32) {
    method IncTxFetched (line 64) | func (r *Reporter) IncTxFetched() {
    method GetTxFetched (line 68) | func (r *Reporter) GetTxFetched() uint32 {
    method SetTxFetched (line 72) | func (r *Reporter) SetTxFetched(n uint32) {
    method IncTxScheduled (line 76) | func (r *Reporter) IncTxScheduled() {
    method GetTxScheduled (line 80) | func (r *Reporter) GetTxScheduled() uint32 {
    method SetTxScheduled (line 84) | func (r *Reporter) SetTxScheduled(n uint32) {
    method IncTxAfterFilter (line 88) | func (r *Reporter) IncTxAfterFilter() {
    method GetTxAfterFilter (line 92) | func (r *Reporter) GetTxAfterFilter() int32 {
    method SetTxAfterFilter (line 96) | func (r *Reporter) SetTxAfterFilter(n int32) {
    method IncPeers (line 100) | func (r *Reporter) IncPeers() {
    method GetPeers (line 104) | func (r *Reporter) GetPeers() int32 {
    method SetPeers (line 108) | func (r *Reporter) SetPeers(n int32) {
  function GetInstance (line 24) | func GetInstance() *Reporter {

FILE: utils/utils.go
  function PanicOnError (line 11) | func PanicOnError(err error) {
  function Max (line 17) | func Max(num uint32, nums ...uint32) uint32 {
  type Network (line 27) | type Network
    method ChainConfig (line 38) | func (n Network) ChainConfig() *chaincfg.Params {
  type BackendName (line 28) | type BackendName
  constant Mainnet (line 31) | Mainnet  Network     = "mainnet"
  constant Testnet (line 32) | Testnet  Network     = "testnet"
  constant Electrum (line 33) | Electrum BackendName = "electrum"
  constant Btcd (line 34) | Btcd     BackendName = "btcd"
  function XpubToNetwork (line 51) | func XpubToNetwork(xpub string) Network {
  function AddressToNetwork (line 63) | func AddressToNetwork(addr string) Network {
  function GenesisBlock (line 80) | func GenesisBlock(network Network) string {
  function VerifyMandN (line 91) | func VerifyMandN(m int, n int) error {
  function GetDefaultServer (line 108) | func GetDefaultServer(network Network, backend BackendName, addr string)...

FILE: utils/utils_test.go
  function TestPanicOnError (line 11) | func TestPanicOnError(t *testing.T) {
  function TestMax (line 16) | func TestMax(t *testing.T) {
  function TestXpubToNetwork (line 39) | func TestXpubToNetwork(t *testing.T) {
  function TestAddressToNetwork (line 47) | func TestAddressToNetwork(t *testing.T) {
  function TestChainConfig (line 58) | func TestChainConfig(t *testing.T) {
  function TestGenesisBlock (line 63) | func TestGenesisBlock(t *testing.T) {
  function TestVerifyMandN (line 68) | func TestVerifyMandN(t *testing.T) {
  function TestGetDefaultServer (line 80) | func TestGetDefaultServer(t *testing.T) {

FILE: vendor/github.com/Masterminds/semver/collection.go
  type Collection (line 6) | type Collection
    method Len (line 10) | func (c Collection) Len() int {
    method Less (line 16) | func (c Collection) Less(i, j int) bool {
    method Swap (line 22) | func (c Collection) Swap(i, j int) {

FILE: vendor/github.com/Masterminds/semver/constraints.go
  type Constraints (line 12) | type Constraints struct
    method Check (line 44) | func (cs Constraints) Check(v *Version) bool {
    method Validate (line 65) | func (cs Constraints) Validate(v *Version) (bool, []error) {
  function NewConstraint (line 18) | func NewConstraint(c string) (*Constraints, error) {
  function init (line 90) | func init() {
  type constraint (line 137) | type constraint struct
    method check (line 158) | func (c *constraint) check(v *Version) bool {
  type cfunc (line 162) | type cfunc
  function parseConstraint (line 164) | func parseConstraint(c string) (*constraint, error) {
  function constraintNotEqual (line 209) | func constraintNotEqual(v *Version, c *constraint) bool {
  function constraintGreaterThan (line 234) | func constraintGreaterThan(v *Version, c *constraint) bool {
  function constraintLessThan (line 252) | func constraintLessThan(v *Version, c *constraint) bool {
  function constraintGreaterThanEqual (line 273) | func constraintGreaterThanEqual(v *Version, c *constraint) bool {
  function constraintLessThanEqual (line 290) | func constraintLessThanEqual(v *Version, c *constraint) bool {
  function constraintTilde (line 317) | func constraintTilde(v *Version, c *constraint) bool {
  function constraintTildeOrEqual (line 349) | func constraintTildeOrEqual(v *Version, c *constraint) bool {
  function constraintCaret (line 371) | func constraintCaret(v *Version, c *constraint) bool {
  constant cvRegex (line 392) | cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
  function isX (line 396) | func isX(x string) bool {
  function rewriteRange (line 405) | func rewriteRange(i string) string {
  function isNonZero (line 420) | func isNonZero(v *Version) bool {

FILE: vendor/github.com/Masterminds/semver/version.go
  constant SemVerRegex (line 31) | SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
  constant ValidPrerelease (line 37) | ValidPrerelease string = `^([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*)`
  type Version (line 40) | type Version struct
    method String (line 110) | func (v *Version) String() string {
    method Original (line 125) | func (v *Version) Original() string {
    method Major (line 130) | func (v *Version) Major() int64 {
    method Minor (line 135) | func (v *Version) Minor() int64 {
    method Patch (line 140) | func (v *Version) Patch() int64 {
    method Prerelease (line 145) | func (v *Version) Prerelease() string {
    method Metadata (line 150) | func (v *Version) Metadata() string {
    method originalVPrefix (line 155) | func (v *Version) originalVPrefix() string {
    method IncPatch (line 169) | func (v Version) IncPatch() Version {
    method IncMinor (line 192) | func (v Version) IncMinor() Version {
    method IncMajor (line 208) | func (v Version) IncMajor() Version {
    method SetPrerelease (line 221) | func (v Version) SetPrerelease(prerelease string) (Version, error) {
    method SetMetadata (line 233) | func (v Version) SetMetadata(metadata string) (Version, error) {
    method LessThan (line 244) | func (v *Version) LessThan(o *Version) bool {
    method GreaterThan (line 249) | func (v *Version) GreaterThan(o *Version) bool {
    method Equal (line 256) | func (v *Version) Equal(o *Version) bool {
    method Compare (line 265) | func (v *Version) Compare(o *Version) int {
    method UnmarshalJSON (line 296) | func (v *Version) UnmarshalJSON(b []byte) error {
    method MarshalJSON (line 316) | func (v *Version) MarshalJSON() ([]byte, error) {
  function init (line 47) | func init() {
  function NewVersion (line 54) | func NewVersion(v string) (*Version, error) {
  function MustParse (line 97) | func MustParse(v string) *Version {
  function compareSegment (line 320) | func compareSegment(v, o int64) int {
  function comparePrerelease (line 331) | func comparePrerelease(v, o string) int {
  function comparePrePart (line 374) | func comparePrePart(s, o string) int {

FILE: vendor/github.com/alecthomas/template/exec.go
  type state (line 22) | type state struct
    method push (line 36) | func (s *state) push(name string, value reflect.Value) {
    method mark (line 41) | func (s *state) mark() int {
    method pop (line 46) | func (s *state) pop(mark int) {
    method setVar (line 51) | func (s *state) setVar(n int, value reflect.Value) {
    method varValue (line 56) | func (s *state) varValue(name string) reflect.Value {
    method at (line 69) | func (s *state) at(node parse.Node) {
    method errorf (line 83) | func (s *state) errorf(format string, args ...interface{}) {
    method walk (line 162) | func (s *state) walk(dot reflect.Value, node parse.Node) {
    method walkIfOrWith (line 195) | func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pi...
    method walkRange (line 243) | func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
    method walkTemplate (line 304) | func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) {
    method evalPipeline (line 327) | func (s *state) evalPipeline(dot reflect.Value, pipe *parse.PipeNode) ...
    method notAFunction (line 345) | func (s *state) notAFunction(args []parse.Node, final reflect.Value) {
    method evalCommand (line 351) | func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode,...
    method idealConstant (line 389) | func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value {
    method evalFieldNode (line 415) | func (s *state) evalFieldNode(dot reflect.Value, field *parse.FieldNod...
    method evalChainNode (line 420) | func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNod...
    method evalVariableNode (line 430) | func (s *state) evalVariableNode(dot reflect.Value, variable *parse.Va...
    method evalFieldChain (line 444) | func (s *state) evalFieldChain(dot, receiver reflect.Value, node parse...
    method evalFunction (line 453) | func (s *state) evalFunction(dot reflect.Value, node *parse.Identifier...
    method evalField (line 466) | func (s *state) evalField(dot reflect.Value, fieldName string, node pa...
    method evalCall (line 524) | func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name...
    method validateType (line 587) | func (s *state) validateType(value reflect.Value, typ reflect.Type) re...
    method evalArg (line 622) | func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.N...
    method evalBool (line 665) | func (s *state) evalBool(typ reflect.Type, n parse.Node) reflect.Value {
    method evalString (line 676) | func (s *state) evalString(typ reflect.Type, n parse.Node) reflect.Val...
    method evalInteger (line 687) | func (s *state) evalInteger(typ reflect.Type, n parse.Node) reflect.Va...
    method evalUnsignedInteger (line 698) | func (s *state) evalUnsignedInteger(typ reflect.Type, n parse.Node) re...
    method evalFloat (line 709) | func (s *state) evalFloat(typ reflect.Type, n parse.Node) reflect.Value {
    method evalComplex (line 720) | func (s *state) evalComplex(typ reflect.Type, n parse.Node) reflect.Va...
    method evalEmptyInterface (line 730) | func (s *state) evalEmptyInterface(dot reflect.Value, n parse.Node) re...
    method printValue (line 774) | func (s *state) printValue(n parse.Node, v reflect.Value) {
  type variable (line 30) | type variable struct
  function doublePercent (line 75) | func doublePercent(str string) string {
  function errRecover (line 96) | func errRecover(errp *error) {
  method ExecuteTemplate (line 116) | func (t *Template) ExecuteTemplate(wr io.Writer, name string, data inter...
  method Execute (line 130) | func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
  function isTrue (line 215) | func isTrue(val reflect.Value) (truth, ok bool) {
  function isHexConstant (line 411) | func isHexConstant(s string) bool {
  function canBeNil (line 578) | func canBeNil(typ reflect.Type) bool {
  function indirect (line 760) | func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
  function printableValue (line 785) | func printableValue(v reflect.Value) (interface{}, bool) {
  type rvs (line 808) | type rvs
    method Len (line 810) | func (x rvs) Len() int      { return len(x) }
    method Swap (line 811) | func (x rvs) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  type rvInts (line 813) | type rvInts struct
    method Less (line 815) | func (x rvInts) Less(i, j int) bool { return x.rvs[i].Int() < x.rvs[j]...
  type rvUints (line 817) | type rvUints struct
    method Less (line 819) | func (x rvUints) Less(i, j int) bool { return x.rvs[i].Uint() < x.rvs[...
  type rvFloats (line 821) | type rvFloats struct
    method Less (line 823) | func (x rvFloats) Less(i, j int) bool { return x.rvs[i].Float() < x.rv...
  type rvStrings (line 825) | type rvStrings struct
    method Less (line 827) | func (x rvStrings) Less(i, j int) bool { return x.rvs[i].String() < x....
  function sortKeys (line 830) | func sortKeys(v []reflect.Value) []reflect.Value {

FILE: vendor/github.com/alecthomas/template/funcs.go
  type FuncMap (line 24) | type FuncMap
  function createValueFuncs (line 52) | func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
  function addValueFuncs (line 59) | func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
  function addFuncs (line 74) | func addFuncs(out, in FuncMap) {
  function goodFunc (line 81) | func goodFunc(typ reflect.Type) bool {
  function findFunction (line 93) | func findFunction(name string, tmpl *Template) (reflect.Value, bool) {
  function index (line 110) | func index(item interface{}, indices ...interface{}) (interface{}, error) {
  function length (line 155) | func length(item interface{}) (int, error) {
  function call (line 171) | func call(fn interface{}, args ...interface{}) (interface{}, error) {
  function truth (line 219) | func truth(a interface{}) bool {
  function and (line 226) | func and(arg0 interface{}, args ...interface{}) interface{} {
  function or (line 241) | func or(arg0 interface{}, args ...interface{}) interface{} {
  function not (line 255) | func not(arg interface{}) (truth bool) {
  type kind (line 270) | type kind
  constant invalidKind (line 273) | invalidKind kind = iota
  constant boolKind (line 274) | boolKind
  constant complexKind (line 275) | complexKind
  constant intKind (line 276) | intKind
  constant floatKind (line 277) | floatKind
  constant integerKind (line 278) | integerKind
  constant stringKind (line 279) | stringKind
  constant uintKind (line 280) | uintKind
  function basicKind (line 283) | func basicKind(v reflect.Value) (kind, error) {
  function eq (line 302) | func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
  function ne (line 354) | func ne(arg1, arg2 interface{}) (bool, error) {
  function lt (line 361) | func lt(arg1, arg2 interface{}) (bool, error) {
  function le (line 403) | func le(arg1, arg2 interface{}) (bool, error) {
  function gt (line 413) | func gt(arg1, arg2 interface{}) (bool, error) {
  function ge (line 423) | func ge(arg1, arg2 interface{}) (bool, error) {
  function HTMLEscape (line 443) | func HTMLEscape(w io.Writer, b []byte) {
  function HTMLEscapeString (line 469) | func HTMLEscapeString(s string) string {
  function HTMLEscaper (line 481) | func HTMLEscaper(args ...interface{}) string {
  function JSEscape (line 499) | func JSEscape(w io.Writer, b []byte) {
  function JSEscapeString (line 546) | func JSEscapeString(s string) string {
  function jsIsSpecial (line 556) | func jsIsSpecial(r rune) bool {
  function JSEscaper (line 566) | func JSEscaper(args ...interface{}) string {
  function URLQueryEscaper (line 572) | func URLQueryEscaper(args ...interface{}) string {
  function evalArgs (line 581) | func evalArgs(args []interface{}) string {

FILE: vendor/github.com/alecthomas/template/helper.go
  function Must (line 21) | func Must(t *Template, err error) *Template {
  function ParseFiles (line 32) | func ParseFiles(filenames ...string) (*Template, error) {
  method ParseFiles (line 39) | func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
  function parseFiles (line 45) | func parseFiles(t *Template, filenames ...string) (*Template, error) {
  function ParseGlob (line 85) | func ParseGlob(pattern string) (*Template, error) {
  method ParseGlob (line 94) | func (t *Template) ParseGlob(pattern string) (*Template, error) {
  function parseGlob (line 99) | func parseGlob(t *Template, pattern string) (*Template, error) {

FILE: vendor/github.com/alecthomas/template/parse/lex.go
  type item (line 15) | type item struct
    method String (line 21) | func (i item) String() string {
  type itemType (line 36) | type itemType
  constant itemError (line 39) | itemError        itemType = iota
  constant itemBool (line 40) | itemBool
  constant itemChar (line 41) | itemChar
  constant itemCharConstant (line 42) | itemCharConstant
  constant itemComplex (line 43) | itemComplex
  constant itemColonEquals (line 44) | itemColonEquals
  constant itemEOF (line 45) | itemEOF
  constant itemField (line 46) | itemField
  constant itemIdentifier (line 47) | itemIdentifier
  constant itemLeftDelim (line 48) | itemLeftDelim
  constant itemLeftParen (line 49) | itemLeftParen
  constant itemNumber (line 50) | itemNumber
  constant itemPipe (line 51) | itemPipe
  constant itemRawString (line 52) | itemRawString
  constant itemRightDelim (line 53) | itemRightDelim
  constant itemElideNewline (line 54) | itemElideNewline
  constant itemRightParen (line 55) | itemRightParen
  constant itemSpace (line 56) | itemSpace
  constant itemString (line 57) | itemString
  constant itemText (line 58) | itemText
  constant itemVariable (line 59) | itemVariable
  constant itemKeyword (line 61) | itemKeyword
  constant itemDot (line 62) | itemDot
  constant itemDefine (line 63) | itemDefine
  constant itemElse (line 64) | itemElse
  constant itemEnd (line 65) | itemEnd
  constant itemIf (line 66) | itemIf
  constant itemNil (line 67) | itemNil
  constant itemRange (line 68) | itemRange
  constant itemTemplate (line 69) | itemTemplate
  constant itemWith (line 70) | itemWith
  constant eof (line 85) | eof = -1
  type stateFn (line 88) | type stateFn
  type lexer (line 91) | type lexer struct
    method next (line 106) | func (l *lexer) next() rune {
    method peek (line 118) | func (l *lexer) peek() rune {
    method backup (line 125) | func (l *lexer) backup() {
    method emit (line 130) | func (l *lexer) emit(t itemType) {
    method ignore (line 136) | func (l *lexer) ignore() {
    method accept (line 141) | func (l *lexer) accept(valid string) bool {
    method acceptRun (line 150) | func (l *lexer) acceptRun(valid string) {
    method lineNumber (line 159) | func (l *lexer) lineNumber() int {
    method errorf (line 165) | func (l *lexer) errorf(format string, args ...interface{}) stateFn {
    method nextItem (line 171) | func (l *lexer) nextItem() item {
    method run (line 197) | func (l *lexer) run() {
    method atTerminator (line 423) | func (l *lexer) atTerminator() bool {
    method scanNumber (line 482) | func (l *lexer) scanNumber() bool {
  function lex (line 178) | func lex(name, input, left, right string) *lexer {
  constant leftDelim (line 206) | leftDelim    = "{{"
  constant rightDelim (line 207) | rightDelim   = "}}"
  constant leftComment (line 208) | leftComment  = "/*"
  constant rightComment (line 209) | rightComment = "*/"
  function lexText (line 213) | func lexText(l *lexer) stateFn {
  function lexLeftDelim (line 234) | func lexLeftDelim(l *lexer) stateFn {
  function lexComment (line 245) | func lexComment(l *lexer) stateFn {
  function lexRightDelim (line 262) | func lexRightDelim(l *lexer) stateFn {
  function lexInsideAction (line 273) | func lexInsideAction(l *lexer) stateFn {
  function lexSpace (line 340) | func lexSpace(l *lexer) stateFn {
  function lexIdentifier (line 349) | func lexIdentifier(l *lexer) stateFn {
  function lexField (line 379) | func lexField(l *lexer) stateFn {
  function lexVariable (line 385) | func lexVariable(l *lexer) stateFn {
  function lexFieldOrVariable (line 395) | func lexFieldOrVariable(l *lexer, typ itemType) stateFn {
  function lexChar (line 443) | func lexChar(l *lexer) stateFn {
  function lexNumber (line 466) | func lexNumber(l *lexer) stateFn {
  function lexQuote (line 509) | func lexQuote(l *lexer) stateFn {
  function lexRawQuote (line 529) | func lexRawQuote(l *lexer) stateFn {
  function isSpace (line 544) | func isSpace(r rune) bool {
  function isEndOfLine (line 549) | func isEndOfLine(r rune) bool {
  function isAlphaNumeric (line 554) | func isAlphaNumeric(r rune) bool {

FILE: vendor/github.com/alecthomas/template/parse/node.go
  type Node (line 21) | type Node interface
  type NodeType (line 35) | type NodeType
    method Type (line 47) | func (t NodeType) Type() NodeType {
  type Pos (line 39) | type Pos
    method Position (line 41) | func (p Pos) Position() Pos {
  constant NodeText (line 52) | NodeText       NodeType = iota
  constant NodeAction (line 53) | NodeAction
  constant NodeBool (line 54) | NodeBool
  constant NodeChain (line 55) | NodeChain
  constant NodeCommand (line 56) | NodeCommand
  constant NodeDot (line 57) | NodeDot
  constant nodeElse (line 58) | nodeElse
  constant nodeEnd (line 59) | nodeEnd
  constant NodeField (line 60) | NodeField
  constant NodeIdentifier (line 61) | NodeIdentifier
  constant NodeIf (line 62) | NodeIf
  constant NodeList (line 63) | NodeList
  constant NodeNil (line 64) | NodeNil
  constant NodeNumber (line 65) | NodeNumber
  constant NodePipe (line 66) | NodePipe
  constant NodeRange (line 67) | NodeRange
  constant NodeString (line 68) | NodeString
  constant NodeTemplate (line 69) | NodeTemplate
  constant NodeVariable (line 70) | NodeVariable
  constant NodeWith (line 71) | NodeWith
  type ListNode (line 77) | type ListNode struct
    method append (line 88) | func (l *ListNode) append(n Node) {
    method tree (line 92) | func (l *ListNode) tree() *Tree {
    method String (line 96) | func (l *ListNode) String() string {
    method CopyList (line 104) | func (l *ListNode) CopyList() *ListNode {
    method Copy (line 115) | func (l *ListNode) Copy() Node {
  method newList (line 84) | func (t *Tree) newList(pos Pos) *ListNode {
  type TextNode (line 120) | type TextNode struct
    method String (line 131) | func (t *TextNode) String() string {
    method tree (line 135) | func (t *TextNode) tree() *Tree {
    method Copy (line 139) | func (t *TextNode) Copy() Node {
  method newText (line 127) | func (t *Tree) newText(pos Pos, text string) *TextNode {
  type PipeNode (line 144) | type PipeNode struct
    method append (line 157) | func (p *PipeNode) append(command *CommandNode) {
    method String (line 161) | func (p *PipeNode) String() string {
    method tree (line 181) | func (p *PipeNode) tree() *Tree {
    method CopyPipe (line 185) | func (p *PipeNode) CopyPipe() *PipeNode {
    method Copy (line 200) | func (p *PipeNode) Copy() Node {
  method newPipeline (line 153) | func (t *Tree) newPipeline(pos Pos, line int, decl []*VariableNode) *Pip...
  type ActionNode (line 207) | type ActionNode struct
    method String (line 219) | func (a *ActionNode) String() string {
    method tree (line 224) | func (a *ActionNode) tree() *Tree {
    method Copy (line 228) | func (a *ActionNode) Copy() Node {
  method newAction (line 215) | func (t *Tree) newAction(pos Pos, line int, pipe *PipeNode) *ActionNode {
  type CommandNode (line 234) | type CommandNode struct
    method append (line 245) | func (c *CommandNode) append(arg Node) {
    method String (line 249) | func (c *CommandNode) String() string {
    method tree (line 264) | func (c *CommandNode) tree() *Tree {
    method Copy (line 268) | func (c *CommandNode) Copy() Node {
  method newCommand (line 241) | func (t *Tree) newCommand(pos Pos) *CommandNode {
  type IdentifierNode (line 280) | type IdentifierNode struct
    method SetPos (line 295) | func (i *IdentifierNode) SetPos(pos Pos) *IdentifierNode {
    method SetTree (line 303) | func (i *IdentifierNode) SetTree(t *Tree) *IdentifierNode {
    method String (line 308) | func (i *IdentifierNode) String() string {
    method tree (line 312) | func (i *IdentifierNode) tree() *Tree {
    method Copy (line 316) | func (i *IdentifierNode) Copy() Node {
  function NewIdentifier (line 288) | func NewIdentifier(ident string) *IdentifierNode {
  type VariableNode (line 322) | type VariableNode struct
    method String (line 333) | func (v *VariableNode) String() string {
    method tree (line 344) | func (v *VariableNode) tree() *Tree {
    method Copy (line 348) | func (v *VariableNode) Copy() Node {
  method newVariable (line 329) | func (t *Tree) newVariable(pos Pos, ident string) *VariableNode {
  type DotNode (line 353) | type DotNode struct
    method Type (line 363) | func (d *DotNode) Type() NodeType {
    method String (line 370) | func (d *DotNode) String() string {
    method tree (line 374) | func (d *DotNode) tree() *Tree {
    method Copy (line 378) | func (d *DotNode) Copy() Node {
  method newDot (line 359) | func (t *Tree) newDot(pos Pos) *DotNode {
  type NilNode (line 383) | type NilNode struct
    method Type (line 393) | func (n *NilNode) Type() NodeType {
    method String (line 400) | func (n *NilNode) String() string {
    method tree (line 404) | func (n *NilNode) tree() *Tree {
    method Copy (line 408) | func (n *NilNode) Copy() Node {
  method newNil (line 389) | func (t *Tree) newNil(pos Pos) *NilNode {
  type FieldNode (line 415) | type FieldNode struct
    method String (line 426) | func (f *FieldNode) String() string {
    method tree (line 434) | func (f *FieldNode) tree() *Tree {
    method Copy (line 438) | func (f *FieldNode) Copy() Node {
  method newField (line 422) | func (t *Tree) newField(pos Pos, ident string) *FieldNode {
  type ChainNode (line 445) | type ChainNode struct
    method Add (line 458) | func (c *ChainNode) Add(field string) {
    method String (line 469) | func (c *ChainNode) String() string {
    method tree (line 480) | func (c *ChainNode) tree() *Tree {
    method Copy (line 484) | func (c *ChainNode) Copy() Node {
  method newChain (line 453) | func (t *Tree) newChain(pos Pos, node Node) *ChainNode {
  type BoolNode (line 489) | type BoolNode struct
    method String (line 500) | func (b *BoolNode) String() string {
    method tree (line 507) | func (b *BoolNode) tree() *Tree {
    method Copy (line 511) | func (b *BoolNode) Copy() Node {
  method newBool (line 496) | func (t *Tree) newBool(pos Pos, true bool) *BoolNode {
  type NumberNode (line 518) | type NumberNode struct
    method simplifyComplex (line 616) | func (n *NumberNode) simplifyComplex() {
    method String (line 631) | func (n *NumberNode) String() string {
    method tree (line 635) | func (n *NumberNode) tree() *Tree {
    method Copy (line 639) | func (n *NumberNode) Copy() Node {
  method newNumber (line 533) | func (t *Tree) newNumber(pos Pos, text string, typ itemType) (*NumberNod...
  type StringNode (line 646) | type StringNode struct
    method String (line 658) | func (s *StringNode) String() string {
    method tree (line 662) | func (s *StringNode) tree() *Tree {
    method Copy (line 666) | func (s *StringNode) Copy() Node {
  method newString (line 654) | func (t *Tree) newString(pos Pos, orig, text string) *StringNode {
  type endNode (line 672) | type endNode struct
    method String (line 682) | func (e *endNode) String() string {
    method tree (line 686) | func (e *endNode) tree() *Tree {
    method Copy (line 690) | func (e *endNode) Copy() Node {
  method newEnd (line 678) | func (t *Tree) newEnd(pos Pos) *endNode {
  type elseNode (line 695) | type elseNode struct
    method Type (line 706) | func (e *elseNode) Type() NodeType {
    method String (line 710) | func (e *elseNode) String() string {
    method tree (line 714) | func (e *elseNode) tree() *Tree {
    method Copy (line 718) | func (e *elseNode) Copy() Node {
  method newElse (line 702) | func (t *Tree) newElse(pos Pos, line int) *elseNode {
  type BranchNode (line 723) | type BranchNode struct
    method String (line 733) | func (b *BranchNode) String() string {
    method tree (line 751) | func (b *BranchNode) tree() *Tree {
    method Copy (line 755) | func (b *BranchNode) Copy() Node {
  type IfNode (line 769) | type IfNode struct
    method Copy (line 777) | func (i *IfNode) Copy() Node {
  method newIf (line 773) | func (t *Tree) newIf(pos Pos, line int, pipe *PipeNode, list, elseList *...
  type RangeNode (line 782) | type RangeNode struct
    method Copy (line 790) | func (r *RangeNode) Copy() Node {
  method newRange (line 786) | func (t *Tree) newRange(pos Pos, line int, pipe *PipeNode, list, elseLis...
  type WithNode (line 795) | type WithNode struct
    method Copy (line 803) | func (w *WithNode) Copy() Node {
  method newWith (line 799) | func (t *Tree) newWith(pos Pos, line int, pipe *PipeNode, list, elseList...
  type TemplateNode (line 808) | type TemplateNode struct
    method String (line 821) | func (t *TemplateNode) String() string {
    method tree (line 828) | func (t *TemplateNode) tree() *Tree {
    method Copy (line 832) | func (t *TemplateNode) Copy() Node {
  method newTemplate (line 817) | func (t *Tree) newTemplate(pos Pos, line int, name string, pipe *PipeNod...

FILE: vendor/github.com/alecthomas/template/parse/parse.go
  type Tree (line 20) | type Tree struct
    method Copy (line 34) | func (t *Tree) Copy() *Tree {
    method next (line 59) | func (t *Tree) next() item {
    method backup (line 69) | func (t *Tree) backup() {
    method backup2 (line 75) | func (t *Tree) backup2(t1 item) {
    method backup3 (line 82) | func (t *Tree) backup3(t2, t1 item) { // Reverse order: we're pushing ...
    method peek (line 89) | func (t *Tree) peek() item {
    method nextNonSpace (line 99) | func (t *Tree) nextNonSpace() (token item) {
    method peekNonSpace (line 110) | func (t *Tree) peekNonSpace() (token item) {
    method ErrorContext (line 134) | func (t *Tree) ErrorContext(n Node) (location, context string) {
    method errorf (line 157) | func (t *Tree) errorf(format string, args ...interface{}) {
    method error (line 164) | func (t *Tree) error(err error) {
    method expect (line 169) | func (t *Tree) expect(expected itemType, context string) item {
    method expectOneOf (line 178) | func (t *Tree) expectOneOf(expected1, expected2 itemType, context stri...
    method unexpected (line 187) | func (t *Tree) unexpected(token item, context string) {
    method recover (line 192) | func (t *Tree) recover(errp *error) {
    method startParse (line 207) | func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer) {
    method stopParse (line 215) | func (t *Tree) stopParse() {
    method Parse (line 225) | func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[s...
    method add (line 237) | func (t *Tree) add(treeSet map[string]*Tree) {
    method parse (line 276) | func (t *Tree) parse(treeSet map[string]*Tree) (next Node) {
    method parseDefinition (line 303) | func (t *Tree) parseDefinition(treeSet map[string]*Tree) {
    method itemList (line 324) | func (t *Tree) itemList() (list *ListNode, next Node) {
    method textOrAction (line 340) | func (t *Tree) textOrAction() Node {
    method elideNewline (line 356) | func (t *Tree) elideNewline() Node {
    method action (line 380) | func (t *Tree) action() (n Node) {
    method pipeline (line 402) | func (t *Tree) pipeline(context string) (pipe *PipeNode) {
    method parseControl (line 454) | func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos...
    method ifControl (line 492) | func (t *Tree) ifControl() Node {
    method rangeControl (line 500) | func (t *Tree) rangeControl() Node {
    method withControl (line 508) | func (t *Tree) withControl() Node {
    method endControl (line 515) | func (t *Tree) endControl() Node {
    method elseControl (line 522) | func (t *Tree) elseControl() Node {
    method templateControl (line 536) | func (t *Tree) templateControl() Node {
    method command (line 562) | func (t *Tree) command() *CommandNode {
    method operand (line 594) | func (t *Tree) operand() Node {
    method term (line 629) | func (t *Tree) term() Node {
    method hasFunction (line 672) | func (t *Tree) hasFunction(name string) bool {
    method popVars (line 685) | func (t *Tree) popVars(n int) {
    method useVar (line 691) | func (t *Tree) useVar(pos Pos, name string) Node {
  function Parse (line 50) | func Parse(name, text, leftDelim, rightDelim string, funcs ...map[string...
  function New (line 124) | func New(name string, funcs ...map[string]interface{}) *Tree {
  function IsEmptyTree (line 249) | func IsEmptyTree(n Node) bool {

FILE: vendor/github.com/alecthomas/template/template.go
  type common (line 15) | type common struct
  type Template (line 27) | type Template struct
    method Name (line 43) | func (t *Template) Name() string {
    method New (line 50) | func (t *Template) New(name string) *Template {
    method init (line 60) | func (t *Template) init() {
    method Clone (line 75) | func (t *Template) Clone() (*Template, error) {
    method copy (line 97) | func (t *Template) copy(c *common) *Template {
    method AddParseTree (line 108) | func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Templ...
    method Templates (line 120) | func (t *Template) Templates() []*Template {
    method Delims (line 137) | func (t *Template) Delims(left, right string) *Template {
    method Funcs (line 147) | func (t *Template) Funcs(funcMap FuncMap) *Template {
    method Lookup (line 156) | func (t *Template) Lookup(name string) *Template {
    method Parse (line 170) | func (t *Template) Parse(text string) (*Template, error) {
    method associate (line 200) | func (t *Template) associate(new *Template, tree *parse.Tree) (bool, e...
  function New (line 36) | func New(name string) *Template {

FILE: vendor/github.com/alecthomas/units/bytes.go
  type Base2Bytes (line 5) | type Base2Bytes
    method String (line 38) | func (b Base2Bytes) String() string {
  constant Kibibyte (line 9) | Kibibyte Base2Bytes = 1024
  constant KiB (line 10) | KiB                 = Kibibyte
  constant Mebibyte (line 11) | Mebibyte            = Kibibyte * 1024
  constant MiB (line 12) | MiB                 = Mebibyte
  constant Gibibyte (line 13) | Gibibyte            = Mebibyte * 1024
  constant GiB (line 14) | GiB                 = Gibibyte
  constant Tebibyte (line 15) | Tebibyte            = Gibibyte * 1024
  constant TiB (line 16) | TiB                 = Tebibyte
  constant Pebibyte (line 17) | Pebibyte            = Tebibyte * 1024
  constant PiB (line 18) | PiB                 = Pebibyte
  constant Exbibyte (line 19) | Exbibyte            = Pebibyte * 1024
  constant EiB (line 20) | EiB                 = Exbibyte
  function ParseBase2Bytes (line 30) | func ParseBase2Bytes(s string) (Base2Bytes, error) {
  type MetricBytes (line 47) | type MetricBytes
    method String (line 71) | func (m MetricBytes) String() string {
  constant Kilobyte (line 51) | Kilobyte MetricBytes = 1000
  constant KB (line 52) | KB                   = Kilobyte
  constant Megabyte (line 53) | Megabyte             = Kilobyte * 1000
  constant MB (line 54) | MB                   = Megabyte
  constant Gigabyte (line 55) | Gigabyte             = Megabyte * 1000
  constant GB (line 56) | GB                   = Gigabyte
  constant Terabyte (line 57) | Terabyte             = Gigabyte * 1000
  constant TB (line 58) | TB                   = Terabyte
  constant Petabyte (line 59) | Petabyte             = Terabyte * 1000
  constant PB (line 60) | PB                   = Petabyte
  constant Exabyte (line 61) | Exabyte              = Petabyte * 1000
  constant EB (line 62) | EB                   = Exabyte
  function ParseMetricBytes (line 66) | func ParseMetricBytes(s string) (MetricBytes, error) {
  function ParseStrictBytes (line 77) | func ParseStrictBytes(s string) (int64, error) {

FILE: vendor/github.com/alecthomas/units/si.go
  type SI (line 4) | type SI
  constant Kilo (line 8) | Kilo SI = 1000
  constant Mega (line 9) | Mega    = Kilo * 1000
  constant Giga (line 10) | Giga    = Mega * 1000
  constant Tera (line 11) | Tera    = Giga * 1000
  constant Peta (line 12) | Peta    = Tera * 1000
  constant Exa (line 13) | Exa     = Peta * 1000
  function MakeUnitMap (line 16) | func MakeUnitMap(suffix, shortSuffix string, scale int64) map[string]flo...

FILE: vendor/github.com/alecthomas/units/util.go
  function ToString (line 13) | func ToString(n int64, scale int64, suffix, baseSuffix string) string {
  function leadingInt (line 36) | func leadingInt(s string) (x int64, rem string, err error) {
  function ParseUnit (line 52) | func ParseUnit(s string, unitMap map[string]float64) (int64, error) {

FILE: vendor/github.com/bcext/cashutil/address.go
  function encodeAddress (line 42) | func encodeAddress(hash160 []byte, netID byte) string {
  type Address (line 53) | type Address interface
  function DecodeAddress (line 85) | func DecodeAddress(addr string, defaultNet *chaincfg.Params) (Address, e...
  type AddressPubKeyHash (line 144) | type AddressPubKeyHash struct
    method EncodeAddress (line 173) | func (a *AddressPubKeyHash) EncodeAddress(cashaddr bool) string {
    method ScriptAddress (line 183) | func (a *AddressPubKeyHash) ScriptAddress() []byte {
    method IsForNet (line 189) | func (a *AddressPubKeyHash) IsForNet(net *chaincfg.Params) bool {
    method String (line 197) | func (a *AddressPubKeyHash) String() string {
    method Hash160 (line 204) | func (a *AddressPubKeyHash) Hash160() *[ripemd160.Size]byte {
  function NewAddressPubKeyHash (line 151) | func NewAddressPubKeyHash(pkHash []byte, param *chaincfg.Params) (*Addre...
  function newAddressPubKeyHash (line 160) | func newAddressPubKeyHash(pkHash []byte, param *chaincfg.Params) (*Addre...
  type AddressScriptHash (line 210) | type AddressScriptHash struct
    method EncodeAddress (line 245) | func (a *AddressScriptHash) EncodeAddress(cashaddr bool) string {
    method ScriptAddress (line 255) | func (a *AddressScriptHash) ScriptAddress() []byte {
    method IsForNet (line 261) | func (a *AddressScriptHash) IsForNet(net *chaincfg.Params) bool {
    method String (line 269) | func (a *AddressScriptHash) String() string {
    method Hash160 (line 276) | func (a *AddressScriptHash) Hash160() *[ripemd160.Size]byte {
  function NewAddressScriptHash (line 216) | func NewAddressScriptHash(serializedScript []byte, param *chaincfg.Param...
  function NewAddressScriptHashFromHash (line 223) | func NewAddressScriptHashFromHash(scriptHash []byte, param *chaincfg.Par...
  function newAddressScriptHashFromHash (line 232) | func newAddressScriptHashFromHash(scriptHash []byte, param *chaincfg.Par...
  type PubKeyFormat (line 281) | type PubKeyFormat
  constant PKFUncompressed (line 286) | PKFUncompressed PubKeyFormat = iota
  constant PKFCompressed (line 290) | PKFCompressed
  constant PKFHybrid (line 294) | PKFHybrid
  type AddressPubKey (line 298) | type AddressPubKey struct
    method serialize (line 334) | func (a *AddressPubKey) serialize() []byte {
    method EncodeAddress (line 357) | func (a *AddressPubKey) EncodeAddress(cashaddr bool) string {
    method ScriptAddress (line 372) | func (a *AddressPubKey) ScriptAddress() []byte {
    method IsForNet (line 378) | func (a *AddressPubKey) IsForNet(net *chaincfg.Params) bool {
    method String (line 384) | func (a *AddressPubKey) String() string {
    method Format (line 390) | func (a *AddressPubKey) Format() PubKeyFormat {
    method SetFormat (line 396) | func (a *AddressPubKey) SetFormat(pkFormat PubKeyFormat) {
    method AddressPubKeyHash (line 406) | func (a *AddressPubKey) AddressPubKeyHash() *AddressPubKeyHash {
    method PubKey (line 413) | func (a *AddressPubKey) PubKey() *btcec.PublicKey {
  function NewAddressPubKey (line 307) | func NewAddressPubKey(serializedPubKey []byte, param *chaincfg.Params) (...

FILE: vendor/github.com/bcext/cashutil/amount.go
  type AmountUnit (line 17) | type AmountUnit
    method String (line 33) | func (u AmountUnit) String() string {
  constant AmountMegaBCH (line 22) | AmountMegaBCH  AmountUnit = 6
  constant AmountKiloBCH (line 23) | AmountKiloBCH  AmountUnit = 3
  constant AmountBCH (line 24) | AmountBCH      AmountUnit = 0
  constant AmountMilliBCH (line 25) | AmountMilliBCH AmountUnit = -3
  constant AmountMicroBCH (line 26) | AmountMicroBCH AmountUnit = -6
  constant AmountSatoshi (line 27) | AmountSatoshi  AmountUnit = -8
  type Amount (line 54) | type Amount
    method ToUnit (line 93) | func (a Amount) ToUnit(u AmountUnit) float64 {
    method ToBCH (line 98) | func (a Amount) ToBCH() float64 {
    method Format (line 106) | func (a Amount) Format(u AmountUnit) string {
    method String (line 112) | func (a Amount) String() string {
    method MulF64 (line 120) | func (a Amount) MulF64(f float64) Amount {
  function round (line 60) | func round(f float64) Amount {
  function NewAmount (line 76) | func NewAmount(f float64) (Amount, error) {

FILE: vendor/github.com/bcext/cashutil/appdata.go
  function appDataDir (line 21) | func appDataDir(goos, appName string, roaming bool) string {
  function AppDataDir (line 103) | func AppDataDir(appName string, roaming bool) string {

FILE: vendor/github.com/bcext/cashutil/base58/alphabet.go
  constant alphabet (line 11) | alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
  constant alphabetIdx0 (line 13) | alphabetIdx0 = '1'

FILE: vendor/github.com/bcext/cashutil/base58/base58.go
  function Decode (line 17) | func Decode(b string) []byte {
  function Encode (line 49) | func Encode(b []byte) string {

FILE: vendor/github.com/bcext/cashutil/base58/base58check.go
  function checksum (line 20) | func checksum(input []byte) (cksum [4]byte) {
  function CheckEncode (line 28) | func CheckEncode(input []byte, version byte) string {
  function CheckDecode (line 38) | func CheckDecode(input string) (result []byte, version byte, err error) {

FILE: vendor/github.com/bcext/cashutil/base58/genalphabet.go
  function write (line 45) | func write(w io.Writer, b []byte) {
  function main (line 52) | func main() {

FILE: vendor/github.com/bcext/cashutil/block.go
  type OutOfRangeError (line 19) | type OutOfRangeError
    method Error (line 27) | func (e OutOfRangeError) Error() string {
  constant BlockHeightUnknown (line 24) | BlockHeightUnknown = int32(-1)
  type Block (line 35) | type Block struct
    method MsgBlock (line 45) | func (b *Block) MsgBlock() *wire.MsgBlock {
    method Bytes (line 53) | func (b *Block) Bytes() ([]byte, error) {
    method Hash (line 75) | func (b *Block) Hash() *chainhash.Hash {
    method Tx (line 93) | func (b *Block) Tx(txNum int) (*Tx, error) {
    method Transactions (line 123) | func (b *Block) Transactions() []*Tx {
    method TxHash (line 155) | func (b *Block) TxHash(txNum int) (*chainhash.Hash, error) {
    method TxLoc (line 172) | func (b *Block) TxLoc() ([]wire.TxLoc, error) {
    method Height (line 189) | func (b *Block) Height() int32 {
    method SetHeight (line 194) | func (b *Block) SetHeight(height int32) {
  function NewBlock (line 200) | func NewBlock(msgBlock *wire.MsgBlock) *Block {
  function NewBlockFromBytes (line 209) | func NewBlockFromBytes(serializedBlock []byte) (*Block, error) {
  function NewBlockFromReader (line 221) | func NewBlockFromReader(r io.Reader) (*Block, error) {
  function NewBlockFromBlockAndBytes (line 238) | func NewBlockFromBlockAndBytes(msgBlock *wire.MsgBlock, serializedBlock ...

FILE: vendor/github.com/bcext/cashutil/cashaddr.go
  constant charset (line 13) | charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
  function encode (line 26) | func encode(prefix string, payload []byte) string {
  function decode (line 39) | func decode(str, defaultPrefix string) (string, []byte) {
  function createChecksum (line 117) | func createChecksum(prefix string, payload []byte) []byte {
  function cat (line 134) | func cat(x, y []byte) []byte {
  function expandPrefix (line 141) | func expandPrefix(prefix string) []byte {
  function polyMod (line 154) | func polyMod(v []byte) uint64 {
  function verifyChecksum (line 251) | func verifyChecksum(prefix string, payload []byte) bool {

FILE: vendor/github.com/bcext/cashutil/cashaddrconv.go
  type addrType (line 15) | type addrType
  constant pubKeyType (line 18) | pubKeyType addrType = iota
  constant scriptType (line 19) | scriptType
  type addrContent (line 28) | type addrContent struct
  function encodeCashAddr (line 33) | func encodeCashAddr(dst Address) string {
  function decodeCashAddr (line 46) | func decodeCashAddr(addr string, param *chaincfg.Params) (Address, error) {
  function packAddrData (line 62) | func packAddrData(id []byte, t uint8) []byte {
  function convertBits (line 100) | func convertBits(frombits uint, tobits uint, pad bool, data []byte) ([]b...
  function decodeCashaddrContent (line 129) | func decodeCashaddrContent(addr string, param *chaincfg.Params) *addrCon...
  function decodeCashAddrDestination (line 179) | func decodeCashAddrDestination(content *addrContent, params *chaincfg.Pa...

FILE: vendor/github.com/bcext/cashutil/certgen.go
  function NewTLSCertPair (line 28) | func NewTLSCertPair(organization string, validUntil time.Time, extraHost...

FILE: vendor/github.com/bcext/cashutil/const.go
  constant SatoshiPerBitcent (line 9) | SatoshiPerBitcent = 1e6
  constant SatoshiPerBitcoin (line 12) | SatoshiPerBitcoin = 1e8
  constant MaxSatoshi (line 15) | MaxSatoshi = 21e6 * SatoshiPerBitcoin

FILE: vendor/github.com/bcext/cashutil/hash160.go
  function calcHash (line 15) | func calcHash(buf []byte, hasher hash.Hash) []byte {
  function Hash160 (line 21) | func Hash160(buf []byte) []byte {

FILE: vendor/github.com/bcext/cashutil/net.go
  function interfaceAddrs (line 16) | func interfaceAddrs() ([]net.Addr, error) {

FILE: vendor/github.com/bcext/cashutil/net_noop.go
  function interfaceAddrs (line 17) | func interfaceAddrs() ([]net.Addr, error) {

FILE: vendor/github.com/bcext/cashutil/tx.go
  constant TxIndexUnknown (line 19) | TxIndexUnknown = -1
  type Tx (line 25) | type Tx struct
    method MsgTx (line 32) | func (t *Tx) MsgTx() *wire.MsgTx {
    method Hash (line 40) | func (t *Tx) Hash() *chainhash.Hash {
    method Index (line 54) | func (t *Tx) Index() int {
    method SetIndex (line 59) | func (t *Tx) SetIndex(index int) {
  function NewTx (line 65) | func NewTx(msgTx *wire.MsgTx) *Tx {
  function NewTxFromBytes (line 74) | func NewTxFromBytes(serializedTx []byte) (*Tx, error) {
  function NewTxFromReader (line 81) | func NewTxFromReader(r io.Reader) (*Tx, error) {

FILE: vendor/github.com/bcext/cashutil/wif.go
  constant compressMagic (line 25) | compressMagic byte = 0x01
  type WIF (line 33) | type WIF struct
    method IsForNet (line 61) | func (w *WIF) IsForNet(net *chaincfg.Params) bool {
    method String (line 127) | func (w *WIF) String() string {
    method SerializePubKey (line 153) | func (w *WIF) SerializePubKey() []byte {
  function NewWIF (line 52) | func NewWIF(privKey *btcec.PrivateKey, net *chaincfg.Params, compress bo...
  function DecodeWIF (line 85) | func DecodeWIF(wif string) (*WIF, error) {
  function paddedAppend (line 164) | func paddedAppend(size uint, dst, src []byte) []byte {

FILE: vendor/github.com/bcext/gcash/btcec/btcec.go
  type KoblitzCurve (line 37) | type KoblitzCurve struct
    method Params (line 69) | func (curve *KoblitzCurve) Params() *elliptic.CurveParams {
    method bigAffineToField (line 75) | func (curve *KoblitzCurve) bigAffineToField(x, y *big.Int) (*fieldVal,...
    method fieldJacobianToBigAffine (line 85) | func (curve *KoblitzCurve) fieldJacobianToBigAffine(x, y, z *fieldVal)...
    method IsOnCurve (line 111) | func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool {
    method addZ1AndZ2EqualsOne (line 126) | func (curve *KoblitzCurve) addZ1AndZ2EqualsOne(x1, y1, z1, x2, y2, x3,...
    method addZ1EqualsZ2 (line 192) | func (curve *KoblitzCurve) addZ1EqualsZ2(x1, y1, z1, x2, y2, x3, y3, z...
    method addZ2EqualsOne (line 261) | func (curve *KoblitzCurve) addZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, ...
    method addGeneric (line 337) | func (curve *KoblitzCurve) addGeneric(x1, y1, z1, x2, y2, z2, x3, y3, ...
    method addJacobian (line 410) | func (curve *KoblitzCurve) addJacobian(x1, y1, z1, x2, y2, z2, x3, y3,...
    method Add (line 454) | func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *bi...
    method doubleZ1EqualsOne (line 482) | func (curve *KoblitzCurve) doubleZ1EqualsOne(x1, y1, x3, y3, z3 *field...
    method doubleGeneric (line 532) | func (curve *KoblitzCurve) doubleGeneric(x1, y1, z1, x3, y3, z3 *field...
    method doubleJacobian (line 579) | func (curve *KoblitzCurve) doubleJacobian(x1, y1, z1, x3, y3, z3 *fiel...
    method Double (line 603) | func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
    method splitK (line 628) | func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
    method moduloReduce (line 666) | func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
    method ScalarMult (line 758) | func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big...
    method ScalarBaseMult (line 863) | func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.In...
    method QPlus1Div4 (line 884) | func (curve *KoblitzCurve) QPlus1Div4() *big.Int {
  function NAF (line 686) | func NAF(k []byte) ([]byte, []byte) {
  function initAll (line 891) | func initAll() {
  function fromHex (line 899) | func fromHex(s string) *big.Int {
  function initS256 (line 907) | func initS256() {
  function S256 (line 955) | func S256() *KoblitzCurve {

FILE: vendor/github.com/bcext/gcash/btcec/ciphering.go
  function GenerateSharedSecret (line 46) | func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte {
  function Encrypt (line 70) | func Encrypt(pubkey *PublicKey, in []byte) ([]byte, error) {
  function Decrypt (line 121) | func Decrypt(priv *PrivateKey, in []byte) ([]byte, error) {
  function addPKCSPadding (line 201) | func addPKCSPadding(src []byte) []byte {
  function removePKCSPadding (line 208) | func removePKCSPadding(src []byte) ([]byte, error) {

FILE: vendor/github.com/bcext/gcash/btcec/field.go
  constant twoBitsMask (line 63) | twoBitsMask   = 0x3
  constant fourBitsMask (line 64) | fourBitsMask  = 0xf
  constant sixBitsMask (line 65) | sixBitsMask   = 0x3f
  constant eightBitsMask (line 66) | eightBitsMask = 0xff
  constant fieldWords (line 73) | fieldWords = 10
  constant fieldBase (line 77) | fieldBase = 26
  constant fieldOverflowBits (line 81) | fieldOverflowBits = 32 - fieldBase
  constant fieldBaseMask (line 86) | fieldBaseMask = (1 << fieldBase) - 1
  constant fieldMSBBits (line 90) | fieldMSBBits = 256 - (fieldBase * (fieldWords - 1))
  constant fieldMSBMask (line 94) | fieldMSBMask = (1 << fieldMSBBits) - 1
  constant fieldPrimeWordZero (line 98) | fieldPrimeWordZero = 0x3fffc2f
  constant fieldPrimeWordOne (line 102) | fieldPrimeWordOne = 0x3ffffbf
  type fieldVal (line 135) | type fieldVal struct
    method String (line 140) | func (f fieldVal) String() string {
    method Zero (line 148) | func (f *fieldVal) Zero() {
    method Set (line 166) | func (f *fieldVal) Set(val *fieldVal) *fieldVal {
    method SetInt (line 177) | func (f *fieldVal) SetInt(ui uint) *fieldVal {
    method SetBytes (line 188) | func (f *fieldVal) SetBytes(b *[32]byte) *fieldVal {
    method SetByteSlice (line 222) | func (f *fieldVal) SetByteSlice(b []byte) *fieldVal {
    method SetHex (line 237) | func (f *fieldVal) SetHex(hexString string) *fieldVal {
    method Normalize (line 248) | func (f *fieldVal) Normalize() *fieldVal {
    method PutBytes (line 377) | func (f *fieldVal) PutBytes(b *[32]byte) {
    method Bytes (line 423) | func (f *fieldVal) Bytes() *[32]byte {
    method IsZero (line 430) | func (f *fieldVal) IsZero() bool {
    method IsOdd (line 443) | func (f *fieldVal) IsOdd() bool {
    method Equals (line 451) | func (f *fieldVal) Equals(val *fieldVal) bool {
    method NegateVal (line 468) | func (f *fieldVal) NegateVal(val *fieldVal, magnitude uint32) *fieldVal {
    method Negate (line 506) | func (f *fieldVal) Negate(magnitude uint32) *fieldVal {
    method AddInt (line 516) | func (f *fieldVal) AddInt(ui uint) *fieldVal {
    method Add (line 530) | func (f *fieldVal) Add(val *fieldVal) *fieldVal {
    method Add2 (line 553) | func (f *fieldVal) Add2(val *fieldVal, val2 *fieldVal) *fieldVal {
    method MulInt (line 579) | func (f *fieldVal) MulInt(val uint) *fieldVal {
    method Mul (line 609) | func (f *fieldVal) Mul(val *fieldVal) *fieldVal {
    method Mul2 (line 621) | func (f *fieldVal) Mul2(val *fieldVal, val2 *fieldVal) *fieldVal {
    method Square (line 890) | func (f *fieldVal) Square() *fieldVal {
    method SquareVal (line 901) | func (f *fieldVal) SquareVal(val *fieldVal) *fieldVal {
    method Inverse (line 1121) | func (f *fieldVal) Inverse() *fieldVal {

FILE: vendor/github.com/bcext/gcash/btcec/genprecomps.go
  function main (line 23) | func main() {

FILE: vendor/github.com/bcext/gcash/btcec/gensecp256k1.go
  method getDoublingPoints (line 26) | func (curve *KoblitzCurve) getDoublingPoints() [][3]fieldVal {
  method SerializedBytePoints (line 43) | func (curve *KoblitzCurve) SerializedBytePoints() []byte {
  function sqrt (line 84) | func sqrt(n *big.Int) *big.Int {
  method EndomorphismVectors (line 109) | func (curve *KoblitzCurve) EndomorphismVectors() (a1, b1, a2, b2 *big.In...

FILE: vendor/github.com/bcext/gcash/btcec/precompute.go
  function loadS256BytePoints (line 23) | func loadS256BytePoints() error {

FILE: vendor/github.com/bcext/gcash/btcec/privkey.go
  type PrivateKey (line 17) | type PrivateKey
    method PubKey (line 48) | func (p *PrivateKey) PubKey() *PublicKey {
    method ToECDSA (line 53) | func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey {
    method Sign (line 61) | func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {
    method Serialize (line 70) | func (p *PrivateKey) Serialize() []byte {
  function PrivKeyFromBytes (line 21) | func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey,
  function NewPrivateKey (line 39) | func NewPrivateKey(curve elliptic.Curve) (*PrivateKey, error) {
  constant PrivKeyBytesLen (line 66) | PrivKeyBytesLen = 32

FILE: vendor/github.com/bcext/gcash/btcec/pubkey.go
  constant PubKeyBytesLenCompressed (line 16) | PubKeyBytesLenCompressed   = 33
  constant PubKeyBytesLenUncompressed (line 17) | PubKeyBytesLenUncompressed = 65
  constant PubKeyBytesLenHybrid (line 18) | PubKeyBytesLenHybrid       = 65
  function isOdd (line 21) | func isOdd(a *big.Int) bool {
  function decompressPoint (line 27) | func decompressPoint(curve *KoblitzCurve, x *big.Int, ybit bool) (*big.I...
  constant pubkeyCompressed (line 63) | pubkeyCompressed   byte = 0x2
  constant pubkeyUncompressed (line 64) | pubkeyUncompressed byte = 0x4
  constant pubkeyHybrid (line 65) | pubkeyHybrid       byte = 0x6
  function IsCompressedPubKey (line 70) | func IsCompressedPubKey(pubKey []byte) bool {
  function ParsePubKey (line 80) | func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *PublicKey,...
  type PublicKey (line 137) | type PublicKey
    method ToECDSA (line 140) | func (p *PublicKey) ToECDSA() *ecdsa.PublicKey {
    method SerializeUncompressed (line 146) | func (p *PublicKey) SerializeUncompressed() []byte {
    method SerializeCompressed (line 154) | func (p *PublicKey) SerializeCompressed() []byte {
    method SerializeHybrid (line 165) | func (p *PublicKey) SerializeHybrid() []byte {
    method IsEqual (line 179) | func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool {
  function paddedAppend (line 187) | func paddedAppend(size uint, dst, src []byte) []byte {

FILE: vendor/github.com/bcext/gcash/btcec/signature.go
  type Signature (line 26) | type Signature struct
    method Serialize (line 47) | func (sig *Signature) Serialize() []byte {
    method Verify (line 76) | func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
    method IsEqual (line 83) | func (sig *Signature) IsEqual(otherSig *Signature) bool {
  function parseSig (line 88) | func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature...
  function ParseSignature (line 205) | func ParseSignature(sigStr []byte, curve elliptic.Curve) (*Signature, er...
  function ParseDERSignature (line 212) | func ParseDERSignature(sigStr []byte, curve elliptic.Curve) (*Signature,...
  function canonicalizeInt (line 222) | func canonicalizeInt(val *big.Int) []byte {
  function canonicalPadding (line 239) | func canonicalPadding(b []byte) error {
  function hashToInt (line 257) | func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
  function recoverKeyFromSignature (line 279) | func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []...
  function SignCompact (line 345) | func SignCompact(curve *KoblitzCurve, key *PrivateKey,
  function RecoverCompact (line 392) | func RecoverCompact(curve *KoblitzCurve, signature,
  function signRFC6979 (line 416) | func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
  function nonceRFC6979 (line 449) | func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int {
  function mac (line 501) | func mac(alg func() hash.Hash, k, m []byte) []byte {
  function int2octets (line 508) | func int2octets(v *big.Int, rolen int) []byte {
  function bits2octets (line 529) | func bits2octets(in []byte, curve elliptic.Curve, rolen int) []byte {

FILE: vendor/github.com/bcext/gcash/chaincfg/chainhash/hash.go
  constant HashSize (line 15) | HashSize = 32
  constant MaxHashStringSize (line 18) | MaxHashStringSize = HashSize * 2
  type Hash (line 29) | type Hash
    method String (line 33) | func (hash Hash) String() string {
    method CloneBytes (line 45) | func (hash *Hash) CloneBytes() []byte {
    method SetBytes (line 54) | func (hash *Hash) SetBytes(newHash []byte) error {
    method IsEqual (line 66) | func (hash *Hash) IsEqual(target *Hash) bool {
  function NewHash (line 78) | func NewHash(newHash []byte) (*Hash, error) {
  function NewHashFromStr (line 90) | func NewHashFromStr(hash string) (*Hash, error) {
  function Decode (line 101) | func Decode(dst *Hash, src string) error {

FILE: vendor/github.com/bcext/gcash/chaincfg/chainhash/hashfuncs.go
  function HashB (line 11) | func HashB(b []byte) []byte {
  function HashH (line 17) | func HashH(b []byte) Hash {
  function DoubleHashB (line 22) | func DoubleHashB(b []byte) []byte {
  function DoubleHashH (line 30) | func DoubleHashH(b []byte) Hash {

FILE: vendor/github.com/bcext/gcash/chaincfg/params.go
  type Checkpoint (line 50) | type Checkpoint struct
  type DNSSeed (line 56) | type DNSSeed struct
    method String (line 580) | func (d DNSSeed) String() string {
  type ConsensusDeployment (line 67) | type ConsensusDeployment struct
  constant DeploymentTestDummy (line 87) | DeploymentTestDummy = iota
  constant DeploymentCSV (line 92) | DeploymentCSV
  constant DefinedDeployments (line 98) | DefinedDeployments
  type Params (line 104) | type Params struct
    method DifficultyAdjustmentInterval (line 556) | func (param *Params) DifficultyAdjustmentInterval() int64 {
  function Register (line 593) | func Register(params *Params) error {
  function mustRegister (line 607) | func mustRegister(params *Params) {
  function IsPubKeyHashAddrID (line 619) | func IsPubKeyHashAddrID(id byte) bool {
  function IsScriptHashAddrID (line 630) | func IsScriptHashAddrID(id byte) bool {
  function HDPrivateKeyToPublicKeyID (line 638) | func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
  function newHashFromStr (line 657) | func newHashFromStr(hexStr string) *chainhash.Hash {
  function init (line 672) | func init() {

FILE: vendor/github.com/bcext/gcash/wire/blockheader.go
  constant MaxBlockHeaderPayload (line 19) | MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2)
  type BlockHeader (line 23) | type BlockHeader struct
    method BlockHash (line 49) | func (h *BlockHeader) BlockHash() chainhash.Hash {
    method BtcDecode (line 64) | func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 72) | func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32) error {
    method Deserialize (line 79) | func (h *BlockHeader) Deserialize(r io.Reader) error {
    method Serialize (line 89) | func (h *BlockHeader) Serialize(w io.Writer) error {
  constant blockHeaderLen (line 46) | blockHeaderLen = 80
  function NewBlockHeader (line 99) | func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.H...
  function readBlockHeader (line 117) | func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
  function writeBlockHeader (line 125) | func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {

FILE: vendor/github.com/bcext/gcash/wire/common.go
  constant MaxVarIntPayload (line 20) | MaxVarIntPayload = 9
  constant binaryFreeListMaxItems (line 24) | binaryFreeListMaxItems = 1024
  type binaryFreeList (line 48) | type binaryFreeList
    method Borrow (line 52) | func (l binaryFreeList) Borrow() []byte {
    method Return (line 64) | func (l binaryFreeList) Return(buf []byte) {
    method Uint8 (line 74) | func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) {
    method Uint16 (line 88) | func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder...
    method Uint32 (line 102) | func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder...
    method Uint64 (line 116) | func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder...
    method PutUint8 (line 129) | func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error {
    method PutUint16 (line 140) | func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOr...
    method PutUint32 (line 151) | func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOr...
    method PutUint64 (line 162) | func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOr...
  type uint32Time (line 182) | type uint32Time
  type int64Time (line 187) | type int64Time
  function readElement (line 191) | func readElement(r io.Reader, element interface{}) error {
  function readElements (line 336) | func readElements(r io.Reader, elements ...interface{}) error {
  function writeElement (line 347) | func writeElement(w io.Writer, element interface{}) error {
  function writeElements (line 465) | func writeElements(w io.Writer, elements ...interface{}) error {
  function ReadVarInt (line 476) | func ReadVarInt(r io.Reader, pver uint32) (uint64, error) {
  function WriteVarInt (line 538) | func WriteVarInt(w io.Writer, pver uint32, val uint64) error {
  function VarIntSerializeSize (line 568) | func VarIntSerializeSize(val uint64) int {
  function ReadVarString (line 595) | func ReadVarString(r io.Reader, pver uint32) (string, error) {
  function WriteVarString (line 621) | func WriteVarString(w io.Writer, pver uint32, str string) error {
  function ReadVarBytes (line 637) | func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
  function WriteVarBytes (line 664) | func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
  function randomUint64 (line 678) | func randomUint64(r io.Reader) (uint64, error) {
  function RandomUint64 (line 687) | func RandomUint64() (uint64, error) {

FILE: vendor/github.com/bcext/gcash/wire/error.go
  type MessageError (line 18) | type MessageError struct
    method Error (line 24) | func (e *MessageError) Error() string {
  function messageError (line 32) | func messageError(f string, desc string) *MessageError {

FILE: vendor/github.com/bcext/gcash/wire/invvect.go
  constant MaxInvPerMsg (line 18) | MaxInvPerMsg = 50000
  constant maxInvVectPayload (line 21) | maxInvVectPayload = 4 + chainhash.HashSize
  type InvType (line 25) | type InvType
    method String (line 44) | func (invtype InvType) String() string {
  constant InvTypeError (line 29) | InvTypeError         InvType = 0
  constant InvTypeTx (line 30) | InvTypeTx            InvType = 1
  constant InvTypeBlock (line 31) | InvTypeBlock         InvType = 2
  constant InvTypeFilteredBlock (line 32) | InvTypeFilteredBlock InvType = 3
  type InvVect (line 55) | type InvVect struct
  function NewInvVect (line 61) | func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect {
  function readInvVect (line 70) | func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
  function writeInvVect (line 75) | func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {

FILE: vendor/github.com/bcext/gcash/wire/message.go
  constant MessageHeaderSize (line 20) | MessageHeaderSize = 24
  constant CommandSize (line 24) | CommandSize = 12
  constant MaxMessagePayload (line 28) | MaxMessagePayload = (1024 * 1024 * 32)
  constant CmdVersion (line 32) | CmdVersion      = "version"
  constant CmdVerAck (line 33) | CmdVerAck       = "verack"
  constant CmdGetAddr (line 34) | CmdGetAddr      = "getaddr"
  constant CmdAddr (line 35) | CmdAddr         = "addr"
  constant CmdGetBlocks (line 36) | CmdGetBlocks    = "getblocks"
  constant CmdInv (line 37) | CmdInv          = "inv"
  constant CmdGetData (line 38) | CmdGetData      = "getdata"
  constant CmdNotFound (line 39) | CmdNotFound     = "notfound"
  constant CmdBlock (line 40) | CmdBlock        = "block"
  constant CmdTx (line 41) | CmdTx           = "tx"
  constant CmdGetHeaders (line 42) | CmdGetHeaders   = "getheaders"
  constant CmdHeaders (line 43) | CmdHeaders      = "headers"
  constant CmdPing (line 44) | CmdPing         = "ping"
  constant CmdPong (line 45) | CmdPong         = "pong"
  constant CmdAlert (line 46) | CmdAlert        = "alert"
  constant CmdMemPool (line 47) | CmdMemPool      = "mempool"
  constant CmdFilterAdd (line 48) | CmdFilterAdd    = "filteradd"
  constant CmdFilterClear (line 49) | CmdFilterClear  = "filterclear"
  constant CmdFilterLoad (line 50) | CmdFilterLoad   = "filterload"
  constant CmdMerkleBlock (line 51) | CmdMerkleBlock  = "merkleblock"
  constant CmdReject (line 52) | CmdReject       = "reject"
  constant CmdSendHeaders (line 53) | CmdSendHeaders  = "sendheaders"
  constant CmdFeeFilter (line 54) | CmdFeeFilter    = "feefilter"
  constant CmdGetCFilters (line 55) | CmdGetCFilters  = "getcfilters"
  constant CmdGetCFHeaders (line 56) | CmdGetCFHeaders = "getcfheaders"
  constant CmdGetCFCheckpt (line 57) | CmdGetCFCheckpt = "getcfcheckpt"
  constant CmdCFilter (line 58) | CmdCFilter      = "cfilter"
  constant CmdCFHeaders (line 59) | CmdCFHeaders    = "cfheaders"
  constant CmdCFCheckpt (line 60) | CmdCFCheckpt    = "cfcheckpt"
  type Message (line 67) | type Message interface
  function makeEmptyMessage (line 76) | func makeEmptyMessage(command string) (Message, error) {
  type messageHeader (line 173) | type messageHeader struct
  function readMessageHeader (line 181) | func readMessageHeader(r io.Reader) (int, *messageHeader, error) {
  function discardInput (line 208) | func discardInput(r io.Reader, n uint32) {
  function WriteMessageN (line 229) | func WriteMessageN(w io.Writer, msg Message, pver uint32, btcnet Bitcoin...
  function WriteMessage (line 299) | func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinN...
  function ReadMessageN (line 310) | func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Mes...
  function ReadMessage (line 396) | func ReadMessage(r io.Reader, pver uint32, btcnet BitcoinNet) (Message, ...

FILE: vendor/github.com/bcext/gcash/wire/msgaddr.go
  constant MaxAddrPerMsg (line 15) | MaxAddrPerMsg = 1000
  type MsgAddr (line 27) | type MsgAddr struct
    method AddAddress (line 32) | func (msg *MsgAddr) AddAddress(na *NetAddress) error {
    method AddAddresses (line 44) | func (msg *MsgAddr) AddAddresses(netAddrs ...*NetAddress) error {
    method ClearAddresses (line 55) | func (msg *MsgAddr) ClearAddresses() {
    method BtcDecode (line 61) | func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 89) | func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 122) | func (msg *MsgAddr) Command() string {
    method MaxPayloadLength (line 128) | func (msg *MsgAddr) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgAddr (line 140) | func NewMsgAddr() *MsgAddr {

FILE: vendor/github.com/bcext/gcash/wire/msgalert.go
  constant fixedAlertSize (line 71) | fixedAlertSize = 45
  constant maxSignatureSize (line 75) | maxSignatureSize = 72
  constant maxAlertSize (line 81) | maxAlertSize = MaxMessagePayload - maxSignatureSize - MaxVarIntPayload - 1
  constant maxCountSetCancel (line 90) | maxCountSetCancel = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + ...
  constant maxCountSetSubVer (line 101) | maxCountSetSubVer = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + ...
  type Alert (line 104) | type Alert struct
    method Serialize (line 152) | func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
    method Deserialize (line 215) | func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
  function NewAlert (line 283) | func NewAlert(version int32, relayUntil int64, expiration int64,
  function NewAlertFromPayload (line 306) | func NewAlertFromPayload(serializedPayload []byte, pver uint32) (*Alert,...
  type MsgAlert (line 322) | type MsgAlert struct
    method BtcDecode (line 337) | func (msg *MsgAlert) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 358) | func (msg *MsgAlert) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 388) | func (msg *MsgAlert) Command() string {
    method MaxPayloadLength (line 394) | func (msg *MsgAlert) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgAlert (line 402) | func NewMsgAlert(serializedPayload []byte, signature []byte) *MsgAlert {

FILE: vendor/github.com/bcext/gcash/wire/msgblock.go
  constant defaultTransactionAlloc (line 21) | defaultTransactionAlloc = 2048
  constant MaxBlocksPerMsg (line 24) | MaxBlocksPerMsg = 500
  constant MaxBlockPayload (line 27) | MaxBlockPayload = 2 * 32000000
  constant maxTxPerBlock (line 31) | maxTxPerBlock = (MaxBlockPayload / minTxPayload) + 1
  type TxLoc (line 35) | type TxLoc struct
  type MsgBlock (line 43) | type MsgBlock struct
    method AddTransaction (line 49) | func (msg *MsgBlock) AddTransaction(tx *MsgTx) error {
    method ClearTransactions (line 56) | func (msg *MsgBlock) ClearTransactions() {
    method BtcDecode (line 64) | func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32) error {
    method Deserialize (line 106) | func (msg *MsgBlock) Deserialize(r io.Reader) error {
    method DeserializeTxLoc (line 117) | func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
    method BtcEncode (line 164) | func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32) error {
    method Serialize (line 194) | func (msg *MsgBlock) Serialize(w io.Writer) error {
    method SerializeSize (line 203) | func (msg *MsgBlock) SerializeSize() int {
    method Command (line 217) | func (msg *MsgBlock) Command() string {
    method MaxPayloadLength (line 223) | func (msg *MsgBlock) MaxPayloadLength(pver uint32) uint32 {
    method BlockHash (line 231) | func (msg *MsgBlock) BlockHash() chainhash.Hash {
    method TxHashes (line 236) | func (msg *MsgBlock) TxHashes() ([]chainhash.Hash, error) {
  function NewMsgBlock (line 246) | func NewMsgBlock(blockHeader *BlockHeader) *MsgBlock {

FILE: vendor/github.com/bcext/gcash/wire/msgcfcheckpt.go
  constant CFCheckptInterval (line 19) | CFCheckptInterval = 1000
  constant maxCFHeadersLen (line 23) | maxCFHeadersLen = 100000
  type MsgCFCheckpt (line 35) | type MsgCFCheckpt struct
    method AddCFHeader (line 42) | func (msg *MsgCFCheckpt) AddCFHeader(header *chainhash.Hash) error {
    method BtcDecode (line 55) | func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 96) | func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32) error {
    method Deserialize (line 135) | func (msg *MsgCFCheckpt) Deserialize(r io.Reader) error {
    method Command (line 144) | func (msg *MsgCFCheckpt) Command() string {
    method MaxPayloadLength (line 150) | func (msg *MsgCFCheckpt) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgCFCheckpt (line 158) | func NewMsgCFCheckpt(filterType FilterType, stopHash *chainhash.Hash,

FILE: vendor/github.com/bcext/gcash/wire/msgcfheaders.go
  constant MaxCFHeaderPayload (line 18) | MaxCFHeaderPayload = chainhash.HashSize
  constant MaxCFHeadersPerMsg (line 22) | MaxCFHeadersPerMsg = 2000
  type MsgCFHeaders (line 30) | type MsgCFHeaders struct
    method AddCFHash (line 38) | func (msg *MsgCFHeaders) AddCFHash(hash *chainhash.Hash) error {
    method BtcDecode (line 51) | func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 101) | func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
    method Deserialize (line 153) | func (msg *MsgCFHeaders) Deserialize(r io.Reader) error {
    method Command (line 162) | func (msg *MsgCFHeaders) Command() string {
    method MaxPayloadLength (line 168) | func (msg *MsgCFHeaders) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgCFHeaders (line 177) | func NewMsgCFHeaders() *MsgCFHeaders {

FILE: vendor/github.com/bcext/gcash/wire/msgcfilter.go
  type FilterType (line 16) | type FilterType
  constant GCSFilterRegular (line 20) | GCSFilterRegular FilterType = iota
  constant MaxCFilterDataSize (line 26) | MaxCFilterDataSize = 256 * 1024
  type MsgCFilter (line 32) | type MsgCFilter struct
    method BtcDecode (line 40) | func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 61) | func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32) error {
    method Deserialize (line 91) | func (msg *MsgCFilter) Deserialize(r io.Reader) error {
    method Command (line 100) | func (msg *MsgCFilter) Command() string {
    method MaxPayloadLength (line 106) | func (msg *MsgCFilter) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgCFilter (line 113) | func NewMsgCFilter(filterType FilterType, blockHash *chainhash.Hash,

FILE: vendor/github.com/bcext/gcash/wire/msgfeefilter.go
  type MsgFeeFilter (line 19) | type MsgFeeFilter struct
    method BtcDecode (line 25) | func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 37) | func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 49) | func (msg *MsgFeeFilter) Command() string {
    method MaxPayloadLength (line 55) | func (msg *MsgFeeFilter) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgFeeFilter (line 61) | func NewMsgFeeFilter(minfee int64) *MsgFeeFilter {

FILE: vendor/github.com/bcext/gcash/wire/msgfilteradd.go
  constant MaxFilterAddDataSize (line 17) | MaxFilterAddDataSize = 520
  type MsgFilterAdd (line 25) | type MsgFilterAdd struct
    method BtcDecode (line 31) | func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 46) | func (msg *MsgFilterAdd) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 65) | func (msg *MsgFilterAdd) Command() string {
    method MaxPayloadLength (line 71) | func (msg *MsgFilterAdd) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgFilterAdd (line 78) | func NewMsgFilterAdd(data []byte) *MsgFilterAdd {

FILE: vendor/github.com/bcext/gcash/wire/msgfilterclear.go
  type MsgFilterClear (line 18) | type MsgFilterClear struct
    method BtcDecode (line 22) | func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 34) | func (msg *MsgFilterClear) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 46) | func (msg *MsgFilterClear) Command() string {
    method MaxPayloadLength (line 52) | func (msg *MsgFilterClear) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgFilterClear (line 58) | func NewMsgFilterClear() *MsgFilterClear {

FILE: vendor/github.com/bcext/gcash/wire/msgfilterload.go
  type BloomUpdateType (line 14) | type BloomUpdateType
  constant BloomUpdateNone (line 19) | BloomUpdateNone BloomUpdateType = 0
  constant BloomUpdateAll (line 24) | BloomUpdateAll BloomUpdateType = 1
  constant BloomUpdateP2PubkeyOnly (line 30) | BloomUpdateP2PubkeyOnly BloomUpdateType = 2
  constant MaxFilterLoadHashFuncs (line 36) | MaxFilterLoadHashFuncs = 50
  constant MaxFilterLoadFilterSize (line 39) | MaxFilterLoadFilterSize = 36000
  type MsgFilterLoad (line 46) | type MsgFilterLoad struct
    method BtcDecode (line 55) | func (msg *MsgFilterLoad) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 85) | func (msg *MsgFilterLoad) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 115) | func (msg *MsgFilterLoad) Command() string {
    method MaxPayloadLength (line 121) | func (msg *MsgFilterLoad) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgFilterLoad (line 130) | func NewMsgFilterLoad(filter []byte, hashFuncs uint32, tweak uint32, fla...

FILE: vendor/github.com/bcext/gcash/wire/msggetaddr.go
  type MsgGetAddr (line 18) | type MsgGetAddr struct
    method BtcDecode (line 22) | func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 28) | func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 34) | func (msg *MsgGetAddr) Command() string {
    method MaxPayloadLength (line 40) | func (msg *MsgGetAddr) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetAddr (line 46) | func NewMsgGetAddr() *MsgGetAddr {

FILE: vendor/github.com/bcext/gcash/wire/msggetblocks.go
  constant MaxBlockLocatorsPerMsg (line 17) | MaxBlockLocatorsPerMsg = 500
  type MsgGetBlocks (line 34) | type MsgGetBlocks struct
    method AddBlockLocatorHash (line 41) | func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *chainhash.Hash) err...
    method BtcDecode (line 54) | func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 89) | func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 119) | func (msg *MsgGetBlocks) Command() string {
    method MaxPayloadLength (line 125) | func (msg *MsgGetBlocks) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetBlocks (line 134) | func NewMsgGetBlocks(hashStop *chainhash.Hash) *MsgGetBlocks {

FILE: vendor/github.com/bcext/gcash/wire/msggetcfcheckpt.go
  type MsgGetCFCheckpt (line 17) | type MsgGetCFCheckpt struct
    method BtcDecode (line 24) | func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 35) | func (msg *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 46) | func (msg *MsgGetCFCheckpt) Command() string {
    method MaxPayloadLength (line 52) | func (msg *MsgGetCFCheckpt) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetCFCheckpt (line 60) | func NewMsgGetCFCheckpt(filterType FilterType, stopHash *chainhash.Hash)...

FILE: vendor/github.com/bcext/gcash/wire/msggetcfheaders.go
  type MsgGetCFHeaders (line 17) | type MsgGetCFHeaders struct
    method BtcDecode (line 25) | func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 41) | func (msg *MsgGetCFHeaders) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 57) | func (msg *MsgGetCFHeaders) Command() string {
    method MaxPayloadLength (line 63) | func (msg *MsgGetCFHeaders) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetCFHeaders (line 71) | func NewMsgGetCFHeaders(filterType FilterType, startHeight uint32,

FILE: vendor/github.com/bcext/gcash/wire/msggetcfilters.go
  constant MaxGetCFiltersReqRange (line 16) | MaxGetCFiltersReqRange = 1000
  type MsgGetCFilters (line 21) | type MsgGetCFilters struct
    method BtcDecode (line 29) | func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 45) | func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 61) | func (msg *MsgGetCFilters) Command() string {
    method MaxPayloadLength (line 67) | func (msg *MsgGetCFilters) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetCFilters (line 75) | func NewMsgGetCFilters(filterType FilterType, startHeight uint32,

FILE: vendor/github.com/bcext/gcash/wire/msggetdata.go
  type MsgGetData (line 23) | type MsgGetData struct
    method AddInvVect (line 28) | func (msg *MsgGetData) AddInvVect(iv *InvVect) error {
    method BtcDecode (line 41) | func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 71) | func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 96) | func (msg *MsgGetData) Command() string {
    method MaxPayloadLength (line 102) | func (msg *MsgGetData) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetData (line 109) | func NewMsgGetData() *MsgGetData {
  function NewMsgGetDataSizeHint (line 125) | func NewMsgGetDataSizeHint(sizeHint uint) *MsgGetData {

FILE: vendor/github.com/bcext/gcash/wire/msggetheaders.go
  type MsgGetHeaders (line 31) | type MsgGetHeaders struct
    method AddBlockLocatorHash (line 38) | func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *chainhash.Hash) er...
    method BtcDecode (line 51) | func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 86) | func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 117) | func (msg *MsgGetHeaders) Command() string {
    method MaxPayloadLength (line 123) | func (msg *MsgGetHeaders) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgGetHeaders (line 132) | func NewMsgGetHeaders() *MsgGetHeaders {

FILE: vendor/github.com/bcext/gcash/wire/msgheaders.go
  constant MaxBlockHeadersPerMsg (line 15) | MaxBlockHeadersPerMsg = 2000
  type MsgHeaders (line 22) | type MsgHeaders struct
    method AddBlockHeader (line 27) | func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error {
    method BtcDecode (line 40) | func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 83) | func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 118) | func (msg *MsgHeaders) Command() string {
    method MaxPayloadLength (line 124) | func (msg *MsgHeaders) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgHeaders (line 133) | func NewMsgHeaders() *MsgHeaders {

FILE: vendor/github.com/bcext/gcash/wire/msginv.go
  constant defaultInvListAlloc (line 20) | defaultInvListAlloc = 1000
  type MsgInv (line 31) | type MsgInv struct
    method AddInvVect (line 36) | func (msg *MsgInv) AddInvVect(iv *InvVect) error {
    method BtcDecode (line 49) | func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 79) | func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 104) | func (msg *MsgInv) Command() string {
    method MaxPayloadLength (line 110) | func (msg *MsgInv) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgInv (line 117) | func NewMsgInv() *MsgInv {
  function NewMsgInvSizeHint (line 133) | func NewMsgInvSizeHint(sizeHint uint) *MsgInv {

FILE: vendor/github.com/bcext/gcash/wire/msgmempool.go
  type MsgMemPool (line 19) | type MsgMemPool struct
    method BtcDecode (line 23) | func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 35) | func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 47) | func (msg *MsgMemPool) Command() string {
    method MaxPayloadLength (line 53) | func (msg *MsgMemPool) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgMemPool (line 59) | func NewMsgMemPool() *MsgMemPool {

FILE: vendor/github.com/bcext/gcash/wire/msgmerkleblock.go
  constant maxFlagsPerMerkleBlock (line 19) | maxFlagsPerMerkleBlock = maxTxPerBlock / 8
  type MsgMerkleBlock (line 25) | type MsgMerkleBlock struct
    method AddTxHash (line 33) | func (msg *MsgMerkleBlock) AddTxHash(hash *chainhash.Hash) error {
    method BtcDecode (line 46) | func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 94) | func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 141) | func (msg *MsgMerkleBlock) Command() string {
    method MaxPayloadLength (line 147) | func (msg *MsgMerkleBlock) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgMerkleBlock (line 153) | func NewMsgMerkleBlock(bh *BlockHeader) *MsgMerkleBlock {

FILE: vendor/github.com/bcext/gcash/wire/msgnotfound.go
  type MsgNotFound (line 20) | type MsgNotFound struct
    method AddInvVect (line 25) | func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
    method BtcDecode (line 38) | func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 68) | func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 93) | func (msg *MsgNotFound) Command() string {
    method MaxPayloadLength (line 99) | func (msg *MsgNotFound) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgNotFound (line 107) | func NewMsgNotFound() *MsgNotFound {

FILE: vendor/github.com/bcext/gcash/wire/msgping.go
  type MsgPing (line 23) | type MsgPing struct
    method BtcDecode (line 31) | func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 47) | func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 63) | func (msg *MsgPing) Command() string {
    method MaxPayloadLength (line 69) | func (msg *MsgPing) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgPing (line 84) | func NewMsgPing(nonce uint64) *MsgPing {

FILE: vendor/github.com/bcext/gcash/wire/msgpong.go
  type MsgPong (line 18) | type MsgPong struct
    method BtcDecode (line 26) | func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 40) | func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 54) | func (msg *MsgPong) Command() string {
    method MaxPayloadLength (line 60) | func (msg *MsgPong) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgPong (line 75) | func NewMsgPong(nonce uint64) *MsgPong {

FILE: vendor/github.com/bcext/gcash/wire/msgreject.go
  type RejectCode (line 17) | type RejectCode
    method String (line 44) | func (code RejectCode) String() string {
  constant RejectMalformed (line 21) | RejectMalformed       RejectCode = 0x01
  constant RejectInvalid (line 22) | RejectInvalid         RejectCode = 0x10
  constant RejectObsolete (line 23) | RejectObsolete        RejectCode = 0x11
  constant RejectDuplicate (line 24) | RejectDuplicate       RejectCode = 0x12
  constant RejectNonstandard (line 25) | RejectNonstandard     RejectCode = 0x40
  constant RejectDust (line 26) | RejectDust            RejectCode = 0x41
  constant RejectInsufficientFee (line 27) | RejectInsufficientFee RejectCode = 0x42
  constant RejectCheckpoint (line 28) | RejectCheckpoint      RejectCode = 0x43
  type MsgReject (line 56) | type MsgReject struct
    method BtcDecode (line 77) | func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 119) | func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 159) | func (msg *MsgReject) Command() string {
    method MaxPayloadLength (line 165) | func (msg *MsgReject) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgReject (line 181) | func NewMsgReject(command string, code RejectCode, reason string) *MsgRe...

FILE: vendor/github.com/bcext/gcash/wire/msgsendheaders.go
  type MsgSendHeaders (line 19) | type MsgSendHeaders struct
    method BtcDecode (line 23) | func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 35) | func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 47) | func (msg *MsgSendHeaders) Command() string {
    method MaxPayloadLength (line 53) | func (msg *MsgSendHeaders) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgSendHeaders (line 59) | func NewMsgSendHeaders() *MsgSendHeaders {

FILE: vendor/github.com/bcext/gcash/wire/msgtx.go
  constant TxVersion (line 19) | TxVersion = 1
  constant MaxTxInSequenceNum (line 23) | MaxTxInSequenceNum uint32 = 0xffffffff
  constant MaxPrevOutIndex (line 27) | MaxPrevOutIndex uint32 = 0xffffffff
  constant SequenceLockTimeDisabled (line 32) | SequenceLockTimeDisabled = 1 << 31
  constant SequenceLockTimeIsSeconds (line 37) | SequenceLockTimeIsSeconds = 1 << 22
  constant SequenceLockTimeMask (line 41) | SequenceLockTimeMask = 0x0000ffff
  constant SequenceLockTimeGranularity (line 48) | SequenceLockTimeGranularity = 9
  constant defaultTxInOutAlloc (line 55) | defaultTxInOutAlloc = 15
  constant minTxInPayload (line 60) | minTxInPayload = 9 + chainhash.HashSize
  constant maxTxInPerMessage (line 64) | maxTxInPerMessage = (MaxMessagePayload / minTxInPayload) + 1
  constant MinTxOutPayload (line 68) | MinTxOutPayload = 9
  constant maxTxOutPerMessage (line 72) | maxTxOutPerMessage = (MaxMessagePayload / MinTxOutPayload) + 1
  constant minTxPayload (line 81) | minTxPayload = 10
  constant freeListMaxScriptSize (line 89) | freeListMaxScriptSize = 512
  constant freeListMaxItems (line 96) | freeListMaxItems = 12500
  type scriptFreeList (line 107) | type scriptFreeList
    method Borrow (line 116) | func (c scriptFreeList) Borrow(size uint64) []byte {
    method Return (line 135) | func (c scriptFreeList) Return(buf []byte) {
  type OutPoint (line 158) | type OutPoint struct
    method String (line 173) | func (o OutPoint) String() string {
  function NewOutPoint (line 165) | func NewOutPoint(hash *chainhash.Hash, index uint32) *OutPoint {
  type TxIn (line 188) | type TxIn struct
    method SerializeSize (line 196) | func (t *TxIn) SerializeSize() int {
  function NewTxIn (line 207) | func NewTxIn(prevOut *OutPoint, signatureScript []byte) *TxIn {
  type TxOut (line 216) | type TxOut struct
    method SerializeSize (line 223) | func (t *TxOut) SerializeSize() int {
  function NewTxOut (line 231) | func NewTxOut(value int64, pkScript []byte) *TxOut {
  type MsgTx (line 244) | type MsgTx struct
    method AddTxIn (line 252) | func (msg *MsgTx) AddTxIn(ti *TxIn) {
    method AddTxOut (line 257) | func (msg *MsgTx) AddTxOut(to *TxOut) {
    method TxHash (line 262) | func (msg *MsgTx) TxHash() chainhash.Hash {
    method Copy (line 274) | func (msg *MsgTx) Copy() *MsgTx {
    method BtcDecode (line 339) | func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
    method Deserialize (line 503) | func (msg *MsgTx) Deserialize(r io.Reader) error {
    method BtcEncode (line 514) | func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error {
    method Serialize (line 559) | func (msg *MsgTx) Serialize(w io.Writer) error {
    method SerializeSize (line 567) | func (msg *MsgTx) SerializeSize() int {
    method Command (line 586) | func (msg *MsgTx) Command() string {
    method MaxPayloadLength (line 592) | func (msg *MsgTx) MaxPayloadLength(pver uint32) uint32 {
    method PkScriptLocs (line 600) | func (msg *MsgTx) PkScriptLocs() []int {
  function NewMsgTx (line 639) | func NewMsgTx(version int32) *MsgTx {
  function readOutPoint (line 648) | func readOutPoint(r io.Reader, pver uint32, version int32, op *OutPoint)...
  function writeOutPoint (line 660) | func writeOutPoint(w io.Writer, pver uint32, version int32, op *OutPoint...
  function readScript (line 676) | func readScript(r io.Reader, pver uint32, maxAllowed uint32, fieldName s...
  function readTxIn (line 702) | func readTxIn(r io.Reader, pver uint32, version int32, ti *TxIn) error {
  function writeTxIn (line 719) | func writeTxIn(w io.Writer, pver uint32, version int32, ti *TxIn) error {
  function readTxOut (line 735) | func readTxOut(r io.Reader, pver uint32, version int32, to *TxOut) error {
  function WriteTxOut (line 748) | func WriteTxOut(w io.Writer, pver uint32, version int32, to *TxOut) error {

FILE: vendor/github.com/bcext/gcash/wire/msgverack.go
  type MsgVerAck (line 17) | type MsgVerAck struct
    method BtcDecode (line 21) | func (msg *MsgVerAck) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 27) | func (msg *MsgVerAck) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 33) | func (msg *MsgVerAck) Command() string {
    method MaxPayloadLength (line 39) | func (msg *MsgVerAck) MaxPayloadLength(pver uint32) uint32 {
  function NewMsgVerAck (line 45) | func NewMsgVerAck() *MsgVerAck {

FILE: vendor/github.com/bcext/gcash/wire/msgversion.go
  constant MaxUserAgentLen (line 18) | MaxUserAgentLen = 256
  constant DefaultUserAgent (line 21) | DefaultUserAgent = "/bcext/"
  type MsgVersion (line 30) | type MsgVersion struct
    method HasService (line 63) | func (msg *MsgVersion) HasService(service ServiceFlag) bool {
    method AddService (line 69) | func (msg *MsgVersion) AddService(service ServiceFlag) {
    method BtcDecode (line 80) | func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32) error {
    method BtcEncode (line 153) | func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32) error {
    method Command (line 204) | func (msg *MsgVersion) Command() string {
    method MaxPayloadLength (line 210) | func (msg *MsgVersion) MaxPayloadLength(pver uint32) uint32 {
    method AddUserAgent (line 255) | func (msg *MsgVersion) AddUserAgent(name string, version string,
  function NewMsgVersion (line 224) | func NewMsgVersion(me *NetAddress, you *NetAddress, nonce uint64,
  function validateUserAgent (line 243) | func validateUserAgent(userAgent string) error {

FILE: vendor/github.com/bcext/gcash/wire/netaddress.go
  function maxNetAddressPayload (line 16) | func maxNetAddressPayload(pver uint32) uint32 {
  type NetAddress (line 31) | type NetAddress struct
    method HasService (line 50) | func (na *NetAddress) HasService(service ServiceFlag) bool {
    method AddService (line 56) | func (na *NetAddress) AddService(service ServiceFlag) {
  function NewNetAddressIPPort (line 62) | func NewNetAddressIPPort(ip net.IP, port uint16, services ServiceFlag) *...
  function NewNetAddressTimestamp (line 69) | func NewNetAddressTimestamp(
  function NewNetAddress (line 84) | func NewNetAddress(addr *net.TCPAddr, services ServiceFlag) *NetAddress {
  function readNetAddress (line 91) | func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) e...
  function writeNetAddress (line 126) | func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) ...

FILE: vendor/github.com/bcext/gcash/wire/protocol.go
  constant ProtocolVersion (line 17) | ProtocolVersion uint32 = 70015
  constant MultipleAddressVersion (line 21) | MultipleAddressVersion uint32 = 209
  constant NetAddressTimeVersion (line 25) | NetAddressTimeVersion uint32 = 31402
  constant BIP0031Version (line 29) | BIP0031Version uint32 = 60000
  constant BIP0035Version (line 33) | BIP0035Version uint32 = 60002
  constant BIP0037Version (line 38) | BIP0037Version uint32 = 70001
  constant RejectVersion (line 42) | RejectVersion uint32 = 70002
  constant BIP0111Version (line 46) | BIP0111Version uint32 = 70011
  constant SendHeadersVersion (line 50) | SendHeadersVersion uint32 = 70012
  constant FeeFilterVersion (line 54) | FeeFilterVersion uint32 = 70013
  type ServiceFlag (line 58) | type ServiceFlag
    method String (line 110) | func (f ServiceFlag) String() string {
  constant SFNodeNetwork (line 62) | SFNodeNetwork ServiceFlag = 1 << iota
  constant SFNodeGetUTXO (line 66) | SFNodeGetUTXO
  constant SFNodeBloom (line 70) | SFNodeBloom
  constant SFNodeXthin (line 73) | SFNodeXthin
  constant SFNodeBitcoinCash (line 81) | SFNodeBitcoinCash
  type BitcoinNet (line 135) | type BitcoinNet
    method String (line 165) | func (n BitcoinNet) String() string {
  constant MainNet (line 143) | MainNet BitcoinNet = 0xe8f3e1e3
  constant TestNet (line 146) | TestNet BitcoinNet = 0xfabfb5da
  constant TestNet3 (line 149) | TestNet3 BitcoinNet = 0xf4f3e5f4
  constant SimNet (line 152) | SimNet BitcoinNet = 0x12141c16

FILE: vendor/github.com/btcsuite/btcd/btcec/btcec.go
  type KoblitzCurve (line 37) | type KoblitzCurve struct
    method Params (line 69) | func (curve *KoblitzCurve) Params() *elliptic.CurveParams {
    method bigAffineToField (line 75) | func (curve *KoblitzCurve) bigAffineToField(x, y *big.Int) (*fieldVal,...
    method fieldJacobianToBigAffine (line 85) | func (curve *KoblitzCurve) fieldJacobianToBigAffine(x, y, z *fieldVal)...
    method IsOnCurve (line 111) | func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool {
    method addZ1AndZ2EqualsOne (line 126) | func (curve *KoblitzCurve) addZ1AndZ2EqualsOne(x1, y1, z1, x2, y2, x3,...
    method addZ1EqualsZ2 (line 192) | func (curve *KoblitzCurve) addZ1EqualsZ2(x1, y1, z1, x2, y2, x3, y3, z...
    method addZ2EqualsOne (line 261) | func (curve *KoblitzCurve) addZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, ...
    method addGeneric (line 337) | func (curve *KoblitzCurve) addGeneric(x1, y1, z1, x2, y2, z2, x3, y3, ...
    method addJacobian (line 410) | func (curve *KoblitzCurve) addJacobian(x1, y1, z1, x2, y2, z2, x3, y3,...
    method Add (line 454) | func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *bi...
    method doubleZ1EqualsOne (line 482) | func (curve *KoblitzCurve) doubleZ1EqualsOne(x1, y1, x3, y3, z3 *field...
    method doubleGeneric (line 532) | func (curve *KoblitzCurve) doubleGeneric(x1, y1, z1, x3, y3, z3 *field...
    method doubleJacobian (line 579) | func (curve *KoblitzCurve) doubleJacobian(x1, y1, z1, x3, y3, z3 *fiel...
    method Double (line 603) | func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
    method splitK (line 628) | func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
    method moduloReduce (line 666) | func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
    method ScalarMult (line 758) | func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big...
    method ScalarBaseMult (line 863) | func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.In...
    method QPlus1Div4 (line 884) | func (curve *KoblitzCurve) QPlus1Div4() *big.Int {
  function NAF (line 686) | func NAF(k []byte) ([]byte, []byte) {
  function initAll (line 891) | func initAll() {
  function fromHex (line 899) | func fromHex(s string) *big.Int {
  function initS256 (line 907) | func initS256() {
  function S256 (line 955) | func S256() *KoblitzCurve {

FILE: vendor/github.com/btcsuite/btcd/btcec/ciphering.go
  function GenerateSharedSecret (line 46) | func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte {
  function Encrypt (line 70) | func Encrypt(pubkey *PublicKey, in []byte) ([]byte, error) {
  function Decrypt (line 121) | func Decrypt(priv *PrivateKey, in []byte) ([]byte, error) {
  function addPKCSPadding (line 201) | func addPKCSPadding(src []byte) []byte {
  function removePKCSPadding (line 208) | func removePKCSPadding(src []byte) ([]byte, error) {

FILE: vendor/github.com/btcsuite/btcd/btcec/field.go
  constant twoBitsMask (line 63) | twoBitsMask   = 0x3
  constant fourBitsMask (line 64) | fourBitsMask  = 0xf
  constant sixBitsMask (line 65) | sixBitsMask   = 0x3f
  constant eightBitsMask (line 66) | eightBitsMask = 0xff
  constant fieldWords (line 73) | fieldWords = 10
  constant fieldBase (line 77) | fieldBase = 26
  constant fieldOverflowBits (line 81) | fieldOverflowBits = 32 - fieldBase
  constant fieldBaseMask (line 86) | fieldBaseMask = (1 << fieldBase) - 1
  constant fieldMSBBits (line 90) | fieldMSBBits = 256 - (fieldBase * (fieldWords - 1))
  constant fieldMSBMask (line 94) | fieldMSBMask = (1 << fieldMSBBits) - 1
  constant fieldPrimeWordZero (line 98) | fieldPrimeWordZero = 0x3fffc2f
  constant fieldPrimeWordOne (line 102) | fieldPrimeWordOne = 0x3ffffbf
  type fieldVal (line 135) | type fieldVal struct
    method String (line 140) | func (f fieldVal) String() string {
    method Zero (line 148) | func (f *fieldVal) Zero() {
    method Set (line 166) | func (f *fieldVal) Set(val *fieldVal) *fieldVal {
    method SetInt (line 177) | func (f *fieldVal) SetInt(ui uint) *fieldVal {
    method SetBytes (line 188) | func (f *fieldVal) SetBytes(b *[32]byte) *fieldVal {
    method SetByteSlice (line 222) | func (f *fieldVal) SetByteSlice(b []byte) *fieldVal {
    method SetHex (line 237) | func (f *fieldVal) SetHex(hexString string) *fieldVal {
    method Normalize (line 248) | func (f *fieldVal) Normalize() *fieldVal {
    method PutBytes (line 377) | func (f *fieldVal) PutBytes(b *[32]byte) {
    method Bytes (line 423) | func (f *fieldVal) Bytes() *[32]byte {
    method IsZero (line 430) | func (f *fieldVal) IsZero() bool {
    method IsOdd (line 443) | func (f *fieldVal) IsOdd() bool {
    method Equals (line 451) | func (f *fieldVal) Equals(val *fieldVal) bool {
    method NegateVal (line 468) | func (f *fieldVal) NegateVal(val *fieldVal, magnitude uint32) *fieldVal {
    method Negate (line 506) | func (f *fieldVal) Negate(magnitude uint32) *fieldVal {
    method AddInt (line 516) | func (f *fieldVal) AddInt(ui uint) *fieldVal {
    method Add (line 530) | func (f *fieldVal) Add(val *fieldVal) *fieldVal {
    method Add2 (line 553) | func (f *fieldVal) Add2(val *fieldVal, val2 *fieldVal) *fieldVal {
    method MulInt (line 579) | func (f *fieldVal) MulInt(val uint) *fieldVal {
    method Mul (line 609) | func (f *fieldVal) Mul(val *fieldVal) *fieldVal {
    method Mul2 (line 621) | func (f *fieldVal) Mul2(val *fieldVal, val2 *fieldVal) *fieldVal {
    method Square (line 890) | func (f *fieldVal) Square() *fieldVal {
    method SquareVal (line 901) | func (f *fieldVal) SquareVal(val *fieldVal) *fieldVal {
    method Inverse (line 1121) | func (f *fieldVal) Inverse() *fieldVal {

FILE: vendor/github.com/btcsuite/btcd/btcec/genprecomps.go
  function main (line 23) | func main() {

FILE: vendor/github.com/btcsuite/btcd/btcec/gensecp256k1.go
  method getDoublingPoints (line 26) | func (curve *KoblitzCurve) getDoublingPoints() [][3]fieldVal {
  method SerializedBytePoints (line 43) | func (curve *KoblitzCurve) SerializedBytePoints() []byte {
  function sqrt (line 84) | func sqrt(n *big.Int) *big.Int {
  method EndomorphismVectors (line 109) | func (curve *KoblitzCurve) EndomorphismVectors() (a1, b1, a2, b2 *big.In...

FILE: vendor/github.com/btcsuite/btcd/btcec/precompute.go
  function loadS256BytePoints (line 23) | func loadS256BytePoints() error {

FILE: vendor/github.com/btcsuite/btcd/btcec/privkey.go
  type PrivateKey (line 17) | type PrivateKey
    method PubKey (line 48) | func (p *PrivateKey) PubKey() *PublicKey {
    method ToECDSA (line 53) | func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey {
    method Sign (line 61) | func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {
    method Serialize (line 70) | func (p *PrivateKey) Serialize() []byte {
  function PrivKeyFromBytes (line 21) | func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey,
  function NewPrivateKey (line 39) | func NewPrivateKey(curve elliptic.Curve) (*PrivateKey, error) {
  constant PrivKeyBytesLen (line 66) | PrivKeyBytesLen = 32

FILE: vendor/github.com/btcsuite/btcd/btcec/pubkey.go
  constant PubKeyBytesLenCompressed (line 16) | PubKeyBytesLenCompressed   = 33
  constant PubKeyBytesLenUncompressed (line 17) | PubKeyBytesLenUncompressed = 65
  constant PubKeyBytesLenHybrid (line 18) | PubKeyBytesLenHybrid       = 65
  function isOdd (line 21) | func isOdd(a *big.Int) bool {
  function decompressPoint (line 27) | func decompressPoint(curve *KoblitzCurve, x *big.Int, ybit bool) (*big.I...
  constant pubkeyCompressed (line 63) | pubkeyCompressed   byte = 0x2
  constant pubkeyUncompressed (line 64) | pubkeyUncompressed byte = 0x4
  constant pubkeyHybrid (line 65) | pubkeyHybrid       byte = 0x6
  function IsCompressedPubKey (line 70) | func IsCompressedPubKey(pubKey []byte) bool {
  function ParsePubKey (line 80) | func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *PublicKey,...
  type PublicKey (line 137) | type PublicKey
    method ToECDSA (line 140) | func (p *PublicKey) ToECDSA() *ecdsa.PublicKey {
    method SerializeUncompressed (line 146) | func (p *PublicKey) SerializeUncompressed() []byte {
    method SerializeCompressed (line 154) | func (p *PublicKey) SerializeCompressed() []byte {
    method SerializeHybrid (line 165) | func (p *PublicKey) SerializeHybrid() []byte {
    method IsEqual (line 179) | func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool {
  function paddedAppend (line 187) | func paddedAppend(size uint, dst, src []byte) []byte {

FILE: vendor/github.com/btcsuite/btcd/btcec/signature.go
  type Signature (line 26) | type Signature struct
    method Serialize (line 47) | func (sig *Signature) Serialize() []byte {
    method Verify (line 76) | func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
    method IsEqual (line 83) | func (sig *Signature) IsEqual(otherSig *Signature) bool {
  constant minSigLen (line 91) | minSigLen = 8
  function parseSig (line 93) | func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature...
  function ParseSignature (line 211) | func ParseSignature(sigStr []byte, curve elliptic.Curve) (*Signature, er...
  function ParseDERSignature (line 218) | func ParseDERSignature(sigStr []byte, curve elliptic.Curve) (*Signature,...
  function canonicalizeInt (line 228) | func canonicalizeInt(val *big.Int) []byte {
  function canonicalPadding (line 245) | func canonicalPadding(b []byte) error {
  function hashToInt (line 263) | func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
  function recoverKeyFromSignature (line 285) | func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []...
  function SignCompact (line 351) | func SignCompact(curve *KoblitzCurve, key *PrivateKey,
  function RecoverCompact (line 398) | func RecoverCompact(curve *KoblitzCurve, signature,
  function signRFC6979 (line 422) | func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
  function nonceRFC6979 (line 455) | func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int {
  function mac (line 507) | func mac(alg func() hash.Hash, k, m []byte) []byte {
  function int2octets (line 514) | func int2octets(v *big.Int, rolen int) []byte {
  function bits2octets (line 535) | func bits2octets(in []byte, curve elliptic.Curve, rolen int) []byte {

FILE: vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go
  type NodeSubCmd (line 13) | type NodeSubCmd
  constant NConnect (line 17) | NConnect NodeSubCmd = "connect"
  constant NRemove (line 21) | NRemove NodeSubCmd = "remove"
  constant NDisconnect (line 24) | NDisconnect NodeSubCmd = "disconnect"
  type NodeCmd (line 28) | type NodeCmd struct
  function NewNodeCmd (line 39) | func NewNodeCmd(subCmd NodeSubCmd, target string, connectSubCmd *string)...
  type DebugLevelCmd (line 49) | type DebugLevelCmd struct
  function NewDebugLevelCmd (line 56) | func NewDebugLevelCmd(levelSpec string) *DebugLevelCmd {
  type GenerateCmd (line 63) | type GenerateCmd struct
  function NewGenerateCmd (line 69) | func NewGenerateCmd(numBlocks uint32) *GenerateCmd {
  type GetBestBlockCmd (line 76) | type GetBestBlockCmd struct
  function NewGetBestBlockCmd (line 80) | func NewGetBestBlockCmd() *GetBestBlockCmd {
  type GetCurrentNetCmd (line 85) | type GetCurrentNetCmd struct
  function NewGetCurrentNetCmd (line 89) | func NewGetCurrentNetCmd() *GetCurrentNetCmd {
  type GetHeadersCmd (line 97) | type GetHeadersCmd struct
  function NewGetHeadersCmd (line 107) | func NewGetHeadersCmd(blockLocators []string, hashStop string) *GetHeade...
  type VersionCmd (line 118) | type VersionCmd struct
  function NewVersionCmd (line 125) | func NewVersionCmd() *VersionCmd { return new(VersionCmd) }
  function init (line 127) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/btcdextresults.go
  type VersionResult (line 13) | type VersionResult struct

FILE: vendor/github.com/btcsuite/btcd/btcjson/btcwalletextcmds.go
  type CreateNewAccountCmd (line 11) | type CreateNewAccountCmd struct
  function NewCreateNewAccountCmd (line 17) | func NewCreateNewAccountCmd(account string) *CreateNewAccountCmd {
  type DumpWalletCmd (line 24) | type DumpWalletCmd struct
  function NewDumpWalletCmd (line 30) | func NewDumpWalletCmd(filename string) *DumpWalletCmd {
  type ImportAddressCmd (line 37) | type ImportAddressCmd struct
  function NewImportAddressCmd (line 44) | func NewImportAddressCmd(address string, rescan *bool) *ImportAddressCmd {
  type ImportPubKeyCmd (line 52) | type ImportPubKeyCmd struct
  function NewImportPubKeyCmd (line 59) | func NewImportPubKeyCmd(pubKey string, rescan *bool) *ImportPubKeyCmd {
  type ImportWalletCmd (line 67) | type ImportWalletCmd struct
  function NewImportWalletCmd (line 73) | func NewImportWalletCmd(filename string) *ImportWalletCmd {
  type RenameAccountCmd (line 80) | type RenameAccountCmd struct
  function NewRenameAccountCmd (line 87) | func NewRenameAccountCmd(oldAccount, newAccount string) *RenameAccountCmd {
  function init (line 94) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go
  type AddNodeSubCmd (line 19) | type AddNodeSubCmd
  constant ANAdd (line 24) | ANAdd AddNodeSubCmd = "add"
  constant ANRemove (line 27) | ANRemove AddNodeSubCmd = "remove"
  constant ANOneTry (line 31) | ANOneTry AddNodeSubCmd = "onetry"
  type AddNodeCmd (line 35) | type AddNodeCmd struct
  function NewAddNodeCmd (line 42) | func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd {
  type TransactionInput (line 51) | type TransactionInput struct
  type CreateRawTransactionCmd (line 57) | type CreateRawTransactionCmd struct
  function NewCreateRawTransactionCmd (line 67) | func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[s...
  type DecodeRawTransactionCmd (line 78) | type DecodeRawTransactionCmd struct
  function NewDecodeRawTransactionCmd (line 84) | func NewDecodeRawTransactionCmd(hexTx string) *DecodeRawTransactionCmd {
  type DecodeScriptCmd (line 91) | type DecodeScriptCmd struct
  function NewDecodeScriptCmd (line 97) | func NewDecodeScriptCmd(hexScript string) *DecodeScriptCmd {
  type GetAddedNodeInfoCmd (line 104) | type GetAddedNodeInfoCmd struct
  function NewGetAddedNodeInfoCmd (line 114) | func NewGetAddedNodeInfoCmd(dns bool, node *string) *GetAddedNodeInfoCmd {
  type GetBestBlockHashCmd (line 122) | type GetBestBlockHashCmd struct
  function NewGetBestBlockHashCmd (line 126) | func NewGetBestBlockHashCmd() *GetBestBlockHashCmd {
  type GetBlockCmd (line 131) | type GetBlockCmd struct
  function NewGetBlockCmd (line 142) | func NewGetBlockCmd(hash string, verbose, verboseTx *bool) *GetBlockCmd {
  type GetBlockChainInfoCmd (line 151) | type GetBlockChainInfoCmd struct
  function NewGetBlockChainInfoCmd (line 155) | func NewGetBlockChainInfoCmd() *GetBlockChainInfoCmd {
  type GetBlockCountCmd (line 160) | type GetBlockCountCmd struct
  function NewGetBlockCountCmd (line 164) | func NewGetBlockCountCmd() *GetBlockCountCmd {
  type GetBlockHashCmd (line 169) | type GetBlockHashCmd struct
  function NewGetBlockHashCmd (line 175) | func NewGetBlockHashCmd(index int64) *GetBlockHashCmd {
  type GetBlockHeaderCmd (line 182) | type GetBlockHeaderCmd struct
  function NewGetBlockHeaderCmd (line 189) | func NewGetBlockHeaderCmd(hash string, verbose *bool) *GetBlockHeaderCmd {
  type TemplateRequest (line 199) | type TemplateRequest struct
    method UnmarshalJSON (line 243) | func (t *TemplateRequest) UnmarshalJSON(data []byte) error {
  function convertTemplateRequestField (line 223) | func convertTemplateRequestField(fieldName string, iface interface{}) (i...
  type GetBlockTemplateCmd (line 269) | type GetBlockTemplateCmd struct
  function NewGetBlockTemplateCmd (line 278) | func NewGetBlockTemplateCmd(request *TemplateRequest) *GetBlockTemplateC...
  type GetCFilterCmd (line 285) | type GetCFilterCmd struct
  function NewGetCFilterCmd (line 292) | func NewGetCFilterCmd(hash string, filterType wire.FilterType) *GetCFilt...
  type GetCFilterHeaderCmd (line 300) | type GetCFilterHeaderCmd struct
  function NewGetCFilterHeaderCmd (line 307) | func NewGetCFilterHeaderCmd(hash string,
  type GetChainTipsCmd (line 316) | type GetChainTipsCmd struct
  function NewGetChainTipsCmd (line 320) | func NewGetChainTipsCmd() *GetChainTipsCmd {
  type GetConnectionCountCmd (line 325) | type GetConnectionCountCmd struct
  function NewGetConnectionCountCmd (line 329) | func NewGetConnectionCountCmd() *GetConnectionCountCmd {
  type GetDifficultyCmd (line 334) | type GetDifficultyCmd struct
  function NewGetDifficultyCmd (line 338) | func NewGetDifficultyCmd() *GetDifficultyCmd {
  type GetGenerateCmd (line 343) | type GetGenerateCmd struct
  function NewGetGenerateCmd (line 347) | func NewGetGenerateCmd() *GetGenerateCmd {
  type GetHashesPerSecCmd (line 352) | type GetHashesPerSecCmd struct
  function NewGetHashesPerSecCmd (line 356) | func NewGetHashesPerSecCmd() *GetHashesPerSecCmd {
  type GetInfoCmd (line 361) | type GetInfoCmd struct
  function NewGetInfoCmd (line 365) | func NewGetInfoCmd() *GetInfoCmd {
  type GetMempoolEntryCmd (line 370) | type GetMempoolEntryCmd struct
  function NewGetMempoolEntryCmd (line 376) | func NewGetMempoolEntryCmd(txHash string) *GetMempoolEntryCmd {
  type GetMempoolInfoCmd (line 383) | type GetMempoolInfoCmd struct
  function NewGetMempoolInfoCmd (line 387) | func NewGetMempoolInfoCmd() *GetMempoolInfoCmd {
  type GetMiningInfoCmd (line 392) | type GetMiningInfoCmd struct
  function NewGetMiningInfoCmd (line 396) | func NewGetMiningInfoCmd() *GetMiningInfoCmd {
  type GetNetworkInfoCmd (line 401) | type GetNetworkInfoCmd struct
  function NewGetNetworkInfoCmd (line 405) | func NewGetNetworkInfoCmd() *GetNetworkInfoCmd {
  type GetNetTotalsCmd (line 410) | type GetNetTotalsCmd struct
  function NewGetNetTotalsCmd (line 414) | func NewGetNetTotalsCmd() *GetNetTotalsCmd {
  type GetNetworkHashPSCmd (line 419) | type GetNetworkHashPSCmd struct
  function NewGetNetworkHashPSCmd (line 429) | func NewGetNetworkHashPSCmd(numBlocks, height *int) *GetNetworkHashPSCmd {
  type GetPeerInfoCmd (line 437) | type GetPeerInfoCmd struct
  function NewGetPeerInfoCmd (line 441) | func NewGetPeerInfoCmd() *GetPeerInfoCmd {
  type GetRawMempoolCmd (line 446) | type GetRawMempoolCmd struct
  function NewGetRawMempoolCmd (line 455) | func NewGetRawMempoolCmd(verbose *bool) *GetRawMempoolCmd {
  type GetRawTransactionCmd (line 465) | type GetRawTransactionCmd struct
  function NewGetRawTransactionCmd (line 475) | func NewGetRawTransactionCmd(txHash string, verbose *int) *GetRawTransac...
  type GetTxOutCmd (line 483) | type GetTxOutCmd struct
  function NewGetTxOutCmd (line 494) | func NewGetTxOutCmd(txHash string, vout uint32, includeMempool *bool) *G...
  type GetTxOutProofCmd (line 503) | type GetTxOutProofCmd struct
  function NewGetTxOutProofCmd (line 513) | func NewGetTxOutProofCmd(txIDs []string, blockHash *string) *GetTxOutPro...
  type GetTxOutSetInfoCmd (line 521) | type GetTxOutSetInfoCmd struct
  function NewGetTxOutSetInfoCmd (line 525) | func NewGetTxOutSetInfoCmd() *GetTxOutSetInfoCmd {
  type GetWorkCmd (line 530) | type GetWorkCmd struct
  function NewGetWorkCmd (line 539) | func NewGetWorkCmd(data *string) *GetWorkCmd {
  type HelpCmd (line 546) | type HelpCmd struct
  function NewHelpCmd (line 555) | func NewHelpCmd(command *string) *HelpCmd {
  type InvalidateBlockCmd (line 562) | type InvalidateBlockCmd struct
  function NewInvalidateBlockCmd (line 568) | func NewInvalidateBlockCmd(blockHash string) *InvalidateBlockCmd {
  type PingCmd (line 575) | type PingCmd struct
  function NewPingCmd (line 579) | func NewPingCmd() *PingCmd {
  type PreciousBlockCmd (line 584) | type PreciousBlockCmd struct
  function NewPreciousBlockCmd (line 590) | func NewPreciousBlockCmd(blockHash string) *PreciousBlockCmd {
  type ReconsiderBlockCmd (line 597) | type ReconsiderBlockCmd struct
  function NewReconsiderBlockCmd (line 603) | func NewReconsiderBlockCmd(blockHash string) *ReconsiderBlockCmd {
  type SearchRawTransactionsCmd (line 610) | type SearchRawTransactionsCmd struct
  function NewSearchRawTransactionsCmd (line 625) | func NewSearchRawTransactionsCmd(address string, verbose, skip, count *i...
  type SendRawTransactionCmd (line 638) | type SendRawTransactionCmd struct
  function NewSendRawTransactionCmd (line 648) | func NewSendRawTransactionCmd(hexTx string, allowHighFees *bool) *SendRa...
  type SetGenerateCmd (line 656) | type SetGenerateCmd struct
  function NewSetGenerateCmd (line 666) | func NewSetGenerateCmd(generate bool, genProcLimit *int) *SetGenerateCmd {
  type StopCmd (line 674) | type StopCmd struct
  function NewStopCmd (line 678) | func NewStopCmd() *StopCmd {
  type SubmitBlockOptions (line 684) | type SubmitBlockOptions struct
  type SubmitBlockCmd (line 690) | type SubmitBlockCmd struct
  function NewSubmitBlockCmd (line 700) | func NewSubmitBlockCmd(hexBlock string, options *SubmitBlockOptions) *Su...
  type UptimeCmd (line 708) | type UptimeCmd struct
  function NewUptimeCmd (line 711) | func NewUptimeCmd() *UptimeCmd {
  type ValidateAddressCmd (line 716) | type ValidateAddressCmd struct
  function NewValidateAddressCmd (line 722) | func NewValidateAddressCmd(address string) *ValidateAddressCmd {
  type VerifyChainCmd (line 729) | type VerifyChainCmd struct
  function NewVerifyChainCmd (line 739) | func NewVerifyChainCmd(checkLevel, checkDepth *int32) *VerifyChainCmd {
  type VerifyMessageCmd (line 747) | type VerifyMessageCmd struct
  function NewVerifyMessageCmd (line 755) | func NewVerifyMessageCmd(address, signature, message string) *VerifyMess...
  type VerifyTxOutProofCmd (line 764) | type VerifyTxOutProofCmd struct
  function NewVerifyTxOutProofCmd (line 770) | func NewVerifyTxOutProofCmd(proof string) *VerifyTxOutProofCmd {
  function init (line 776) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/chainsvrresults.go
  type GetBlockHeaderVerboseResult (line 12) | type GetBlockHeaderVerboseResult struct
  type GetBlockVerboseResult (line 30) | type GetBlockVerboseResult struct
  type CreateMultiSigResult (line 52) | type CreateMultiSigResult struct
  type DecodeScriptResult (line 58) | type DecodeScriptResult struct
  type GetAddedNodeInfoResultAddr (line 68) | type GetAddedNodeInfoResultAddr struct
  type GetAddedNodeInfoResult (line 74) | type GetAddedNodeInfoResult struct
  type SoftForkDescription (line 82) | type SoftForkDescription struct
  type Bip9SoftForkDescription (line 92) | type Bip9SoftForkDescription struct
  type GetBlockChainInfoResult (line 102) | type GetBlockChainInfoResult struct
  type GetBlockTemplateResultTx (line 119) | type GetBlockTemplateResultTx struct
  type GetBlockTemplateResultAux (line 130) | type GetBlockTemplateResultAux struct
  type GetBlockTemplateResult (line 136) | type GetBlockTemplateResult struct
  type GetMempoolEntryResult (line 178) | type GetMempoolEntryResult struct
  type GetMempoolInfoResult (line 197) | type GetMempoolInfoResult struct
  type NetworksResult (line 203) | type NetworksResult struct
  type LocalAddressesResult (line 213) | type LocalAddressesResult struct
  type GetNetworkInfoResult (line 221) | type GetNetworkInfoResult struct
  type GetPeerInfoResult (line 238) | type GetPeerInfoResult struct
  type GetRawMempoolVerboseResult (line 265) | type GetRawMempoolVerboseResult struct
  type ScriptPubKeyResult (line 278) | type ScriptPubKeyResult struct
  type GetTxOutResult (line 287) | type GetTxOutResult struct
  type GetNetTotalsResult (line 296) | type GetNetTotalsResult struct
  type ScriptSig (line 305) | type ScriptSig struct
  type Vin (line 313) | type Vin struct
    method IsCoinBase (line 323) | func (v *Vin) IsCoinBase() bool {
    method HasWitness (line 329) | func (v *Vin) HasWitness() bool {
    method MarshalJSON (line 334) | func (v *Vin) MarshalJSON() ([]byte, error) {
  type PrevOut (line 380) | type PrevOut struct
  type VinPrevOut (line 386) | type VinPrevOut struct
    method IsCoinBase (line 397) | func (v *VinPrevOut) IsCoinBase() bool {
    method HasWitness (line 403) | func (v *VinPrevOut) HasWitness() bool {
    method MarshalJSON (line 408) | func (v *VinPrevOut) MarshalJSON() ([]byte, error) {
  type Vout (line 457) | type Vout struct
  type GetMiningInfoResult (line 464) | type GetMiningInfoResult struct
  type GetWorkResult (line 480) | type GetWorkResult struct
  type InfoChainResult (line 488) | type InfoChainResult struct
  type TxRawResult (line 502) | type TxRawResult struct
  type SearchRawTransactionsResult (line 520) | type SearchRawTransactionsResult struct
  type TxRawDecodeResult (line 537) | type TxRawDecodeResult struct
  type ValidateAddressChainResult (line 547) | type ValidateAddressChainResult struct

FILE: vendor/github.com/btcsuite/btcd/btcjson/chainsvrwscmds.go
  type AuthenticateCmd (line 12) | type AuthenticateCmd struct
  function NewAuthenticateCmd (line 19) | func NewAuthenticateCmd(username, passphrase string) *AuthenticateCmd {
  type NotifyBlocksCmd (line 27) | type NotifyBlocksCmd struct
  function NewNotifyBlocksCmd (line 31) | func NewNotifyBlocksCmd() *NotifyBlocksCmd {
  type StopNotifyBlocksCmd (line 36) | type StopNotifyBlocksCmd struct
  function NewStopNotifyBlocksCmd (line 40) | func NewStopNotifyBlocksCmd() *StopNotifyBlocksCmd {
  type NotifyNewTransactionsCmd (line 45) | type NotifyNewTransactionsCmd struct
  function NewNotifyNewTransactionsCmd (line 54) | func NewNotifyNewTransactionsCmd(verbose *bool) *NotifyNewTransactionsCmd {
  type SessionCmd (line 61) | type SessionCmd struct
  function NewSessionCmd (line 65) | func NewSessionCmd() *SessionCmd {
  type StopNotifyNewTransactionsCmd (line 70) | type StopNotifyNewTransactionsCmd struct
  function NewStopNotifyNewTransactionsCmd (line 77) | func NewStopNotifyNewTransactionsCmd() *StopNotifyNewTransactionsCmd {
  type NotifyReceivedCmd (line 84) | type NotifyReceivedCmd struct
  function NewNotifyReceivedCmd (line 92) | func NewNotifyReceivedCmd(addresses []string) *NotifyReceivedCmd {
  type OutPoint (line 100) | type OutPoint struct
  type LoadTxFilterCmd (line 110) | type LoadTxFilterCmd struct
  function NewLoadTxFilterCmd (line 121) | func NewLoadTxFilterCmd(reload bool, addresses []string, outPoints []Out...
  type NotifySpentCmd (line 132) | type NotifySpentCmd struct
  function NewNotifySpentCmd (line 140) | func NewNotifySpentCmd(outPoints []OutPoint) *NotifySpentCmd {
  type StopNotifyReceivedCmd (line 149) | type StopNotifyReceivedCmd struct
  function NewStopNotifyReceivedCmd (line 157) | func NewStopNotifyReceivedCmd(addresses []string) *StopNotifyReceivedCmd {
  type StopNotifySpentCmd (line 166) | type StopNotifySpentCmd struct
  function NewStopNotifySpentCmd (line 174) | func NewStopNotifySpentCmd(outPoints []OutPoint) *StopNotifySpentCmd {
  type RescanCmd (line 183) | type RescanCmd struct
  function NewRescanCmd (line 197) | func NewRescanCmd(beginBlock string, addresses []string, outPoints []Out...
  type RescanBlocksCmd (line 210) | type RescanBlocksCmd struct
  function NewRescanBlocksCmd (line 220) | func NewRescanBlocksCmd(blockHashes []string) *RescanBlocksCmd {
  function init (line 224) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsntfns.go
  constant BlockConnectedNtfnMethod (line 16) | BlockConnectedNtfnMethod = "blockconnected"
  constant BlockDisconnectedNtfnMethod (line 23) | BlockDisconnectedNtfnMethod = "blockdisconnected"
  constant FilteredBlockConnectedNtfnMethod (line 27) | FilteredBlockConnectedNtfnMethod = "filteredblockconnected"
  constant FilteredBlockDisconnectedNtfnMethod (line 32) | FilteredBlockDisconnectedNtfnMethod = "filteredblockdisconnected"
  constant RecvTxNtfnMethod (line 40) | RecvTxNtfnMethod = "recvtx"
  constant RedeemingTxNtfnMethod (line 48) | RedeemingTxNtfnMethod = "redeemingtx"
  constant RescanFinishedNtfnMethod (line 55) | RescanFinishedNtfnMethod = "rescanfinished"
  constant RescanProgressNtfnMethod (line 62) | RescanProgressNtfnMethod = "rescanprogress"
  constant TxAcceptedNtfnMethod (line 66) | TxAcceptedNtfnMethod = "txaccepted"
  constant TxAcceptedVerboseNtfnMethod (line 72) | TxAcceptedVerboseNtfnMethod = "txacceptedverbose"
  constant RelevantTxAcceptedNtfnMethod (line 77) | RelevantTxAcceptedNtfnMethod = "relevanttxaccepted"
  type BlockConnectedNtfn (line 83) | type BlockConnectedNtfn struct
  function NewBlockConnectedNtfn (line 93) | func NewBlockConnectedNtfn(hash string, height int32, time int64) *Block...
  type BlockDisconnectedNtfn (line 104) | type BlockDisconnectedNtfn struct
  function NewBlockDisconnectedNtfn (line 114) | func NewBlockDisconnectedNtfn(hash string, height int32, time int64) *Bl...
  type FilteredBlockConnectedNtfn (line 124) | type FilteredBlockConnectedNtfn struct
  function NewFilteredBlockConnectedNtfn (line 132) | func NewFilteredBlockConnectedNtfn(height int32, header string, subscrib...
  type FilteredBlockDisconnectedNtfn (line 142) | type FilteredBlockDisconnectedNtfn struct
  function NewFilteredBlockDisconnectedNtfn (line 149) | func NewFilteredBlockDisconnectedNtfn(height int32, header string) *Filt...
  type BlockDetails (line 157) | type BlockDetails struct
  type RecvTxNtfn (line 168) | type RecvTxNtfn struct
  function NewRecvTxNtfn (line 178) | func NewRecvTxNtfn(hexTx string, block *BlockDetails) *RecvTxNtfn {
  type RedeemingTxNtfn (line 189) | type RedeemingTxNtfn struct
  function NewRedeemingTxNtfn (line 199) | func NewRedeemingTxNtfn(hexTx string, block *BlockDetails) *RedeemingTxN...
  type RescanFinishedNtfn (line 209) | type RescanFinishedNtfn struct
  function NewRescanFinishedNtfn (line 219) | func NewRescanFinishedNtfn(hash string, height int32, time int64) *Resca...
  type RescanProgressNtfn (line 230) | type RescanProgressNtfn struct
  function NewRescanProgressNtfn (line 240) | func NewRescanProgressNtfn(hash string, height int32, time int64) *Resca...
  type TxAcceptedNtfn (line 249) | type TxAcceptedNtfn struct
  function NewTxAcceptedNtfn (line 256) | func NewTxAcceptedNtfn(txHash string, amount float64) *TxAcceptedNtfn {
  type TxAcceptedVerboseNtfn (line 264) | type TxAcceptedVerboseNtfn struct
  function NewTxAcceptedVerboseNtfn (line 270) | func NewTxAcceptedVerboseNtfn(rawTx TxRawResult) *TxAcceptedVerboseNtfn {
  type RelevantTxAcceptedNtfn (line 278) | type RelevantTxAcceptedNtfn struct
  function NewRelevantTxAcceptedNtfn (line 284) | func NewRelevantTxAcceptedNtfn(txHex string) *RelevantTxAcceptedNtfn {
  function init (line 288) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsresults.go
  type SessionResult (line 9) | type SessionResult struct
  type RescannedBlock (line 18) | type RescannedBlock struct

FILE: vendor/github.com/btcsuite/btcd/btcjson/cmdinfo.go
  function CmdMethod (line 16) | func CmdMethod(cmd interface{}) (string, error) {
  function MethodUsageFlags (line 33) | func MethodUsageFlags(method string) (UsageFlag, error) {
  function subStructUsage (line 54) | func subStructUsage(structType reflect.Type) string {
  function subArrayUsage (line 101) | func subArrayUsage(arrayType reflect.Type, fieldName string) string {
  function fieldUsage (line 131) | func fieldUsage(structField reflect.StructField, defaultVal *reflect.Val...
  function methodUsageText (line 180) | func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, m...
  function MethodUsageText (line 224) | func MethodUsageText(method string) (string, error) {

FILE: vendor/github.com/btcsuite/btcd/btcjson/cmdparse.go
  function makeParams (line 16) | func makeParams(rt reflect.Type, rv reflect.Value) []interface{} {
  function MarshalCmd (line 38) | func MarshalCmd(id interface{}, cmd interface{}) ([]byte, error) {
  function checkNumParams (line 71) | func checkNumParams(numParams int, info *methodInfo) error {
  function populateDefaults (line 95) | func populateDefaults(numParams int, info *methodInfo, rv reflect.Value) {
  function UnmarshalCmd (line 110) | func UnmarshalCmd(r *Request) (interface{}, error) {
  function isNumeric (line 165) | func isNumeric(kind reflect.Kind) bool {
  function typesMaybeCompatible (line 180) | func typesMaybeCompatible(dest reflect.Type, src reflect.Type) bool {
  function baseType (line 222) | func baseType(arg reflect.Type) (reflect.Type, int) {
  function assignField (line 236) | func assignField(paramNum int, fieldName string, dest reflect.Value, src...
  function NewCmd (line 511) | func NewCmd(method string, args ...interface{}) (interface{}, error) {

FILE: vendor/github.com/btcsuite/btcd/btcjson/error.go
  type ErrorCode (line 13) | type ErrorCode
    method String (line 86) | func (e ErrorCode) String() string {
  constant ErrDuplicateMethod (line 19) | ErrDuplicateMethod ErrorCode = iota
  constant ErrInvalidUsageFlags (line 23) | ErrInvalidUsageFlags
  constant ErrInvalidType (line 27) | ErrInvalidType
  constant ErrEmbeddedType (line 31) | ErrEmbeddedType
  constant ErrUnexportedField (line 35) | ErrUnexportedField
  constant ErrUnsupportedFieldType (line 39) | ErrUnsupportedFieldType
  constant ErrNonOptionalField (line 43) | ErrNonOptionalField
  constant ErrNonOptionalDefault (line 47) | ErrNonOptionalDefault
  constant ErrMismatchedDefault (line 51) | ErrMismatchedDefault
  constant ErrUnregisteredMethod (line 55) | ErrUnregisteredMethod
  constant ErrMissingDescription (line 59) | ErrMissingDescription
  constant ErrNumParams (line 63) | ErrNumParams
  constant numErrorCodes (line 66) | numErrorCodes
  type Error (line 98) | type Error struct
    method Error (line 104) | func (e Error) Error() string {
  function makeError (line 109) | func makeError(c ErrorCode, desc string) Error {

FILE: vendor/github.com/btcsuite/btcd/btcjson/help.go
  type descLookupFunc (line 45) | type descLookupFunc
  function reflectTypeToJSONType (line 49) | func reflectTypeToJSONType(xT descLookupFunc, rt reflect.Type) string {
  function resultStructHelp (line 82) | func resultStructHelp(xT descLookupFunc, rt reflect.Type, indentLevel in...
  function reflectTypeToJSONExample (line 143) | func reflectTypeToJSONExample(xT descLookupFunc, rt reflect.Type, indent...
  function resultTypeHelp (line 252) | func resultTypeHelp(xT descLookupFunc, rt reflect.Type, fieldDescKey str...
  function argTypeHelp (line 285) | func argTypeHelp(xT descLookupFunc, structField reflect.StructField, def...
  function argHelp (line 328) | func argHelp(xT descLookupFunc, rtp reflect.Type, defaults map[int]refle...
  function methodHelp (line 396) | func methodHelp(xT descLookupFunc, rtp reflect.Type, defaults map[int]re...
  function isValidResultType (line 445) | func isValidResultType(kind reflect.Kind) bool {
  function GenerateHelp (line 505) | func GenerateHelp(method string, descs map[string]string, resultTypes .....

FILE: vendor/github.com/btcsuite/btcd/btcjson/helpers.go
  function Bool (line 9) | func Bool(v bool) *bool {
  function Int (line 17) | func Int(v int) *int {
  function Uint (line 25) | func Uint(v uint) *uint {
  function Int32 (line 33) | func Int32(v int32) *int32 {
  function Uint32 (line 41) | func Uint32(v uint32) *uint32 {
  function Int64 (line 49) | func Int64(v int64) *int64 {
  function Uint64 (line 57) | func Uint64(v uint64) *uint64 {
  function Float64 (line 65) | func Float64(v float64) *float64 {
  function String (line 73) | func String(v string) *string {

FILE: vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go
  type RPCErrorCode (line 16) | type RPCErrorCode
  type RPCError (line 20) | type RPCError struct
    method Error (line 30) | func (e RPCError) Error() string {
  function NewRPCError (line 36) | func NewRPCError(code RPCErrorCode, message string) *RPCError {
  function IsValidIDType (line 50) | func IsValidIDType(id interface{}) bool {
  type Request (line 69) | type Request struct
  function NewRequest (line 84) | func NewRequest(id interface{}, method string, params []interface{}) (*R...
  type Response (line 112) | type Response struct
  function NewResponse (line 124) | func NewResponse(id interface{}, marshalledResult []byte, rpcErr *RPCErr...
  function MarshalResponse (line 140) | func MarshalResponse(id interface{}, result interface{}, rpcErr *RPCErro...

FILE: vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go
  constant ErrRPCMisc (line 33) | ErrRPCMisc                RPCErrorCode = -1
  constant ErrRPCForbiddenBySafeMode (line 34) | ErrRPCForbiddenBySafeMode RPCErrorCode = -2
  constant ErrRPCType (line 35) | ErrRPCType                RPCErrorCode = -3
  constant ErrRPCInvalidAddressOrKey (line 36) | ErrRPCInvalidAddressOrKey RPCErrorCode = -5
  constant ErrRPCOutOfMemory (line 37) | ErrRPCOutOfMemory         RPCErrorCode = -7
  constant ErrRPCInvalidParameter (line 38) | ErrRPCInvalidParameter    RPCErrorCode = -8
  constant ErrRPCDatabase (line 39) | ErrRPCDatabase            RPCErrorCode = -20
  constant ErrRPCDeserialization (line 40) | ErrRPCDeserialization     RPCErrorCode = -22
  constant ErrRPCVerify (line 41) | ErrRPCVerify              RPCErrorCode = -25
  constant ErrRPCClientNotConnected (line 46) | ErrRPCClientNotConnected      RPCErrorCode = -9
  constant ErrRPCClientInInitialDownload (line 47) | ErrRPCClientInInitialDownload RPCErrorCode = -10
  constant ErrRPCClientNodeNotAdded (line 48) | ErrRPCClientNodeNotAdded      RPCErrorCode = -24
  constant ErrRPCWallet (line 53) | ErrRPCWallet                    RPCErrorCode = -4
  constant ErrRPCWalletInsufficientFunds (line 54) | ErrRPCWalletInsufficientFunds   RPCErrorCode = -6
  constant ErrRPCWalletInvalidAccountName (line 55) | ErrRPCWalletInvalidAccountName  RPCErrorCode = -11
  constant ErrRPCWalletKeypoolRanOut (line 56) | ErrRPCWalletKeypoolRanOut       RPCErrorCode = -12
  constant ErrRPCWalletUnlockNeeded (line 57) | ErrRPCWalletUnlockNeeded        RPCErrorCode = -13
  constant ErrRPCWalletPassphraseIncorrect (line 58) | ErrRPCWalletPassphraseIncorrect RPCErrorCode = -14
  constant ErrRPCWalletWrongEncState (line 59) | ErrRPCWalletWrongEncState       RPCErrorCode = -15
  constant ErrRPCWalletEncryptionFailed (line 60) | ErrRPCWalletEncryptionFailed    RPCErrorCode = -16
  constant ErrRPCWalletAlreadyUnlocked (line 61) | ErrRPCWalletAlreadyUnlocked     RPCErrorCode = -17
  constant ErrRPCBlockNotFound (line 68) | ErrRPCBlockNotFound     RPCErrorCode = -5
  constant ErrRPCBlockCount (line 69) | ErrRPCBlockCount        RPCErrorCode = -5
  constant ErrRPCBestBlockHash (line 70) | ErrRPCBestBlockHash     RPCErrorCode = -5
  constant ErrRPCDifficulty (line 71) | ErrRPCDifficulty        RPCErrorCode = -5
  constant ErrRPCOutOfRange (line 72) | ErrRPCOutOfRange        RPCErrorCode = -1
  constant ErrRPCNoTxInfo (line 73) | ErrRPCNoTxInfo          RPCErrorCode = -5
  constant ErrRPCNoCFIndex (line 74) | ErrRPCNoCFIndex         RPCErrorCode = -5
  constant ErrRPCNoNewestBlockInfo (line 75) | ErrRPCNoNewestBlockInfo RPCErrorCode = -5
  constant ErrRPCInvalidTxVout (line 76) | ErrRPCInvalidTxVout     RPCErrorCode = -5
  constant ErrRPCRawTxString (line 77) | ErrRPCRawTxString       RPCErrorCode = -32602
  constant ErrRPCDecodeHexString (line 78) | ErrRPCDecodeHexString   RPCErrorCode = -22
  constant ErrRPCNoWallet (line 83) | ErrRPCNoWallet      RPCErrorCode = -1
  constant ErrRPCUnimplemented (line 84) | ErrRPCUnimplemented RPCErrorCode = -1

FILE: vendor/github.com/btcsuite/btcd/btcjson/register.go
  type UsageFlag (line 19) | type UsageFlag
    method String (line 50) | func (fl UsageFlag) String() string {
  constant UFWalletOnly (line 24) | UFWalletOnly UsageFlag = 1 << iota
  constant UFWebsocketOnly (line 30) | UFWebsocketOnly
  constant UFNotification (line 34) | UFNotification
  constant highestUsageFlagBit (line 39) | highestUsageFlagBit
  type methodInfo (line 76) | type methodInfo struct
  function baseKindString (line 95) | func baseKindString(rt reflect.Type) string {
  function isAcceptableKind (line 108) | func isAcceptableKind(kind reflect.Kind) bool {
  function RegisterCmd (line 157) | func RegisterCmd(method string, cmd interface{}, flags UsageFlag) error {
  function MustRegisterCmd (line 272) | func MustRegisterCmd(method string, cmd interface{}, flags UsageFlag) {
  function RegisteredCmdMethods (line 281) | func RegisteredCmdMethods() []string {

FILE: vendor/github.com/btcsuite/btcd/btcjson/walletsvrcmds.go
  type AddMultisigAddressCmd (line 11) | type AddMultisigAddressCmd struct
  function NewAddMultisigAddressCmd (line 22) | func NewAddMultisigAddressCmd(nRequired int, keys []string, account *str...
  type AddWitnessAddressCmd (line 31) | type AddWitnessAddressCmd struct
  function NewAddWitnessAddressCmd (line 37) | func NewAddWitnessAddressCmd(address string) *AddWitnessAddressCmd {
  type CreateMultisigCmd (line 44) | type CreateMultisigCmd struct
  function NewCreateMultisigCmd (line 51) | func NewCreateMultisigCmd(nRequired int, keys []string) *CreateMultisigC...
  type DumpPrivKeyCmd (line 59) | type DumpPrivKeyCmd struct
  function NewDumpPrivKeyCmd (line 65) | func NewDumpPrivKeyCmd(address string) *DumpPrivKeyCmd {
  type EncryptWalletCmd (line 72) | type EncryptWalletCmd struct
  function NewEncryptWalletCmd (line 78) | func NewEncryptWalletCmd(passphrase string) *EncryptWalletCmd {
  type EstimateFeeCmd (line 85) | type EstimateFeeCmd struct
  function NewEstimateFeeCmd (line 91) | func NewEstimateFeeCmd(numBlocks int64) *EstimateFeeCmd {
  type EstimatePriorityCmd (line 98) | type EstimatePriorityCmd struct
  function NewEstimatePriorityCmd (line 104) | func NewEstimatePriorityCmd(numBlocks int64) *EstimatePriorityCmd {
  type GetAccountCmd (line 111) | type GetAccountCmd struct
  function NewGetAccountCmd (line 117) | func NewGetAccountCmd(address string) *GetAccountCmd {
  type GetAccountAddressCmd (line 124) | type GetAccountAddressCmd struct
  function NewGetAccountAddressCmd (line 130) | func NewGetAccountAddressCmd(account string) *GetAccountAddressCmd {
  type GetAddressesByAccountCmd (line 137) | type GetAddressesByAccountCmd struct
  function NewGetAddressesByAccountCmd (line 143) | func NewGetAddressesByAccountCmd(account string) *GetAddressesByAccountC...
  type GetBalanceCmd (line 150) | type GetBalanceCmd struct
  function NewGetBalanceCmd (line 160) | func NewGetBalanceCmd(account *string, minConf *int) *GetBalanceCmd {
  type GetNewAddressCmd (line 168) | type GetNewAddressCmd struct
  function NewGetNewAddressCmd (line 177) | func NewGetNewAddressCmd(account *string) *GetNewAddressCmd {
  type GetRawChangeAddressCmd (line 184) | type GetRawChangeAddressCmd struct
  function NewGetRawChangeAddressCmd (line 193) | func NewGetRawChangeAddressCmd(account *string) *GetRawChangeAddressCmd {
  type GetReceivedByAccountCmd (line 200) | type GetReceivedByAccountCmd struct
  function NewGetReceivedByAccountCmd (line 210) | func NewGetReceivedByAccountCmd(account string, minConf *int) *GetReceiv...
  type GetReceivedByAddressCmd (line 218) | type GetReceivedByAddressCmd struct
  function NewGetReceivedByAddressCmd (line 228) | func NewGetReceivedByAddressCmd(address string, minConf *int) *GetReceiv...
  type GetTransactionCmd (line 236) | type GetTransactionCmd struct
  function NewGetTransactionCmd (line 246) | func NewGetTransactionCmd(txHash string, includeWatchOnly *bool) *GetTra...
  type GetWalletInfoCmd (line 254) | type GetWalletInfoCmd struct
  function NewGetWalletInfoCmd (line 258) | func NewGetWalletInfoCmd() *GetWalletInfoCmd {
  type ImportPrivKeyCmd (line 263) | type ImportPrivKeyCmd struct
  function NewImportPrivKeyCmd (line 274) | func NewImportPrivKeyCmd(privKey string, label *string, rescan *bool) *I...
  type KeyPoolRefillCmd (line 283) | type KeyPoolRefillCmd struct
  function NewKeyPoolRefillCmd (line 292) | func NewKeyPoolRefillCmd(newSize *uint) *KeyPoolRefillCmd {
  type ListAccountsCmd (line 299) | type ListAccountsCmd struct
  function NewListAccountsCmd (line 308) | func NewListAccountsCmd(minConf *int) *ListAccountsCmd {
  type ListAddressGroupingsCmd (line 315) | type ListAddressGroupingsCmd struct
  function NewListAddressGroupingsCmd (line 319) | func NewListAddressGroupingsCmd() *ListAddressGroupingsCmd {
  type ListLockUnspentCmd (line 324) | type ListLockUnspentCmd struct
  function NewListLockUnspentCmd (line 328) | func NewListLockUnspentCmd() *ListLockUnspentCmd {
  type ListReceivedByAccountCmd (line 333) | type ListReceivedByAccountCmd struct
  function NewListReceivedByAccountCmd (line 344) | func NewListReceivedByAccountCmd(minConf *int, includeEmpty, includeWatc...
  type ListReceivedByAddressCmd (line 353) | type ListReceivedByAddressCmd struct
  function NewListReceivedByAddressCmd (line 364) | func NewListReceivedByAddressCmd(minConf *int, includeEmpty, includeWatc...
  type ListSinceBlockCmd (line 373) | type ListSinceBlockCmd struct
  function NewListSinceBlockCmd (line 384) | func NewListSinceBlockCmd(blockHash *string, targetConfirms *int, includ...
  type ListTransactionsCmd (line 393) | type ListTransactionsCmd struct
  function NewListTransactionsCmd (line 405) | func NewListTransactionsCmd(account *string, count, from *int, includeWa...
  type ListUnspentCmd (line 415) | type ListUnspentCmd struct
  function NewListUnspentCmd (line 426) | func NewListUnspentCmd(minConf, maxConf *int, addresses *[]string) *List...
  type LockUnspentCmd (line 435) | type LockUnspentCmd struct
  function NewLockUnspentCmd (line 442) | func NewLockUnspentCmd(unlock bool, transactions []TransactionInput) *Lo...
  type MoveCmd (line 450) | type MoveCmd struct
  function NewMoveCmd (line 463) | func NewMoveCmd(fromAccount, toAccount string, amount float64, minConf *...
  type SendFromCmd (line 474) | type SendFromCmd struct
  function NewSendFromCmd (line 488) | func NewSendFromCmd(fromAccount, toAddress string, amount float64, minCo...
  type SendManyCmd (line 500) | type SendManyCmd struct
  function NewSendManyCmd (line 512) | func NewSendManyCmd(fromAccount string, amounts map[string]float64, minC...
  type SendToAddressCmd (line 522) | type SendToAddressCmd struct
  function NewSendToAddressCmd (line 534) | func NewSendToAddressCmd(address string, amount float64, comment, commen...
  type SetAccountCmd (line 544) | type SetAccountCmd struct
  function NewSetAccountCmd (line 551) | func NewSetAccountCmd(address, account string) *SetAccountCmd {
  type SetTxFeeCmd (line 559) | type SetTxFeeCmd struct
  function NewSetTxFeeCmd (line 565) | func NewSetTxFeeCmd(amount float64) *SetTxFeeCmd {
  type SignMessageCmd (line 572) | type SignMessageCmd struct
  function NewSignMessageCmd (line 579) | func NewSignMessageCmd(address, message string) *SignMessageCmd {
  type RawTxInput (line 588) | type RawTxInput struct
  type SignRawTransactionCmd (line 596) | type SignRawTransactionCmd struct
  function NewSignRawTransactionCmd (line 608) | func NewSignRawTransactionCmd(hexEncodedTx string, inputs *[]RawTxInput,...
  type WalletLockCmd (line 618) | type WalletLockCmd struct
  function NewWalletLockCmd (line 622) | func NewWalletLockCmd() *WalletLockCmd {
  type WalletPassphraseCmd (line 627) | type WalletPassphraseCmd struct
  function NewWalletPassphraseCmd (line 634) | func NewWalletPassphraseCmd(passphrase string, timeout int64) *WalletPas...
  type WalletPassphraseChangeCmd (line 642) | type WalletPassphraseChangeCmd struct
  function NewWalletPassphraseChangeCmd (line 649) | func NewWalletPassphraseChangeCmd(oldPassphrase, newPassphrase string) *...
  function init (line 656) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/walletsvrresults.go
  type GetTransactionDetailsResult (line 12) | type GetTransactionDetailsResult struct
  type GetTransactionResult (line 23) | type GetTransactionResult struct
  type InfoWalletResult (line 40) | type InfoWalletResult struct
  type ListTransactionsResult (line 60) | type ListTransactionsResult struct
  type ListReceivedByAccountResult (line 86) | type ListReceivedByAccountResult struct
  type ListReceivedByAddressResult (line 94) | type ListReceivedByAddressResult struct
  type ListSinceBlockResult (line 104) | type ListSinceBlockResult struct
  type ListUnspentResult (line 110) | type ListUnspentResult struct
  type SignRawTransactionError (line 124) | type SignRawTransactionError struct
  type SignRawTransactionResult (line 134) | type SignRawTransactionResult struct
  type ValidateAddressWalletResult (line 142) | type ValidateAddressWalletResult struct
  type GetBestBlockResult (line 158) | type GetBestBlockResult struct

FILE: vendor/github.com/btcsuite/btcd/btcjson/walletsvrwscmds.go
  type CreateEncryptedWalletCmd (line 11) | type CreateEncryptedWalletCmd struct
  function NewCreateEncryptedWalletCmd (line 17) | func NewCreateEncryptedWalletCmd(passphrase string) *CreateEncryptedWall...
  type ExportWatchingWalletCmd (line 24) | type ExportWatchingWalletCmd struct
  function NewExportWatchingWalletCmd (line 34) | func NewExportWatchingWalletCmd(account *string, download *bool) *Export...
  type GetUnconfirmedBalanceCmd (line 42) | type GetUnconfirmedBalanceCmd struct
  function NewGetUnconfirmedBalanceCmd (line 51) | func NewGetUnconfirmedBalanceCmd(account *string) *GetUnconfirmedBalance...
  type ListAddressTransactionsCmd (line 59) | type ListAddressTransactionsCmd struct
  function NewListAddressTransactionsCmd (line 69) | func NewListAddressTransactionsCmd(addresses []string, account *string) ...
  type ListAllTransactionsCmd (line 77) | type ListAllTransactionsCmd struct
  function NewListAllTransactionsCmd (line 86) | func NewListAllTransactionsCmd(account *string) *ListAllTransactionsCmd {
  type RecoverAddressesCmd (line 93) | type RecoverAddressesCmd struct
  function NewRecoverAddressesCmd (line 100) | func NewRecoverAddressesCmd(account string, n int) *RecoverAddressesCmd {
  type WalletIsLockedCmd (line 108) | type WalletIsLockedCmd struct
  function NewWalletIsLockedCmd (line 112) | func NewWalletIsLockedCmd() *WalletIsLockedCmd {
  function init (line 116) | func init() {

FILE: vendor/github.com/btcsuite/btcd/btcjson/walletsvrwsntfns.go
  constant AccountBalanceNtfnMethod (line 13) | AccountBalanceNtfnMethod = "accountbalance"
  constant BtcdConnectedNtfnMethod (line 17) | BtcdConnectedNtfnMethod = "btcdconnected"
  constant WalletLockStateNtfnMethod (line 21) | WalletLockStateNtfnMethod = "walletlockstate"
  constant NewTxNtfnMethod (line 25) | NewTxNtfnMethod = "newtx"
  type AccountBalanceNtfn (line 29) | type AccountBalanceNtfn struct
  function NewAccountBalanceNtfn (line 37) | func NewAccountBalanceNtfn(account string, balance float64, confirmed bo...
  type BtcdConnectedNtfn (line 46) | type BtcdConnectedNtfn struct
  function NewBtcdConnectedNtfn (line 52) | func NewBtcdConnectedNtfn(connected bool) *BtcdConnectedNtfn {
  type WalletLockStateNtfn (line 59) | type WalletLockStateNtfn struct
  function NewWalletLockStateNtfn (line 65) | func NewWalletLockStateNtfn(locked bool) *WalletLockStateNtfn {
  type NewTxNtfn (line 72) | type NewTxNtfn struct
  function NewNewTxNtfn (line 79) | func NewNewTxNtfn(account string, details ListTransactionsResult) *NewTx...
  function init (line 86) | func init() {

FILE: vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hash.go
  constant HashSize (line 14) | HashSize = 32
  constant MaxHashStringSize (line 17) | MaxHashStringSize = HashSize * 2
  type Hash (line 25) | type Hash
    method String (line 29) | func (hash Hash) String() string {
    method CloneBytes (line 41) | func (hash *Hash) CloneBytes() []byte {
    method SetBytes (line 50) | func (hash *Hash) SetBytes(newHash []byte) error {
    method IsEqual (line 62) | func (hash *Hash) IsEqual(target *Hash) bool {
  function NewHash (line 74) | func NewHash(newHash []byte) (*Hash, error) {
  function NewHashFromStr (line 86) | func NewHashFromStr(hash string) (*Hash, error) {
  function Decode (line 97) | func Decode(dst *Hash, src string) error {

FILE: vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hashfuncs.go
  function HashB (line 11) | func HashB(b []byte) []byte {
  function HashH (line 17) | func HashH(b []byte) Hash {
  function DoubleHashB (line 22) | func DoubleHashB(b []byte) []byte {
  function DoubleHashH (line 30) | func DoubleHashH(b []byte) Hash {

FILE: vendor/github.com/btcsuite/btcd/chaincfg/params.go
  type Checkpoint (line 50) | type Checkpoint struct
  type DNSSeed (line 56) | type DNSSeed struct
    method String (line 592) | func (d DNSSeed) String() string {
  type ConsensusDeployment (line 67) | type ConsensusDeployment struct
  constant DeploymentTestDummy (line 87) | DeploymentTestDummy = iota
  constant DeploymentCSV (line 92) | DeploymentCSV
  constant DeploymentSegwit (line 97) | DeploymentSegwit
  constant DefinedDeployments (line 103) | DefinedDeployments
  type Params (line 109) | type Params struct
  function Register (line 605) | func Register(params *Params) error {
  function mustRegister (line 622) | func mustRegister(params *Params) {
  function IsPubKeyHashAddrID (line 634) | func IsPubKeyHashAddrID(id byte) bool {
  function IsScriptHashAddrID (line 645) | func IsScriptHashAddrID(id byte) bool {
  function IsBech32SegwitPrefix (line 653) | func IsBech32SegwitPrefix(prefix string) bool {
  function HDPrivateKeyToPublicKeyID (line 662) | func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
  function newHashFromStr (line 681) | func newHashFromStr(hexStr string) *chainhash.Hash {
  function init (line 696) | func init() {

FILE: vendor/github.com/btcsuite/btcd/rpcclient/chain.go
  type FutureGetBestBlockHashResult (line 20) | type FutureGetBestBlockHashResult
    method Receive (line 24) | func (r FutureGetBestBlockHashResult) Receive() (*chainhash.Hash, erro...
  method GetBestBlockHashAsync (line 44) | func (c *Client) GetBestBlockHashAsync() FutureGetBestBlockHashResult {
  method GetBestBlockHash (line 51) | func (c *Client) GetBestBlockHash() (*chainhash.Hash, error) {
  type FutureGetBlockResult (line 57) | type FutureGetBlockResult
    method Receive (line 61) | func (r FutureGetBlockResult) Receive() (*wire.MsgBlock, error) {
  method GetBlockAsync (line 94) | func (c *Client) GetBlockAsync(blockHash *chainhash.Hash) FutureGetBlock...
  method GetBlock (line 108) | func (c *Client) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, er...
  type FutureGetBlockVerboseResult (line 114) | type FutureGetBlockVerboseResult
    method Receive (line 118) | func (r FutureGetBlockVerboseResult) Receive() (*btcjson.GetBlockVerbo...
  method GetBlockVerboseAsync (line 138) | func (c *Client) GetBlockVerboseAsync(blockHash *chainhash.Hash) FutureG...
  method GetBlockVerbose (line 153) | func (c *Client) GetBlockVerbose(blockHash *chainhash.Hash) (*btcjson.Ge...
  method GetBlockVerboseTxAsync (line 162) | func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) Futur...
  method GetBlockVerboseTx (line 177) | func (c *Client) GetBlockVerboseTx(blockHash *chainhash.Hash) (*btcjson....
  type FutureGetBlockCountResult (line 183) | type FutureGetBlockCountResult
    method Receive (line 187) | func (r FutureGetBlockCountResult) Receive() (int64, error) {
  method GetBlockCountAsync (line 207) | func (c *Client) GetBlockCountAsync() FutureGetBlockCountResult {
  method GetBlockCount (line 213) | func (c *Client) GetBlockCount() (int64, error) {
  type FutureGetDifficultyResult (line 219) | type FutureGetDifficultyResult
    method Receive (line 223) | func (r FutureGetDifficultyResult) Receive() (float64, error) {
  method GetDifficultyAsync (line 243) | func (c *Client) GetDifficultyAsync() FutureGetDifficultyResult {
  method GetDifficulty (line 250) | func (c *Client) GetDifficulty() (float64, error) {
  type FutureGetBlockChainInfoResult (line 256) | type FutureGetBlockChainInfoResult
    method Receive (line 260) | func (r FutureGetBlockChainInfoResult) Receive() (*btcjson.GetBlockCha...
  method GetBlockChainInfoAsync (line 278) | func (c *Client) GetBlockChainInfoAsync() FutureGetBlockChainInfoResult {
  method GetBlockChainInfo (line 286) | func (c *Client) GetBlockChainInfo() (*btcjson.GetBlockChainInfoResult, ...
  type FutureGetBlockHashResult (line 292) | type FutureGetBlockHashResult
    method Receive (line 296) | func (r FutureGetBlockHashResult) Receive() (*chainhash.Hash, error) {
  method GetBlockHashAsync (line 316) | func (c *Client) GetBlockHashAsync(blockHeight int64) FutureGetBlockHash...
  method GetBlockHash (line 323) | func (c *Client) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
  type FutureGetBlockHeaderResult (line 329) | type FutureGetBlockHeaderResult
    method Receive (line 333) | func (r FutureGetBlockHeaderResult) Receive() (*wire.BlockHeader, erro...
  method GetBlockHeaderAsync (line 366) | func (c *Client) GetBlockHeaderAsync(blockHash *chainhash.Hash) FutureGe...
  method GetBlockHeader (line 380) | func (c *Client) GetBlockHeader(blockHash *chainhash.Hash) (*wire.BlockH...
  type FutureGetBlockHeaderVerboseResult (line 386) | type FutureGetBlockHeaderVerboseResult
    method Receive (line 390) | func (r FutureGetBlockHeaderVerboseResult) Receive() (*btcjson.GetBloc...
  method GetBlockHeaderVerboseAsync (line 411) | func (c *Client) GetBlockHeaderVerboseAsync(blockHash *chainhash.Hash) F...
  method GetBlockHeaderVerbose (line 425) | func (c *Client) GetBlockHeaderVerbose(blockHash *chainhash.Hash) (*btcj...
  type FutureGetMempoolEntryResult (line 431) | type FutureGetMempoolEntryResult
    method Receive (line 436) | func (r FutureGetMempoolEntryResult) Receive() (*btcjson.GetMempoolEnt...
  method GetMempoolEntryAsync (line 457) | func (c *Client) GetMempoolEntryAsync(txHash string) FutureGetMempoolEnt...
  method GetMempoolEntry (line 464) | func (c *Client) GetMempoolEntry(txHash string) (*btcjson.GetMempoolEntr...
  type FutureGetRawMempoolResult (line 470) | type FutureGetRawMempoolResult
    method Receive (line 474) | func (r FutureGetRawMempoolResult) Receive() ([]*chainhash.Hash, error) {
  method GetRawMempoolAsync (line 505) | func (c *Client) GetRawMempoolAsync() FutureGetRawMempoolResult {
  method GetRawMempool (line 514) | func (c *Client) GetRawMempool() ([]*chainhash.Hash, error) {
  type FutureGetRawMempoolVerboseResult (line 520) | type FutureGetRawMempoolVerboseResult
    method Receive (line 525) | func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjso...
  method GetRawMempoolVerboseAsync (line 546) | func (c *Client) GetRawMempoolVerboseAsync() FutureGetRawMempoolVerboseR...
  method GetRawMempoolVerbose (line 556) | func (c *Client) GetRawMempoolVerbose() (map[string]btcjson.GetRawMempoo...
  type FutureEstimateFeeResult (line 562) | type FutureEstimateFeeResult
    method Receive (line 566) | func (r FutureEstimateFeeResult) Receive() (float64, error) {
  method EstimateFeeAsync (line 587) | func (c *Client) EstimateFeeAsync(numBlocks int64) FutureEstimateFeeResu...
  method EstimateFee (line 593) | func (c *Client) EstimateFee(numBlocks int64) (float64, error) {
  type FutureVerifyChainResult (line 600) | type FutureVerifyChainResult
    method Receive (line 605) | func (r FutureVerifyChainResult) Receive() (bool, error) {
  method VerifyChainAsync (line 625) | func (c *Client) VerifyChainAsync() FutureVerifyChainResult {
  method VerifyChain (line 634) | func (c *Client) VerifyChain() (bool, error) {
  method VerifyChainLevelAsync (line 643) | func (c *Client) VerifyChainLevelAsync(checkLevel int32) FutureVerifyCha...
  method VerifyChainLevel (line 657) | func (c *Client) VerifyChainLevel(checkLevel int32) (bool, error) {
  method VerifyChainBlocksAsync (line 666) | func (c *Client) VerifyChainBlocksAsync(checkLevel, numBlocks int32) Fut...
  method VerifyChainBlocks (line 682) | func (c *Client) VerifyChainBlocks(checkLevel, numBlocks int32) (bool, e...
  type FutureGetTxOutResult (line 688) | type FutureGetTxOutResult
    method Receive (line 692) | func (r FutureGetTxOutResult) Receive() (*btcjson.GetTxOutResult, erro...
  method GetTxOutAsync (line 719) | func (c *Client) GetTxOutAsync(txHash *chainhash.Hash, index uint32, mem...
  method GetTxOut (line 731) | func (c *Client) GetTxOut(txHash *chainhash.Hash, index uint32, mempool ...
  type FutureRescanBlocksResult (line 740) | type FutureRescanBlocksResult
    method Receive (line 747) | func (r FutureRescanBlocksResult) Receive() ([]btcjson.RescannedBlock,...
  method RescanBlocksAsync (line 770) | func (c *Client) RescanBlocksAsync(blockHashes []chainhash.Hash) FutureR...
  method RescanBlocks (line 786) | func (c *Client) RescanBlocks(blockHashes []chainhash.Hash) ([]btcjson.R...
  type FutureInvalidateBlockResult (line 792) | type FutureInvalidateBlockResult
    method Receive (line 796) | func (r FutureInvalidateBlockResult) Receive() error {
  method InvalidateBlockAsync (line 807) | func (c *Client) InvalidateBlockAsync(blockHash *chainhash.Hash) FutureI...
  method InvalidateBlock (line 818) | func (c *Client) InvalidateBlock(blockHash *chainhash.Hash) error {
  type FutureGetCFilterResult (line 824) | type FutureGetCFilterResult
    method Receive (line 828) | func (r FutureGetCFilterResult) Receive() (*wire.MsgCFilter, error) {
  method GetCFilterAsync (line 860) | func (c *Client) GetCFilterAsync(blockHash *chainhash.Hash,
  method GetCFilter (line 872) | func (c *Client) GetCFilter(blockHash *chainhash.Hash,
  type FutureGetCFilterHeaderResult (line 879) | type FutureGetCFilterHeaderResult
    method Receive (line 883) | func (r FutureGetCFilterHeaderResult) Receive() (*wire.MsgCFHeaders, e...
  method GetCFilterHeaderAsync (line 913) | func (c *Client) GetCFilterHeaderAsync(blockHash *chainhash.Hash,
  method GetCFilterHeader (line 926) | func (c *Client) GetCFilterHeader(blockHash *chainhash.Hash,

FILE: vendor/github.com/btcsuite/btcd/rpcclient/extensions.go
  type FutureDebugLevelResult (line 23) | type FutureDebugLevelResult
    method Receive (line 28) | func (r FutureDebugLevelResult) Receive() (string, error) {
  method DebugLevelAsync (line 50) | func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult {
  method DebugLevel (line 65) | func (c *Client) DebugLevel(levelSpec string) (string, error) {
  type FutureCreateEncryptedWalletResult (line 71) | type FutureCreateEncryptedWalletResult
    method Receive (line 74) | func (r FutureCreateEncryptedWalletResult) Receive() error {
  method CreateEncryptedWalletAsync (line 86) | func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCre...
  method CreateEncryptedWallet (line 99) | func (c *Client) CreateEncryptedWallet(passphrase string) error {
  type FutureListAddressTransactionsResult (line 105) | type FutureListAddressTransactionsResult
    method Receive (line 109) | func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.List...
  method ListAddressTransactionsAsync (line 131) | func (c *Client) ListAddressTransactionsAsync(addresses []btcutil.Addres...
  method ListAddressTransactions (line 145) | func (c *Client) ListAddressTransactions(addresses []btcutil.Address, ac...
  type FutureGetBestBlockResult (line 151) | type FutureGetBestBlockResult
    method Receive (line 155) | func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, e...
  method GetBestBlockAsync (line 184) | func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult {
  method GetBestBlock (line 193) | func (c *Client) GetBestBlock() (*chainhash.Hash, int32, error) {
  type FutureGetCurrentNetResult (line 199) | type FutureGetCurrentNetResult
    method Receive (line 203) | func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) {
  method GetCurrentNetAsync (line 226) | func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult {
  method GetCurrentNet (line 234) | func (c *Client) GetCurrentNet() (wire.BitcoinNet, error) {
  type FutureGetHeadersResult (line 243) | type FutureGetHeadersResult
    method Receive (line 250) | func (r FutureGetHeadersResult) Receive() ([]wire.BlockHeader, error) {
  method GetHeadersAsync (line 285) | func (c *Client) GetHeadersAsync(blockLocators []chainhash.Hash, hashSto...
  method GetHeaders (line 304) | func (c *Client) GetHeaders(blockLocators []chainhash.Hash, hashStop *ch...
  type FutureExportWatchingWalletResult (line 310) | type FutureExportWatchingWalletResult
    method Receive (line 314) | func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, e...
  method ExportWatchingWalletAsync (line 362) | func (c *Client) ExportWatchingWalletAsync(account string) FutureExportW...
  method ExportWatchingWallet (line 373) | func (c *Client) ExportWatchingWallet(account string) ([]byte, []byte, e...
  type FutureSessionResult (line 379) | type FutureSessionResult
    method Receive (line 383) | func (r FutureSessionResult) Receive() (*btcjson.SessionResult, error) {
  method SessionAsync (line 406) | func (c *Client) SessionAsync() FutureSessionResult {
  method Session (line 421) | func (c *Client) Session() (*btcjson.SessionResult, error) {
  type FutureVersionResult (line 430) | type FutureVersionResult
    method Receive (line 437) | func (r FutureVersionResult) Receive() (map[string]btcjson.VersionResult,
  method VersionAsync (line 462) | func (c *Client) VersionAsync() FutureVersionResult {
  method Version (line 471) | func (c *Client) Version() (map[string]btcjson.VersionResult, error) {

FILE: vendor/github.com/btcsuite/btcd/rpcclient/infrastructure.go
  constant sendBufferSize (line 77) | sendBufferSize = 50
  constant sendPostBufferSize (line 81) | sendPostBufferSize = 100
  constant connectionRetryInterval (line 85) | connectionRetryInterval = time.Second * 5
  type sendPostDetails (line 91) | type sendPostDetails struct
  type jsonRequest (line 98) | type jsonRequest struct
  type Client (line 118) | type Client struct
    method NextID (line 167) | func (c *Client) NextID() uint64 {
    method addRequest (line 179) | func (c *Client) addRequest(jReq *jsonRequest) error {
    method removeRequest (line 205) | func (c *Client) removeRequest(id uint64) *jsonRequest {
    method removeAllRequests (line 223) | func (c *Client) removeAllRequests() {
    method trackRegisteredNtfns (line 231) | func (c *Client) trackRegisteredNtfns(cmd interface{}) {
    method handleMessage (line 309) | func (c *Client) handleMessage(msg []byte) {
    method shouldLogReadError (line 379) | func (c *Client) shouldLogReadError(err error) bool {
    method wsInHandler (line 400) | func (c *Client) wsInHandler() {
    method disconnectChan (line 433) | func (c *Client) disconnectChan() <-chan struct{} {
    method wsOutHandler (line 443) | func (c *Client) wsOutHandler() {
    method sendMessage (line 478) | func (c *Client) sendMessage(marshalledJSON []byte) {
    method reregisterNtfns (line 490) | func (c *Client) reregisterNtfns() error {
    method resendRequests (line 566) | func (c *Client) resendRequests() {
    method wsReconnectHandler (line 619) | func (c *Client) wsReconnectHandler() {
    method handleSendPostMessage (line 692) | func (c *Client) handleSendPostMessage(details *sendPostDetails) {
    method sendPostHandler (line 731) | func (c *Client) sendPostHandler() {
    method sendPostRequest (line 768) | func (c *Client) sendPostRequest(httpReq *http.Request, jReq *jsonRequ...
    method sendPost (line 806) | func (c *Client) sendPost(jReq *jsonRequest) {
    method sendRequest (line 832) | func (c *Client) sendRequest(jReq *jsonRequest) {
    method sendCmd (line 867) | func (c *Client) sendCmd(cmd interface{}) chan *response {
    method sendCmdAndWait (line 898) | func (c *Client) sendCmdAndWait(cmd interface{}) (interface{}, error) {
    method Disconnected (line 906) | func (c *Client) Disconnected() bool {
    method doDisconnect (line 923) | func (c *Client) doDisconnect() bool {
    method doShutdown (line 949) | func (c *Client) doShutdown() bool {
    method Disconnect (line 968) | func (c *Client) Disconnect() {
    method Shutdown (line 995) | func (c *Client) Shutdown() {
    method start (line 1022) | func (c *Client) start() {
    method WaitForShutdown (line 1047) | func (c *Client) WaitForShutdown() {
    method Connect (line 1290) | func (c *Client) Connect(tries int) error {
  type inMessage (line 270) | type inMessage struct
  type rawNotification (line 277) | type rawNotification struct
  type rawResponse (line 284) | type rawResponse struct
    method result (line 301) | func (r rawResponse) result() (result []byte, err error) {
  type response (line 292) | type response struct
  function newFutureError (line 785) | func newFutureError(err error) chan *response {
  function receiveFuture (line 795) | func receiveFuture(f chan *response) ([]byte, error) {
  type ConnConfig (line 1053) | type ConnConfig struct
  function newHTTPClient (line 1118) | func newHTTPClient(config *ConnConfig) (*http.Client, error) {
  function dial (line 1153) | func dial(config *ConnConfig) (*websocket.Conn, error) {
  function New (line 1222) | func New(config *ConnConfig, ntfnHandlers *NotificationHandlers) (*Clien...

FILE: vendor/github.com/btcsuite/btcd/rpcclient/log.go
  function init (line 17) | func init() {
  function DisableLog (line 23) | func DisableLog() {
  function UseLogger (line 28) | func UseLogger(logger btclog.Logger) {
  type logClosure (line 35) | type logClosure
    method String (line 38) | func (c logClosure) String() string {
  function newLogClosure (line 45) | func newLogClosure(c func() string) logClosure {

FILE: vendor/github.com/btcsuite/btcd/rpcclient/mining.go
  type FutureGenerateResult (line 19) | type FutureGenerateResult
    method Receive (line 23) | func (r FutureGenerateResult) Receive() ([]*chainhash.Hash, error) {
  method GenerateAsync (line 54) | func (c *Client) GenerateAsync(numBlocks uint32) FutureGenerateResult {
  method Generate (line 60) | func (c *Client) Generate(numBlocks uint32) ([]*chainhash.Hash, error) {
  type FutureGetGenerateResult (line 66) | type FutureGetGenerateResult
    method Receive (line 70) | func (r FutureGetGenerateResult) Receive() (bool, error) {
  method GetGenerateAsync (line 91) | func (c *Client) GetGenerateAsync() FutureGetGenerateResult {
  method GetGenerate (line 97) | func (c *Client) GetGenerate() (bool, error) {
  type FutureSetGenerateResult (line 103) | type FutureSetGenerateResult
    method Receive (line 107) | func (r FutureSetGenerateResult) Receive() error {
  method SetGenerateAsync (line 117) | func (c *Client) SetGenerateAsync(enable bool, numCPUs int) FutureSetGen...
  method SetGenerate (line 123) | func (c *Client) SetGenerate(enable bool, numCPUs int) error {
  type FutureGetHashesPerSecResult (line 129) | type FutureGetHashesPerSecResult
    method Receive (line 134) | func (r FutureGetHashesPerSecResult) Receive() (int64, error) {
  method GetHashesPerSecAsync (line 155) | func (c *Client) GetHashesPerSecAsync() FutureGetHashesPerSecResult {
  method GetHashesPerSec (line 163) | func (c *Client) GetHashesPerSec() (int64, error) {
  type FutureGetMiningInfoResult (line 169) | type FutureGetMiningInfoResult
    method Receive (line 173) | func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoRe...
  method GetMiningInfoAsync (line 194) | func (c *Client) GetMiningInfoAsync() FutureGetMiningInfoResult {
  method GetMiningInfo (line 200) | func (c *Client) GetMiningInfo() (*btcjson.GetMiningInfoResult, error) {
  type FutureGetNetworkHashPS (line 206) | type FutureGetNetworkHashPS
    method Receive (line 211) | func (r FutureGetNetworkHashPS) Receive() (int64, error) {
  method GetNetworkHashPSAsync (line 232) | func (c *Client) GetNetworkHashPSAsync() FutureGetNetworkHashPS {
  method GetNetworkHashPS (line 242) | func (c *Client) GetNetworkHashPS() (int64, error) {
  method GetNetworkHashPS2Async (line 251) | func (c *Client) GetNetworkHashPS2Async(blocks int) FutureGetNetworkHash...
  method GetNetworkHashPS2 (line 263) | func (c *Client) GetNetworkHashPS2(blocks int) (int64, error) {
  method GetNetworkHashPS3Async (line 272) | func (c *Client) GetNetworkHashPS3Async(blocks, height int) FutureGetNet...
  method GetNetworkHashPS3 (line 283) | func (c *Client) GetNetworkHashPS3(blocks, height int) (int64, error) {
  type FutureGetWork (line 289) | type FutureGetWork
    method Receive (line 293) | func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) {
  method GetWorkAsync (line 314) | func (c *Client) GetWorkAsync() FutureGetWork {
  method GetWork (line 322) | func (c *Client) GetWork() (*btcjson.GetWorkResult, error) {
  type FutureGetWorkSubmit (line 328) | type FutureGetWorkSubmit
    method Receive (line 332) | func (r FutureGetWorkSubmit) Receive() (bool, error) {
  method GetWorkSubmitAsync (line 353) | func (c *Client) GetWorkSubmitAsync(data string) FutureGetWorkSubmit {
  method GetWorkSubmit (line 362) | func (c *Client) GetWorkSubmit(data string) (bool, error) {
  type FutureSubmitBlockResult (line 368) | type FutureSubmitBlockResult
    method Receive (line 372) | func (r FutureSubmitBlockResult) Receive() error {
  method SubmitBlockAsync (line 397) | func (c *Client) SubmitBlockAsync(block *btcutil.Block, options *btcjson...
  method SubmitBlock (line 413) | func (c *Client) SubmitBlock(block *btcutil.Block, options *btcjson.Subm...

FILE: vendor/github.com/btcsuite/btcd/rpcclient/net.go
  type AddNodeCommand (line 15) | type AddNodeCommand
    method String (line 32) | func (cmd AddNodeCommand) String() string {
  constant ANAdd (line 21) | ANAdd AddNodeCommand = "add"
  constant ANRemove (line 24) | ANRemove AddNodeCommand = "remove"
  constant ANOneTry (line 28) | ANOneTry AddNodeCommand = "onetry"
  type FutureAddNodeResult (line 38) | type FutureAddNodeResult
    method Receive (line 42) | func (r FutureAddNodeResult) Receive() error {
  method AddNodeAsync (line 52) | func (c *Client) AddNodeAsync(host string, command AddNodeCommand) Futur...
  method AddNode (line 62) | func (c *Client) AddNode(host string, command AddNodeCommand) error {
  type FutureNodeResult (line 68) | type FutureNodeResult
    method Receive (line 72) | func (r FutureNodeResult) Receive() error {
  method NodeAsync (line 82) | func (c *Client) NodeAsync(command btcjson.NodeSubCmd, host string,
  method Node (line 95) | func (c *Client) Node(command btcjson.NodeSubCmd, host string,
  type FutureGetAddedNodeInfoResult (line 102) | type FutureGetAddedNodeInfoResult
    method Receive (line 106) | func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNod...
  method GetAddedNodeInfoAsync (line 127) | func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeIn...
  method GetAddedNodeInfo (line 136) | func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeIn...
  type FutureGetAddedNodeInfoNoDNSResult (line 142) | type FutureGetAddedNodeInfoNoDNSResult
    method Receive (line 146) | func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
  method GetAddedNodeInfoNoDNSAsync (line 167) | func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedN...
  method GetAddedNodeInfoNoDNS (line 177) | func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) {
  type FutureGetConnectionCountResult (line 183) | type FutureGetConnectionCountResult
    method Receive (line 187) | func (r FutureGetConnectionCountResult) Receive() (int64, error) {
  method GetConnectionCountAsync (line 208) | func (c *Client) GetConnectionCountAsync() FutureGetConnectionCountResult {
  method GetConnectionCount (line 214) | func (c *Client) GetConnectionCount() (int64, error) {
  type FuturePingResult (line 220) | type FuturePingResult
    method Receive (line 224) | func (r FuturePingResult) Receive() error {
  method PingAsync (line 234) | func (c *Client) PingAsync() FuturePingResult {
  method Ping (line 243) | func (c *Client) Ping() error {
  type FutureGetPeerInfoResult (line 249) | type FutureGetPeerInfoResult
    method Receive (line 253) | func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResul...
  method GetPeerInfoAsync (line 274) | func (c *Client) GetPeerInfoAsync() FutureGetPeerInfoResult {
  method GetPeerInfo (line 280) | func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
  type FutureGetNetTotalsResult (line 286) | type FutureGetNetTotalsResult
    method Receive (line 290) | func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResu...
  method GetNetTotalsAsync (line 311) | func (c *Client) GetNetTotalsAsync() FutureGetNetTotalsResult {
  method GetNetTotals (line 317) | func (c *Client) GetNetTotals() (*btcjson.GetNetTotalsResult, error) {

FILE: vendor/github.com/btcsuite/btcd/rpcclient/notify.go
  type notificationState (line 34) | type notificationState struct
    method Copy (line 43) | func (s *notificationState) Copy() *notificationState {
  function newNotificationState (line 61) | func newNotificationState() *notificationState {
  function newNilFutureResult (line 72) | func newNilFutureResult() chan *response {
  type NotificationHandlers (line 87) | type NotificationHandlers struct
  method handleNotification (line 213) | func (c *Client) handleNotification(ntfn *rawNotification) {
  type wrongNumParams (line 479) | type wrongNumParams
    method Error (line 482) | func (e wrongNumParams) Error() string {
  function parseChainNtfnParams (line 488) | func parseChainNtfnParams(params []json.RawMessage) (*chainhash.Hash,
  function parseFilteredBlockConnectedParams (line 533) | func parseFilteredBlockConnectedParams(params []json.RawMessage) (int32,
  function parseFilteredBlockDisconnectedParams (line 589) | func parseFilteredBlockDisconnectedParams(params []json.RawMessage) (int32,
  function parseHexParam (line 618) | func parseHexParam(param json.RawMessage) ([]byte, error) {
  function parseRelevantTxAcceptedParams (line 629) | func parseRelevantTxAcceptedParams(params []json.RawMessage) (transactio...
  function parseChainTxNtfnParams (line 640) | func parseChainTxNtfnParams(params []json.RawMessage) (*btcutil.Tx,
  function parseRescanProgressParams (line 683) | func parseRescanProgressParams(params []json.RawMessage) (*chainhash.Has...
  function parseTxAcceptedNtfnParams (line 720) | func parseTxAcceptedNtfnParams(params []json.RawMessage) (*chainhash.Hash,
  function parseTxAcceptedVerboseNtfnParams (line 758) | func parseTxAcceptedVerboseNtfnParams(params []json.RawMessage) (*btcjso...
  function parseBtcdConnectedNtfnParams (line 780) | func parseBtcdConnectedNtfnParams(params []json.RawMessage) (bool, error) {
  function parseAccountBalanceNtfnParams (line 798) | func parseAccountBalanceNtfnParams(params []json.RawMessage) (account st...
  function parseWalletLockStateNtfnParams (line 835) | func parseWalletLockStateNtfnParams(params []json.RawMessage) (account s...
  type FutureNotifyBlocksResult (line 859) | type FutureNotifyBlocksResult
    method Receive (line 863) | func (r FutureNotifyBlocksResult) Receive() error {
  method NotifyBlocksAsync (line 875) | func (c *Client) NotifyBlocksAsync() FutureNotifyBlocksResult {
  method NotifyBlocks (line 901) | func (c *Client) NotifyBlocks() error {
  type FutureNotifySpentResult (line 909) | type FutureNotifySpentResult
    method Receive (line 913) | func (r FutureNotifySpentResult) Receive() error {
  method notifySpentInternal (line 921) | func (c *Client) notifySpentInternal(outpoints []btcjson.OutPoint) Futur...
  function newOutPointFromWire (line 939) | func newOutPointFromWire(op *wire.OutPoint) btcjson.OutPoint {
  method NotifySpentAsync (line 955) | func (c *Client) NotifySpentAsync(outpoints []*wire.OutPoint) FutureNoti...
  method NotifySpent (line 987) | func (c *Client) NotifySpent(outpoints []*wire.OutPoint) error {
  type FutureNotifyNewTransactionsResult (line 993) | type FutureNotifyNewTransactionsResult
    method Receive (line 997) | func (r FutureNotifyNewTransactionsResult) Receive() error {
  method NotifyNewTransactionsAsync (line 1009) | func (c *Client) NotifyNewTransactionsAsync(verbose bool) FutureNotifyNe...
  method NotifyNewTransactions (line 1036) | func (c *Client) NotifyNewTransactions(verbose bool) error {
  type FutureNotifyReceivedResult (line 1044) | type FutureNotifyReceivedResult
    method Receive (line 1048) | func (r FutureNotifyReceivedResult) Receive() error {
  method notifyReceivedInternal (line 1056) | func (c *Client) notifyReceivedInternal(addresses []string) FutureNotify...
  method NotifyReceivedAsync (line 1082) | func (c *Client) NotifyReceivedAsync(addresses []btcutil.Address) Future...
  method NotifyReceived (line 1122) | func (c *Client) NotifyReceived(addresses []btcutil.Address) error {
  type FutureRescanResult (line 1130) | type FutureRescanResult
    method Receive (line 1134) | func (r FutureRescanResult) Receive() error {
  method RescanAsync (line 1154) | func (c *Client) RescanAsync(startBlock *chainhash.Hash,
  method Rescan (line 1219) | func (c *Client) Rescan(startBlock *chainhash.Hash,
  method RescanEndBlockAsync (line 1235) | func (c *Client) RescanEndBlockAsync(startBlock *chainhash.Hash,
  method RescanEndHeight (line 1297) | func (c *Client) RescanEndHeight(startBlock *chainhash.Hash,
  type FutureLoadTxFilterResult (line 1310) | type FutureLoadTxFilterResult
    method Receive (line 1317) | func (r FutureLoadTxFilterResult) Receive() error {
  method LoadTxFilterAsync (line 1330) | func (c *Client) LoadTxFilterAsync(reload bool, addresses []btcutil.Addr...
  method LoadTxFilter (line 1355) | func (c *Client) LoadTxFilter(reload bool, addresses []btcutil.Address, ...

FILE: vendor/github.com/btcsuite/btcd/rpcclient/rawrequest.go
  type FutureRawResult (line 16) | type FutureRawResult
    method Receive (line 20) | func (r FutureRawResult) Receive() (json.RawMessage, error) {
  method RawRequestAsync (line 29) | func (c *Client) RawRequestAsync(method string, params []json.RawMessage...
  method RawRequest (line 76) | func (c *Client) RawRequest(method string, params []json.RawMessage) (js...

FILE: vendor/github.com/btcsuite/btcd/rpcclient/rawtransactions.go
  type SigHashType (line 20) | type SigHashType
    method String (line 57) | func (s SigHashType) String() string {
  constant SigHashAll (line 25) | SigHashAll SigHashType = "ALL"
  constant SigHashNone (line 30) | SigHashNone SigHashType = "NONE"
  constant SigHashSingle (line 35) | SigHashSingle SigHashType = "SINGLE"
  constant SigHashAllAnyoneCanPay (line 41) | SigHashAllAnyoneCanPay SigHashType = "ALL|ANYONECANPAY"
  constant SigHashNoneAnyoneCanPay (line 47) | SigHashNoneAnyoneCanPay SigHashType = "NONE|ANYONECANPAY"
  constant SigHashSingleAnyoneCanPay (line 53) | SigHashSingleAnyoneCanPay SigHashType = "SINGLE|ANYONECANPAY"
  type FutureGetRawTransactionResult (line 63) | type FutureGetRawTransactionResult
    method Receive (line 67) | func (r FutureGetRawTransactionResult) Receive() (*btcutil.Tx, error) {
  method GetRawTransactionAsync (line 99) | func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGe...
  method GetRawTransaction (line 113) | func (c *Client) GetRawTransaction(txHash *chainhash.Hash) (*btcutil.Tx,...
  type FutureGetRawTransactionVerboseResult (line 120) | type FutureGetRawTransactionVerboseResult
    method Receive (line 124) | func (r FutureGetRawTransactionVerboseResult) Receive() (*btcjson.TxRa...
  method GetRawTransactionVerboseAsync (line 145) | func (c *Client) GetRawTransactionVerboseAsync(txHash *chainhash.Hash) F...
  method GetRawTransactionVerbose (line 159) | func (c *Client) GetRawTransactionVerbose(txHash *chainhash.Hash) (*btcj...
  type FutureDecodeRawTransactionResult (line 165) | type FutureDecodeRawTransactionResult
    method Receive (line 169) | func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawRes...
  method DecodeRawTransactionAsync (line 190) | func (c *Client) DecodeRawTransactionAsync(serializedTx []byte) FutureDe...
  method DecodeRawTransaction (line 198) | func (c *Client) DecodeRawTransaction(serializedTx []byte) (*btcjson.TxR...
  type FutureCreateRawTransactionResult (line 204) | type FutureCreateRawTransactionResult
    method Receive (line 209) | func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, erro...
  method CreateRawTransactionAsync (line 241) | func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionI...
  method CreateRawTransaction (line 254) | func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput,
  type FutureSendRawTransactionResult (line 262) | type FutureSendRawTransactionResult
    method Receive (line 267) | func (r FutureSendRawTransactionResult) Receive() (*chainhash.Hash, er...
  method SendRawTransactionAsync (line 288) | func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees b...
  method SendRawTransaction (line 305) | func (c *Client) SendRawTransaction(tx *wire.MsgTx, allowHighFees bool) ...
  type FutureSignRawTransactionResult (line 312) | type FutureSignRawTransactionResult
    method Receive (line 316) | func (r FutureSignRawTransactionResult) Receive() (*wire.MsgTx, bool, ...
  method SignRawTransactionAsync (line 349) | func (c *Client) SignRawTransactionAsync(tx *wire.MsgTx) FutureSignRawTr...
  method SignRawTransaction (line 371) | func (c *Client) SignRawTransaction(tx *wire.MsgTx) (*wire.MsgTx, bool, ...
  method SignRawTransaction2Async (line 380) | func (c *Client) SignRawTransaction2Async(tx *wire.MsgTx, inputs []btcjs...
  method SignRawTransaction2 (line 405) | func (c *Client) SignRawTransaction2(tx *wire.MsgTx, inputs []btcjson.Ra...
  method SignRawTransaction3Async (line 414) | func (c *Client) SignRawTransaction3Async(tx *wire.MsgTx,
  method SignRawTransaction3 (line 450) | func (c *Client) SignRawTransaction3(tx *wire.MsgTx,
  method SignRawTransaction4Async (line 462) | func (c *Client) SignRawTransaction4Async(tx *wire.MsgTx,
  method SignRawTransaction4 (line 500) | func (c *Client) SignRawTransaction4(tx *wire.MsgTx,
  type FutureSearchRawTransactionsResult (line 510) | type FutureSearchRawTransactionsResult
    method Receive (line 514) | func (r FutureSearchRawTransactionsResult) Receive() ([]*wire.MsgTx, e...
  method SearchRawTransactionsAsync (line 553) | func (c *Client) SearchRawTransactionsAsync(address btcutil.Address, ski...
  method SearchRawTransactions (line 568) | func (c *Client) SearchRawTransactions(address btcutil.Address, skip, co...
  type FutureSearchRawTransactionsVerboseResult (line 575) | type FutureSearchRawTransactionsVerboseResult
    method Receive (line 579) | func (r FutureSearchRawTransactionsVerboseResult) Receive() ([]*btcjso...
  method SearchRawTransactionsVerboseAsync (line 600) | func (c *Client) SearchRawTransactionsVerboseAsync(address btcutil.Addre...
  method SearchRawTransactionsVerbose (line 621) | func (c *Client) SearchRawTransactionsVerbose(address btcutil.Address, s...
  type FutureDecodeScriptResult (line 630) | type FutureDecodeS
Condensed preview — 374 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,106K chars).
[
  {
    "path": ".github/dependabot.yml",
    "chars": 127,
    "preview": "version: 2\nupdates:\n- package-ecosystem: gomod\n  directory: \"/\"\n  schedule:\n    interval: daily\n  open-pull-requests-lim"
  },
  {
    "path": ".gitignore",
    "chars": 23,
    "preview": "tmp/\nbeancounter\n*.csv\n"
  },
  {
    "path": ".travis.yml",
    "chars": 492,
    "preview": "---\n\nlanguage: go\n\ngo:\n  - '1.13.4'\n\nbefore_install:\n  - go get github.com/mattn/goveralls\n\ninstall:\n  - GOOS=linux GOAR"
  },
  {
    "path": "BUG-BOUNTY.md",
    "chars": 364,
    "preview": "Serious about security\n======================\n\nSquare recognizes the important contributions the security research commu"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 797,
    "preview": "# Contributing\n\nWe appreciate your desire to contribute code to this repo. You may do so through GitHub\nby forking the r"
  },
  {
    "path": "LICENSE",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README.md",
    "chars": 6059,
    "preview": "Beancounter\n==========\n\n[![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.git"
  },
  {
    "path": "WHY.md",
    "chars": 7780,
    "preview": "# Why we wrote Beancounter\n### _and why it wasn't trivial_\nIntuitively, computing the balance for a Bitcoin wallet shoul"
  },
  {
    "path": "accounter/accounter.go",
    "chars": 9451,
    "preview": "package accounter\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/btcsuite/btcutil\"\n\t\"github.com/s"
  },
  {
    "path": "accounter/accounter_test.go",
    "chars": 6426,
    "preview": "package accounter\n\nimport (\n\t\"testing\"\n\n\t\"github.com/square/beancounter/backend\"\n\t\"github.com/square/beancounter/deriver"
  },
  {
    "path": "accounter/testdata/tpub_data.json",
    "chars": 64051,
    "preview": "{\n    \"addresses\": [\n        {\n            \"address\": \"mfsNoNz57ANkYrCzHaLZDLoMGujBW8u3zv\",\n            \"path\": \"m/1'/12"
  },
  {
    "path": "backend/backend.go",
    "chars": 2175,
    "preview": "package backend\n\nimport (\n\t\"github.com/square/beancounter/deriver\"\n\ttime \"time\"\n)\n\n// Backend is an interface which abst"
  },
  {
    "path": "backend/btcd_backend.go",
    "chars": 9561,
    "preview": "package backend\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"sync\"\n\n\t\"github.com/btcsuite/btcd/btcjson\"\n\t\"github.com/btcsuite/btcd/chaincfg"
  },
  {
    "path": "backend/common.go",
    "chars": 1449,
    "preview": "package backend\n\nimport (\n\t. \"github.com/square/beancounter/utils\"\n\t\"time\"\n)\n\n// index, address and transaction and help"
  },
  {
    "path": "backend/electrum/LICENSE",
    "chars": 1080,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015 Tristan Rice\n\nPermission is hereby granted, free of charge, to any person obta"
  },
  {
    "path": "backend/electrum/README.md",
    "chars": 145,
    "preview": "This code was imported from github.com/mbyczkowski/go-electrum, a fork of\ngithub.com/qshuai/go-electrum, a fork of githu"
  },
  {
    "path": "backend/electrum/blockchain.go",
    "chars": 8038,
    "preview": "package electrum\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/bcext/cashutil"
  },
  {
    "path": "backend/electrum/tcp.go",
    "chars": 3745,
    "preview": "package electrum\n\nimport (\n\t\"bufio\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"log\"\n\t\"net\"\n\t\"time\"\n)\n\nvar DebugMode bool"
  },
  {
    "path": "backend/electrum_backend.go",
    "chars": 14492,
    "preview": "package backend\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/btcs"
  },
  {
    "path": "backend/electrum_backend_test.go",
    "chars": 1593,
    "preview": "package backend\n\nimport (\n\t\"github.com/square/beancounter/backend/electrum\"\n\t\"github.com/square/beancounter/deriver\"\n\t. "
  },
  {
    "path": "backend/fixture_backend.go",
    "chars": 5721,
    "preview": "package backend\n\nimport (\n\t\"encoding/json\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"sync\"\n\n\tpkgerr \"github.com/pkg/errors\"\n\t\"github.c"
  },
  {
    "path": "backend/fixture_backend_test.go",
    "chars": 3866,
    "preview": "package backend\n\nimport (\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/square/beancounter/deriver\"\n\t. \"github.com/square/bea"
  },
  {
    "path": "backend/recorder_backend.go",
    "chars": 5445,
    "preview": "package backend\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"sync\"\n\n\t\"github.com/square/beancounter/deriver\"\n\t\"gith"
  },
  {
    "path": "backend/testdata/nonjsonfixture",
    "chars": 32,
    "preview": "SOME DATA THAT'S NOT VALID JSON\n"
  },
  {
    "path": "blockfinder/blockfinder.go",
    "chars": 2944,
    "preview": "package blockfinder\n\nimport (\n\t\"fmt\"\n\t\"github.com/square/beancounter/backend\"\n\t\"sort\"\n\t\"time\"\n)\n\n// Blockfinder uses the"
  },
  {
    "path": "blockfinder/blockfinder_test.go",
    "chars": 484,
    "preview": "package blockfinder\n\nimport (\n\t\"github.com/square/beancounter/backend\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"testing\"\n"
  },
  {
    "path": "deriver/address_deriver.go",
    "chars": 5613,
    "preview": "package deriver\n\nimport (\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"log\"\n\t\"sort\"\n\n\t\"github.com/btcsuite/btcd/tx"
  },
  {
    "path": "deriver/address_deriver_test.go",
    "chars": 1769,
    "preview": "package deriver\n\nimport (\n\t\"testing\"\n\n\t. \"github.com/square/beancounter/utils\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\n"
  },
  {
    "path": "fixtures/blocks.json",
    "chars": 20143,
    "preview": "{\n    \"metadata\": {\n        \"height\": 546110\n    },\n    \"addresses\": [],\n    \"transactions\": [],\n    \"blocks\": [\n       "
  },
  {
    "path": "go.mod",
    "chars": 960,
    "preview": "module github.com/square/beancounter\n\ngo 1.12\n\nrequire (\n\tgithub.com/Masterminds/semver v1.5.0\n\tgithub.com/alecthomas/te"
  },
  {
    "path": "go.sum",
    "chars": 5812,
    "preview": "github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=\ngithub.com/Masterminds/semver v1.4."
  },
  {
    "path": "main.go",
    "chars": 12198,
    "preview": "package main\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"github.com/btcsuite/btcutil/hdkeychain\"\n\t\"github.com/square/beancounter/blockfi"
  },
  {
    "path": "reporter/reporter.go",
    "chars": 2390,
    "preview": "package reporter\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\n// Reporter tracks our progress while we are fetching data. "
  },
  {
    "path": "utils/utils.go",
    "chars": 2740,
    "preview": "package utils\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/btcsuite/btcd/chaincfg\"\n)\n\n// PanicOnError panics if err is not nil\n"
  },
  {
    "path": "utils/utils_test.go",
    "chars": 3370,
    "preview": "package utils\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/btcsuite/btcd/chaincfg\"\n\t\"github.com/stretchr/testify/assert\"\n)\n"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/.travis.yml",
    "chars": 709,
    "preview": "language: go\n\ngo:\n  - 1.6.x\n  - 1.7.x\n  - 1.8.x\n  - 1.9.x\n  - 1.10.x\n  - tip\n\n# Setting sudo access to false will let Tr"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/CHANGELOG.md",
    "chars": 2301,
    "preview": "# 1.4.2 (2018-04-10)\n\n## Changed\n- #72: Updated the docs to point to vert for a console appliaction\n- #71: Update the do"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/LICENSE.txt",
    "chars": 1094,
    "preview": "The Masterminds\nCopyright (C) 2014-2015, Matt Butcher and Matt Farina\n\nPermission is hereby granted, free of charge, to "
  },
  {
    "path": "vendor/github.com/Masterminds/semver/Makefile",
    "chars": 667,
    "preview": ".PHONY: setup\nsetup:\n\tgo get -u gopkg.in/alecthomas/gometalinter.v1\n\tgometalinter.v1 --install\n\n.PHONY: test\ntest: valid"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/README.md",
    "chars": 5933,
    "preview": "# SemVer\n\nThe `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifica"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/appveyor.yml",
    "chars": 805,
    "preview": "version: build-{build}.{branch}\n\nclone_folder: C:\\gopath\\src\\github.com\\Masterminds\\semver\nshallow_clone: true\n\nenvironm"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/collection.go",
    "chars": 729,
    "preview": "package semver\n\n// Collection is a collection of Version instances and implements the sort\n// interface. See the sort pa"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/constraints.go",
    "chars": 10179,
    "preview": "package semver\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// Constraints is one or more constraint that a semant"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/doc.go",
    "chars": 3720,
    "preview": "/*\nPackage semver provides the ability to work with Semantic Versions (http://semver.org) in Go.\n\nSpecifically it provid"
  },
  {
    "path": "vendor/github.com/Masterminds/semver/version.go",
    "chars": 10281,
    "preview": "package semver\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// The compiled v"
  },
  {
    "path": "vendor/github.com/alecthomas/template/LICENSE",
    "chars": 1479,
    "preview": "Copyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "vendor/github.com/alecthomas/template/README.md",
    "chars": 381,
    "preview": "# Go's `text/template` package with newline elision\n\nThis is a fork of Go 1.4's [text/template](http://golang.org/pkg/te"
  },
  {
    "path": "vendor/github.com/alecthomas/template/doc.go",
    "chars": 15420,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/exec.go",
    "chars": 26374,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/funcs.go",
    "chars": 14890,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/helper.go",
    "chars": 3723,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/parse/lex.go",
    "chars": 14064,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/parse/node.go",
    "chars": 20545,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/parse/parse.go",
    "chars": 18588,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/template/template.go",
    "chars": 6740,
    "preview": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license "
  },
  {
    "path": "vendor/github.com/alecthomas/units/COPYING",
    "chars": 1055,
    "preview": "Copyright (C) 2014 Alec Thomas\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis sof"
  },
  {
    "path": "vendor/github.com/alecthomas/units/README.md",
    "chars": 280,
    "preview": "# Units - Helpful unit multipliers and functions for Go\n\nThe goal of this package is to have functionality similar to th"
  },
  {
    "path": "vendor/github.com/alecthomas/units/bytes.go",
    "chars": 2271,
    "preview": "package units\n\n// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte,\n// etc.).\ntype Base2Byte"
  },
  {
    "path": "vendor/github.com/alecthomas/units/doc.go",
    "chars": 348,
    "preview": "// Package units provides helpful unit multipliers and functions for Go.\n//\n// The goal of this package is to have funct"
  },
  {
    "path": "vendor/github.com/alecthomas/units/si.go",
    "chars": 650,
    "preview": "package units\n\n// SI units.\ntype SI int64\n\n// SI unit multiples.\nconst (\n\tKilo SI = 1000\n\tMega    = Kilo * 1000\n\tGiga   "
  },
  {
    "path": "vendor/github.com/alecthomas/units/util.go",
    "chars": 2756,
    "preview": "package units\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nvar (\n\tsiUnits = []string{\"\", \"K\", \"M\", \"G\", \"T\", \"P\", \"E\"}\n)\n\nfu"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/.gitignore",
    "chars": 317,
    "preview": "# Temp files\r\n*~\r\n\r\n# Log files\r\n*.log\r\n\r\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\r\n*.o\r\n*.a\r\n*"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/.travis.yml",
    "chars": 342,
    "preview": "language: go\ngo:\n  - \"1.9.4\"\n  - \"1.10\"\nsudo: false\ninstall:\n  - go get -d -t -v ./...\n  - go get -v github.com/alecthom"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/LICENSE",
    "chars": 853,
    "preview": "ISC License\n\nCopyright (c) 2013-2017 The btcsuite developers\nCopyright (c) 2016-2017 The Lightning Network Developers\nCo"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/README.md",
    "chars": 1871,
    "preview": "cashutil\n=======\n\n[![Build Status](http://img.shields.io/travis/bcext/cashutil.svg)](https://travis-ci.org/bcext/cashuti"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/address.go",
    "chars": 14840,
    "preview": "// Copyright (c) 2013-2017 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/amount.go",
    "chars": 4138,
    "preview": "// Copyright (c) 2013, 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/appdata.go",
    "chars": 3373,
    "preview": "// Copyright (c) 2013-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/README.md",
    "chars": 1457,
    "preview": "base58\n==========\n\n[![Build Status](http://img.shields.io/travis/bcext/cashutil.svg)](https://travis-ci.org/bcext/cashut"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/alphabet.go",
    "chars": 1646,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/base58.go",
    "chars": 1480,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/base58check.go",
    "chars": 1509,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/cov_report.sh",
    "chars": 512,
    "preview": "#!/bin/sh\n\n# This script uses gocov to generate a test coverage report.\n# The gocov tool my be obtained with the followi"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/doc.go",
    "chars": 1260,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/base58/genalphabet.go",
    "chars": 1475,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/block.go",
    "chars": 7904,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/cashaddr.go",
    "chars": 8289,
    "preview": "// Copyright (c) 2018 The bcext developers\n// Use of this source code is governed by an ISC\n// license that can be found"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/cashaddrconv.go",
    "chars": 4428,
    "preview": "// Copyright (c) 2018 The bcext developers\n// Use of this source code is governed by an ISC\n// license that can be found"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/certgen.go",
    "chars": 3545,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/const.go",
    "chars": 478,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/cov_report.sh",
    "chars": 512,
    "preview": "#!/bin/sh\n\n# This script uses gocov to generate a test coverage report.\n# The gocov tool my be obtained with the followi"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/doc.go",
    "chars": 1718,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/glide.yaml",
    "chars": 432,
    "preview": "package: github.com/bcext/cashutil\nimport:\n- package: github.com/aead/siphash\n- package: github.com/bcext/gcash\n  versio"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/goclean.sh",
    "chars": 1619,
    "preview": "#!/bin/bash\n# The script does automatic checking on a Go package and its sub-packages, including:\n# 1. gofmt         (ht"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/hash160.go",
    "chars": 533,
    "preview": "// Copyright (c) 2013-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/net.go",
    "chars": 513,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/net_noop.go",
    "chars": 553,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/cashutil/profile.cov",
    "chars": 47997,
    "preview": "mode: count\ngithub.com/bcext/cashutil/net.go:16.43,18.2 1 1\ngithub.com/bcext/cashutil/tx.go:32.34,35.2 1 2\ngithub.com/bc"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/test_coverage.txt",
    "chars": 7103,
    "preview": "ok  \tgithub.com/bcext/cashutil\t0.237s\tcoverage: 90.1% of statements\n\ngithub.com/bcext/cashutil/cashaddrconv.go\t    packA"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/tx.go",
    "chars": 2684,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/cashutil/wif.go",
    "chars": 6321,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/LICENSE",
    "chars": 842,
    "preview": "ISC License\n\nCopyright (c) 2013-2017 The btcsuite developers\nCopyright (c) 2015-2016 The Decred developers\nCopyright (c)"
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/README.md",
    "chars": 2828,
    "preview": "btcec\n=====\n\n[![Build Status](https://travis-ci.org/bcext/gcash.png?branch=master)](https://travis-ci.org/bcext/btcec)\n["
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/btcec.go",
    "chars": 37787,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Copyright 2011 ThePiachu. All rights reserved.\n// Copyright 20"
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/ciphering.go",
    "chars": 6215,
    "preview": "// Copyright (c) 2015-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/doc.go",
    "chars": 947,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/field.go",
    "chars": 48181,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2013-2016 Dave Collins\n// Use of this source code is"
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/genprecomps.go",
    "chars": 1807,
    "preview": "// Copyright 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be found "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/gensecp256k1.go",
    "chars": 5988,
    "preview": "// Copyright (c) 2014-2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/precompute.go",
    "chars": 1972,
    "preview": "// Copyright 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be found "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/privkey.go",
    "chars": 2252,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/pubkey.go",
    "chars": 5945,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/secp256k1.go",
    "chars": 1189266,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/bcext/gcash/btcec/signature.go",
    "chars": 16394,
    "preview": "// Copyright (c) 2013-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/README.md",
    "chars": 2256,
    "preview": "chaincfg\n========\n\n[![Build Status](http://img.shields.io/travis/bcext/gcash.svg)](https://travis-ci.org/bcext/gcash)\n[!"
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/chainhash/README.md",
    "chars": 1256,
    "preview": "chainhash\n=========\n\n[![Build Status](http://img.shields.io/travis/bcext/gcash.svg)](https://travis-ci.org/bcext/gcash)\n"
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/chainhash/doc.go",
    "chars": 213,
    "preview": "// Package chainhash provides abstracted hash functionality.\n//\n// This package provides a generic hash type and associa"
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/chainhash/hash.go",
    "chars": 3761,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2015 The Decred developers\n// Copyright (c) 2018 The"
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/chainhash/hashfuncs.go",
    "chars": 886,
    "preview": "// Copyright (c) 2015 The Decred developers\n// Copyright (c) 2016-2017 The btcsuite developers\n// Use of this source cod"
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/doc.go",
    "chars": 2524,
    "preview": "// Package chaincfg defines chain configuration parameters.\n//\n// In addition to the main Bitcoin network, which is inte"
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/genesis.go",
    "chars": 7615,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/chaincfg/params.go",
    "chars": 26436,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/README.md",
    "chars": 4039,
    "preview": "wire\n====\n\n[![Build Status](http://img.shields.io/travis/bcext/gcash.svg)](https://travis-ci.org/bcext/gcash)\n[![ISC Lic"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/blockheader.go",
    "chars": 4908,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/common.go",
    "chars": 17698,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/doc.go",
    "chars": 7275,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/error.go",
    "chars": 1102,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/invvect.go",
    "chars": 2149,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/message.go",
    "chars": 11741,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgaddr.go",
    "chars": 4307,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgalert.go",
    "chars": 13055,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgblock.go",
    "chars": 8733,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgcfcheckpt.go",
    "chars": 5018,
    "preview": "// Copyright (c) 2018 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgcfheaders.go",
    "chars": 5450,
    "preview": "// Copyright (c) 2017 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgcfilter.go",
    "chars": 3740,
    "preview": "// Copyright (c) 2017 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgfeefilter.go",
    "chars": 2049,
    "preview": "// Copyright (c) 2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgfilteradd.go",
    "chars": 2547,
    "preview": "// Copyright (c) 2014-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgfilterclear.go",
    "chars": 1912,
    "preview": "// Copyright (c) 2014-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgfilterload.go",
    "chars": 4326,
    "preview": "// Copyright (c) 2014-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetaddr.go",
    "chars": 1582,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetblocks.go",
    "chars": 4761,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetcfcheckpt.go",
    "chars": 2050,
    "preview": "// Copyright (c) 2018 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetcfheaders.go",
    "chars": 2254,
    "preview": "// Copyright (c) 2017 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetcfilters.go",
    "chars": 2347,
    "preview": "// Copyright (c) 2017 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetdata.go",
    "chars": 4470,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msggetheaders.go",
    "chars": 4612,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgheaders.go",
    "chars": 4174,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msginv.go",
    "chars": 4779,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgmempool.go",
    "chars": 1904,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgmerkleblock.go",
    "chars": 4711,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgnotfound.go",
    "chars": 3296,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgping.go",
    "chars": 2693,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgpong.go",
    "chars": 2509,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgreject.go",
    "chars": 5405,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgsendheaders.go",
    "chars": 1981,
    "preview": "// Copyright (c) 2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code is g"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgtx.go",
    "chars": 25707,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgverack.go",
    "chars": 1488,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/msgversion.go",
    "chars": 7927,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/netaddress.go",
    "chars": 4696,
    "preview": "// Copyright (c) 2013-2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/bcext/gcash/wire/protocol.go",
    "chars": 5223,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2018 The bcext developers\n// Use of this source code"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/LICENSE",
    "chars": 802,
    "preview": "ISC License\n\nCopyright (c) 2013-2017 The btcsuite developers\nCopyright (c) 2015-2016 The Decred developers\n\nPermission t"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/README.md",
    "chars": 2847,
    "preview": "btcec\n=====\n\n[![Build Status](https://travis-ci.org/btcsuite/btcd.png?branch=master)](https://travis-ci.org/btcsuite/btc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/btcec.go",
    "chars": 37787,
    "preview": "// Copyright 2010 The Go Authors. All rights reserved.\n// Copyright 2011 ThePiachu. All rights reserved.\n// Copyright 20"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/ciphering.go",
    "chars": 6215,
    "preview": "// Copyright (c) 2015-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/doc.go",
    "chars": 947,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/field.go",
    "chars": 48181,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2013-2016 Dave Collins\n// Use of this source code is"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/genprecomps.go",
    "chars": 1809,
    "preview": "// Copyright 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be found "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/gensecp256k1.go",
    "chars": 5988,
    "preview": "// Copyright (c) 2014-2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/precompute.go",
    "chars": 1972,
    "preview": "// Copyright 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be found "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/privkey.go",
    "chars": 2252,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/pubkey.go",
    "chars": 5945,
    "preview": "// Copyright (c) 2013-2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/secp256k1.go",
    "chars": 1189266,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcec/signature.go",
    "chars": 16592,
    "preview": "// Copyright (c) 2013-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/CONTRIBUTORS",
    "chars": 592,
    "preview": "# This is the list of people who have contributed code to the repository.\n#\n# Names should be added to this file only af"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/README.md",
    "chars": 2879,
    "preview": "btcjson\n=======\n\n[![Build Status](https://travis-ci.org/btcsuite/btcd.png?branch=master)](https://travis-ci.org/btcsuite"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go",
    "chars": 4347,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Copyright (c) 2015-2016 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/btcdextresults.go",
    "chars": 722,
    "preview": "// Copyright (c) 2016-2017 The btcsuite developers\n// Copyright (c) 2015-2017 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/btcwalletextcmds.go",
    "chars": 3024,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go",
    "chars": 26236,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/chainsvrresults.go",
    "chars": 20196,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/chainsvrwscmds.go",
    "chars": 7801,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Copyright (c) 2015-2017 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsntfns.go",
    "chars": 10209,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Copyright (c) 2015-2017 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsresults.go",
    "chars": 645,
    "preview": "// Copyright (c) 2015-2017 The btcsuite developers\n// Copyright (c) 2015-2017 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/cmdinfo.go",
    "chars": 7988,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/cmdparse.go",
    "chars": 18089,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/doc.go",
    "chars": 6536,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/error.go",
    "chars": 3707,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/help.go",
    "chars": 18753,
    "preview": "// Copyright (c) 2015 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/helpers.go",
    "chars": 2184,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go",
    "chars": 5269,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go",
    "chars": 2578,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/register.go",
    "chars": 8955,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/walletsvrcmds.go",
    "chars": 22988,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/walletsvrresults.go",
    "chars": 6740,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/walletsvrwscmds.go",
    "chars": 4408,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/btcjson/walletsvrwsntfns.go",
    "chars": 3008,
    "preview": "// Copyright (c) 2014 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can be fo"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/README.md",
    "chars": 2266,
    "preview": "chaincfg\n========\n\n[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/chainhash/README.md",
    "chars": 1264,
    "preview": "chainhash\n=========\n\n[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/bt"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/chainhash/doc.go",
    "chars": 213,
    "preview": "// Package chainhash provides abstracted hash functionality.\n//\n// This package provides a generic hash type and associa"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hash.go",
    "chars": 3578,
    "preview": "// Copyright (c) 2013-2016 The btcsuite developers\n// Copyright (c) 2015 The Decred developers\n// Use of this source cod"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hashfuncs.go",
    "chars": 886,
    "preview": "// Copyright (c) 2015 The Decred developers\n// Copyright (c) 2016-2017 The btcsuite developers\n// Use of this source cod"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/doc.go",
    "chars": 2527,
    "preview": "// Package chaincfg defines chain configuration parameters.\n//\n// In addition to the main Bitcoin network, which is inte"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/genesis.go",
    "chars": 7619,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/chaincfg/params.go",
    "chars": 27462,
    "preview": "// Copyright (c) 2014-2016 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/rpcclient/CONTRIBUTORS",
    "chars": 492,
    "preview": "# This is the list of people who have contributed code to the repository.\n#\n# Names should be added to this file only af"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/rpcclient/README.md",
    "chars": 2474,
    "preview": "rpcclient\n=========\n\n[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/bt"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/rpcclient/chain.go",
    "chars": 31289,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Copyright (c) 2015-2017 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/rpcclient/doc.go",
    "chars": 8150,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/rpcclient/extensions.go",
    "chars": 15323,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Copyright (c) 2015-2017 The Decred developers\n// Use of this sourc"
  },
  {
    "path": "vendor/github.com/btcsuite/btcd/rpcclient/infrastructure.go",
    "chars": 40933,
    "preview": "// Copyright (c) 2014-2017 The btcsuite developers\n// Use of this source code is governed by an ISC\n// license that can "
  }
]

// ... and 174 more files (download for full content)

About this extraction

This page contains the full source code of the square/beancounter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 374 files (4.7 MB), approximately 1.3M tokens, and a symbol index with 4827 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!