{"id":13569736,"url":"https://github.com/C-Otto/rebalance-lnd","last_synced_at":"2025-04-04T06:31:11.754Z","repository":{"id":38354022,"uuid":"162001337","full_name":"C-Otto/rebalance-lnd","owner":"C-Otto","description":"A script that can be used to balance lightning channels of a lnd node","archived":false,"fork":false,"pushed_at":"2025-03-23T10:40:39.000Z","size":677,"stargazers_count":350,"open_issues_count":22,"forks_count":83,"subscribers_count":23,"default_branch":"main","last_synced_at":"2025-03-23T11:28:37.298Z","etag":null,"topics":["bitcoin","lightning-network","lnd"],"latest_commit_sha":null,"homepage":"","language":"Python","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/C-Otto.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2018-12-16T12:58:56.000Z","updated_at":"2025-03-23T10:40:41.000Z","dependencies_parsed_at":"2023-10-02T08:48:05.344Z","dependency_job_id":"f97e9f22-9ccc-4b37-95a6-a7562796e223","html_url":"https://github.com/C-Otto/rebalance-lnd","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/C-Otto%2Frebalance-lnd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/C-Otto%2Frebalance-lnd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/C-Otto%2Frebalance-lnd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/C-Otto%2Frebalance-lnd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/C-Otto","download_url":"https://codeload.github.com/C-Otto/rebalance-lnd/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247134401,"owners_count":20889396,"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","lightning-network","lnd"],"created_at":"2024-08-01T14:00:43.486Z","updated_at":"2025-04-04T06:31:11.289Z","avatar_url":"https://github.com/C-Otto.png","language":"Python","funding_links":[],"categories":["Applications"],"sub_categories":["Command Line Interfaces"],"readme":"# rebalance-lnd\n\nUsing this script you can easily rebalance individual channels of your `lnd` node by\nsending funds out one channel, through the lightning network, back to yourself.\n\nThis script helps you move funds between your channels so that you can increase the outbound liquidity in one channel,\nwhile decreasing the outbound liquidity in another channel.\nThis way you can, for example, make sure that all of your channels have enough outbound liquidity to send/route\ntransactions.\n\nBecause you are both the sender and the receiver of the corresponding transactions, you only have to pay for routing\nfees.\nAside from paid fees, your total liquidity does not change.\n\n## Installation\n\nThere are several options for installing rebalance-lnd.\n\n1. [Using Python](#using-python)\n1. [Using Docker](#using-docker)\n1. [Using Umbrel's app store](#using-umbrels-app-store)\n1. [Using the RaspiBolt manual installation guide on any Debian-based OS](#using-the-raspibolt-guide)\n\n### Using Python\n\n#### lnd\n\nThis script needs an active `lnd` (tested with v0.17.5, https://github.com/lightningnetwork/lnd) instance running.\nIf you compile `lnd` yourself, you need to include the `routerrpc` build tag:\n\nExample:\n`make tags=\"autopilotrpc signrpc walletrpc chainrpc invoicesrpc routerrpc\"`\n\nYou need to have admin rights to control this node.\nBy default, this script connects to `localhost:10009`, using the macaroon file in `~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon`.\nIf this does not help, it also tries to find the file in `~/umbrel/lnd/data/chain/bitcoin/mainnet/admin.macaroon`\n(or `~/umbrel/app-data/lightning/data/lnd/data/chain/bitcoin/mainnet/admin.macaroon`).\nIf you need to change this, please have a look at the optional arguments `--grpc` and `--lnddir`.\n\n#### rebalance-lnd itself\n\nYou need to download the files that are part of this project, for example using [git](https://git-scm.com/):\n\n```sh\ncd /some/where/\ngit clone https://github.com/C-Otto/rebalance-lnd.git\ncd rebalance-lnd/\n```\n\nAlternatively, you may also download the files in a ZIP file offered by GitHub:\nhttps://github.com/C-Otto/rebalance-lnd/archive/refs/heads/main.zip\n\n#### Python Dependencies\n\nYou need to install Python 3. You also need to install the gRPC dependencies which can be done by running:\n\n```sh\npip install -r requirements.txt\n```\n\nIf this fails, make sure you are running Python 3. You might want to try `pip3` instead of `pip`.\n\nTo test if your installation works, you can run `rebalance.py` without any arguments.\nDepending on your system, you can do this in one of the following ways:\n\n- `python3 rebalance.py`\n- `./rebalance.py`\n- `python rebalance.py`\n\n### Using Docker\n\nUsing the containerized version of rebalance-lnd spares you from the installation of python and its dependencies.\nYou start by fetching the latest version of the dedicated docker container.\n\n```sh\ndocker pull rebalancelnd/rebalance-lnd:latest\n```\n\nYou can now have the docker image interact with your lnd installation:\n\n```sh\ndocker run --rm --network=host --add-host=host.docker.internal:host-gateway -it -v /home/lnd:/root/.lnd rebalancelnd/rebalance-lnd --grpc host.docker.internal:10009\n```\n\nThe above command assumes `/home/lnd` is your lnd configuration directory. Please adjust as required.\n\n#### Note for Umbrel/Umbrel-OS users\n\nTo inject rebalance-lnd into your umbrel network you can run it using the following command line:\n\n```sh\ndocker run --rm --network=umbrel_main_network -it -v /home/umbrel/umbrel/app-data/lightning/data/lnd:/root/.lnd rebalancelnd/rebalance-lnd --grpc 10.21.21.9:10009\n```\n\nOptionally you can create an alias in your shell's environment file like so:\n\n```sh\nalias rebalance-lnd=\"docker run --rm --network=umbrel_main_network -it -v /home/umbrel/umbrel/app-data/lightning/data/lnd:/root/.lnd rebalancelnd/rebalance-lnd --grpc 10.21.21.9:10009\"\n```\n\nFor older versions of Umbrel please use `/home/umbrel/umbrel/lnd` instead of `/home/umbrel/umbrel/app-data/lightning/data/lnd`.\n\n### Using Umbrel's app store\n\nThe [`lightning-shell`](https://github.com/ibz/lightning-shell) app available in the Umbrel app store comes with rebalance-lnd installed and configured. It should just work out of the box!\n\n#### Note for BTCPayServer Users\n\nTo inject rebalance-lnd into your BTCPayServer network you can run it using the following command line:\n\n```sh\ndocker run --rm --network=generated_default -it -v /var/lib/docker/volumes/generated_lnd_bitcoin_datadir/_data:/root/.lnd rebalancelnd/rebalance-lnd --grpc lnd_bitcoin:10009\n```\n\nOptionally you can create an alias in your shell's environment file like so:\n\n```sh\nalias rebalance-lnd=\"docker run --rm --network=generated_default -it -v /var/lib/docker/volumes/generated_lnd_bitcoin_datadir/_data:/root/.lnd rebalancelnd/rebalance-lnd --grpc lnd_bitcoin:10009\"\n```\n\n## Updating\n\nIf you use docker, update the image running `docker pull rebalancelnd/rebalance-lnd:latest` again, otherwise follow these steps to update the python version:\n\nIf you already have a version of `rebalance-lnd` checked out via `git`, you can just use `git pull` to update to the\nlatest version. You may also delete everything and start over with a fresh installation, as the script does not store\nany data that needs to be kept.\n\nDo not forget to update the Python dependencies as described above.\n\n### Using the RaspiBolt guide\n\nIf you run a node on a Debian-based OS, you can follow the [RaspiBolt guide](https://raspibolt.org/guide/bonus/lightning/rebalance-lnd.html) that explains how to manually install, use, update and uninstall rebalance-lnd on your node.\n\n# Usage\n\n### List of channels\n\nRun `rebalance.py -l` (or `rebalance.py -l -i`) to see a list of channels which can be rebalanced.\nThis list only contains channels where you should increase the outbound liquidity (you can specify `--show-all` to see\nall channels).\n\nYou can also see the list of channels where the inbound liquidity should be increased by running `rebalance.py -l -o`.\n\nAs an example the following indicates a channel with around 17.7% of the funds\non the local side:\n\n```sh\nChannel ID:       11111111\nAlias:            The Best Node Ever\nPubkey:           012345[...]abcdef\nChannel Point:    abc0123[...]abc:0\nLocal ratio:      0.176\nFee rates:        123ppm (own), 456ppm (peer)\nCapacity:         5,000,000\nRemote available: 4,110,320\nLocal available:    883,364\nRebalance amount:   116,636\n[█████░░░░░░░░░░░░░░░░░░░░░░░]\n```\n\nBy sending 116,636 satoshis to yourself using this channel, an outbound liquidity of 1,000,000 satoshis can be achieved.\nThis number is shown as \"Rebalance amount\" (where negative amounts indicate that you need to increase your inbound\nliquidity).\n\nThe last line shows a graphical representation of the channel.\nThe total width is determined by the channel's capacity, where your largest channel (maximum capacity) occupies the full\nwidth of your terminal.\nThe bar (`█`) indicates the funds on the local side of the channel, i.e. your outbound liquidity.\n\n## Rebalancing a channel\n\n### Basic Scenario\n\nIn this scenario you already know what you want to do, possibly because you identified a channel with high\noutbound liquidity.\n\nLet us assume you want to move some funds from this channel to another channel with low outbound\nliquidity:\n\n- move 100,000 satoshis around\n- take those funds (plus fees) out of channel `11111111`\n- move those funds back into channel `22222222`\n\nYou can achieve this by running:\n\n```sh\nrebalance.py --amount 100000 --from 11111111 --to 22222222\n```\n\nThe script now tries to find a route through the lightning network that starts with channel `11111111` and ends with\nchannel `22222222`. If successful, you take 100,000 satoshis (plus fees) out of channel `11111111` (which means that you\ndecrease your outbound liquidity and increase your inbound liquidity). In return, you get 100,000 satoshis back through\nchannel `22222222` (which means that you increase your outbound liquidity and decrease your inbound liquidity).\n\n### Automatically determined amount\n\nIf you do not specify the amount, i.e. you invoke `rebalance.py --from 11111111 --to 22222222`, the script\nautomatically determines the amount.\nFor this two main constraints are taken into consideration:\n\nAfter the rebalance transaction is finished,\n\n- the destination channel (`22222222`) should have (up to) 1,000,000 satoshis outbound liquidity\n- the source channel (`11111111`) should have (at least) 1,000,000 satoshis outbound liquidity\n\nIf the source channel has enough surplus outbound liquidity, the script constructs a transaction that ensures\n1,000,000 satoshis of outbound liquidity in the destination channel.\nHowever, if the source channel does not have enough outbound liquidity, the amount is determined so that (after the\nrebalance transaction is performed) the source channel has 1,000,000 satoshis of outbound liquidity and the destination\nchannel has more outbound liquidity than before (but not necessarily 1,000,000 satoshis).\n\nNote that for smaller channels these criteria cannot be met.\nIf that is the case, a ratio of 50% is targeted instead: the destination channel receives up to 50% outbound\nliquidity, and for the sending channel at least 50% outbound liquidity are maintained.\n\n### Limiting the automatically determined amount\n\nIf you use both `-a` to specify an amount and `-A` (shorthand for `--adjust-amount-to-limits`), the computed amount is\nadjusted to the given amount. If, for example, you send funds to a channel that lacks 500,000sat to reach the\n`--min-local` value, the computed amount is 500,000sat. If you invoke the script with `-A -a 90000` this amount is\nreduced to 90,000sat. If the adjusted amount is below the `--min-amount` setting, the script stops.\n\nThis way, using both options (`-a xxx -A`) you can start a rebalance attempt with the given amount, which will only be\nattempted if it is necessary. Thus, you may want to run `./rebalance.py -t xxx -A -a 50000` in a loop or cron job to\nautomatically send up to 50,000sat to channel `xxx` until it has reached the `--min-local` limit. If the channel already\nsatisfies the `--min-local` limit, the script exits and does not attempt to send any funds.\n\n### Only specifying one channel\n\nInstead of specifying both `--from` and `--to`, you can also just pick one of those options.\nThe script then considers all of your other channels as possible \"partners\", still taking into account the constraints\ndescribed above.\n\nAs an example, if you run `rebalance.py --amount 100000 --to 22222222`, the script tries to find source channels\nthat, after sending 100,000 satoshis (plus fees), still have at least 1,000,000 satoshis of outbound liquidity.\nIn other words, the script does not send funds from already \"empty\" channels.\n\nLikewise, when only specifying `--from`, the script only considers target channels which still have at least 1,000,000\nsatoshis of outbound liquidity after receiving the payment.\n\nIf you also let the script determine the amount, e.g. you run `rebalance.py --to 22222222`, the script first\ncomputes the amount that is necessary to reach 1,000,000 satoshis of outbound liquidity in channel `22222222`,\nand then tries to find source channels for the computed amount.\n\n### Safety Checks and Limitations\n\nNote that, by default, nothing is done if the amount (either given or computed) is smaller than 10,000 satoshis.\nYou can change this number using `--min-amount`.\n\nFurthermore, a rebalance transaction is only sent if it is economically viable as described below.\nThis way, by default, you only send rebalance transactions that improve your node's situation, for example by providing\noutbound liquidity to channels where you charge a lot, and taking those funds out of channels where you charge less.\n\nTo protect you from making mistakes, in the fee computation (described below) the fee rate of the destination channel\nis capped at 2,000ppm (which corresponds to a 0.2% fee), even if the channel is configured with a higher fee rate.\n\n## Fees\n\nIn order for the network to route your rebalance transaction, you have to pay fees.\nIn addition to the fees charged by the nodes routing your transaction, two other values are taken into account:\n\n1. The fee you would earn if, instead of sending the funds out of the source channel as part of the rebalance transaction, your node is paid to forward the amount\n2. The fee you would earn if, after the rebalance transaction is done, your node forwards the amount through the destination channel\n\nThe first bullet point describes opportunity/implicit costs.\nIf you take lots of funds out of the source channel, you cannot use those funds to earn routing fees via that channel.\nAs such, taking funds out of a channel where you configured a high fee rate can be considered costly.\n\nThe second bullet points describes future earnings.\nIf you send funds to the destination channel and increase your outbound liquidity in that channel, you might earn fees\nfor routing those funds.\nAs such, increasing the outbound liquidity of the destination is a good idea, assuming the fee rate configured for the\ndestination channel is higher than the fee rate you configured for the source channel.\nHowever, keep in mind that you will only earn those fees if your node actually forwards the funds via the channel!\n\nThe rebalance transaction is not performed if the transaction fees plus the implicit costs (1) are higher than the\npossible future earnings (2).\n\n**If you really want to, you may disable these safety checks with `--reckless`.**\n\n### Example\n\nYou have lots of funds in channel `11111111` and nothing in channel `22222222`.\nYou would like to send funds through channel `11111111` (source channel) through the lightning network, and finally\nback into channel `22222222`.\nThis incurs a transaction fee you would have to pay for the transaction.\n\nFurthermore, if in the future there is demand for your node to route funds\nthrough channel `11111111`, you cannot do that as much (because you decreased your outbound liquidity in the channel).\nThe associated fees are the implicit cost (1).\n\nFinally, you send funds into channel `22222222` in the hope that later on someone requests your node to forward funds\nfrom your own node through channel `22222222` towards the peer at the other end, so that you can earn fees for this.\nThese fees are the possible future income (2).\n\n### Fee Factor\n\nThe value set with `--fee-factor` is used to scale the future income used in the computation outlined above.\nAs such, you can fool the script into believing that the fee rate configured for the destination channel is\nhigher (fee factor \u003e 1) or lower (fee factor \u003c 1) than it actually is.\n\nAs such, if you set `--fee-factor` to a value higher than 1, more routes are considered.\nAs an example, with `--fee-factor 1.5` you can include routes that cost up to 150% of the future income.\n\nWith values smaller than 1 only cheaper routes are considered.\n\n### Fee Limit\n\nUnrelated to `--fee-factor` (which is the default, with a value of 1), you can also specify an absolute fee\nlimit using `--fee-limit`. If you decide to do so, only routes that cost up to the given number (in satoshis) are\nconsidered.\n\nNote that the script rejects routes/channels that are deemed uneconomical based on the configured fee rates\n(i.e. with `--fee-factor` set to 1) (as explained above).\n\n### Fee Rate (ppm) Limit\n\nYou can use `--fee-ppm-limit` as another alternative to specify a fee limit.\nIn this case the amount sent as part of the rebalance is considered, so that the fee is at most\n\n```sh\namount * fee-ppm-limit / 1_000_000\n```\n\nNote that the script rejects routes/channels that are deemed uneconomical based on the configured fee rates\n(i.e. with `--fee-factor` set to 1) (as explained above).\n\n### Warning\n\nTo determine the future income, the fee rate you configured for the destination channel is used in the computation.\nAs such, if you set an unrealistic fee rate that will not lead to forward transactions, you would allow more expensive\nrebalance transactions without earning anything in return.\nPlease make sure to set realistic fee rates, which at best are already known to attract forwardings.\n\n### Command line arguments\n\n```sh\nusage: rebalance.py [-h] [--lnddir LNDDIR] [--network NETWORK] [--grpc GRPC]\n                    [-l] [--show-all | --show-only CHANNEL | -c] [-o | -i]\n                    [-f CHANNEL] [-t CHANNEL] [-A] [-a AMOUNT | -p PERCENTAGE]\n                    [--min-amount MIN_AMOUNT] [--min-local MIN_LOCAL]\n                    [--min-remote MIN_REMOTE] [-e EXCLUDE] [--reckless]\n                    [--ignore-missed-fee] [--fee-factor FEE_FACTOR]\n                    [--fee-limit FEE_LIMIT | --fee-ppm-limit FEE_PPM_LIMIT]\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --lnddir LNDDIR       (default ~/.lnd) lnd directory\n  --network NETWORK     (default mainnet) lnd network (mainnet, testnet,\n                        simnet, ...)\n  --grpc GRPC           (default localhost:10009) lnd gRPC endpoint\n\nlist candidates:\n  Show the unbalanced channels.\n\n  -l, --list-candidates\n                        list candidate channels for rebalance\n  --show-all            also show channels with zero rebalance amount\n  --show-only CHANNEL   only show information about the given channel\n  -c, --compact         Shows a compact list of all channels, one per line\n                        including ID, inbound/outbound liquidity, and alias\n  -o, --outgoing        lists channels with less than 1,000,000 (--min-remote)\n                        satoshis inbound liquidity\n  -i, --incoming        (default) lists channels with less than 1,000,000\n                        (--min-local) satoshis outbound liquidity\n\nrebalance:\n  Rebalance a channel. You need to specify at least the 'from' channel (-f)\n  or the 'to' channel (-t).\n\n  -f CHANNEL, --from CHANNEL\n                        Channel ID of the outgoing channel (funds will be\n                        taken from this channel). You may also specify the ID\n                        using the colon notation (12345:12:1), or the x\n                        notation (12345x12x1). You may also use -1 to choose a\n                        random candidate.\n  -t CHANNEL, --to CHANNEL\n                        Channel ID of the incoming channel (funds will be sent\n                        to this channel). You may also specify the ID using\n                        the colon notation (12345:12:1), or the x notation\n                        (12345x12x1). You may also use -1 to choose a random\n                        candidate.\n  -A, --adjust-amount-to-limits\n                        If set, adjust the amount to the limits (--min-local\n                        and --min-remote). The script will exit if the\n                        adjusted amount is below the --min-amount threshold.\n                        As such, this switch can be used if you do NOT want to\n                        rebalance if the channel is within the limits.\n  -a AMOUNT, --amount AMOUNT\n                        Amount of the rebalance, in satoshis. If not\n                        specified, the amount computed for a perfect rebalance\n                        will be used\n  -p PERCENTAGE, --percentage PERCENTAGE\n                        Set the amount to a percentage of the computed amount.\n                        As an example, if this is set to 50, half of the\n                        computed amount will be used. See --amount.\n  --min-amount MIN_AMOUNT\n                        (Default: 10,000) If the given or computed rebalance\n                        amount is below this limit, nothing is done.\n  --min-local MIN_LOCAL\n                        (Default: 1,000,000) Ensure that the channels have at\n                        least this amount as outbound liquidity.\n  --min-remote MIN_REMOTE\n                        (Default: 1,000,000) Ensure that the channels have at\n                        least this amount as inbound liquidity.\n  -e EXCLUDE, --exclude EXCLUDE\n                        Exclude the given channel. Can be used multiple times.\n  --exclude-private     Exclude private channels. This will not affect channel\n                        ID used at --to and/or --from but will take effect if\n                        you used -1 to get a random channel.\n  --reckless            Allow rebalance transactions that are not economically\n                        viable. You might also want to set --min-local 0 and\n                        --min-remote 0. If set, you also need to set --amount\n                        and either --fee-limit or --fee-ppm-limit, and you\n                        must not enable --adjust-amount-to-limits (-A).\n  --ignore-missed-fee   Ignore missed fee from source channel.\n  --fee-factor FEE_FACTOR\n                        (default: 1.0) Compare the costs against the expected\n                        income, scaled by this factor. As an example, with\n                        --fee-factor 1.5, routes that cost at most 150% of the\n                        expected earnings are tried. Use values smaller than\n                        1.0 to restrict routes to only consider those earning\n                        more/costing less. This factor is ignored with\n                        --reckless.\n  --fee-limit FEE_LIMIT\n                        If set, only consider rebalance transactions that cost\n                        up to the given number of satoshis.\n  --fee-ppm-limit FEE_PPM_LIMIT\n                        If set, only consider rebalance transactions that cost\n                        up to the given number of satoshis per 1M satoshis\n                        sent.\n```\n\n## Contributing\n\nContributions are highly welcome!\nFeel free to submit issues and pull requests on https://github.com/C-Otto/rebalance-lnd/\n\nYou can also send donations via keysend.\nFor example, to send 500 satoshis to C-Otto with a message \"Thank you for rebalance-lnd\":\n\n```sh\nlncli sendpayment --amt=500 --data 7629168=5468616e6b20796f7520666f7220726562616c616e63652d6c6e64 --keysend --dest=027ce055380348d7812d2ae7745701c9f93e70c1adeb2657f053f91df4f2843c71\n```\n\nYou can also specify an arbitrary message:\n\n```sh\nlncli sendpayment --amt=500 --data 7629168=$(echo -n \"your message here\" | xxd -pu -c 10000) --keysend --dest=027ce055380348d7812d2ae7745701c9f93e70c1adeb2657f053f91df4f2843c71\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FC-Otto%2Frebalance-lnd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FC-Otto%2Frebalance-lnd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FC-Otto%2Frebalance-lnd/lists"}