{"id":19219378,"url":"https://github.com/bwt-dev/bwt","last_synced_at":"2025-04-04T11:15:36.613Z","repository":{"id":38187744,"uuid":"263651969","full_name":"bwt-dev/bwt","owner":"bwt-dev","description":"A lightweight wallet indexer for Bitcoin, available as an Electrum RPC server and a modern HTTP REST API.","archived":false,"fork":false,"pushed_at":"2023-03-25T00:51:42.000Z","size":1733,"stargazers_count":279,"open_issues_count":49,"forks_count":25,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-03-28T10:09:50.848Z","etag":null,"topics":["bitcoin","bitcoin-api","descriptors","electrum-server","hd-wallet","http-api","xpub"],"latest_commit_sha":null,"homepage":"https://bwt.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bwt-dev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-13T14:22:18.000Z","updated_at":"2025-03-23T12:39:38.000Z","dependencies_parsed_at":"2024-11-09T14:33:19.103Z","dependency_job_id":"b56138db-7840-490b-a773-326d2d6020eb","html_url":"https://github.com/bwt-dev/bwt","commit_stats":{"total_commits":663,"total_committers":5,"mean_commits":132.6,"dds":0.006033182503770718,"last_synced_commit":"e1885d97eb70c8f84db3383e7e2d04ad063f3ec0"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwt-dev%2Fbwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwt-dev%2Fbwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwt-dev%2Fbwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bwt-dev%2Fbwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bwt-dev","download_url":"https://codeload.github.com/bwt-dev/bwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166169,"owners_count":20894654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bitcoin","bitcoin-api","descriptors","electrum-server","hd-wallet","http-api","xpub"],"created_at":"2024-11-09T14:31:00.722Z","updated_at":"2025-04-04T11:15:36.595Z","avatar_url":"https://github.com/bwt-dev.png","language":"Rust","readme":"# Bitcoin Wallet Tracker\n\n[![Build Status](https://travis-ci.org/bwt-dev/bwt.svg?branch=master)](https://travis-ci.org/bwt-dev/bwt)\n[![Latest release](https://img.shields.io/crates/v/bwt.svg?label=release)](https://github.com/bwt-dev/bwt/releases/latest)\n[![Downloads](https://img.shields.io/github/downloads/bwt-dev/bwt/total.svg?color=blueviolet)](https://github.com/bwt-dev/bwt/releases)\n[![Docker release](https://img.shields.io/docker/pulls/shesek/bwt.svg)](https://hub.docker.com/r/shesek/bwt)\n[![Crate package](https://img.shields.io/crates/d/bwt.svg?label=crate+installs)](https://crates.io/crates/bwt)\n[![MIT license](https://img.shields.io/github/license/bwt-dev/bwt.svg?color=yellow)](https://github.com/bwt-dev/bwt/blob/master/LICENSE)\n[![Pull Requests Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#developing)\n[![Chat on Telegram](https://img.shields.io/badge/chat-on%20telegram-blue)](https://t.me/bwt_dev)\n[![Chat on IRC](https://img.shields.io/badge/chat-on%20IRC-green.svg)](https://webchat.freenode.net/##bwt)\n\n`bwt` is a lightweight wallet descriptor/xpub tracker and query engine for Bitcoin, implemented in Rust.\n\n🔸 Personal wallet indexer (EPS-like)\u003cbr\u003e\n🔸 Descriptor-based tracking\u003cbr\u003e\n🔸 Electrum RPC server (also available as a plugin!)\u003cbr\u003e\n🔸 Developer-friendly, modern HTTP REST API\u003cbr\u003e\n🔸 Real-time updates with Server-Sent-Events or Web Hooks\n\nSupport development: [⛓️ on-chain or ⚡ lightning via BTCPay](https://btcpay.shesek.info/)\n\n- [Intro](#intro)\n- [Setting up bwt](#setting-up-bwt)\n  - [Installation](#installation)\n  - [Electrum-only server](#electrum-only-server)\n  - [Pruning](#pruning)\n  - [Real-time indexing](#real-time-indexing)\n  - [Advanced options](#advanced-options)\n- [Electrum plugin](#electrum-plugin) 💥\n- [Manual Electrum setup](#manual-electrum-setup-without-the-plugin)\n- [HTTP API](#http-api)\n  - [Wallets](#wallets)\n  - [Transactions](#transactions)\n  - [Addresses](#addresses-scripthashes--keys)\n  - [Outputs](#outputs)\n  - [Blocks](#blocks)\n  - [Mempool \u0026 Fees](#mempool--fees)\n  - [Server-Sent Events](#server-sent-events) 🌟\n  - [Miscellaneous](#miscellaneous)\n- [Web Hooks](#web-hooks)\n- [Developing](#developing) 👩‍💻\n- [Reproducible builds](#reproducible-builds)\n- [Thanks](#thanks)\n\n## Intro\n\n`bwt` is a lightweight and performant descriptor-based wallet indexer backed by a bitcoin full node, using a model similar to that of Electrum Personal Server.\nIt can serve as a personal alternative to public Electrum servers or power bitcoin apps such as wallet backends, payment processors and more.\n\nIt uses bitcoind to keep track of your wallet addresses (derived from your xpub(s)) and builds an index of their\nhistory that can be queried using the Electrum RPC protocol or using bwt's custom designed [HTTP API](#http-api).\n\nReal-time updates are available through [Server-Sent events](#server-sent-events) (a streaming long-lived HTTP connection),\nor using [Web Hooks](#web-hooks) push updates (an HTTP request sent to your URL with the event).\n\nThe index is currently managed in-memory and does not get persisted (this is expected to change), but building it is pretty fast: bwt can index thousands of transactions in under a second.\n\n*TL;DR: EPS + Rust + Modern HTTP API*\n\n## Setting up bwt\n\nGet yourself a synced Bitcoin Core node (v0.19 is recommended, v0.17 is sufficient. `txindex` is not required, pruning [is supported](#pruning))\nand install bwt using one of the methods below.\n\n### Installation\n\n💥 Electrum desktop users can also [install bwt as an Electrum plugin](https://github.com/bwt-dev/bwt-electrum-plugin),\nwhich provides a GUI and doesn't require the standalone server installation described below.\n\n#### Signed pre-built binaries\n\nAvailable for download on [the releases page](https://github.com/bwt-dev/bwt/releases) (Linux, Mac, Windows and ARMv7/v8).\n\nThe releases are signed by Nadav Ivgi (@shesek).\nThe public key can be verified on\nthe [PGP WoT](http://keys.gnupg.net/pks/lookup?op=vindex\u0026fingerprint=on\u0026search=0x81F6104CD0F150FC),\n[github](https://api.github.com/users/shesek/gpg_keys),\n[twitter](https://twitter.com/shesek),\n[keybase](https://keybase.io/nadav),\n[hacker news](https://news.ycombinator.com/user?id=nadaviv)\nand [this video presentation](https://youtu.be/SXJaN2T3M10?t=4) (bottom of slide).\n\n```bash\n# Download (change x86_64-linux to your platform)\n$ wget https://github.com/bwt-dev/bwt/releases/download/v0.2.4/bwt-0.2.4-x86_64-linux.tar.gz\n\n# Fetch public key\n$ gpg --keyserver keyserver.ubuntu.com --recv-keys FCF19B67866562F08A43AAD681F6104CD0F150FC\n\n# Verify signature\n$ wget -qO - https://github.com/bwt-dev/bwt/releases/download/v0.2.4/SHA256SUMS.asc \\\n  | gpg --decrypt - | grep ' bwt-0.2.4-x86_64-linux.tar.gz$' | sha256sum -c -\n\n$ tar zxvf bwt-0.2.4-x86_64-linux.tar.gz\n$ ./bwt-0.1.5-x86_64-linux/bwt --xpub \u003cxpub\u003e ...\n```\n\nThe signature verification should show `Good signature from \"Nadav Ivgi \u003cnadav@shesek.info\u003e\" ... Primary key fingerprint: FCF1 9B67 ...` and `bwt-0.2.4-x86_64-linux.tar.gz: OK`.\n\nThe builds are reproducible and can be verified against Travis CI. See [more details here](#reproducible-builds).\n\n#### From source\n\n[Install Rust](https://rustup.rs/) and:\n\n```bash\n$ sudo apt install build-essential\n$ git clone https://github.com/bwt-dev/bwt \u0026\u0026 cd bwt\n$ cargo build --release\n$ ./target/release/bwt --xpub \u003cxpub\u003e ...\n```\n\nOr using the crates.io package:\n\n```bash\n$ cargo install bwt\n$ bwt --xpub \u003cxpub\u003e\n```\n\n(Make sure `~/.cargo/bin` is in your `PATH`)\n\n#### With Docker\n\nAssuming your bitcoin datadir is at `~/.bitcoin`,\n\n```bash\n$ docker run -it --net host -v ~/.bitcoin:/bitcoin:ro shesek/bwt --xpub \u003cxpub\u003e ...\n```\n\n(Mounting the bitcoin datadir is not necessary if you're not using the cookie file.)\n\n#### Running bwt\n\n`bwt --xpub \u003cxpub\u003e` should be sufficient to get you rolling.\n\nYou can configure the `--network` (defaults to `bitcoin`),\nyour `--bitcoind-url` (defaults to `http://127.0.0.1:\u003cdefault-rpc-port\u003e`),\n`--bitcoind-dir` (defaults to `~/.bitcoin`) and\n`--bitcoind-auth \u003cuser:pass\u003e` (defaults to using the cookie file from `bitcoind-dir`).\n\nYou can set multiple `--xpub`s to track. This also supports ypubs and zpubs.\nTo set an explicit script type, use `--xpub \u003cxpub\u003e:\u003ctype\u003e`, where type is one of `wpkh`, `shwpkh` or `pkh`.\n\nYou can also track output script descriptors using `--descriptor`. For example, `--descriptor 'wpkh(\u003cxpub\u003e/0/*)'`.\n\nStandalone addresses can be tracked with `--address \u003caddress\u003e` or `--addresses-file \u003cpath\u003e`.\n\nTo speed up rescanning for historical transactions, you can provide the wallet creation date with `--rescan-since \u003ctimestmap\u003e`.\nThe timestamp can be a `YYYY-MM-DD` formatted string or 'now' to disable rescanning and watch for new\ntransactions only (for newly created wallets).\n*Setting this is highly recommended.*\n\nBy default, the Electrum server will be bound on port `50001`/`60001`/`60401` (according to the network)\nand the HTTP server will be bound on port `3060`. This can be controlled with `--electrum-addr`\nand `--http-addr`.\n\n\u003e ⚠️ Both the HTTP API server and the Electrum server are *unauthenticated and unencrypted* by default.\n\u003e If you're exposing them over the internet, they should be put behind a secure transport like an SSH tunnel,\n\u003e a VPN, or a Tor hidden service.\n\u003e\n\u003e Authentication (but not encryption) can be enabled by following [the instructions here](doc/auth.md).\n\n\nYou may set `-v` to increase verbosity or `-vv` to increase it more.\n\nSee `--help` for the full list of options.\n\n#### Configuration file\n\nConfiguration options can be set under `~/bwt.env` as environment variables in the dotenv format.\n\nOptions that accept multiple values (`DESCRIPTORS`, `XPUBS`, `ADDRESSES` and `WEBHOOKS_URLs`)\ncan be provided as a `;`-separated list, or using wildcard `XPUB_*`/`DESC_*`/`ADDRESS_*` variables.\n\nFor example:\n\n```\nNETWORK=regtest\nGAP_LIMIT=20\nRESCAN_SINCE=2020-01-01\nXPUBS='\u003cxpub1\u003e;\u003cxpub2\u003e'\nDESCRIPTORS=pkh(\u003cxpub\u003e/0/*)\nXPUB_BOB=\u003cxpub3\u003e\nXPUB_ALICE=\u003cxpub4\u003e\n```\n\nSetting the environment variables directly is also supported.\n\n### Electrum-only server\n\nIf you're only interested in a standalone Electrum server, you may disable the HTTP API server\nby downloading the `electrum_only` pre-built binary,\nusing the `shesek/bwt:electrum` docker image\nor building bwt with `--no-default-features --features cli,electrum`.\n\nThis removes several large dependencies and disables the `track-spends` database index\n(which is not needed for the electrum server).\n\n(Also see the [Electrum plugin](https://github.com/bwt-dev/bwt-electrum-plugin).)\n\n### Pruning\n\nYou can use bwt with pruning, but a pruned node is only able to scan the recent blocks it still has available for transactions related to your wallet. This means that the `--rescan-since` date has to be within the range of non-pruned blocks, or set to 'now'. This makes pruned nodes primarily suitable for tracking newly created wallets.\n\nThere is, however, an opportunity to scan for your wallet's full history during the initial sync of your node, as the blocks will get scanned before getting pruned. You'll need to set `--no-wait-sync` to import the addresses without waiting for bitcoind to finish syncing first and make sure bwt runs before the earliest block containing a wallet transaction gets processed.\n\nYou can use `--prune-until \u003ctarget\u003e` to automatically prune the chain up to the given target (height, unix timestamp or YYYY-MM-DD formatted date). This requires configuring bitcoind with `prune=1` to allow manual pruning via the RPC.\n\nTo connect Electrum, you will need to configure it with [`--skipmerklecheck`](https://github.com/spesmilo/electrum/pull/4957) to tolerate missing SPV proofs (they will be unavailable for transactions in pruned blocks).\n\n\u003e If you're running Electrum with `--skipmerklecheck`, you may also configure bwt with `--electrum-skip-merkle` to save some resources by not generating SPV proofs even when it's possible.\n\u003e Both of these settings are automatically enabled when using the Electrum plugin.\n\n### Bitcoin Core multi-wallet\n\nIf you're using [multi-wallet](https://bitcoin.org/en/release/v0.15.0.1#multi-wallet-support),\nyou can specify which wallet to use with `--bitcoind-wallet \u003cname\u003e` (or `-w \u003cname\u003e`).\n\nUsing a separate wallet for bwt is recommended. You can set\n`-w bwt --create-wallet-if-missing` to have bwt create one for you.\n\n*Note that EPS and bwt should not be run on the same bitcoind wallet with the same xpub, they will conflict.*\n\n### Advanced options\n\n#### Real-time indexing\n\nBy default, bwt will query bitcoind for new blocks/transactions every 5 seconds.\nThis can be adjusted with `--poll-interval \u003cseconds\u003e`.\n\nTo get *real* real-time updates, you may configure your bitcoind node to send a `POST /sync` request to the bwt\nhttp server whenever a new block or wallet transaction is found, using the `walletnotify` and `blocknotify` options.\n\nExample bitcoind configuration:\n```\nwalletnotify=curl -X POST http://localhost:3060/sync\nblocknotify=curl -X POST http://localhost:3060/sync\n```\n\nAfter verifying this works, you may increase your `--interval-poll` to avoid unnecessary indexing and reduce cpu usage.\n\nIf you're using the electrum-only mode without the http server, you may instead configure bwt to bind\non a unix socket using `--unix-listener-path \u003cpath\u003e` and open a connection to it initiate an indexer sync.\n\nFor example, start with `--unix-listener-path /home/satoshi/bwt-sync-socket` and configure your bitcoind with:\n```\nwalletnotify=nc -U /home/satoshi/bwt-sync-socket\nblocknotify=nc -U /home/satoshi/bwt-sync-socket\n```\n\nIf `nc` is not available, you can also use `socat - UNIX-CONNECT:/home/satoshi/bwt-sync-socket`.\n\nIf you're using docker, you can bind the socket on a directory mounted from the host to make it available outside the container.\nFor example, `--unix-listener-path /bitcoin/bwt-socket`.\n\n##### Gap limit\n\nYou may configure the gap limit with `--gap--limit \u003cN\u003e` (defaults to 20).\nThe gap limit sets the maximum number of consecutive unused addresses to be imported before assuming there are no more used addresses to be discovered.\n\nYou can import larger batches with a higher gap during the initial sync using `--initial-import-size \u003cN\u003e` (defaults to 350).\nHigher value means less rescans. Should be increased for large wallets.\n\n##### Scriptable transaction broadcast\n\nYou may set a custom command for broadcasting transactions via `--tx-broadcast-cmd \u003ccmd\u003e`. The string `{tx_hex}` will be replaced with the hex-encoded transaction.\n\nThe command will be used in place of broadcasting transactions using the full node,\nwhich may provide better privacy in some circumstances.\n\nFor example, to broadcast transactions over Tor using the blockstream.info onion service, you can use:\n\n```\n--tx-broadcast-cmd '[ $(curl -s -x socks5h://localhost:9050 http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/api/tx -d {tx_hex} -o /dev/stderr -w \"%{http_code}\" -H \"User-Agent: curl/7.$(shuf -n1 -e 47 58 64 68).0\") -eq 200 ]'\n```\n\n(Replace port `9050` with `9150` if you're using the Tor browser bundle.)\n\n## Electrum plugin\n\nYou can setup bwt as an Electrum plugin, which allows connecting Electrum to a Bitcoin Core full node backend\nby running an embedded Electrum server within the Electrum wallet itself.\n\nSee https://github.com/bwt-dev/bwt-electrum-plugin for more details and installation instructions.\n\n![Screenshot of bwt integrated into Electrum](https://raw.githubusercontent.com/bwt-dev/bwt/master/doc/img/electrum-plugin.png)\n\n## Manual Electrum setup (without the plugin)\n\n[Setup the bwt server](#setting-up-bwt), then start Electrum with:\n\n```bash\n$ electrum --skipmerklecheck --oneserver --server 127.0.0.1:50001:t\n```\n\nAlternatively, you can also set `127.0.0.1:50001:t` as your server using the server selection GUI\n(note the `:t`, which disables TLS). Note, however, that it is not possible to configure `oneserver`\nand `skipmerklecheck` using the GUI.\n\n\u003e Note that setting `--skipmerklecheck` is only necessary if your node is pruned,\nbut it can also be used to save some resource when combined with `--electrum-skip-merkle`.\nSee [more details here](#pruning).\n\n## HTTP API\n\nAll the endpoints return JSON. All bitcoin amounts are in satoshis.\n\n### Wallets\n\nEach wallet represents an output script descriptor.\n\nNote that xpubs specified via `--xpub` will be represented as two descriptor wallet entries, one for the\nexternal chain (used for receive addresses) and one for the internal chain (used for change addresses).\nYou can associate the wallets to their parent xpub using the `bip32_origins` field.\n\n#### Wallet format\n\n- `desc` - the output script descriptor tracked by this wallet\n- `network` - the network this wallet belongs to (`bitcoin`, `testnet`, `signet` or `regtest`)\n- `is_wildcard` - a boolean indicating whether the descriptor includes wildcard keys (`xpub../*`)\n- `bip32_origins` - bip32 origin information for the keys contained in the descriptor\n- `gap_limit` - the gap limited configured for this wallet\n- `initial_import_size` - the gap limit used during the initial import\n- `rescan_policy` - how far back rescanning should take place\n- `max_funded_index` - the maximum derivation index that is known to have history\n- `max_imported_index` - the maximum derivation index imported into bitcoind\n- `satisfaction_weight` - an upper bound on the weight of a satisfying witness to the transaction (also see [here](https://docs.rs/miniscript/3.0.0/miniscript/descriptor/enum.Descriptor.html#method.max_satisfaction_weight))\n\nSee [`GET /wallet/:checksum`](#get-walletchecksum) for an example.\n\n#### `GET /wallets`\n\nGet a map of all tracked descriptor wallets, as a json object indexed by the descriptor checksum.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nExample:\n```\n$ curl localhost:3060/wallets\n\n{\n  \"xjm8w0el\": {\n    \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/*)#xjm8w0el\",\n    \"network\": \"bitcoin\",\n    \"is_wildcard\": true,\n    \"bip32_origins\": [ \"80e042a9/0\" ],\n    ...\n  },\n  \"k38panl4\": {\n    \"desc\": \"wsh(multi(2,xpub661MyMwAqRbcEuy9nKLTbGCi2NhqTWeQPT3gd2QdfmeaieDHLHiwTnSnw1GrP2xdaJwEDQJLasfw6LNK7hVADcCN9d1M1RtxitrR3CwvtjV/0/*,[16eabcf7/2]xpub684GUXwH4bY8Pf3fgSunTGz3hwJZhJzaNwgT55aWGWQM7KsiUFEXWLYPy1Q19gAEvc9LG5TN5PdmGPoyocmkkpKCCMV27ugL7XqHeHRwJzH/1/*))#k38panl4\",\n    \"network\": \"bitcoin\",\n    \"is_wildcard\": true,\n    \"bip32_origins\": [ \"367e5b47/0\", \"16eabcf7/2/1\" ],\n    ...\n  },\n  \"cletf5fc\": {\n    \"desc\": \"pkh(xpub661MyMwAqRbcEoHAdGB6AaGRhLmHVemxe6acQikhJgfV3sr1SmapjQv8ZfBwWa1YKmFbyR6ta96TKiCNTctvZix58hAR7mDtjdWK2E18PjR/0/*)#cletf5fc\",\n    \"network\": \"bitcoin\",\n    \"is_wildcard\": true,\n    \"bip32_origins\": [ \"7a32efaa/0\" ],\n    ...\n  },\n  \"ftu25peq\": {\n    \"desc\": \"pkh(xpub661MyMwAqRbcEoHAdGB6AaGRhLmHVemxe6acQikhJgfV3sr1SmapjQv8ZfBwWa1YKmFbyR6ta96TKiCNTctvZix58hAR7mDtjdWK2E18PjR/1/*)#ftu25peq\",\n    \"network\": \"bitcoin\",\n    \"is_wildcard\": true,\n    \"bip32_origins\": [ \"7a32efaa/1\" ],\n    ...\n  }\n}\n\n```\n\nThese wallets are the result of starting bwt with:\n\n- `--descriptor 'wpkh(xpub...xToJdcy/0/*)'` (the `xjm8w0el` wallet)\n- `--descriptor 'wsh(multi(2,xpub...3CwvtjV/0/*,[16eabcf7/2]xpub...eHRwJzH/1/*))'` (the `k38panl4` wallet)\n- `--xpub 'xpub...2E18PjR'` (the `cletf5fc` and `ftu25peq` wallets)\n\n\u003c/details\u003e\n\n#### `GET /wallet/:checksum`\n\nGet information about the descriptor wallet identified by its `checksum`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nExample:\n```\n$ curl localhost:3060/wallet/xjm8w0el\n{\n  \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/*)#xjm8w0el\",\n  \"network\": \"bitcoin\",\n  \"is_wildcard\": true,\n  \"bip32_origins\": [ \"80e042a9/0\" ],\n  \"rescan_policy\": \"now\",\n  \"max_funded_index\": null,\n  \"max_imported_index\": 19,\n  \"gap_limit\": 20,\n  \"initial_import_size\": 20\n}\n\n```\n\u003c/details\u003e\n\n#### `GET /wallet/:checksum/:index`\n\nGet basic information for the wallet child address at derivation index `index`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned fields:\n- `address`\n- `scripthash`\n- `origin` - descriptor wallet origin information in `\u003cchecksum\u003e/\u003cindex\u003e` format\n- `desc` - the descriptor for this address\n- `bip32_origins` - an array of bip32 origins for the derived keys at this index\n\nExamples:\n```\n$ curl localhost:3060/wallet/xjm8w0el/8\n{\n  \"address\": \"bc1qlwdpe3a0ulss57tqxxkpepylazpy9f07f2jufa\",\n  \"scripthash\": \"5e643e168a629406504ee2651f76efc3510a79d0aaa1fda9893b2a98c73440dc\",\n  \"origin\": \"xjm8w0el/8\",\n  \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/8)#dtxjzdej\",\n  \"bip32_origins\": [ \"80e042a9/0/8\" ]\n}\n\n$ curl localhost:3060/wallet/k38panl4/5\n{\n  \"address\": \"bc1q9r669mzwaal8cj0hplp7qsqd6kl4xu76w6nuprqd75zrll8s5lsqgeka5t\",\n  \"scripthash\": \"2eb2e9b8b0ee5b6e2aea7a8ee5897d448ab089c7d360a287b27e767320d5902a\",\n  \"origin\": \"k38panl4/5\",\n  \"desc\": \"wsh(multi(2,xpub661MyMwAqRbcEuy9nKLTbGCi2NhqTWeQPT3gd2QdfmeaieDHLHiwTnSnw1GrP2xdaJwEDQJLasfw6LNK7hVADcCN9d1M1RtxitrR3CwvtjV/0/5,[16eabcf7/2]xpub684GUXwH4bY8Pf3fgSunTGz3hwJZhJzaNwgT55aWGWQM7KsiUFEXWLYPy1Q19gAEvc9LG5TN5PdmGPoyocmkkpKCCMV27ugL7XqHeHRwJzH/1/5))#5sd0njd0\",\n  \"bip32_origins\": [ \"367e5b47/0/5\", \"16eabcf7/2/1/5\" ]\n}\n```\n\u003c/details\u003e\n\n#### `GET /wallet/:checksum/next`\n\nGet the next unused address in the specified wallet.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nIssues a 307 redirection to the url of the next derivation index (`/wallet/:checksum/:index`) *and* responds with the derivation index in the responses body.\n\nNote that the returned address is not marked as used until receiving funds; If you wish to skip it and generate a different\naddress without receiving funds to it, you can specify an explicit derivation index instead.\n\nNon-wildcard descriptors always return `0` as their next index.\n\nExamples:\n```\n$ curl localhost:3060/wallet/xjm8w0el/next\n\u003c HTTP/1.1 307 Temporary Redirect\n\u003c Location: /wallet/xjm8w0el/104\n104\n\n# Follow the redirect to get the full address json\n\n$ curl --location localhost:3060/wallet/xjm8w0el/next\n{\n  \"address\": \"bc1qu8k2dv6s8kjaywvdrrk3mvju6utyx537puaeal\",\n  \"origin\": \"xjm8w0el/104\",\n  ...\n}\n```\n\u003c/details\u003e\n\n#### `GET /wallet/:checksum/gap`\n\nGet the current maximum number of consecutive unused addresses in the specified wallet.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nExample:\n```\n$ curl localhost:3060/wallet/xjm8w0el/gap\n\n7\n```\n\u003c/details\u003e\n\n### Transactions\n\n#### Wallet transaction format\n\nThis format is only available for wallet transactions and includes contextual wallet information about funded outputs and spent inputs.\nIt does not include inputs/outputs that are unrelated the wallet.\n\nTransaction fields:\n- `txid`\n- `block_height` - the confirming block height or `null` for unconfirmed transactions\n- `funding` - contains an entry for every output created by this transaction that is owned by the wallet\n  - `vout` - the output index\n  - `amount` - the output amount in satoshis\n  - scriptPubKey fields\n    - `address` - the address funded by this output\n    - `scripthash` - the scripthash funded by this output\n    - `origin` - descriptor wallet origin information in `\u003cchecksum\u003e/\u003cindex\u003e` format\n    - `desc` - the descriptor for this script\n    - `bip32_origins` - an array of bip32 origins for this script keys\n  - `spent_by` - the transaction input spending this output in `txid:vin` format, or `null` for unspent outputs (only available with `track-spends`)\n- `spending` - contains an entry for every input spending a wallet output\n  - `vin` - the input index\n  - `amount` - the amount in satoshis of the previous output spent by this input\n  - `prevout` - the `\u003ctxid\u003e:\u003cvout\u003e` being spent\n  - scriptPubKey fields\n    - `address`, `scripthash`, `origin`, `desc`, `bip32_origins`\u003cbr\u003e*(same format as above for `funding`)*\n- `balance_change` - the net change to the wallet balance inflicted by this transaction\n\nAdditional fields for unconfirmed mempool transactions:\n\n- `own_feerate` - the fee rate paid directly by the transaction, in `sat/vB`\n- `effective_feerate` - the effective transaction fee rate, taking unconfirmed ancestor transactions into account\n- `bip125_replacelable` - whether this transaction can be replaced due to BIP 125 replace-by-fee (because either it or one of its unconfirmed ancestors are signaling to opt-into rbf)\n- `has_unconfirmed_parents` - whether this transaction has unconfirmed parents used as its inputs\n\nThe effective fee rate is calculated as `MIN(own_fee/own_vsize, (own_fee+ancestor_fee)/(own_vsize+ancestor_vsize))`.\n\n\u003e The mempool fields may be temporarily unavailable if an error is encountered while syncing the mempool entries.\n\u003e This should be a rare event, for example if Bitcoin Core crashes, but API clients should prepare for the possibility.\n\n#### `GET /tx/:txid`\n\nGet the transaction in the [wallet transaction format](#wallet-transaction-format).\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\n*Available for wallet transactions only.*\n\nExample:\n```\n$ curl localhost:3060/tx/e700187477d262f370b4f1dfd17c496d108524ee2d440a0b7e476f66da872dda\n{\n  \"txid\": \"e700187477d262f370b4f1dfd17c496d108524ee2d440a0b7e476f66da872dda\",\n  \"block_height\": 113,\n  \"fee\": 141,\n  \"funding\": [\n    {\n      \"vout\": 1,\n      \"amount\": 949373,\n      \"address\": \"bcrt1qu04qqzwkjvya65g2agwx5gnqvgzwpjkr6q5jvf\",\n      \"scripthash\": \"6bf2d435bc4e020d839900d708f02c721728ca6793024919c2c5bc029c00f033\",\n      \"origin\": \"xjm8w0el/16\",\n      \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/16)#dtxjzdej\",\n      \"bip32_origins\": [ \"80e042a9/0/16\" ],\n      \"spent_by\": \"950cc16e572062fa16956c4244738b35ea7b05e16c8efbd6b9812d561d68be3a:0\"\n    }\n  ],\n  \"spending\": [\n    {\n      \"vin\": 0,\n      \"amount\": 1049514,\n      \"prevout\": \"70650243572b90705f7fe95c9f30a85a0cc55e4ea3159a8ada5f4d62d9841d7b:1\",\n      \"address\": \"bcrt1qxsvdm3jmwr79u67d82s08uykw6a82agzy42c6y\",\n      \"scripthash\": \"a55c30f4f7d79600d568bdfa0b4f48cdce4e59b6ffbf286e99856c3e8699740d\",\n      \"origin\": \"xjm8w0el/19\",\n      \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/19)#wjtzksqe\",\n      \"bip32_origins\": [ \"80e042a9/0/19\" ]\n    }\n  ],\n  \"balance_change\": -100141\n}\n```\n\u003c/details\u003e\n\n#### `GET /tx/:txid/verbose`\n\nGet the transaction in JSON as formatted by [bitcoind's `getrawtransaction`](https://bitcoincore.org/en/doc/0.19.0/rpc/rawtransactions/getrawtransaction/) with `verbose=true`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nAvailable for all transactions that bitcoind is aware of (i.e. not pruned).\nRequires `txindex` to work for non-wallet transactions.\n\nExample:\n```\n$ curl localhost:3060/tx/1f2e3c4cee8ea127a79c5dbc951f1e005671a1e8bf385e791ff95b780deda68f/verbose\n{\n  \"blockhash\": \"7a9b99f78066f22a26c56b2035445285a5a992fc19719c9c27f2255f20f1f2f8\",\n  \"blocktime\": 1589376781,\n  \"confirmations\": 1,\n  \"hash\": \"0ed38dcfe3de4e96852631d9c1f692db581513aa51845976a7097e618a1002a7\",\n  \"hex\": \"0200000000010132d8a06f451ca6e8487a25343586f4186faecbbd185c324f5c3cfe674d1385460100000000feffffff0200e1f505000000001600143e730c6086a8417e2532356bd43e34b86c0f6055d6df0a1e010000001600146873ceae00e9140ea09b71963ee0e493b678a0ec02473044022025500722fd65172f8f7fe448ee484e5659aa9ff23d055546480588840b8eef40022023509d517614fa0c51d55511826250ead7d44ada9d9d6671837f44e8088d678b012102b3ce722e57fa6b66985154305e3d06831976499cf9f1db0c4e30450c1d5d7724af000000\",\n  \"in_active_chain\": true,\n  \"locktime\": 175,\n  \"size\": 222,\n  \"time\": 1589376781,\n  \"txid\": \"1f2e3c4cee8ea127a79c5dbc951f1e005671a1e8bf385e791ff95b780deda68f\",\n  \"version\": 2,\n  \"vin\": [ ... ],\n  \"vout\": [ ... ],\n  \"vsize\": 141,\n  \"weight\": 561\n}\n```\n\u003c/details\u003e\n\n#### `GET /tx/:txid/hex`\n\nGet the raw transaction formatted as a hex string.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nExample:\n```\n$ curl localhost:3060/tx/1f2e3c4cee8ea127a79c5dbc951f1e005671a1e8bf385e791ff95b780deda68f/hex\n0200000000010132d8a06f451ca6e8487a25343586f4186faecbbd185c324f5c3cfe674d1385460100000000feffffff0200e1f505000000001600143e730c6086a8417e2532356bd43e34b86c0f6055d6df0a1e010000001600146873ceae00e9140ea09b71963ee0e493b678a0ec02473044022025500722fd65172f8f7fe448ee484e5659aa9ff23d055546480588840b8eef40022023509d517614fa0c51d55511826250ead7d44ada9d9d6671837f44e8088d678b012102b3ce722e57fa6b66985154305e3d06831976499cf9f1db0c4e30450c1d5d7724af000000\n```\n\n\u003c/details\u003e\n\n#### `GET /tx/:txid/proof`\n\nGet the merkle inclusion proof for the transaction.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned in [bitcoind's `merkleblock`](https://developer.bitcoin.org/reference/p2p_networking.html#merkleblock) format.\n\nExample:\n```\n$ curl localhost:3060/tx/1f2e3c4cee8ea127a79c5dbc951f1e005671a1e8bf385e791ff95b780deda68f/proof\n\n010000302d2659e4f39beb46eeef8579841250550a78d2a4fc2d53022a3ac0c069dbe865a987be21bcaae85f1423967b22c09b61ab00fd2c5aeccc247ef8ab421a960f950df7bb5effff7f20030000000400000003e7e777f5557142e8725218ae37547e1834a0466d5bb63952a7915d9cdc7adf392bb0a723f73dc23b52b7bd2641fb22d283b7c8a863b6dd012c64243b5da66b418fa6ed0d785bf91f795e38bfe8a17156001e1f95bc5d9ca727a18eee4c3c2e1f0115\n```\n\n\u003c/details\u003e\n\n#### `GET /txs`\n#### `GET /txs/since/:block-height`\n\nGet all wallet transactions confirmed at or after `block-height`, plus all unconfirmed transactions,\nfor all tracked addresses.\n\n`GET /txs` is an alias for `GET /txs/since/0`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned in the [wallet transaction format](#wallet-transaction-format). Sorted with oldest first.\n\nExample:\n```\n$ curl localhost:3060/txs\n[\n  {\n    \"txid\": \"e700187477d262f370b4f1dfd17c496d108524ee2d440a0b7e476f66da872dda\",\n    \"funding\": [ .. ],\n    \"spending\": [ .. ],\n    ...\n  },\n  ...\n]\n```\n\n\u003c/details\u003e\n\n#### `GET /txs/since/:block-height/compact`\n\nGet a compact minimal representation of all wallet transactions since `block-height`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturns a simple JSON array of `[txid, block_height]` tuples, where `block_height` is null for unconfirmed transactions. Sorted with oldest first.\n\nExample:\n```\n$ curl localhost:3060/txs/since/105/compcat\n[\n  [\"859d5c41661426ab13a7816b9e845a3353b66f00a3c14bc412d20f87dcf19caa\", 105],\n  [\"3c3c8722b493bcf43adab323581ea1da9f9a9e79628c0d4c89793f7fe21b68cf\", 107],\n  [\"e51414f57bdee681d48a6ade696049c4d7569a062278803fb7968d9a022c6a96\", null],\n  ...\n]\n```\n\n\u003c/details\u003e\n\n#### `POST /tx`\n\nBroadcast a raw transaction to the Bitcoin network.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturns the `txid` on success.\n\nBody parameters:\n- `tx_hex` - the raw transaction encoded as a hex string\n\nExample:\n\n```\n$ curl -X POST localhost:3060/tx -H 'Content-Type: application/json' \\\n       -d '{\"tx_hex\":\"\u003chex-serialized-tx\u003e\"}'\n\n33047288f0502eb3f2ad0729f6cfa24a8db87842f9c9a8eba7c0dbfaf7ea75b4\n```\n\n\u003c/details\u003e\n\n### Addresses, Scripthashes \u0026 Keys\n\n#### `GET /address/:address`\n#### `GET /scripthash/:scripthash`\n#### `GET /wallet/:checksum/:index`\n\n\nGet basic information for the provided address, scripthash or descriptor index.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned fields:\n- `address`\n- `scripthash`\n- `origin` - descriptor wallet origin information in `\u003cchecksum\u003e/\u003cindex\u003e` format\n- `desc` - the descriptor for this address\n- `bip32_origins` - an array of bip32 origins for the derived keys at this index\n\nExample:\n```\n$ curl localhost:3060/address/bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg\n{\n  \"address\": \"bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg\",\n  \"scripthash\": \"4c1af417b86da82af887678c36c93d3d8de15a5930f326600e533bf3ab9d0339\",\n  \"origin\": \"xjm8w0el/10\",\n  \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/10)#v9use49n\",\n  \"bip32_origins\": [ \"80e042a9/0/10\" ]\n}\n```\n\n\u003c/details\u003e\n\n#### `GET /address/:address/stats`\n#### `GET /scripthash/:scripthash/stats`\n#### `GET /wallet/:checksum/:index/stats`\n\nGet basic information and stats for the provided address, scripthash or descriptor index.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned fields:\n- scriptPubKey fields\n  - `address`\n  - `scripthash`\n  - `origin`\n  - `desc`\n  - `bip32_origins`\n- `tx_count`\n- `confirmed_balanace`\n- `unconfirmed_balanace`\n\nExample:\n```\n$ curl localhost:3060/address/bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg/stats\n{\n  \"address\": \"bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg\",\n  \"origin\": \"xjm8w0el/10\",\n  ...,\n  \"tx_count\": 2,\n  \"confirmed_balance\": 120050000,\n  \"unconfirmed_balance\": 0\n}\n```\n\u003c/details\u003e\n\n#### `GET /address/:address/utxos`\n#### `GET /scripthash/:scripthash/utxos`\n#### `GET /wallet/:checksum/:index/utxos`\n\nGet the list of unspent transaction outputs owned by the provided address, scripthash or descriptor index.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nQuery string parameters:\n- `min_conf` - minimum number of confirmations, defaults to 0\n- `include_unsafe` - whether to include outputs that are not safe to spend (unconfirmed from outside keys or with RBF), defaults to true\n\nExamples:\n```\n$ curl localhost:3060/address/bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg/utxos\n[\n  {\n    \"txid\": \"664fba0bcc745b05fda0fbf1f6fb6fc003afd82e64caad2c9fea0e3d566f6a58\",\n    \"vout\": 1,\n    \"amount\": 1500000,\n    \"address\": \"bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg\",\n    \"scripthash\": \"4c1af417b86da82af887678c36c93d3d8de15a5930f326600e533bf3ab9d0339\",\n    \"origin\": \"xjm8w0el/10\",\n    \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/10)#v9use49n\",\n    \"bip32_origins\": [ \"80e042a9/0/10\" ],\n    \"block_height\": 114,\n    \"spent_by\": null\n  },\n  {\n    \"txid\": \"3a1c4dea8d376a2762dd9be1d39f7f13376b4c9ccb961725574689183c20cb90\",\n    \"vout\": 1,\n    \"amount\": 1440000,\n    \"address\": \"bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg\",\n    \"scripthash\": \"4c1af417b86da82af887678c36c93d3d8de15a5930f326600e533bf3ab9d0339\",\n    \"origin\": \"xjm8w0el/10\",\n    \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/10)#v9use49n\",\n    \"bip32_origins\": [ \"80e042a9/0/10\" ],\n    \"block_height\": 115,\n    \"spent_by\": null\n  },\n  ...\n]\n```\n\u003c/details\u003e\n\n#### `GET /address/:address/txs`\n#### `GET /scripthash/:scripthash/txs`\n#### `GET /wallet/:checksum/:index/txs`\n\nGet the list of all transactions in the history of the provided address, scripthash or descriptor index.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned in the [wallet transaction format](#wallet-transaction-format).\n\nExample:\n```\n$ curl localhost:3060/address/bc1qaxlg48awxth5k72ltgrjp6qyegzdmfkfupyhhg/txs\n[\n  {\n    \"txid\": \"859d5c41661426ab13a7816b9e845a3353b66f00a3c14bc412d20f87dcf19caa\",\n    \"block_height\": 654835,\n    \"funding\": [ ... ],\n    \"spending\": [ ...],\n    \"balance_change\": 11000000\n  },\n  ...\n]\n```\n\n\u003c/details\u003e\n\n#### `GET /address/:address/txs/compact`\n#### `GET /scripthash/:scripthash/txs/compact`\n#### `GET /wallet/:checksum/:index/txs/compact`\n\nGet a compact minimal representation of the history of the provided address, scripthash or descriptor index.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturns a simple JSON array of `[txid, block_height]` tuples, where `block_height` is null for unconfirmed transactions.\n\nExample:\n```\n$ curl localhost:3060/scripthash/c511375da743d7f6276db6cdaf9f03d7244c74d5569c9a862433e37c5bc84cb2/txs/minimal\n[\n  [\"859d5c41661426ab13a7816b9e845a3353b66f00a3c14bc412d20f87dcf19caa\", 105],\n  [\"3c3c8722b493bcf43adab323581ea1da9f9a9e79628c0d4c89793f7fe21b68cf\", 107],\n  [\"e51414f57bdee681d48a6ade696049c4d7569a062278803fb7968d9a022c6a96\", null],\n  ...\n]\n```\n\n\u003c/details\u003e\n\n\n### Outputs\n\n#### Output format\n\n- `txid` - the transaction funding this output\n- `vout` - the output index\n- `amount` - the output amount in satoshis\n- scriptPubKey fields\n  - `address` - the address funded by this output\n  - `scripthash` - the scripthash funded by this output\n  - `origin` - descriptor wallet origin information in `\u003cchecksum\u003e/\u003cindex\u003e` format\n  - `desc` - the descriptor for the funded script\n  - `bip32_origins` - an array of bip32 origins for this script keys\n- `block_height` - the confirming block height or `null` for unconfirmed transactions\n- `spent_by` - the transaction input spending this output in `txid:vin` format, or `null` for unspent outputs (only available with `track-spends`)\n\n#### `GET /txo/:txid/:vout`\n\nGet information about the specified transaction output.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\n*Available for wallet outputs only.*\n\nExample:\n```\n$ curl localhost:3060/txo/1b1170ac5996df9255299ae47b26ec3ad57c9801bc7bae68203b1222350d52fe/0\n{\n  \"txid\": \"1b1170ac5996df9255299ae47b26ec3ad57c9801bc7bae68203b1222350d52fe\",\n  \"vout\": 0,\n  \"amount\": 99791,\n  \"scripthash\": \"d7a6ac0b7af9fe218f24019dc2fe7919bd14fb56694056528464326a44917d20\",\n  \"address\": \"bc1qrkud59a02lacfsa8hlp6yhg7qed30f2w7g2eh3\",\n  \"origin\": \"xjm8w0el/32,\n  \"desc\": \"wpkh(xpub661MyMwAqRbcEhsxS9g2qyYKSGA3seqWVNhmVhU27ddQx952PaZ6G4V26msGKrqYBjoBRwFyzaucPUkhw7DNaeMVUYJV1bqosxzVxToJdcy/0/32)#v9use49n\",\n  \"bip32_origins\": [ \"80e042a9/0/32\" ],\n  \"block_height\": 654712,\n  \"spent_by\": null\n}\n```\n\u003c/details\u003e\n\n#### `GET /utxos`\n\nGet all unspent wallet outputs.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nQuery string parameters:\n- `min_conf` - minimum number of confirmations, defaults to 0\n- `include_unsafe` - whether to include outputs that are not safe to spend (unconfirmed from outside keys or with RBF), defaults to true\n\nExample:\n```\n$ curl localhost:3060/utxos?min_conf=1\n[\n  {\n    \"txid\": \"1973551cc7670237606561ba3f7579d46d38e7145a72cf6a55ff8975e7143fee\",\n    \"vout\": 0,\n    \"amount\": 99791,\n    ...\n  },\n  ...\n]\n```\n\u003c/details\u003e\n\n\u003e Also see: [`GET /address/:address/utxos`](#get-addressaddressutxos)\n\n\n### Blocks\n\n#### `GET /block/tip`\n\nGet the current tip of the block chain.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned fields:\n- `height`\n- `hash`\n\nExample:\n```\n$ curl localhost:3060/block/tip\n{\n  \"height\": 176,\n  \"hash\": \"7a9b99f78066f22a26c56b2035445285a5a992fc19719c9c27f2255f20f1f2f8\"\n}\n```\n\n\u003c/details\u003e\n\n#### `GET /block/:hash`\n\nGet the block header of the specified block hash as formatted by [bitcoind's `getblockheader`](https://bitcoincore.org/en/doc/0.19.0/rpc/blockchain/getblockheader/) with `verbose=true`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nExample:\n```\n$ curl localhost:3060/block/65e8db69c0c03a2a02532dfca4d2780a555012847985efee46eb9bf3e459262d\n{\n  \"hash\": \"65e8db69c0c03a2a02532dfca4d2780a555012847985efee46eb9bf3e459262d\",\n  \"confirmations\": 2,\n  \"height\": 175,\n  \"version\": 805306369,\n  \"versionHex\": \"30000001\",\n  \"merkleroot\": \"b7a646abfd377964da19837c454e9d2d30c61b9bc22246c8589f7e80fda1a3e5\",\n  \"time\": 1589360866,\n  \"mediantime\": 1589269430,\n  \"nonce\": 0,\n  \"bits\": \"207fffff\",\n  \"difficulty\": 4.6565423739069247e-10,\n  \"chainwork\": \"0000000000000000000000000000000000000000000000000000000000000160\",\n  \"nTx\": 1,\n  \"previousblockhash\": \"26d435bdea859667e9d396ad0f28b74e6fd98ca6c737f1bd895c3b6539b4ee76\",\n  \"nextblockhash\": \"7a9b99f78066f22a26c56b2035445285a5a992fc19719c9c27f2255f20f1f2f8\"\n}\n```\n\u003c/details\u003e\n\n#### `GET /block/:hash/hex`\n\nGet the block header of the specified block hash as a hex string.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nExample:\n```\n$ curl localhost:3060/block/65e8db69c0c03a2a02532dfca4d2780a555012847985efee46eb9bf3e459262d/hex\n\n0100003076eeb439653b5c89bdf137c7a68cd96f4eb7280fad96d3e9679685eabd35d426e5a3a1fd807e9f58c84622c29b1bc6302d9d4e457c8319da647937fdab46a6b7e2b8bb5effff7f2000000000\n```\n\n\u003c/details\u003e\n\n#### `GET /block/:height`\n\nGet the block hash at the specified block height.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nIssues a 307 redirection to the block url (`/block/:hash`) *and* responds with the block hash in the responses body.\n\nExample:\n```\n$ curl localhost:3060/block/104\n\u003c HTTP/1.1 307 Temporary Redirect\n\u003c Location: /block/117324e95584f14ba767610f4ef9c939004b02c9f3881a94f46c0772d8e9b365\n117324e95584f14ba767610f4ef9c939004b02c9f3881a94f46c0772d8e9b365\n\n# Follow the redirect to get the block header json\n\n$ curl --location localhost:3060/block/104\n{\n  \"hash\": \"117324e95584f14ba767610f4ef9c939004b02c9f3881a94f46c0772d8e9b365\",\n  \"confirmations\": 73,\n  \"height\": 104,\n  ...\n}\n```\n\u003c/details\u003e\n\n### Mempool \u0026 Fees\n\n#### `GET /mempool/histogram`\n\nGet the mempool feerate distribution histogram.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturns an array of `(feerate, vsize)` tuples, where each entry's `vsize` is the total vsize of transactions\npaying more than `feerate` but less than the previous entry's `feerate` (except for the first entry, which has no upper bound).\nThis matches the format used by the Electrum RPC protocol for `mempool.get_fee_histogram`.\n\nCached for 2 minutes.\n\nExample:\n\n```\n$ curl localhost:3060/mempool/histogram\n\n[[53.01, 102131], [38.56, 110990], [34.12, 138976], [24.34, 112619], [3.16, 246346], [2.92, 239701], [1.1, 775272]]\n```\n\n\u003e In this example, there are transactions weighting a total of 102,131 vbytes that are paying more than 53 sat/vB,\n110,990 vbytes of transactions paying between 38 and 53 sat/vB, 138,976 vbytes paying between 34 and 38, etc.\n\n\u003c/details\u003e\n\n#### `GET /fee-estimate/:target`\n\nGet the feerate estimate for confirming within `target` blocks.\nUses bitcoind's `smartestimatefee`.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nReturned in `sat/vB`, or `null` if no estimate is available.\n\nCached for 2 minutes.\n\nExample:\n```\n$ curl localhost:3060/fee-estimate/3\n\n5.61\n```\n\n\u003c/details\u003e\n\n\n### Server-Sent Events\n\n#### Event categories\n\n- `ChainTip(block_height, block_hash)` - emitted whenever a new block extends the best chain.\n- `Reorg(block_height, prev_block_hash, curr_block_hash)` - indicates that a re-org was detected on `block_height`, with the previous block hash at this height and the current one.\n- `Transaction(txid, block_height)` - emitted for new transactions as well as transactions changing their confirmation status (typically from unconfirmed to confirmed, possibly the other way around in case of reorgs).\n- `TransactionReplaced(txid)` - indicates that the transaction conflicts with another transaction and can no longer be confirmed (aka double-spent).\n- `TxoFunded(funding_txid:vout, scripthash, amount, block_height)` - emitted when an unspent wallet output is created (for new transactions as well as confirmation status changes).\n- `TxoSpent(spending_txid:vin, scripthash, prevout, block_height)` - emitted when a wallet output is spent (for new transactions as well as confirmation status changes).\n\nFor unconfirmed transactions, `block_height` will be `null`.\n\n#### `GET /stream`\n\nSubscribe to a real-time [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) stream of indexer update notifications.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nQuery string parameters for filtering the event stream:\n- `category`\n- `scripthash`\n- `outpoint`\n\nExamples:\n```bash\n$ curl localhost:3060/stream\n\u003c HTTP/1.1 200 OK\n\u003c content-type: text/event-stream\n\ndata:{\"category\":\"ChainTip\",\"params\":[114,\"0a1a199aed012b280b36370e393867e03b46eb39b7130bb017a6757b6d4014ec\"]}\n\ndata:{\"category\":\"Transaction\",\"params\":[\"ac42d918b45351835bf9448bbd0c2f8e9ddad56a8bd118fe93919cc74bd0c487\",114]}\n\ndata:{\"category\":\"TxoFunded\",\"params\":[\"ac42d918b45351835bf9448bbd0c2f8e9ddad56a8bd118fe93919cc74bd0c487:0\",\"db576ad85b0f09680dfe3f3f7160be50c1a36db8b4949ffe21fe5b4564c1d42b\",10000000,114]}\n\ndata:{\"category\":\"TxoFunded\",\"params\":[\"ac42d918b45351835bf9448bbd0c2f8e9ddad56a8bd118fe93919cc74bd0c487:1\",\"48138c88b8cb17544ac2450c4bd147106a9f773d6cf2b7f31a5a9dde75a8387a\",399999856,114]}\n\ndata:{\"category\":\"TxoSpent\",\"params\":[\"ac42d918b45351835bf9448bbd0c2f8e9ddad56a8bd118fe93919cc74bd0c487:0\",\"5f26eb39e19b0bef205bb451082f941cef0707d38949d3ffe51f5614fab70f5d\",\"aa5b889f6cf1c314bc02c5187f31d0d5ff56f568c85a384027cb155fdc377069:1\",114]}\n```\n\n```\n$ curl localhost:3060/stream?category=ChainTip\n\ndata:{\"category\":\"ChainTip\",\"params\":[114,\"0a1a199aed012b280b36370e393867e03b46eb39b7130bb017a6757b6d4014ec\"]}\n\ndata:{\"category\":\"ChainTip\",\"params\":[115,\"1c293df0c95d94a345e7578868ee679c9f73b905ac74da51e692af18e0425387\"]}\n```\n\n```\n$ curl localhost:3060/stream?outpoint=aa5b889f6cf1c314bc02c5187f31d0d5ff56f568c85a384027cb155fdc377069:1\n\ndata:{\"category\":\"TxoFunded\",\"params\":[\"43916225aeadc3d6f17ffd5cdcc72fe81508eab4de66532507bc032b50c89732:0\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",99900000,null]}\n\ndata:{\"category\":\"TxoSpent\",\"params\":[\"0ac67648be03f7fd547a828b78b920cb73f8c883320f30d770fb14d59655b125:0\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",\"43916225aeadc3d6f17ffd5cdcc72fe81508eab4de66532507bc032b50c89732:0\",null]}\n```\n\n\u003c/details\u003e\n\n#### `GET /address/:address/stream`\n#### `GET /scripthash/:scripthash/stream`\n#### `GET /wallet/:checksum/:index/stream`\n\nSubscribe to a real-time notification stream of `TxoFunded`/`TxoSpent` events for the provided address, scripthash or descriptor index.\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\n\nThis is equivalent to `GET /stream?scripthash=\u003cscripthash\u003e`.\n\nExample:\n```\n$ curl localhost:3060/address/bcrt1qxs3mrrre37rphadyg4wu0zk4t33qklv0u0gmps/stream\n\ndata:{\"category\":\"TxoFunded\",\"params\":[\"bb94b1547397cd89441edd74d0581913d8bb3005d070fa6f9744af44f654c25a:0\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",77700000,115]}\n\ndata:{\"category\":\"TxoFunded\",\"params\":[\"a0fe8a8fc855a9deaed533cf5f2053c77d640ff5f50a7c44d1cca314d4e00e5d:0\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",100000,116]}\n\ndata:{\"category\":\"TxoSpent\",\"params\":[\"a3bc61a974b113223c336c866bc656cd23481d1466e063e46930a5983e70c20d:0\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",\"a0fe8a8fc855a9deaed533cf5f2053c77d640ff5f50a7c44d1cca314d4e00e5d:0\",117]}\n\ndata:{\"category\":\"TxoSpent\",\"params\":[\"a3bc61a974b113223c336c866bc656cd23481d1466e063e46930a5983e70c20d:1\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",\"bb94b1547397cd89441edd74d0581913d8bb3005d070fa6f9744af44f654c25a:0\",117]}\n```\n\u003c/details\u003e\n\n#### Catching up with missed events \u0026 re-org detection\n\nTo catch-up with historical events that your app missed while being down, you can specify the `synced-tip` query string parameter with the `\u003cblock-height\u003e:\u003cblock-hash\u003e` of the latest block known to be processed.\n\nIf the `synced-tip` is still part of the best chain, this will return all historical  `Transaction`, `TxoFunded` and `TxoSpent` events that occurred after `block-height` (exclusive, ordered with oldest first, unconfirmed included at the end), followed by a *single* `ChainTip` event with the currently synced tip, followed by a stream of real-time events.\n\nIf the `synced-tip` is no longer part of the best chain, a `410 Gone` error will be returned indicating that a reorg took place.\nOne way to recover from reorgs is to re-sync since `N` blocks before the orphaned `synced-tip` and consider any entries that\nno longer show up as double-spent (where `N` is large enough such that reorgs deeper than it are unlikely).\n\nYou can specify `synced-tip` with just the height to skip reorg detection (for example, `0` to get all events since the genesis block).\n\n\u003cdetails\u003e\u003csummary\u003eExpand...\u003c/summary\u003e\u003cp\u003e\u003c/p\u003e\nExample:\n\n```\n# Start by syncing everything from the beginning\n$ curl localhost:3060/stream?synced-tip=0\ndata:{\"category\":\"TxoFunded\",\"params\":[\"ac42d918b45351835bf9448bbd0c2f8e9ddad56a8bd118fe93919cc74bd0c487:1\",\"48138c88b8cb17544ac2450c4bd147106a9f773d6cf2b7f31a5a9dde75a8387a\",399999856,114]}\ndata:{\"category\":\"ChainTip\",\"params\":[120,\"5cc1fb1153f8eb12d445d0db06e96bbb39c45b8ed22d4f0de718aa6b0ef00cd1\"]}\n\n# Oops, we got disconnected! Let's try again with the last `ChainTip` we heard of\n$ curl localhost:3060/stream?synced-tip=120:5cc1fb1153f8eb12d445d0db06e96bbb39c45b8ed22d4f0de718aa6b0ef00cd1\ndata:{\"category\":\"TxoSpent\",\"params\":[\"a3bc61a974b113223c336c866bc656cd23481d1466e063e46930a5983e70c20d:1\",\"97e9cc06a9a9d95a7ff26a9e5fdf9e1836792a3337c0ff718c88e012feb217bd\",\"bb94b1547397cd89441edd74d0581913d8bb3005d070fa6f9744af44f654c25a:0\",122]}\ndata:{\"category\":\"ChainTip\",\"params\":[130,\"57d17db78d5017c89e86e863a7397c02027f09327222feb72cdfe8372644c589\"]}\n\n# Disconnected again, this time while a reorg happened\n$ curl localhost:3060/stream?synced-tip=130:57d17db78d5017c89e86e863a7397c02027f09327222feb72cdfe8372644c589\n\u003c HTTP/1.1 410 Gone\nReorg detected at height 130 (previous=57d17db78d5017c89e86e863a7397c02027f09327222feb72cdfe8372644c589 current=43b482862ba3fc883187f534be1971186b11c534494129397e8a2b4faf4bf2f4)\n\n# Re-sync events from height 110 (N=20 blocks before the reported reorg)\n$ curl localhost:3060/stream?synced-tip=110\n```\n\nThe `synced-tip` functionality also supports the SSE `Last-Event-ID` header. This makes it work transparently with the [built-in automatic reconnection mechanism](https://kaazing.com/kaazing.io/doc/understanding-server-sent-events/#last-event-id). You'll still need to manually persist and specify the `synced-tip` in case your app restarts.\n\n\u003c/details\u003e\n\n### Miscellaneous\n\n#### `POST /sync`\n\nTrigger an indexer sync. See [Real-time updates](#real-time-updates).\n\n#### `GET /dump`\n\nDumps the contents of the index store as JSON.\n\n#### `GET /debug`\n\nDumps the contents of the index store as a debug string.\n\n#### `GET /banner.txt`\n\nGet the welcome banner text.\n(see [live example here](https://bwt.dev/banner.txt), or a [static one here](https://gist.githubusercontent.com/shesek/4986c4291df1a7c6de62c20bc72e58bf/raw/42539cd10f1836ae511f4c2ec7b4fc82ad52252a/bwt-welcome-banner.txt))\n\n## Web Hooks\n\nYou can set `--webhook-url \u003curl\u003e` to have bwt send push notifications as a `POST` request to the provided `\u003curl\u003e`. Requests will be sent with a JSON-serialized *array* of one or more index updates as the body.\n\nIt is recommended to include a secret key within the URL to verify the authenticity of the request.\n\nYou can specify multiple `--webhook-url` to notify all of them.\n\nNote that bwt currently attempts to send the webhook request once and does not retry in case of failures.\nIt is recommended to occasionally catch up using the [`GET /txs/since/:block-height`](#get-txssinceblock-height) or\n[`GET /stream`](#get-stream) endpoints (see [\"Catching up with missed events\"](#catching-up-with-missed-events--re-org-detection)).\n\nTip: services like [webhook.site](https://webhook.site/) or [requestbin](http://requestbin.net/) can come in handy for debugging webhooks. (needless to say, for non-privacy-sensitive regtest/testnet use only)\n\n\u003e If you're building bwt from source, you'll need to set `--features webhooks` to enable web hooks support. This will also require to `apt install libssl-dev pkg-config`.\n\u003e\n\u003e The pre-built binaries ([except for ARM](https://github.com/bwt-dev/bwt/issues/52)) and the `shesek/bwt` docker image come with webhooks support enabled by default.\n\n## Developing\n\n### Developer Resources\n\nTo integrate bwt into non-Rust software, check out [libbwt](https://github.com/bwt-dev/libbwt) and [libbwt-jni](https://github.com/bwt-dev/libbwt-jni).\n\nDocumentation for the public Rust API is [available on docs.rs](https://docs.rs/bwt).\n\nA yuml diagram showing how the big pieces interact together is [available here](https://yuml.me/edit/39229813).\n\nAn example of initializing bwt and issuing queries against its db from Rust is available at [`examples/use-from-rust.rs`](examples/use-from-rust.rs).\n(Note that the Rust API provides weaker backwards compatibility guarantees compared to the HTTP API.)\n\nAn example JavaScript client utilizing the HTTP API for wallet tracking\nis available at [`examples/wallet-tracker.js`](https://github.com/bwt-dev/bwt/blob/master/examples/wallet-tracker.js).\n\n\n### Development environment\n\nTo quickly setup a development environment, you can use [`scripts/dev-env.sh`](https://github.com/bwt-dev/bwt/blob/master/scripts/dev-env.sh) to create a bitcoind regtest network and two Electrum wallets, fund the wallets, start bwt with tracking for both wallets' xpubs, and start the Electrum GUI.\n\nTo use it, simply run `$ ./scripts/dev-env.sh` from the root directory with `bitcoind`, `bitcoin-cli` and `electrum` installed in your `PATH`.\n\nYou can set `FEATURES` to specify which features to enable (see below) or set `NO_GUI=1` to leave the Electrum wallet running in daemon mode without starting the GUI.\n\nIf you have [`cargo watch`](https://github.com/passcod/cargo-watch) installed, it'll be used to watch for changes and automatically restart bwt.\n\n### Features\n\nbwt has 7 optional features: `cli`, `http`, `electrum`, `webhooks`, `track-spends`, `proxy`, `ffi` and `extra`.\n\nAll are enabled by default except for `webhooks` and `ffi`.\n\nIf you're working on code that is unrelated to the HTTP API, it is faster to build without the `http` feature.\n\nYou can use `scripts/check.sh` to run `cargo check` for some feature combos. This is important to ensure no errors were introduced for feature combos that you didn't use.\n\n### Tests\n\nEnd-to-end integration tests can be run with [`./test/tests.sh`](https://github.com/bwt-dev/bwt/blob/master/test/tests.sh).\nThe tests deploy a regtest network, a bwt instance and an Electrum wallet connected to it (in headless mode), then run some basic tests using the Electrum client and against the HTTP REST API.\n\nRun with `bash -x test/tests.sh -v` to get more verbose output.\n\n### Contributions\n\nAre welcome!\n\nThe only guideline is to use `cargo fmt`.\n\nYou can check out [the list of enhancement issues](https://github.com/bwt-dev/bwt/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement).\n\n## Reproducible builds\n\nThe builds can be reproduced in a Docker container environment as follows:\n\n```\n$ git clone https://github.com/bwt-dev/bwt \u0026\u0026 cd bwt\n$ git checkout \u003ctag\u003e\n$ git verify-commit HEAD\n\n# Linux, Windows \u0026 ARMv7/v8\n$ docker build -t bwt-builder - \u003c scripts/builder.Dockerfile\n$ docker run -it -u `id -u` -v `pwd`:/usr/src/bwt bwt-builder\n\n# Mac OSX (cross-compiled via osxcross)\n$ docker build -t bwt-builder-osx - \u003c scripts/builder-osx.Dockerfile\n$ docker run -it -u `id -u` -v `pwd`:/usr/src/bwt bwt-builder-osx\n\n$ sha256sum dist/*\n```\n\nThe builds are [reproduced on Travis CI](https://travis-ci.org/github/bwt-dev/bwt/branches) using the code from GitHub.\nThe SHA256 checksums are available under the \"Reproducible builds\" stage.\n\n## Thanks\n\n- [@romanz](https://github.com/romanz)'s [electrs](https://github.com/romanz/electrs) for the fantastic electrum server implementation that bwt is based on.\n\n- [@chris-belcher](https://github.com/chris-belcher)'s [electrum-personal-server](https://github.com/chris-belcher/electrum-personal-server) for inspiring this project and the personal tracker model.\n\n- [rust-bitcoin](https://github.com/rust-bitcoin), [rust-bitcoincore-rpc](https://github.com/rust-bitcoin/rust-bitcoincore-rpc) and the other incredible modules from the rust-bitcoin family.\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbwt-dev%2Fbwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbwt-dev%2Fbwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbwt-dev%2Fbwt/lists"}