Initial commit
This commit is contained in:
commit
6ea2d9b111
|
@ -0,0 +1,2 @@
|
|||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
|
@ -0,0 +1,127 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Rishi Panthee
|
||||
|
||||
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.
|
|
@ -0,0 +1,27 @@
|
|||
To setup:
|
||||
|
||||
Install Node.JS
|
||||
|
||||
```
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||
sudo apt install nodejs -y
|
||||
sudo apt install npm -y
|
||||
hash -r
|
||||
sudo npm install -g npm
|
||||
```
|
||||
|
||||
|
||||
Install dependencies:
|
||||
|
||||
```
|
||||
npm i
|
||||
npm i -g pm2
|
||||
```
|
||||
|
||||
Modify swap routes and accounts, index.js variable at line 4 and 110.
|
||||
|
||||
Start it up
|
||||
|
||||
```
|
||||
pm2 start index.js --name autoSwapWithdraw
|
||||
```
|
|
@ -0,0 +1,124 @@
|
|||
let axios = require("axios")
|
||||
let hive = require("@hiveio/hive-js")
|
||||
|
||||
const SERVICES = {
|
||||
"swaps": {
|
||||
"account": "swaps",
|
||||
"minimum": 1.501,
|
||||
},
|
||||
"beeswap": {
|
||||
"account": "hiveswap",
|
||||
"minimum": 1.001
|
||||
},
|
||||
"leodex": {
|
||||
"account": "leodex",
|
||||
"minimum": 1.001
|
||||
}
|
||||
}
|
||||
|
||||
const HIVE_ENGINE_RPC = "https://engine.rishipanthee.com/";
|
||||
const HIVE_RPC = "https://api.deathwing.me"
|
||||
|
||||
async function getUserBalance(username) {
|
||||
let account = await getAccount(username)
|
||||
let balance = {}
|
||||
if (account) {
|
||||
balance.HIVE = parseFloat(account.balance.split(" ")[0])
|
||||
balance.HBD = parseFloat(account.hbd_balance.split(" ")[0])
|
||||
} else {
|
||||
balance.HIVE = 0
|
||||
balance.HBD = 0
|
||||
}
|
||||
let engine = await getEngineBalances(username);
|
||||
balance["SWAP.HIVE"] = engine["SWAP.HIVE"] || 0
|
||||
return balance
|
||||
}
|
||||
|
||||
async function getEngineBalances(username) {
|
||||
let getBalancesQuery = { id: 0, jsonrpc: "2.0", method: "contracts.find", params: { contract: "tokens", table: "balances", query: { symbol: "SWAP.HIVE", account: username, $expr: { $gt: [{ $toDouble: "$balance" }, 0] } }, limit: 1000, offset: 0, indexes: [] } }
|
||||
let result = await axios.post(HIVE_ENGINE_RPC, getBalancesQuery)
|
||||
let balances = result.data.result
|
||||
let validBalances = {}
|
||||
for (let i in balances) {
|
||||
let balance = balances[i]
|
||||
if (parseFloat(balance.balance) !== 0) {
|
||||
validBalances[balance.symbol] = parseFloat(balance.balance)
|
||||
}
|
||||
}
|
||||
return validBalances
|
||||
}
|
||||
|
||||
|
||||
async function getAccount(user) {
|
||||
let res = null;
|
||||
try {
|
||||
res = await axios.post(HIVE_RPC, {
|
||||
'id': 0,
|
||||
'jsonrpc': '2.0',
|
||||
'method': 'condenser_api.get_accounts',
|
||||
'params': [[user]]
|
||||
});
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
if (res.data && res.data.result) {
|
||||
return res.data.result[0] || null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function doIt(account, activeKey, route) {
|
||||
let userBalance = await getUserBalance(account)
|
||||
for (let i in route) {
|
||||
if (SERVICES[route[i]]) {
|
||||
let serviceBalance = await getUserBalance(SERVICES[route[i]].account)
|
||||
if (SERVICES[route[i]].account === "swaps") {
|
||||
//Swaps is unique in that it uses other's to provide liquidity. We need to modify their max liquidity to account for that here
|
||||
let swapsRes = await axios("https://swaps.deathwing.me/liquidity")
|
||||
let swapsBalances = swapsRes.data
|
||||
let maxHive = 0
|
||||
for (let provider in swapsBalances) {
|
||||
if (provider.endsWith('he')) { //the swap.hive balance is kept with he at the end
|
||||
continue
|
||||
}
|
||||
if (swapsBalances[provider] > maxHive) {
|
||||
maxHive = swapsBalances[provider]
|
||||
}
|
||||
}
|
||||
serviceBalance["HIVE"] = maxHive - 1 //Subtract 1
|
||||
}
|
||||
if (serviceBalance["HIVE"] >= SERVICES[route[i]].minimum && userBalance["SWAP.HIVE"] >= SERVICES[route[i]].minimum) {
|
||||
let amountToSend = (userBalance["SWAP.HIVE"] > serviceBalance["HIVE"] ? serviceBalance["HIVE"] : userBalance["SWAP.HIVE"]) - 0.001
|
||||
let sendJSON = { "contractName": "tokens", "contractAction": "transfer", "contractPayload": { "symbol": "SWAP.HIVE", "to": SERVICES[route[i]].account, "quantity": amountToSend.toFixed(3), "memo": "" } }
|
||||
hive.broadcast.customJson(activeKey, [account], null, "ssc-mainnet-hive", JSON.stringify(sendJSON), (err, result) => {
|
||||
if (!err) {
|
||||
console.log(`Withdrew ${amountToSend.toFixed(3)} SWAP.HIVE with ${route[i]} for ${account}`)
|
||||
} else {
|
||||
console.error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function sleep(seconds) {
|
||||
return new Promise(resolve => setTimeout(resolve, seconds * 1000))
|
||||
}
|
||||
|
||||
let accounts = [
|
||||
{ username: "null", privateActiveKey: "YOURACTIVEKEYGOESHERE", routes: ["swaps", "beeswap", "leodex"] },
|
||||
]
|
||||
|
||||
async function withdraw() {
|
||||
for (let i in accounts) {
|
||||
await doIt(accounts[i].username, accounts[i].privateActiveKey, accounts[i].routes)
|
||||
await sleep(10)
|
||||
}
|
||||
}
|
||||
|
||||
withdraw()
|
||||
setInterval(() => {
|
||||
withdraw()
|
||||
}, 1000 * ((accounts.length + 3) * 10))
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "autoswapwithdraw",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@hiveio/hive-js": "^2.0.4",
|
||||
"axios": "^1.1.3"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue