Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
DATA_ROOT_PATH=
HASURA_URL=
HASURA_ADMIN_KEY=
IMPORT_ENABLED=
DELTA_HEIGHT=
BTC_RPC_ENDPOINT=
INTERVAL_TIME_CONFIG=
INTERVAL_TIME_MINING=

6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.env
.idea
node_modules
.env
.idea
node_modules
.DS_Store
*/.DS_Store
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "1.0.0",
"description": "",
"scripts": {
"test": "node --max_old_space_size=4096 -r ts-eager/register ./src/script/test.ts",
"start": "node --max_old_space_size=4096 -r ts-eager/register ./src/index.ts",
"generate-graphql": "graphql-codegen --config codegen.js"
},
"author": "",
Expand Down Expand Up @@ -34,6 +34,7 @@
"got": "^12.0.1",
"graphql": "^16.2.0",
"js-sha512": "^0.8.0",
"node-cron": "^3.0.0",
"secp256k1": "^4.0.3"
}
}
10 changes: 6 additions & 4 deletions src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ dotenv.config();
export const HASURA_URL = process.env.HASURA_URL;
export const HASURA_ADMIN_KEY = process.env.HASURA_ADMIN_KEY;
export const STACKS_NODE_SQLITE_PATH = process.env.DATA_ROOT_PATH;
export const DELTA_HEIGHT = process.env.DELTA_HEIGHT
export const BTC_RPC_ENDPOINT = process.env.BTC_RPC_ENDPOINT
export const INTERVAL_TIME_CONFIG = process.env.INTERVAL_TIME_CONFIG
export const INTERVAL_TIME_MINING= process.env.INTERVAL_TIME_MINING
export const DELTA_HEIGHT = process.env.DELTA_HEIGHT;
export const BTC_RPC_ENDPOINT = process.env.BTC_RPC_ENDPOINT;
export const INTERVAL_TIME_CONFIG = process.env.INTERVAL_TIME_CONFIG;
export const INTERVAL_TIME_MINING= process.env.INTERVAL_TIME_MINING;
export const BINANCE_BASE_URL= 'https://api.binance.com/api/v3';
export const BLOCKCHAIN_INFO_BASE_URL= 'https://api.blockchain.info';
25 changes: 25 additions & 0 deletions src/connections/binance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import axios from "axios";
import {BINANCE_BASE_URL} from "../common/constants";

export const binanceApi = axios.create({
baseURL: BINANCE_BASE_URL,
});

const tickerPriceUrl = (coinPair: string) => `/ticker/price?symbol=${coinPair}`;

export const getStxPrice = async () => {
try {
const response = await binanceApi.get(tickerPriceUrl('STXUSDT'));
return response.data?.price;
} catch (e) {
throw Error(`Cant Fetch latest Stx Price ${e}`);
}
}
export const getBtcPrice = async () => {
try {
const response = await binanceApi.get(tickerPriceUrl('BTCUSDT'));
return response.data?.price;
} catch (e) {
throw Error(`Cant Fetch latest BTC Price ${e}`);
}
}
6 changes: 6 additions & 0 deletions src/connections/blockchainInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import axios from "axios";
import {BLOCKCHAIN_INFO_BASE_URL} from "../common/constants";

export const blockchainInfo = axios.create({
baseURL: BLOCKCHAIN_INFO_BASE_URL,
});
34 changes: 34 additions & 0 deletions src/connections/btcRpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import axios from "axios";
import {BTC_RPC_ENDPOINT} from "../common/constants";

export const btcRpc = axios.create({
baseURL: BTC_RPC_ENDPOINT,
});

enum BTC_RPC_METHODS {
GET_RAW_TRANSACTION= 'getrawtransaction'
}

export const fetchBtcRpcData = async (method: BTC_RPC_METHODS, params: any[]) => {
try {
return await btcRpc.post(BTC_RPC_ENDPOINT, {
jsonrpc: "1.0",
id: "curltest",
method,
params,
})
} catch (e) {
console.error(e);
}
}


export const getRawTransaction = async (transactionId: string) => {
try {
const response = await fetchBtcRpcData(BTC_RPC_METHODS.GET_RAW_TRANSACTION, [transactionId, true]);
return {response, error: undefined}
} catch (e) {
return {response: undefined, error: e}
}
}

