{"id":23542945,"url":"https://github.com/primeroz/sats-stacker","last_synced_at":"2026-03-03T23:31:16.483Z","repository":{"id":54273002,"uuid":"319103363","full_name":"primeroz/sats-stacker","owner":"primeroz","description":"Stack Sats on Kraken exchange.","archived":false,"fork":false,"pushed_at":"2023-02-25T07:24:17.000Z","size":156,"stargazers_count":2,"open_issues_count":6,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T22:03:05.592Z","etag":null,"topics":["bitcoin","buythedip","dca","kraken","sats","sats-stacker","stack","stack-sats"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/primeroz.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":"2020-12-06T18:32:28.000Z","updated_at":"2022-04-04T06:14:58.000Z","dependencies_parsed_at":"2024-06-20T11:04:03.947Z","dependency_job_id":"6b76fff0-92a0-4a6e-a651-ac981f1f06d9","html_url":"https://github.com/primeroz/sats-stacker","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/primeroz/sats-stacker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primeroz%2Fsats-stacker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primeroz%2Fsats-stacker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primeroz%2Fsats-stacker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primeroz%2Fsats-stacker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/primeroz","download_url":"https://codeload.github.com/primeroz/sats-stacker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/primeroz%2Fsats-stacker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30065769,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T18:21:05.932Z","status":"ssl_error","status_checked_at":"2026-03-03T18:20:59.341Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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","buythedip","dca","kraken","sats","sats-stacker","stack","stack-sats"],"created_at":"2024-12-26T06:17:13.053Z","updated_at":"2026-03-03T23:31:16.468Z","avatar_url":"https://github.com/primeroz.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sats Stacker\n\nA simple tool to stack, create orders to try and buy dips, withdraw sats from exchanges. At the moment only the [Kraken](https://www.kraken.com) plugin is implemented.\n\n_sats-stacker_ is intented to be run through a scheduler like _Systemd Timer_ or _Crontab_ and is is provided as [Docker Images](https://hub.docker.com/r/primeroz/sats-stacker) and pre-compiled binaries.\n\n**Use this at your own risk and decide for yourself whether or not you want to run this tool** - access to your exchange account , and so your funds, is required so you are expected to validate the Code before running it. This software is provided as it is.\n\n## Supported Exchanges\n\n#### Kraken\n\nYou will need to get your Kraken API Key and Secret Key from the [Api Settings page](https://www.kraken.com/u/settings/api).\n\nRequired permissions are:\n* Query Funds\n* Modify Orders\n* Withdraw Funds ( Only if you plan to automate the withdrawal )\n\n**Note** sats-stacker, on Kraken exchange, can only withdraw to a pre-configured withdrawal address referenced by name. You will need to create it using the UI before you can automate withdrawals. This is to avoid allowing this tool to create new withdrawal addresses on kraken and potentially loose you funds.\n\n## Supported Notifiers\n\n_sats-stacker_ support sending notifications for each _stack_ or _withdraw_ event so you always know how your stacking is going.\n\nThe infrastructure for notifications is pluggable but somewhat limited at the moment to `STDOUT` and [`SIMPLEPUSH.IO`](https://simplepush.io/)\n\n#### STDOUT\n\nThe simplest of notifications. Just redirect `stdout` to whatever/wherever you like\n\n#### SIMPLEPUSH\n\nSend notification using [`SIMPLEPUSH.IO`](https://simplepush.io/) notification infrastructure with optional support for encrypting your message.\n\n## Help\n\n#### Global Options\n```\nGLOBAL OPTIONS:\n   --debug, -d            debug logging (default: false) [$STACKER_DEBUG]\n   --dry-run, --validate  dry-run (default: true) [$STACKER_VALIDATE, $STACKER_DRY_RUN]\n   --exchange value       Exchange ['kraken', 'binance'] (default: \"kraken\") [$STACKER_EXCHANGE]\n   --api-key value        Exchange Api Key [$STACKER_API_KEY]\n   --secret-key value     Exchange Api Secret [$STACKER_SECRET_KEY, $STACKER_API_SECRET]\n   --notifier value       What notifier to use ['stdout','simplepush'] (default: \"stdout\") [$STACKER_NOTIFIER]\n   --sp-encrypt           Simplepush: If set, the message will be sent end-to-end encrypted with the provided Password/Salt. If false, the message is sent unencrypted. (default: true) [$STACKER_SP_ENCRYPT]\n   --sp-key value         Simplepush: Your simplepush.io Key [$STACKER_SP_KEY]\n   --sp-event value       Simplepush: The event the message should be associated with [$STACKER_SP_EVENT]\n   --sp-password value    Simplepush: Encryption Password [$STACKER_SP_PASSWORD]\n   --sp-salt value        Simplepush: The salt for the encrypted message [$STACKER_SP_SALT]\n   --help, -h             show help (default: false)\n   --version, -v          print the version (default: false)\n```\n\n#### Stack command options\nthe `stack` command will buy the specified _amount_ of _fiat_ in _btc_ using a market value order\n\nThis is the default `Dollar Cost Averaging` mode and will buy you some btc every time you run it.\n\n```\nOPTIONS:\n   --amount value                    Amount of fiat to exchange (default: 0) [$STACKER_STACK_AMOUNT]\n   --fiat value                      Fiat to exchange [$STACKER_STACK_FIAT]\n   --order-type value, --type value  Order type (default: \"limit\") [$STACKER_STACK_ORDER_TYPE]\n   --help, -h                        show help (default: false)\n```\n\n#### BTD command options\nthe `btd` command will place a number of orders at progressively more discounted prices and progressively higher amount of fiat, trying to catch a DIP in price.\n\nthis mode will _first delete_ any previous _btd_ order, will then place the new orders based on the budget it is allowed to spend.\\\nThe frequency at which you run this command will define the window of time in which you will try and catch a DIP.\n\nThe first order will be placed at a discount of `dip-percentage` from the current ASK price for a given amount of fiat. Every successive order will apply a bigger discount, based on `dip-increments` for an amount of fiat higher the previous one.\n\n```\nOPTIONS:\n   --budget value                     Budget to allocate for the DIPs, set to 0 to allocate all of the available budget (default: 0) [$STACKER_BTD_BUDGET]\n   --dip-percentage value             Initial percentage of the firt dip, the other values will be calculated (default: 10) [$STACKER_BTD_DIP_PERCENTAGE]\n   --dip-increments value             Increment of dip percentage for each order (default: 5) [$STACKER_BTD_DIP_INCREMENTS_PERCENTAGE]\n   --n-orders value                   Number of DIPS orders to place (default: 5) [$STACKER_BTD_DIP_N_ORDERS]\n   --high-price-gap-percentage value  Gap between current price and high price to trigger modifier (default: 5) [$STACKER_BTD_HIGH_PRICE_GAP_PERCENTAGE]\n   --fiat value                       Fiat to exchange [$STACKER_BTD_FIAT]\n   --help, -h                         show help (default: false)\n```\n\n##### Example BTD orders\n* Budget: 500\n* Fiat: Eur\n* Dip-Percentage: 5%\n* Dip-Ingrements: 5%\n* N of Orders: 4\n* Current Ask Price: 10000EUR\n\nGiven this conditions the following orders would be placed:\n* 1st Order: FIAT: 50EUR - PRICE: 10000 - ( 5% of 10000) = 9500 - Volume: 0.00526315789 BTC\n* 2nd Order: FIAT: 100EUR - PRICE: 10000 - ( 10% of 10000) = 9000 - Volume: 0.01111111111 BTC\n* 3rd Order: FIAT: 150EUR - PRICE: 10000 - ( 15% of 10000) = 8500 - Volume: 0.01764705882 BTC\n* 4th Order: FIAT: 200EUR - PRICE: 10000 - ( 20% of 10000) = 8000 - Volume: 0.025 BTC\n\n##### Gap from High price discount\nA modifier to the discount will be applied based on the gap between the _current Ask Price_ and the _Highest price_ in the last week. ( This is currently not configurable)\\\nThe bigger the Gap between the current Ask price and the highest price in the last week the bigger the modifier is up to 40% of the actualy `dip-discount` specified.\n\nThis cannot be disabled right now but by using the `--high-price-gap-percentage` flag you can trick _sats-stacker_ to never initiate this modifier by setting it to 100 since it will only apply if the gap\\\nbetween _current Ask Price_ and _Highest price_ in the last week is \u003e than that value.\n\n##### Frequency of run\nIn order for the tool to try and catch the Dips you need to run the tool on a regular basis, the frequency at which you run it will determine the _window of time_ in which you will try to catch a dip. At every run the old orders will be deleted and new ones, based on the current Ask Price, will be created\n\nI run the tool every 2 hour with an initial dip value of 5% , so i try to catch any dip of 5% in 2 hours of time.\n\nThe right values are entirely up to you depending on how big and how fast of a dip you are trying to catch\n\n#### Withdraw command options\n```\nOPTIONS:\n   --max-fee value  Max fee in percentage, only withdraw if the relative fee does not exceed this limit (default: 0) [$STACKER_WITHDRAW_MAX_FEE]\n   --address value  Address to withdraw to, the actual value will depend on the exchange selected [$STACKER_WITHDRAW_ADDRESS]\n   --help, -h       show help (default: false)\n```\n\n## Configuration\n\n_sats-stacker_ support being configured either via Environment variables or cli arguments.\n\n#### Running _sats-stacker_ using systemd timers\n\nExample `systemd` units and timers , and environment configuration files, can be found in the [contrib/systemd](./contrib/systemd) directory\n\n## Example Run of _sats-stacker_\n\n```\nexport STACKER_DEBUG=true\nexport STACKER_DRY_RUN=false\nexport STACKER_EXCHANGE=kraken\nexport STACKER_NOTIFIER=stdout\nexport STACKER_API_KEY=YOUR_KRAKEN_KEY\nexport STACKER_API_SECRET=YOUR_KRAKEN_SECRET_KEY\n```\n\n`stack some sats`\n```\n# Stack with a too small amount of fiat\n\n./sats-stacker stack --amount 10 --fiat eur\nINFO[2020-12-30T10:46:06+01:00] Stacking some sats on KRAKEN                  action=stack exchange=kraken\nDEBU[2020-12-30T10:46:07+01:00] Balance before placing the Order              action=stack crypto=XBT cryptoBalance=0.0040813 exchange=kraken fiat=EUR fiatBalance=291.1935\nMinimum volume for BTC Order on Kraken is 0.001 got 0.00044237. Consider increasing the amount of Fiat\n```\n\n```\n# Increase amount of fiat so that we can stack\n./sats-stacker stack --amount 25 --fiat eur 2\u003e/dev/null\n\nKraken - Stack Sats\n\n🙌 Limit order successful\n\n💰 Balance Before Order\n   Crypto  XBT: 0.004081\n   Fiat EUR: 291.193500\n\n📈 Ask Price: 22608.00000\n\n💸: buy 0.00110580 XBTEUR @ limit 22608.0\n📎 Transatcion: DryRun\n```\n\n```\n# Stack at market price rather than ask price ( In this case the ASK Price is printed for reference only )\n./sats-stacker stack --amount 25 --fiat eur 2\u003e/dev/null\n\nKraken - Stack Sats\n\n🙌 Market order successful\n\n💰 Balance Before Order\n   Crypto  XBT: 0.004081\n   Fiat EUR: 291.193500\n\n📈 Ask Price: 22652.20000\n\n💸: buy 0.00110365 XBTEUR @ market\n📎 Transatcion: DryRun\n```\n\n---\n`withdraw sats to pre-existing kraken address`\n```\n# Set relative fee to 0.5%  - Won't withdraw since the relative fee of withdrawal ( Kraken fee / XBT Amount ) = 3.55% \u003e 0.5%\n\n./sats-stacker withdraw --address \"address\" --max-fee 0.5 2\u003e/dev/null\n\nKraken - Withdraw Sats\n\n💡 Relative fee of withdrawal: 3.55%\n❌ Fees are too high for withdrawal\n\n👛 Kraken Address: address\n💰 Withdraw Amount XBT: 0.01408130\n🏦 Kraken Fees: 0.00050000\n\n📎 Transatcion: DRY-RUN\n```\n\n### Example Run of BTD Command\n\n```\nexport STACKER_DEBUG=true\nexport STACKER_DRY_RUN=false\nexport STACKER_EXCHANGE=kraken\nexport STACKER_API_KEY=YOUR_KRAKEN_KEY\nexport STACKER_API_SECRET=YOUR_KRAKEN_SECRET_KEY\n```\n\n`Create some Orders`\n```\n./sats-stacker btd --amount 500 --fiat eur --dip-percentage 5 --dip-increments 4 --n-orders 4\n\nFeb 27 18:16:07 DietPi docker[18792]: time=\"2021-02-27T18:16:07Z\" level=info msg=\"4 Open Orders Canceled\" action=btd exchange=KRAKEN userref=300\n\nFeb 27 18:16:07 DietPi docker[18792]: time=\"2021-02-27T18:16:07Z\" level=info msg=\"Order Placed 1\" action=btd askPrice=39074.00000 dryrun= exchange=KRAKEN order=\"buy 0.00132620 XBTEUR @ limit 37701.6\" order-number=1 orderFlags=fciq orderId=AAAAAA-AAAAA-AAAAAA orderType=limit price=37701.6 userref=300 volume=0.00132620\nFeb 27 18:16:07 DietPi docker[18792]: time=\"2021-02-27T18:16:07Z\" level=info msg=\"Order Placed 2\" action=btd askPrice=39074.00000 dryrun= exchange=KRAKEN order=\"buy 0.00273197 XBTEUR @ limit 36603.7\" order-number=2 orderFlags=fciq orderId=BBBBBB-BBBBB-BBBBBB orderType=limit price=36603.7 userref=300 volume=0.00273197\nFeb 27 18:16:08 DietPi docker[18792]: time=\"2021-02-27T18:16:08Z\" level=info msg=\"Order Placed 3\" action=btd askPrice=39074.00000 dryrun= exchange=KRAKEN order=\"buy 0.00422467 XBTEUR @ limit 35505.7\" order-number=3 orderFlags=fciq orderId=CCCCCC-CCCCC-CCCCCC orderType=limit price=35505.7 userref=300 volume=0.00422467\nFeb 27 18:16:08 DietPi docker[18792]: time=\"2021-02-27T18:16:08Z\" level=info msg=\"Order Placed 4\" action=btd askPrice=39074.00000 dryrun= exchange=KRAKEN order=\"buy 0.00581263 XBTEUR @ limit 34407.8\" order-number=4 orderFlags=fciq orderId=DDDDDD-DDDDD-DDDDDD orderType=limit price=34407.8 userref=300 volume=0.00581263\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprimeroz%2Fsats-stacker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprimeroz%2Fsats-stacker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprimeroz%2Fsats-stacker/lists"}