🛠 Refactor to use commands
This commit is contained in:
12
README.md
12
README.md
@@ -113,21 +113,21 @@ You should regularly take ownership of your coins by withdrawing to your own wal
|
||||
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 witdrawal script.*
|
||||
*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
|
||||
➡️ 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
|
||||
➡️ 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.
|
||||
@@ -144,9 +144,7 @@ You should see something like this:
|
||||
|
||||
```text
|
||||
💡 Relative fee of withdrawal amount: 5.57%
|
||||
❌ Don't withdraw now. Fee is too high – max rel. fee: 0.50%
|
||||
|
||||
🚨 THIS WAS JUST A VALIDATION RUN, NO WITHDRAWAL HAS BEEN PLACED!
|
||||
❌ Fee is too high – max rel. fee: 0.50%
|
||||
```
|
||||
|
||||
It is recommended to run the withdrawal script every time you stacked sats:
|
||||
@@ -155,7 +153,7 @@ It is recommended to run the withdrawal script every time you stacked sats:
|
||||
npm run withdraw-sats
|
||||
```
|
||||
|
||||
Since it can take a couple seconds or minutes for your order to fill, you should run the following script maybe a couple hours later after your `stack-sats` script ran.
|
||||
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 your `stack-sats` script.
|
||||
Just set up a second cron job which executes the following script.
|
||||
|
||||
Here's a sample `withdraw-sats.sh` script:
|
||||
|
||||
31
commands/stack.js
Normal file
31
commands/stack.js
Normal file
@@ -0,0 +1,31 @@
|
||||
module.exports = async (kraken, validate, getEnv) => {
|
||||
const [fiat, amount] = getEnv('KRAKEN_API_FIAT', 'KRAKEN_BUY_AMOUNT')
|
||||
|
||||
// https://www.kraken.com/features/api
|
||||
const crypto = 'XBT'
|
||||
const pair = `X${crypto}Z${fiat}`
|
||||
|
||||
// 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
|
||||
const details = { pair, type: 'buy', ordertype: 'limit', price, volume }
|
||||
if (validate) details.validate = true
|
||||
|
||||
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
25
commands/withdraw.js
Normal 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)}%`)
|
||||
}
|
||||
}
|
||||
24
index.js
Normal file
24
index.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const assert = require('assert')
|
||||
const Kraken = require('kraken-api')
|
||||
|
||||
const getEnv = (...vars) => vars.map(name => {
|
||||
const value = process.env[name]
|
||||
assert(value, `Provide the ${name} environment variable.`)
|
||||
return value
|
||||
})
|
||||
const command = process.argv[2].replace('--cmd=', '')
|
||||
const validate = process.argv.includes('--validate') || process.env['KRAKEN_DRY_RUN_PLACE_NO_ORDER']
|
||||
|
||||
;(async () => {
|
||||
try {
|
||||
const [apiKey, secret] = getEnv('KRAKEN_API_KEY', 'KRAKEN_API_SECRET')
|
||||
const kraken = new Kraken(apiKey, secret)
|
||||
|
||||
const cmd = require(`./commands/${command}`)
|
||||
await cmd(kraken, validate, getEnv)
|
||||
|
||||
if (validate) console.log('\n🚨 THIS WAS JUST A VALIDATION RUN!')
|
||||
} catch (err) {
|
||||
console.log(`\n🚨 Failure:`, err.message)
|
||||
}
|
||||
})()
|
||||
@@ -7,10 +7,10 @@
|
||||
"license": "MIT",
|
||||
"main": "stack.js",
|
||||
"scripts": {
|
||||
"stack-sats": "node stack.js",
|
||||
"withdraw-sats": "node withdraw.js",
|
||||
"test:stack-sats": "node stack.js --validate",
|
||||
"test:withdraw-sats": "node withdraw.js --validate"
|
||||
"stack-sats": "node index.js --cmd=stack",
|
||||
"withdraw-sats": "node index.js --cmd=withdraw",
|
||||
"test:stack-sats": "node index.js --cmd=stack --validate",
|
||||
"test:withdraw-sats": "node index.js --cmd=withdraw --validate"
|
||||
},
|
||||
"dependencies": {
|
||||
"kraken-api": "1.0.0"
|
||||
|
||||
49
stack.js
49
stack.js
@@ -1,49 +0,0 @@
|
||||
const assert = require('assert')
|
||||
const Kraken = require('kraken-api')
|
||||
|
||||
const {
|
||||
KRAKEN_API_KEY: key,
|
||||
KRAKEN_API_SECRET: secret,
|
||||
KRAKEN_API_FIAT: fiat,
|
||||
KRAKEN_BUY_AMOUNT: amount
|
||||
} = process.env
|
||||
|
||||
assert(key && secret, 'Provide the KRAKEN_API_KEY and KRAKEN_API_SECRET environment variables.')
|
||||
assert(fiat && amount, 'Provide the KRAKEN_API_FIAT and KRAKEN_BUY_AMOUNT environment variables.')
|
||||
|
||||
// https://www.kraken.com/features/api
|
||||
const kraken = new Kraken(key, secret)
|
||||
const crypto = 'XBT'
|
||||
const pair = `X${crypto}Z${fiat}`
|
||||
const validate = process.argv[2] === '--validate'
|
||||
|
||||
;(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 {
|
||||
const details = { pair, type: 'buy', ordertype: 'limit', price, volume }
|
||||
if (validate) details.validate = true
|
||||
|
||||
const { result: { descr: { order }, txid } } = await kraken.api('AddOrder', details)
|
||||
|
||||
console.log('💸 Order:', order)
|
||||
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) {
|
||||
console.log(`\n🚨 Failure:`, err.message)
|
||||
}
|
||||
})()
|
||||
47
withdraw.js
47
withdraw.js
@@ -1,47 +0,0 @@
|
||||
const assert = require('assert')
|
||||
const Kraken = require('kraken-api')
|
||||
|
||||
const {
|
||||
KRAKEN_API_KEY: key,
|
||||
KRAKEN_API_SECRET: secret,
|
||||
KRAKEN_MAX_REL_FEE: max_fee,
|
||||
KRAKEN_WITHDRAW_KEY: wdr_key
|
||||
} = process.env
|
||||
|
||||
assert(key && secret, 'Provide the KRAKEN_API_KEY and KRAKEN_API_SECRET environment variables.')
|
||||
assert(max_fee && wdr_key, 'Provide the KRAKEN_MAX_REL_FEE and KRAKEN_WITHDRAW_KEY environment variables.')
|
||||
|
||||
// https://www.kraken.com/features/api
|
||||
const kraken = new Kraken(key, secret)
|
||||
const asset = 'XBT'
|
||||
const validate = process.argv[2] === '--validate'
|
||||
|
||||
;(async () => {
|
||||
// Get withdrawal information
|
||||
// URL: https://api.kraken.com/0/private/WithdrawInfo
|
||||
const withdrawdetails = { asset, key: wdr_key, amount: 0 }
|
||||
try {
|
||||
const { result: { limit, fee } } = await kraken.api('WithdrawInfo', withdrawdetails);
|
||||
const rel_fee = 1/parseFloat(limit)*parseFloat(fee)
|
||||
console.log(`💡 Relative fee of withdrawal amount: ${(rel_fee*100).toFixed(2)}%`)
|
||||
|
||||
// Place withdrawal when fee is low enough (relatively)
|
||||
if (rel_fee < max_fee/100) {
|
||||
console.log(`💰 Withdraw ${limit} ${asset} now.`)
|
||||
const withdraw = { asset, key: wdr_key, amount: limit }
|
||||
if (!validate) {
|
||||
try {
|
||||
const { result: { refid } } = await kraken.api('Withdraw', withdraw)
|
||||
if (refid) console.log(`📎 Withdrawal reference ID: ${refid}`)
|
||||
} catch (err) {
|
||||
console.log(`\n🚨 Failure:`, err.message)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`❌ Don't withdraw now. Fee is too high - max rel. fee: ${parseFloat(max_fee).toFixed(2)}%`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(`\n🚨 Failure:`, err.message)
|
||||
}
|
||||
if (validate) console.log('\n🚨 THIS WAS JUST A VALIDATION RUN, NO WITHDRAWAL HAS BEEN PLACED!')
|
||||
})()
|
||||
Reference in New Issue
Block a user