19 changes: 19 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {importMiningData } from "./script/block";
import {updateHashPower, updateTokenPrice} from "./script/config";
import cron from 'node-cron';


cron.schedule('* * * * *', async function() {
console.log('here');
await updateTokenPrice()
await updateHashPower();
});




cron.schedule('0 */5 * * *', async function() {
await importMiningData();
});


130 changes: 11 additions & 119 deletions src/script/test.ts → src/script/block.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
// import {importData} from "./mining-importer";
import {getMinerInfo, getTransactionFromBtcRpc} from "./mining-test";
import axios from "axios";
import {graphClient} from "../common/graphql-client";
import {importBlockInfos} from "./common/importer-block-info";
import {getMinerInfo, getTransactionFromBtcRpc} from "./mining";
import {importBlockInfos} from "../services/graphql/importer-block-info";
import {
Block_Info_Insert_Input, Commit_Gas_Info_Insert_Input,
Commit_Info_Arr_Rel_Insert_Input,
Commit_Info_Insert_Input, Config_Insert_Input
Commit_Info_Insert_Input,
} from "../../graphql/node-types";
import {block} from "@graphql-codegen/visitor-plugin-common";
import c32 from "c32check";
import {fetchLatestBlock} from "./common/fetch-latest-block-height";
import {fetchBurnchainOpsRowid} from "./common/fetch-burnchain-ops-rowid";
import {fetchLatestTxId} from "./common/fetch-latest-txid";
import {DELTA_HEIGHT, INTERVAL_TIME_CONFIG, INTERVAL_TIME_MINING} from "../common/constants";
import {importConfigItem} from "./common/import-config-item";
import {fetchLatestBlock} from "../services/graphql/fetch-latest-block-height";
import {fetchBurnchainOpsRowid} from "../services/graphql/fetch-burnchain-ops-rowid";
import {DELTA_HEIGHT} from "../common/constants";
import fs from "fs"
const file = fs.createWriteStream('./log.txt');
let logger = new console.Console(file, file);
Expand All @@ -23,16 +16,16 @@ let logger = new console.Console(file, file);



