40 Commits

Author SHA1 Message Date
william
f20bba964c Merge tag 'v0.4.5'
0.4.5

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEE8ghYQ1eZpvEAiagrUAnheX8D+NAFAmLo16oACgkQUAnheX8D
# +NDarQ/+NioaiaeUUiP+B8kZwnCXi1/AarfCtpce4eKEUnzGe84OqeMR9sm9Q5ty
# z9Dqc+x/mkOysd0bPDz+Pt+Mw45U7lkx76+jf9aZj7T+fQ15TIeJ0kHtwod1wJs1
# CUaCfVKvlqLh3PdUZHU1KYe7KlD2LBevzNAy7HtS/okr074jnDz8C6o9qUPTritP
# dy/i7LLlAkTSS4oJXMApuVc2DMdf7CU6xmkA0UkDiabE8BfsSEddFYs09I7YY432
# BzD80aZPXvX4NbUy1U3dHKQf/f2xfP9AySOQR9rXVeBhpiSGtRQ2bXIULUh/vpNp
# SEPwPWi3ahtWJXRs6sWvdt1eI1RcPcMBAZCkZxcF2GBMTLiTJa65mReFPnV1sP7o
# KjsXoSYUAZO07/yRv/H0ZFzbd1t7vWs/iQ0Xr1h0mAsRnLNMlItLkANetNyDrQSg
# P9RFkkxf5RKy6lGZNalWfX5p9ePZ/nmf2xoFegtDy0nZ55QoofZxF7jx0/uy18cQ
# HDq3kUoRnc4Xwd5sXsbxhtPpptUMa+CaUS2TkiSgGkL7gPVbolSv8VtSUyU4e9Ur
# rvMz0gXnSaGZI+Si6rKbVcrwb1Gs6FmwAStUxnS506U0DNhS1X/zsPBu8cuc31im
# Qb5JWWtV0lnDUF4hq7Bl21DX7Yi/z61k8cnfEJC0zHUj8nWkq94=
# =0nG+
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue Aug  2 09:52:10 2022
# gpg:                using RSA key F20858435799A6F10089A82B5009E1797F03F8D0
# gpg: Can't check signature: No public key