async function importMiningData() {
export async function importMiningData() {
// find the start_stacks_block_height and start_burn_block_height
let latest_block = await fetchLatestBlock()
const latest_block = await fetchLatestBlock()
//console.log(latest_block.block_info[0].stacks_block_height, latest_block.block_info[0].btc_block_height)
//let latest_txid_ob = await fetchLatestTxId()
//let latest_txid = latest_txid_ob.commit_gas_info.length == 0? "": latest_txid_ob.commit_gas_info[0].commit_btc_tx_id
let latest_txid = ""
const latest_txid = ""
// find latest burnchain ops rowid
let latest_rowid_ob = await fetchBurnchainOpsRowid()
let latest_rowid = latest_rowid_ob.config.length === 0 ? 0 : parseInt(latest_rowid_ob.config[0].value)
const latest_rowid_ob = await fetchBurnchainOpsRowid()
const latest_rowid = latest_rowid_ob.config.length === 0 ? 0 : parseInt(latest_rowid_ob.config[0].value)

let start_stacks_block_height = latest_block.block_info.length === 0? 0 : latest_block.block_info[0].stacks_block_height
let start_btc_block_height = latest_block.block_info.length === 0? 666050 : latest_block.block_info[0].btc_block_height
Expand All @@ -54,15 +47,13 @@ async function importMiningData() {
but block_commits has ${Object.getOwnPropertyNames(miningInfo.block_commits).length} items`);
return
} else {

// handle blockInfo and commitInfo
let rowsToImport : Block_Info_Insert_Input[] = []
for (let k of Object.keys(miningInfo.winner_info)){
let miningInfoLen = Object.getOwnPropertyNames(miningInfo.winner_info).length
let block_info = miningInfo.winner_info[k]
let commit_info = miningInfo.block_commits[k]
let blockInfoItem: Block_Info_Insert_Input = {}

// blockInfo
// force check to confirm if stacks_block_height is 0
if (block_info.stacks_block_height < start_stacks_block_height || block_info.burn_chain_height < start_btc_block_height){
Expand Down Expand Up @@ -116,112 +107,13 @@ async function importMiningData() {
}
rowsToImport.push(blockInfoItem)
}

await importBlockInfos(rowsToImport)
}


// handle graphql insert

}


async function updateTokenPrice(){
return new Promise(async function (resolve, reject) {
try {
let stx_usdt_url = "https://api.binance.com/api/v3/ticker/price?symbol=STXUSDT";
let btc_usdt_url = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT";
const stx_resp = await axios(stx_usdt_url)
const btc_resp = await axios(btc_usdt_url)
console.log(stx_resp.data)
console.log(btc_resp.data)
if (stx_resp.data != undefined && btc_resp.data != undefined){
let rows :Config_Insert_Input[] = []
let stx_row : Config_Insert_Input = {
name: "stx_price",
value: stx_resp.data.price,
comment: "stx price"
}
let btc_row : Config_Insert_Input = {
name: "btc_price",
value: btc_resp.data.price,
comment: "btc price"
}
rows.push(stx_row)
rows.push(btc_row)
await importConfigItem(rows)
resolve("finished")
}
} catch (error){
reject(error)
}
}).catch((error) => {
console.log(error)
})
}

async function updateHashPower(){
return new Promise(async function (resolve, reject) {
try {
let url = "https://api.blockchain.info/stats";
let res = await axios((url).toString())

if (res.data != undefined) {
let hash_rate = (res.data.hash_rate / 1E9).toFixed(2)
console.log(`hash_rate: ${hash_rate}`)
let rows: Config_Insert_Input[] = []
let hash_rate_row: Config_Insert_Input = {
name: "btc_hashrate",
value: String(hash_rate),
comment: "btc hash rate"
}
rows.push(hash_rate_row)
await importConfigItem(rows)
resolve("finished")
}
} catch (error) {
reject(error)
}
}).catch((error) => {
console.log(error)
})

}



async function sleep(ms) {
console.log("sleeping")
return new Promise<void>((resolve, reject) => {
setTimeout(
() => {
console.log("sleep time out")
resolve()
}, ms)
})
}

/*
Main Function
*/

(async () => {
setInterval(
async function (){
await updateTokenPrice()
await updateHashPower()
},
parseInt(INTERVAL_TIME_CONFIG) * 1000
)
while (true){
try {
await sleep(parseInt(INTERVAL_TIME_MINING) * 1000)
await importMiningData()
} catch (e) {
console.log(e)
}
}
}) ()



Expand Down
52 changes: 52 additions & 0 deletions src/script/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {getBtcPrice, getStxPrice} from "../connections/binance";
import {Config_Insert_Input} from "../../graphql/node-types";
import {importConfigItem} from "../services/graphql/import-config-item";
import {blockchainInfo} from "../connections/blockchainInfo";

export async function updateTokenPrice(){
try {
const stxPrice = await getStxPrice();
const btcPrice = await getBtcPrice();
console.log(stxPrice)
console.log(btcPrice)
if (stxPrice != undefined && btcPrice != undefined){
let rows :Config_Insert_Input[] = []
let stx_row : Config_Insert_Input = {
name: "stx_price",
value: stxPrice,
comment: "stx price"
}
let btc_row : Config_Insert_Input = {
name: "btc_price",
value: btcPrice,
comment: "btc price"
}
rows.push(stx_row)
rows.push(btc_row)
await importConfigItem(rows)
}
} catch (error){
throw (error);
}
}

export const updateHashPower = async() => {
try {
const res = await blockchainInfo.get('/stats');
if (res.data != undefined) {
let hash_rate = (res.data.hash_rate / 1E9).toFixed(2)
console.log(`hash_rate: ${hash_rate}`)
let rows: Config_Insert_Input[] = []
let hash_rate_row: Config_Insert_Input = {
name: "btc_hashrate",
value: String(hash_rate),
comment: "btc hash rate"
}
rows.push(hash_rate_row)
await importConfigItem(rows)
}
} catch (error) {
console.log(error);
throw (error);
}
}
Loading