# Conflicts:
#	package-lock.json
2022-10-06 23:09:52 +02:00
Dennis Reimann
d6b4f892ec 0.4.5 2022-08-02 09:52:09 +02:00
Dennis Reimann
0956705d1a Upgrade dependencies 2022-08-02 09:51:51 +02:00
william
ec84cda4c9 Merge remote-tracking branch 'upstream/dependabot/npm_and_yarn/got-11.8.5' 2022-07-15 09:51:11 +02:00
dependabot[bot]
afe1555d08 Bump got from 11.8.0 to 11.8.5
Bumps [got](https://github.com/sindresorhus/got) from 11.8.0 to 11.8.5.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.0...v11.8.5)

---
updated-dependencies:
- dependency-name: got
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-22 18:11:53 +00:00
root
a66b3f036f use node:alpine and don't checkout git 2022-05-08 20:33:41 +02:00
william
fef80dd77d Merge tag 'v0.4.4'
0.4.4

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEE8ghYQ1eZpvEAiagrUAnheX8D+NAFAmEc9HkACgkQUAnheX8D
# +NANmw//WZo8nk1ODqx2AVi1wlrcbNsA3RzzocAZkXiIBa5O2eqQk6vsG017OZFn
# /cBRqmsxWnYQK4IS22s0Ec85c8RkPP/XcJxneKYg/VTI4cbnD2gpJMUBm11Tuvkn
# CmdbikVjcBzlLYXpNIYDiwkQo3dbS3/6+qqxr+4YAHpK7CZqg+lEdSR5jFOOJzSw
# zTAk0Y5c8yMpQubkeSWQL6hYQ+Ei0JxISv6hrG3ulE9rhIpm5Re+cDHu/HXd8Q7x
# 1FFRsH8RgaUvA/dpmBON3TYztqHyEqt840Vvr/afakA/phZ/SG1javeZkrl8WXMG
# Yhyrbi8f62/5uEY5foG4p6b8+83K2Gtyj8W8KU3I5AFIMwiHJ37RYsOa2JuIhJb5
# nV5ET568vI1AHF3G1R7O39lbQJpk+0arShbGbkidFyxxhvI/Qm5Fx8cTIqxLltYE
# YbApNgR1YvQvFEB68fTsGn8WtEPCt3mrg/YnjHY6JQloeDje3IruQhOBOlkP1Shl
# +tL3o7RUx0lCZNT0Lunuh6E82nSRS6DIq4/V975JMgwQDZngTj+9cDPhuNkZFUbk
# LCOga/0hVs2IDbWRQ7f7l6PbldiLp9FY3c5XWoMkfr1QZsCF2YGHBovq6GBTqgS2
# p24ciXW0yyo3D1qPc1mMrNf40aLltN47ShFyodvRLSfDZD3LrpU=
# =9LIp
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed Aug 18 13:52:25 2021
# gpg:                using RSA key F20858435799A6F10089A82B5009E1797F03F8D0
# gpg: Can't check signature: No public key
2022-05-08 20:25:49 +02:00
Dennis Reimann
0d01b6978e 0.4.4 2021-08-18 13:52:25 +02:00
william
4db9952578 Merge tag 'v0.4.3'
0.4.3

revert order price from custom "bid" to default "ask"
as now order type "market" is available.

# gpg: directory '/c/Users/william/.gnupg' created
# gpg: keybox '/c/Users/william/.gnupg/pubring.kbx' created
# gpg: Signature made Wed Apr 21 11:43:06 2021
# gpg:                using RSA key F20858435799A6F10089A82B5009E1797F03F8D0
# gpg: Can't check signature: No public key

# Conflicts:
#	commands/stack.js
2021-08-08 18:52:15 +02:00
Wolf
f03876f875 ommit api call (#11) 2021-08-03 17:04:41 +02:00
Dennis Reimann
0029d8ff3a Merge remote-tracking branch 'origin/master' 2021-06-15 12:50:58 +02:00
Dennis Reimann
cc8a27ad09 Upgrade dependencies 2021-06-15 12:50:50 +02:00
Aaron Dewes
11dd547947 Bittr is back! (#10) 2021-05-30 11:12:10 +02:00
Dennis Reimann
2384360d63 Add license file
Closes #9.
2021-04-25 21:19:45 +02:00
Dennis Reimann
0a9ddef452 0.4.3 2021-04-21 11:43:05 +02:00
Dennis Reimann
177874217d Increase request timeout
https://support.kraken.com/hc/en-us/articles/360000914386-How-can-I-avoid-excessive-timeouts-
2021-04-21 11:42:57 +02:00
Dennis Reimann
add9855f8b 0.4.2 2021-04-03 20:48:26 +02:00
Simon Stöferle
e907387b12 Set Fee currency (#8)
Fees are by default paid with the fiat money. This means that you bought
crypto for the specified amount (e.g. 25 USD) and the fees are charged
separately. When you want to spend 100 USD over 4 weeks, meaning 1 order
per week, the last order won't be placed since there is not enough fiat
money left.
In my case I wanted to spend 100 EUR a month, meaning 25 € once per
week. When testing it the first time I was charged 25,065 EUR. By
setting the fee to XBT instead of EUR, I can run the script 4 times a
month.
2021-04-03 20:47:12 +02:00
Dennis Reimann
a2cf01202d 0.4.1 2021-04-03 18:43:32 +02:00
Dennis Reimann
5f44df78d1 Remove version requirement 2021-04-03 18:43:21 +02:00
sstoefe
62409bb4a2 Trading agreement fix for Germans (#7)
As a German trying to place an order via the API you will get an
exception: 'EOrder:Trading agreement required'.
You have to set the 'trading_agreement' parameter to 'agree' (see
https://support.kraken.com/hc/en-us/articles/360000920026--Trading-agreement-required-error-for-German-residents).
2021-04-03 18:33:35 +02:00
Dennis Reimann
89f7d4b020 0.4.0 2021-03-02 19:28:34 +01:00
Dennis Reimann
4517af870a Add market buy option 2021-03-02 19:26:31 +01:00
Dennis Reimann
e50c80cdbf Update raspiblitz script path and instructions 2020-12-10 14:57:46 +01:00
Dennis Reimann
dde741ed35 Fix shell script example 2020-12-08 16:55:08 +01:00
Dennis Reimann
ed7c7a4d04 Update lockfile 2020-12-08 16:51:17 +01:00
Dennis Reimann
27217fa9bc Add package meta fields 2020-12-08 16:51:06 +01:00
Christoph Stenglein
4e03422821 Update kraken-api; remove deprecation warning in example script (#6)
* Update kraken-api; remove deprecation warning in example script

* Update package.json

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
2020-12-08 16:49:39 +01:00
Dennis Reimann
92eccff5cc Update README.md 2020-12-04 11:47:35 +01:00
william
eedfb51522 add dockerfile 2020-11-20 10:34:26 +01:00
william
fb1e5b96c9 change current price from bid to ask 2020-11-20 10:14:29 +01:00
william
57435f0de6 make cryptocurrency configurable 2020-11-20 10:13:48 +01:00
Dennis Reimann
e133d56072 0.3.0 2020-11-10 21:43:21 +01:00
Dennis Reimann
fa7fe94d6d 🛠 Rename scripts and unify shell script 2020-11-10 21:42:52 +01:00
Dennis Reimann
7fd9fe1043 🐛 Fix pair names
Allows for usage with CHF.
2020-11-10 21:00:44 +01:00
Dennis Reimann
0e571e8965 🛠 Refactor to use commands 2020-11-10 11:17:07 +01:00
Dennis Reimann
d1b2052494 🧤 Cleanups 2020-11-09 21:50:51 +01:00
Tobias Koller
a9694ac1dd Withdrawal script (#4)
* Withdrawal script. Added a script that lets you withdraw through Kraken API if the charged fees are under a certain level

* refactored code and added validation functionality

* Enhanced README to reflect the option to also withdraw in an automated manner

* fixed typo
2020-11-09 21:15:52 +01:00
Dennis Reimann
c387bb3ea3 ️ Document RaspiBlitz Integration 2020-08-24 14:18:45 +02:00
Dennis Reimann
4a2fb94dc4 🔑 Document API Key 2020-08-24 14:18:21 +02:00
10 changed files with 822 additions and 173 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.env .env
node_modules node_modules
stacksats.sh

9
Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM node:alpine
COPY . /krakenbot
WORKDIR /krakenbot
RUN pwd
RUN npm install
CMD npm run stack

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2020 Dennis Reimann <mail@dennisreimann.de> (https://dennisreimann.de)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

184
README.md
View File

@@ -5,6 +5,13 @@ First off: Here's to you, [Bittr](https://getbittr.com/) you will be missed!
This script is not a full replacement for the incredible service Bittr offered, but it's a start: This script is not a full replacement for the incredible service Bittr offered, but it's a start:
Automate your Stacking Sats process by regularly placing buy orders using the [Kraken API](https://www.kraken.com/features/api). Automate your Stacking Sats process by regularly placing buy orders using the [Kraken API](https://www.kraken.com/features/api).
---
The original [Bittr is back](https://getbittr.com/press-releases/bittr-is-back)!
This script is still fully working.
---
## ✋ Caveat ## ✋ Caveat
You need to install the dependency [kraken-api](https://github.com/nothingisdead/npm-kraken-api), which is a third-party package. You need to install the dependency [kraken-api](https://github.com/nothingisdead/npm-kraken-api), which is a third-party package.
@@ -13,7 +20,88 @@ Also the version is fixed, so that unwanted changes do not slip in.
However: Use this at your own risk and decide for yourself whether or not you want to run this script and its dependencies! However: Use this at your own risk and decide for yourself whether or not you want to run this script and its dependencies!
## 📦 Setup ## 🔑 API Key
Obtain your Kraken API Key via [the API settings page](https://www.kraken.com/u/settings/api).
Generate a new API key dedicated for stacking using the "Query Funds" and "Modify Orders" permissions:
![Kraken API Key Permissions](./api-permissions.png)
Only check the "Withdraw Funds" option if you plan to automatically withdraw Bitcoin from Kraken.
See details below.
## ⚙️ Configuration
These are the environment variables used by the script:
```sh
# used to authenticate with Kraken
KRAKEN_API_KEY="apiKeyFromTheKrakenSettings"
KRAKEN_API_SECRET="privateKeyFromTheKrakenSettings"
# used for buying
KRAKEN_ORDER_TYPE="market" # "limit" (default) or "market"
KRAKEN_API_FIAT="USD" # the governmental shitcoin you are selling
KRAKEN_BUY_AMOUNT=21 # fiat amount you trade for the future of money
KRAKEN_FEE_CURRENCY="XBT" # pay fee in this currency, e.g. buying XBT for USD and paying fee in XBT
# used for withdrawal
KRAKEN_MAX_REL_FEE=0.5 # maximum fee in % that you are willing to pay
KRAKEN_WITHDRAW_KEY="descriptionOfWithdrawalAddress"
# set this if you live in Germany and get the 'EOrder:Trading agreement required' error
# see https://support.kraken.com/hc/en-us/articles/360000920026--Trading-agreement-required-error-for-German-residents
KRAKEN_GERMANY_TRADING_AGREEMENT="agree"
# remove this line after verifying everything works
KRAKEN_DRY_RUN_PLACE_NO_ORDER=1
```
## ⚡️ RaspiBlitz Integration
This script ships with the [RaspiBlitz](https://github.com/rootzoll/raspiblitz) (v1.6 and above).
You can enable it via the Console of your RaspiBlitz.
Leave the main menu via the last option "Console" and use the following commands:
```sh
# enable the script
./config.scripts/bonus.stacking-sats-kraken.sh on
# switch to the stackingsats user
sudo su - stackingsats
# edit your configuration (see the "Configuration" section above)
nano /mnt/hdd/app-data/stacking-sats-kraken/.env
# follow the instructions from the first step to set up a cronjob
crontab -e
```
Here is an example for a daily cronjob at 6:15am ...
```sh
SHELL=/bin/bash
PATH=/bin:/usr/sbin:/usr/bin:/usr/local/bin
15 6 * * * /home/stackingsats/stacking-sats-kraken/stacksats.sh > /dev/null 2>&1
```
**Note:** Do not run `npm` directly on the RaspiBlitz, like show in the examples below.
Please use the `/home/stackingsats/stacking-sats-kraken/stacksats.sh` shell script instead, as this loads your configuration.
To run the script manually, switch to the `stackingsats` user and use this command:
```sh
# switch to the stackingsats user
sudo su - stackingsats
# run the script
./stacking-sats-kraken/stacksats.sh
```
- - -
## 📦 Custom Setup
Prerequisite: At least the current LTS version of [Node.js](https://nodejs.org/). Prerequisite: At least the current LTS version of [Node.js](https://nodejs.org/).
@@ -23,19 +111,13 @@ Install the dependencies:
npm install npm install
``` ```
Setup the environment variables for the script: Setup the environment variables for the script.
See the [config section above](#-configuration).
```sh
export KRAKEN_API_KEY="apiKeyFromTheKrakenSettings"
export KRAKEN_API_SECRET="privateKeyFromTheKrakenSettings"
export KRAKEN_API_FIAT="USD" # the governmental shitcoin you are selling
export KRAKEN_BUY_AMOUNT=21 # fiat amount you trade for the future of money
```
Use a dry run to test the script and see the output without placing an order: Use a dry run to test the script and see the output without placing an order:
```sh ```sh
npm test npm run test:stack
``` ```
You should see something like this sample output: You should see something like this sample output:
@@ -55,38 +137,98 @@ You should see something like this sample output:
When you are good to go, execute this command in a regular interval: When you are good to go, execute this command in a regular interval:
```sh ```sh
npm run stack-sats npm run stack
``` ```
The best and easiest way is to wrap it all up in a shell script. The best and easiest way is to wrap it all up in a shell script.
This script can be triggered via cron job, e.g. weekly, daily or hourly. This script can be triggered via cron job, e.g. weekly, daily or hourly.
Here's a sample `stack-sats.sh` script: Here's a sample `stacksats.sh` script:
```sh ```sh
#!/bin/bash #!/bin/bash
set -e set -e
# hide deprecation warning
export NODE_OPTIONS="--no-deprecation"
export KRAKEN_API_KEY="apiKeyFromTheKrakenSettings" export KRAKEN_API_KEY="apiKeyFromTheKrakenSettings"
export KRAKEN_API_SECRET="privateKeyFromTheKrakenSettings" export KRAKEN_API_SECRET="privateKeyFromTheKrakenSettings"
export KRAKEN_ORDER_TYPE="market"
export KRAKEN_API_FIAT="USD" export KRAKEN_API_FIAT="USD"
export KRAKEN_BUY_AMOUNT=21 export KRAKEN_BUY_AMOUNT=21
export KRAKEN_MAX_REL_FEE=0.5
export KRAKEN_WITHDRAW_KEY="descriptionOfWithdrawalAddress"
export KRAKEN_DRY_RUN_PLACE_NO_ORDER=1
BASE_DIR=$(cd `dirname $0` && pwd) # run script
cd $BASE_DIR/stacking-sats-kraken cd $(cd `dirname $0` && pwd)
result=$(npm run stack-sats 2>&1) cmd=${1:-"stack"}
echo $result
# Optional: Send yourself an email if [[ "${KRAKEN_DRY_RUN_PLACE_NO_ORDER}" ]]; then
result=$(npm run test:$cmd --silent 2>&1)
else
result=$(npm run $cmd --silent 2>&1)
fi
echo "$result"
# optional: send yourself an email
recipient="satstacker@example.org" recipient="satstacker@example.org"
echo "Subject: Sats got stacked echo "Subject: Sats got stacked
From: satstacker@example.org From: satstacker@example.org
To: $recipient $result" | /usr/sbin/sendmail $recipient To: $recipient $result" | /usr/sbin/sendmail $recipient
``` ```
Make it executable with `chmod +x stack-sats.sh` and go wild. Make it executable with `chmod +x stacksats.sh` and go wild.
[Stay humble!](https://twitter.com/matt_odell/status/1117222441867194374) 🙏 [Stay humble!](https://twitter.com/matt_odell/status/1117222441867194374) 🙏
## 🔑 Withdrawal
Holding significant amounts on an exchange is never a good idea.
You should regularly take ownership of your coins by withdrawing to your own wallet.
This can either be done manually or it can be automated.
The script provided here will only withdraw to a previously defined Bitcoin address if the relative fees do not exceed a certain limit.
*It is optional to run the withdrawal script.*
### Example 1
- Max. relative fee: 0.5%
- Fixed Kraken fee: ₿ 0.00050
- Balance: ₿ 0.06000
➡️ No withdrawal since fee actual (0.83%) is too high
### Example 2
- Max. relative fee: 0.5%
- Fixed Kraken fee: ₿ 0.00050
- Balance: ₿ 0.12000
➡️ Withdrawal executed since actual fee (0.42%) is low enough
In case you plan to automatically withdraw from Kraken, a withdrawal method must first be defined.
If you already set up a methode you can reuse it.
Otherwise generate a new one by going to **Funding > Bitcoin (XBT) withdraw > Add address**.
The description field will later be used as an environment variable in the script.
To test the withdrawal of funds to your defined address run:
```sh
npm run test:withdraw
```
You should see something like this:
```text
💡 Relative fee of withdrawal amount: 5.57%
❌ Fee is too high  max rel. fee: 0.50%
```
It is recommended to run the withdrawal script every time you stacked sats:
```sh
npm run withdraw
```
Since it can take a couple seconds or minutes for your order to fill, you should run the following script a couple hours later after the stacking script.
Just set up a second cron job which executes the withdrawal script.
If you are using the aforementioned `stacksats.sh` script you can withdraw via this command:
`stacksats.sh withdraw`

BIN
api-permissions.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

55
commands/stack.js Normal file
View File

@@ -0,0 +1,55 @@
module.exports = async (kraken, validate, { getEnv, getEnvOpt }) => {
const [crypto, fiat, amount, feeCurrency] = getEnv('KRAKEN_API_CRYPTO', 'KRAKEN_API_FIAT', 'KRAKEN_BUY_AMOUNT', 'KRAKEN_FEE_CURRENCY')
const ordertype = getEnvOpt('KRAKEN_ORDER_TYPE', 'limit', ['limit', 'market'])
// if living in Germany, one needs to add an additional parameter to explicitly agree to the trade
// if the parameter is not set one will get the following error: EOrder:Trading agreement required
// see https://support.kraken.com/hc/en-us/articles/360000920026--Trading-agreement-required-error-for-German-residents
const trading_agreement = getEnvOpt('KRAKEN_GERMANY_TRADING_AGREEMENT', '', ['agree', ''])
// https://www.kraken.com/features/api
const pair = `${crypto}${fiat}`
// for explanation of oflags see https://www.kraken.com/features/api#add-standard-order
var fee = ""
if (feeCurrency == crypto) {
fee = "fcib"
} else if (feeCurrency == fiat) {
fee = "fciq"
} else {
fee = ""
}
// Fetch and display information
const { result: balance } = await kraken.api('Balance')
const { result: ticker } = await kraken.api('Ticker', { pair })
const fiatBalance = balance[`Z${fiat}`] || balance[fiat] || 0.0
const cryptoBalance = balance[`X${crypto}`] || balance[crypto] || 0.0
const [{ a: [a], b: [b] }] = Object.values(ticker)
const ask = parseFloat(a)
const bid = parseFloat(b)
const price = bid
// Calculate volume and adjust precision
const volume = (amount / price).toFixed(8)
console.log('💰 Balance:', fiatBalance, fiat, '/', cryptoBalance, crypto, '\n')
console.log('📈 Ask:', ask, fiat)
console.log('📉 Bid:', bid, fiat, '\n')
if (parseFloat(fiatBalance) < parseFloat(amount)) {
console.log('❌ Insufficient funds')
return
}
// Place order
const details = { pair, type: 'buy', ordertype, price, volume }
if (validate) details.validate = true
if (trading_agreement) details.trading_agreement = trading_agreement
if (fee) details.oflags = fee
const { result: { descr: { order }, txid } } = await kraken.api('AddOrder', details)
console.log('💸 Order:', order)
if (txid) console.log('📎 Transaction ID:', txid.join(', '))
}

25
commands/withdraw.js Normal file
View File

@@ -0,0 +1,25 @@
module.exports = async (kraken, validate, { getEnv }) => {
const [maxFee, key] = getEnv('KRAKEN_MAX_REL_FEE', 'KRAKEN_WITHDRAW_KEY')
// https://api.kraken.com/0/private/WithdrawInfo
const asset = 'XBT'
const withdrawdetails = { asset, key, amount: 0 }
// Get withdrawal information
const { result: { limit, fee } } = await kraken.api('WithdrawInfo', withdrawdetails)
const relFee = 1/parseFloat(limit)*parseFloat(fee)
console.log(`💡 Relative fee of withdrawal amount: ${(relFee*100).toFixed(2)}%`)
// Place withdrawal when fee is low enough (relatively)
if (relFee < maxFee/100) {
console.log(`💰 Withdraw ${limit} ${asset} now.`)
const withdraw = { asset, key, amount: limit }
if (!validate) {
const { result: { refid } } = await kraken.api('Withdraw', withdraw)
if (refid) console.log(`📎 Withdrawal reference ID: ${refid}`)
}
} else {
console.log(`❌ Fee is too high - max rel. fee: ${parseFloat(maxFee).toFixed(2)}%`)
}
}

View File

@@ -1,48 +1,28 @@
const assert = require('assert') const assert = require('assert')
const Kraken = require('kraken-api') const Kraken = require('kraken-api')
const { const getEnv = (...vars) => vars.map(name => {
KRAKEN_API_KEY: key, const value = process.env[name]
KRAKEN_API_SECRET: secret, assert(value, `Provide the ${name} environment variable.`)
KRAKEN_API_FIAT: fiat, return value
KRAKEN_BUY_AMOUNT: amount })
} = process.env const getEnvOpt = (varname, defaultValue, allowedValues) => {
const value = process.env[varname] || defaultValue
assert(key && secret, 'Provide the KRAKEN_API_KEY and KRAKEN_API_SECRET environment variables.') if (allowedValues) assert(allowedValues.includes(value), `The ${varname} environment variable must be one of ${allowedValues.map(v => `"${v}"`).join(", ")}.`)
assert(fiat && amount, 'Provide the KRAKEN_API_FIAT and KRAKEN_BUY_AMOUNT environment variables.') return value
}
// https://www.kraken.com/features/api const command = process.argv[2].replace('--cmd=', '')
const kraken = new Kraken(key, secret) const validate = process.argv.includes('--validate') || process.env['KRAKEN_DRY_RUN_PLACE_NO_ORDER']
const crypto = 'XBT'
const pair = `X${crypto}Z${fiat}`
const validate = process.argv[2] === '--validate'
;(async () => { ;(async () => {
// Fetch and display information
const { result: { [`Z${fiat}`]: fiatBalance, [`X${crypto}`]: cryptoBalance } } = await kraken.api('Balance')
const { result: { [pair]: { a: [a], b: [b] } } } = await kraken.api('Ticker', { pair })
const ask = parseFloat(a)
const bid = parseFloat(b)
const price = bid
// Calculate volume and adjust precision
const volume = (amount / price).toFixed(8)
console.log('💰 Balance:', fiatBalance, fiat, '/', cryptoBalance, crypto, '\n')
console.log('📈 Ask:', ask, fiat)
console.log('📉 Bid:', bid, fiat, '\n')
// Place order
try { try {
const details = { pair, type: 'buy', ordertype: 'limit', price, volume } const [apiKey, secret] = getEnv('KRAKEN_API_KEY', 'KRAKEN_API_SECRET')
if (validate) details.validate = true const kraken = new Kraken(apiKey, secret, { timeout: 30000 })
const { result: { descr: { order }, txid } } = await kraken.api('AddOrder', details) const cmd = require(`./commands/${command}`)
await cmd(kraken, validate, { getEnv, getEnvOpt })
console.log('💸 Order:', order) if (validate) console.log('\n🚨 THIS WAS JUST A VALIDATION RUN!')
if (txid) console.log('📎 Transaction ID:', txid.join(', '))
if (validate) console.log('\n🚨 THIS WAS JUST A VALIDATION RUN, NO ORDER HAS BEEN PLACED!')
} catch (err) { } catch (err) {
console.log(`\n🚨 Failure:`, err.message) console.log(`\n🚨 Failure:`, err.message)
} }

643
package-lock.json generated
View File

@@ -1,159 +1,582 @@
{ {
"name": "stacking-sats-kraken", "name": "stacking-sats-kraken",
"version": "0.2.0", "version": "0.4.5",
"lockfileVersion": 1, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": {
"": {
"name": "stacking-sats-kraken",
"version": "0.4.5",
"license": "MIT",
"dependencies": {
"kraken-api": "1.0.1"
},
"funding": {
"url": "https://github.com/dennisreimann/stacking-sats-kraken?sponsor=1"
}
},
"node_modules/@sindresorhus/is": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz",
"integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/@szmarczak/http-timer": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
"integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
"dependencies": {
"defer-to-connect": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@types/cacheable-request": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
"integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
"dependencies": {
"@types/http-cache-semantics": "*",
"@types/keyv": "*",
"@types/node": "*",
"@types/responselike": "*"
}
},
"node_modules/@types/http-cache-semantics": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
"integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A=="
},
"node_modules/@types/json-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz",
"integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ=="
},
"node_modules/@types/keyv": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
"integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "14.14.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ=="
},
"node_modules/@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/cacheable-lookup": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz",
"integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==",
"engines": {
"node": ">=10"
}
},
"node_modules/cacheable-request": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz",
"integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==",
"dependencies": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"dependencies": {
"mimic-response": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/compress-brotli": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz",
"integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==",
"dependencies": {
"@types/json-buffer": "~3.0.0",
"json-buffer": "~3.0.1"
},
"engines": {
"node": ">= 12"
}
},
"node_modules/decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"dependencies": {
"mimic-response": "^3.1.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/decompress-response/node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"engines": {
"node": ">=10"
}
},
"node_modules/defer-to-connect": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
"integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==",
"engines": {
"node": ">=10"
}
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/got": {
"version": "11.8.5",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz",
"integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==",
"dependencies": {
"@sindresorhus/is": "^4.0.0",
"@szmarczak/http-timer": "^4.0.5",
"@types/cacheable-request": "^6.0.1",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^5.0.3",
"cacheable-request": "^7.0.2",
"decompress-response": "^6.0.0",
"http2-wrapper": "^1.0.0-beta.5.2",
"lowercase-keys": "^2.0.0",
"p-cancelable": "^2.0.0",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=10.19.0"
},
"funding": {
"url": "https://github.com/sindresorhus/got?sponsor=1"
}
},
"node_modules/http-cache-semantics": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
},
"node_modules/http2-wrapper": {
"version": "1.0.0-beta.5.2",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz",
"integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==",
"dependencies": {
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
},
"engines": {
"node": ">=10.19.0"
}
},
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
},
"node_modules/keyv": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz",
"integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==",
"dependencies": {
"compress-brotli": "^1.3.8",
"json-buffer": "3.0.1"
}
},
"node_modules/kraken-api": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/kraken-api/-/kraken-api-1.0.1.tgz",
"integrity": "sha512-cOdQCobNlskn1hzFBZDwIliFYP+bAv2SUITG6oGWdVNHnxflcZo4hb/oY/t+RKkKtp95KTL+8R1iSZYQS4ZDwA==",
"dependencies": {
"got": "^11.1.4",
"qs": "^6.9.4"
},
"engines": {
"node": ">=8"
}
},
"node_modules/lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"engines": {
"node": ">=8"
}
},
"node_modules/mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"engines": {
"node": ">=4"
}
},
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/p-cancelable": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
"integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==",
"engines": {
"node": ">=8"
}
},
"node_modules/pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"node_modules/qs": {
"version": "6.9.4",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
"engines": {
"node": ">=10"
}
},
"node_modules/resolve-alpn": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz",
"integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA=="
},
"node_modules/responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"dependencies": {
"lowercase-keys": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
}
},
"dependencies": { "dependencies": {
"decompress-response": { "@sindresorhus/is": {
"version": "3.3.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ=="
},
"@szmarczak/http-timer": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
"integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
"requires": {
"defer-to-connect": "^2.0.0"
}
},
"@types/cacheable-request": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
"integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
"requires": {
"@types/http-cache-semantics": "*",
"@types/keyv": "*",
"@types/node": "*",
"@types/responselike": "*"
}
},
"@types/http-cache-semantics": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
"integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A=="
},
"@types/json-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz",
"integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ=="
},
"@types/keyv": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
"integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "14.14.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ=="
},
"@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
"requires": {
"@types/node": "*"
}
},
"cacheable-lookup": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz",
"integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w=="
},
"cacheable-request": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz",
"integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==",
"requires": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
}
},
"clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"requires": { "requires": {
"mimic-response": "^1.0.0" "mimic-response": "^1.0.0"
} }
}, },
"duplexer3": { "compress-brotli": {
"version": "0.1.4", "version": "1.3.8",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.8.tgz",
"integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" "integrity": "sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==",
"requires": {
"@types/json-buffer": "~3.0.0",
"json-buffer": "~3.0.1"
}
},
"decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"requires": {
"mimic-response": "^3.1.0"
},
"dependencies": {
"mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
}
}
},
"defer-to-connect": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
"integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg=="
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"requires": {
"once": "^1.4.0"
}
}, },
"get-stream": { "get-stream": {
"version": "3.0.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"requires": {
"pump": "^3.0.0"
}
}, },
"got": { "got": {
"version": "7.1.0", "version": "11.8.5",
"resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz",
"integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==",
"requires": { "requires": {
"decompress-response": "^3.2.0", "@sindresorhus/is": "^4.0.0",
"duplexer3": "^0.1.4", "@szmarczak/http-timer": "^4.0.5",
"get-stream": "^3.0.0", "@types/cacheable-request": "^6.0.1",
"is-plain-obj": "^1.1.0", "@types/responselike": "^1.0.0",
"is-retry-allowed": "^1.0.0", "cacheable-lookup": "^5.0.3",
"is-stream": "^1.0.0", "cacheable-request": "^7.0.2",
"isurl": "^1.0.0-alpha5", "decompress-response": "^6.0.0",
"lowercase-keys": "^1.0.0", "http2-wrapper": "^1.0.0-beta.5.2",
"p-cancelable": "^0.3.0", "lowercase-keys": "^2.0.0",
"p-timeout": "^1.1.1", "p-cancelable": "^2.0.0",
"safe-buffer": "^5.0.1", "responselike": "^2.0.0"
"timed-out": "^4.0.0",
"url-parse-lax": "^1.0.0",
"url-to-options": "^1.0.1"
} }
}, },
"has-symbol-support-x": { "http-cache-semantics": {
"version": "1.4.2", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
}, },
"has-to-string-tag-x": { "http2-wrapper": {
"version": "1.4.1", "version": "1.0.0-beta.5.2",
"resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz",
"integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==",
"requires": { "requires": {
"has-symbol-support-x": "^1.4.1" "quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
} }
}, },
"is-object": { "json-buffer": {
"version": "1.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=" "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
}, },
"is-plain-obj": { "keyv": {
"version": "1.1.0", "version": "4.3.3",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.3.3.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" "integrity": "sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==",
},
"is-retry-allowed": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
"integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"isurl": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
"integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
"requires": { "requires": {
"has-to-string-tag-x": "^1.2.0", "compress-brotli": "^1.3.8",
"is-object": "^1.0.1" "json-buffer": "3.0.1"
} }
}, },
"kraken-api": { "kraken-api": {
"version": "1.0.0", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/kraken-api/-/kraken-api-1.0.0.tgz", "resolved": "https://registry.npmjs.org/kraken-api/-/kraken-api-1.0.1.tgz",
"integrity": "sha512-JAfLh9Laks+2KZTM/WW+bpy+iZfImUok0aeLBOb0ehwTEGvcBWWAXlmkthhJXfUTSoOIHuoqqToC94+iBeBBAg==", "integrity": "sha512-cOdQCobNlskn1hzFBZDwIliFYP+bAv2SUITG6oGWdVNHnxflcZo4hb/oY/t+RKkKtp95KTL+8R1iSZYQS4ZDwA==",
"requires": { "requires": {
"got": "^7.1.0", "got": "^11.1.4",
"qs": ">=6.4.0" "qs": "^6.9.4"
} }
}, },
"lowercase-keys": { "lowercase-keys": {
"version": "1.0.1", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
}, },
"mimic-response": { "mimic-response": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
}, },
"p-cancelable": { "normalize-url": {
"version": "0.3.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
}, },
"p-finally": { "once": {
"version": "1.0.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
},
"p-timeout": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
"integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
"requires": { "requires": {
"p-finally": "^1.0.0" "wrappy": "1"
} }
}, },
"prepend-http": { "p-cancelable": {
"version": "1.0.4", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg=="
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
}, },
"qs": { "qs": {
"version": "6.9.3", "version": "6.9.4",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
"integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==" "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ=="
}, },
"safe-buffer": { "quick-lru": {
"version": "5.2.0", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="
}, },
"timed-out": { "resolve-alpn": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
"integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
},
"url-parse-lax": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz",
"integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA=="
},
"responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"requires": { "requires": {
"prepend-http": "^1.0.1" "lowercase-keys": "^2.0.0"
} }
}, },
"url-to-options": { "wrappy": {
"version": "1.0.1", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=" "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
} }
} }
} }

View File

@@ -1,16 +1,23 @@
{ {
"private": true, "private": true,
"name": "stacking-sats-kraken", "name": "stacking-sats-kraken",
"version": "0.2.0", "version": "0.4.5",
"description": "Use the Kraken API to stack sats", "description": "Use the Kraken API to stack sats",
"author": "Dennis Reimann <mail@dennisreimann.de>", "author": "Dennis Reimann <mail@dennisreimann.de>",
"homepage": "https://github.com/dennisreimann/stacking-sats-kraken",
"bugs": "https://github.com/dennisreimann/stacking-sats-kraken/issues",
"funding": {
"url": "https://github.com/dennisreimann/stacking-sats-kraken?sponsor=1"
},
"license": "MIT", "license": "MIT",
"main": "index.js", "main": "stack.js",
"scripts": { "scripts": {
"stack-sats": "node index.js", "stack": "node index.js --cmd=stack",
"test": "node index.js --validate" "withdraw": "node index.js --cmd=withdraw",
"test:stack": "node index.js --cmd=stack --validate",
"test:withdraw": "node index.js --cmd=withdraw --validate"
}, },
"dependencies": { "dependencies": {
"kraken-api": "1.0.0" "kraken-api": "1.0.1"
} }
} }