55 changed files with 15453 additions and 0 deletions
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"env": { |
||||||
|
"test": { |
||||||
|
"presets": [ |
||||||
|
[ |
||||||
|
"@babel/preset-env", |
||||||
|
{ |
||||||
|
"targets": { |
||||||
|
"node": "current" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
# editorconfig.org |
||||||
|
root = true |
||||||
|
|
||||||
|
[*] |
||||||
|
indent_style = space |
||||||
|
indent_size = 2 |
||||||
|
end_of_line = lf |
||||||
|
charset = utf-8 |
||||||
|
trim_trailing_whitespace = true |
||||||
|
insert_final_newline = true |
||||||
|
|
||||||
|
[*.md] |
||||||
|
trim_trailing_whitespace = false |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
module.exports = { |
||||||
|
root: true, |
||||||
|
env: { |
||||||
|
browser: true, |
||||||
|
node: true, |
||||||
|
}, |
||||||
|
parserOptions: { |
||||||
|
parser: 'babel-eslint', |
||||||
|
}, |
||||||
|
extends: [ |
||||||
|
'@nuxtjs', |
||||||
|
'prettier', |
||||||
|
'plugin:prettier/recommended', |
||||||
|
'plugin:nuxt/recommended', |
||||||
|
], |
||||||
|
plugins: ['prettier'], |
||||||
|
// add your custom rules here
|
||||||
|
rules: {}, |
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
version: 2 |
||||||
|
updates: |
||||||
|
# Fetch and update latest `npm` packages |
||||||
|
- package-ecosystem: npm |
||||||
|
directory: '/' |
||||||
|
schedule: |
||||||
|
interval: daily |
||||||
|
time: '00:00' |
||||||
|
open-pull-requests-limit: 10 |
||||||
|
reviewers: |
||||||
|
- iquidus |
||||||
|
assignees: |
||||||
|
- iquidus |
||||||
|
commit-message: |
||||||
|
prefix: fix |
||||||
|
prefix-development: chore |
||||||
|
include: scope |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
# Always validate the PR title AND all the commits |
||||||
|
titleAndCommits: true |
||||||
|
# Allows use of Merge commits (eg on github: "Merge branch 'master' into feature/ride-unicorns") |
||||||
|
# this is only relevant when using commitsOnly: true (or titleAndCommits: true) |
||||||
|
allowMergeCommits: true |
||||||
@ -0,0 +1,93 @@ |
|||||||
|
# Created by .ignore support plugin (hsz.mobi) |
||||||
|
### Node template |
||||||
|
# Logs |
||||||
|
/logs |
||||||
|
*.log |
||||||
|
npm-debug.log* |
||||||
|
yarn-debug.log* |
||||||
|
yarn-error.log* |
||||||
|
|
||||||
|
# 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 |
||||||
|
|
||||||
|
# nyc test coverage |
||||||
|
.nyc_output |
||||||
|
|
||||||
|
# Grunt intermediate storage (http://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/ |
||||||
|
|
||||||
|
# TypeScript v1 declaration files |
||||||
|
typings/ |
||||||
|
|
||||||
|
# Optional npm cache directory |
||||||
|
.npm |
||||||
|
|
||||||
|
# Optional eslint cache |
||||||
|
.eslintcache |
||||||
|
|
||||||
|
# Optional REPL history |
||||||
|
.node_repl_history |
||||||
|
|
||||||
|
# Output of 'npm pack' |
||||||
|
*.tgz |
||||||
|
|
||||||
|
# Yarn Integrity file |
||||||
|
.yarn-integrity |
||||||
|
|
||||||
|
# dotenv environment variables file |
||||||
|
.env |
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/) |
||||||
|
.cache |
||||||
|
|
||||||
|
# next.js build output |
||||||
|
.next |
||||||
|
|
||||||
|
# nuxt.js build output |
||||||
|
.nuxt |
||||||
|
|
||||||
|
# Nuxt generate |
||||||
|
dist |
||||||
|
|
||||||
|
# vuepress build output |
||||||
|
.vuepress/dist |
||||||
|
|
||||||
|
# Serverless directories |
||||||
|
.serverless |
||||||
|
|
||||||
|
# IDE / Editor |
||||||
|
.idea |
||||||
|
|
||||||
|
# Service worker |
||||||
|
sw.* |
||||||
|
|
||||||
|
# macOS |
||||||
|
.DS_Store |
||||||
|
|
||||||
|
# Vim swap files |
||||||
|
*.swp |
||||||
|
|
||||||
|
# params/config.json |
||||||
|
params/config.json |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
#!/bin/sh |
||||||
|
. "$(dirname "$0")/_/husky.sh" |
||||||
|
|
||||||
|
yarn lint |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
# vue-core-pool |
||||||
|
|
||||||
|
vue based frontend for core-pool |
||||||
|
|
||||||
|
## Install |
||||||
|
|
||||||
|
```bash |
||||||
|
# clone the repo |
||||||
|
git clone https://github.com/etclabscore/vue-core-pool.git |
||||||
|
cd vue-core-pool |
||||||
|
|
||||||
|
# configure |
||||||
|
cp params/example.config.json params/config.json |
||||||
|
nano params/config.json |
||||||
|
``` |
||||||
|
|
||||||
|
See: [params/README.md](https://github.com/etclabscore/vue-core-pool/blob/master/params/README.md) for more details. |
||||||
|
|
||||||
|
## Build Setup |
||||||
|
|
||||||
|
```bash |
||||||
|
# install dependencies |
||||||
|
$ yarn |
||||||
|
|
||||||
|
# serve with hot reload at localhost:3000 |
||||||
|
$ yarn dev |
||||||
|
|
||||||
|
# generate static project |
||||||
|
$ yarn generate |
||||||
|
``` |
||||||
|
|
||||||
|
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). |
||||||
|
|
||||||
|
## Example caddy v2 config |
||||||
|
|
||||||
|
``` |
||||||
|
{ |
||||||
|
email your@email.com |
||||||
|
} |
||||||
|
|
||||||
|
your.pool.domain.com { |
||||||
|
file_server |
||||||
|
root * /home/etclabscore/vue-core-pool/dist |
||||||
|
try_files {path} /index.html |
||||||
|
encode gzip |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## Development |
||||||
|
|
||||||
|
vue-core-pool is built using [Vue.js](https://vuejs.org/), [NuxtJS](https://nuxtjs.org/), and [Vuetify](https://vuetifyjs.com/). If modifying/contributing a basic understanding of these frameworks is recommended. |
||||||
|
|
||||||
|
## screenshots |
||||||
|
|
||||||
|
### index page |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
### pool blocks page |
||||||
|
|
||||||
|
 |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
// Ref: https://github.com/nuxt-community/vuetify-module#customvariables |
||||||
|
// |
||||||
|
// The variables you want to modify |
||||||
|
// $font-size-root: 20px; |
||||||
@ -0,0 +1,122 @@ |
|||||||
|
<template> |
||||||
|
<a :href="formatUrl()" target="_blank">{{ formatHash(hash, clip) }}</a> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
props: { |
||||||
|
hash: { |
||||||
|
// the tx or block hash/number |
||||||
|
type: String, |
||||||
|
default() { |
||||||
|
return '0x0' |
||||||
|
}, |
||||||
|
}, |
||||||
|
linkType: { |
||||||
|
// link type (tx or block) |
||||||
|
type: String, |
||||||
|
default() { |
||||||
|
return 'tx' |
||||||
|
}, |
||||||
|
}, |
||||||
|
clip: { |
||||||
|
// shorten inner url to (0x[clip][separator][clip]) characters. 0 = dont clip. |
||||||
|
type: Number, |
||||||
|
default() { |
||||||
|
return 0 |
||||||
|
}, |
||||||
|
}, |
||||||
|
separator: { |
||||||
|
type: String, |
||||||
|
default() { |
||||||
|
return '...' |
||||||
|
}, |
||||||
|
}, |
||||||
|
config: { |
||||||
|
// config |
||||||
|
type: Object, |
||||||
|
default() { |
||||||
|
return {} |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
formatUrl() { |
||||||
|
// see: https://github.com/ethereum/EIPs/pull/3091 |
||||||
|
// explorer.type |
||||||
|
// expedition, blockscout, etherscan, etherchain, spectrum |
||||||
|
// note, most of these are fairly similar however keeping all as options incase of future deviations. |
||||||
|
const url = this.config.explorer.url |
||||||
|
const type = this.config.explorer.type |
||||||
|
let network = this.config.network |
||||||
|
const symbol = this.config.symbol.toLowerCase() |
||||||
|
let append = '/' |
||||||
|
|
||||||
|
// handle link type deviations |
||||||
|
switch (this.linkType) { |
||||||
|
case 'block': |
||||||
|
if (type === 'blockscout') { |
||||||
|
append = append + 'blocks/' |
||||||
|
} else { |
||||||
|
// etherscan, etherchain or expedition, spectrum |
||||||
|
append = append + 'block/' |
||||||
|
} |
||||||
|
break |
||||||
|
case 'account': |
||||||
|
if (type === 'etherchain') { |
||||||
|
append = append + 'account/' |
||||||
|
} else { |
||||||
|
// etherscan, blockscout, expedition, spectrum |
||||||
|
append = append + 'address/' |
||||||
|
} |
||||||
|
break |
||||||
|
case 'token': |
||||||
|
if (type === 'blockscout') { |
||||||
|
append = append + 'tokens/' |
||||||
|
} else { |
||||||
|
// etherscan, etherchain, expedition, spectrum |
||||||
|
append = append + 'token/' |
||||||
|
} |
||||||
|
break |
||||||
|
case 'tx': |
||||||
|
append = append + 'tx/' // yayyy conformity |
||||||
|
break |
||||||
|
default: |
||||||
|
// o.O something very odd has occured O.o |
||||||
|
// check your link-type argument, it should be: |
||||||
|
// block, account, token, or tx |
||||||
|
} |
||||||
|
|
||||||
|
// handle network deviations |
||||||
|
switch (type) { |
||||||
|
case 'expedition': |
||||||
|
if (network === 'classic') { |
||||||
|
network = 'mainnet' |
||||||
|
} |
||||||
|
append = append + this.hash + '?network=' + network |
||||||
|
break |
||||||
|
case 'blockscout': |
||||||
|
if (network === 'classic') { |
||||||
|
network = 'mainnet' |
||||||
|
} |
||||||
|
append = '/' + symbol + '/' + network + append + this.hash |
||||||
|
break |
||||||
|
default: |
||||||
|
append = append + this.hash |
||||||
|
} |
||||||
|
return url + append |
||||||
|
}, |
||||||
|
formatHash(hash, len) { |
||||||
|
if (hash === '0x0' || !hash) { |
||||||
|
return 'N/A' |
||||||
|
} |
||||||
|
if (len > 0) { |
||||||
|
const start = hash.substring(0, len + 2) |
||||||
|
const end = hash.substring(hash.length - len) |
||||||
|
return start + this.separator + end |
||||||
|
} |
||||||
|
return hash |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,134 @@ |
|||||||
|
<template> |
||||||
|
<v-card flat tile> |
||||||
|
<v-card-title> |
||||||
|
<v-text-field |
||||||
|
v-model="search" |
||||||
|
append-icon="mdi-magnify" |
||||||
|
:label="$t('pages.blocks.search')" |
||||||
|
single-line |
||||||
|
outlined |
||||||
|
hide-details |
||||||
|
></v-text-field> |
||||||
|
</v-card-title> |
||||||
|
<v-data-table |
||||||
|
dense |
||||||
|
:headers="headers" |
||||||
|
:items="blocks" |
||||||
|
:footer-props="{ |
||||||
|
itemsPerPageText: $t('pages.blocks.blocksPerPage'), |
||||||
|
itemsPerPageOptions: [25, 50, 100], |
||||||
|
}" |
||||||
|
:items-per-page="25" |
||||||
|
:search="search" |
||||||
|
:no-data-text="noDataText" |
||||||
|
> |
||||||
|
<template #[`item.height`]="{ item }"> |
||||||
|
{{ nf.format(item.height) }} |
||||||
|
</template> |
||||||
|
<template #[`item.shares`]="{ item }"> |
||||||
|
{{ nf.format(((item.shares / item.difficulty) * 100).toFixed(0)) }}% |
||||||
|
</template> |
||||||
|
<template #[`item.uncle`]="{ item }"> |
||||||
|
<v-chip label small :color="formatBlockType(item).color">{{ |
||||||
|
formatBlockType(item).text |
||||||
|
}}</v-chip> |
||||||
|
</template> |
||||||
|
<template #[`item.timestamp`]="{ item }"> |
||||||
|
{{ dtf.format(item.timestamp * 1000) }} |
||||||
|
</template> |
||||||
|
<template #[`item.hash`]="{ item }"> |
||||||
|
<explorer-link |
||||||
|
:hash="item.hash" |
||||||
|
link-type="block" |
||||||
|
:clip="8" |
||||||
|
:config="config" |
||||||
|
/> |
||||||
|
</template> |
||||||
|
<template #[`item.reward`]="{ item }"> |
||||||
|
{{ formatReward(item.reward).toFixed(6) }} |
||||||
|
</template> |
||||||
|
</v-data-table> |
||||||
|
</v-card> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import ExplorerLink from '~/components/ExplorerLink' |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
ExplorerLink, |
||||||
|
}, |
||||||
|
props: { |
||||||
|
blocks: { |
||||||
|
type: Array, |
||||||
|
default() { |
||||||
|
return [] |
||||||
|
}, |
||||||
|
}, |
||||||
|
config: { |
||||||
|
type: Object, |
||||||
|
default() { |
||||||
|
return {} |
||||||
|
}, |
||||||
|
}, |
||||||
|
noDataText: { |
||||||
|
type: String, |
||||||
|
default() { |
||||||
|
return 'No blocks' |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
search: null, |
||||||
|
dtf: new Intl.DateTimeFormat('en', { |
||||||
|
year: 'numeric', |
||||||
|
month: 'numeric', |
||||||
|
day: 'numeric', |
||||||
|
hour: 'numeric', |
||||||
|
minute: 'numeric', |
||||||
|
second: 'numeric', |
||||||
|
}), |
||||||
|
nf: new Intl.NumberFormat(this.locale, {}), |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
headers() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
text: this.$t('pages.blocks.blockNumber'), |
||||||
|
align: 'start', |
||||||
|
value: 'height', |
||||||
|
}, |
||||||
|
{ text: this.$t('pages.blocks.blockHash'), value: 'hash' }, |
||||||
|
{ text: this.$t('pages.blocks.timeFound'), value: 'timestamp' }, |
||||||
|
{ text: this.$t('pages.blocks.variance'), value: 'shares' }, |
||||||
|
{ |
||||||
|
text: |
||||||
|
this.$t('pages.blocks.reward') + ' (' + this.config.symbol + ')', |
||||||
|
align: 'right', |
||||||
|
value: 'reward', |
||||||
|
}, |
||||||
|
{ text: this.$t('pages.blocks.type'), value: 'uncle', align: 'right' }, |
||||||
|
] |
||||||
|
}, |
||||||
|
locale() { |
||||||
|
return this.$i18n.locale |
||||||
|
}, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
formatBlockType(block) { |
||||||
|
if (!block.uncle && !block.orphan) { |
||||||
|
return { color: 'success', text: this.$t('pages.blocks.block') } |
||||||
|
} else if (block.uncle) { |
||||||
|
return { color: 'warning', text: this.$t('pages.blocks.uncle') } |
||||||
|
} else { |
||||||
|
return { color: 'error', text: this.$t('pages.blocks.orphan') } |
||||||
|
} |
||||||
|
}, |
||||||
|
formatReward(wei) { |
||||||
|
return wei / 1000000000000000000 |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,126 @@ |
|||||||
|
<template> |
||||||
|
<v-card flat tile> |
||||||
|
<v-card-title> |
||||||
|
<v-text-field |
||||||
|
v-model="search" |
||||||
|
append-icon="mdi-magnify" |
||||||
|
:label="$t('pages.payments.search')" |
||||||
|
single-line |
||||||
|
outlined |
||||||
|
hide-details |
||||||
|
></v-text-field> |
||||||
|
</v-card-title> |
||||||
|
<v-data-table |
||||||
|
dense |
||||||
|
:headers="headers" |
||||||
|
:items="payments" |
||||||
|
:footer-props="{ |
||||||
|
itemsPerPageText: $t('pages.payments.paymentsPerPage'), |
||||||
|
itemsPerPageOptions: [25, 50, 100], |
||||||
|
}" |
||||||
|
:items-per-page="25" |
||||||
|
:search="search" |
||||||
|
:no-data-text="$t('pages.payments.noPayments')" |
||||||
|
> |
||||||
|
<template #[`item.timestamp`]="{ item }"> |
||||||
|
{{ dtf.format(item.timestamp * 1000) }} |
||||||
|
</template> |
||||||
|
<template #[`item.address`]="{ item }"> |
||||||
|
<nuxt-link :to="'/account/' + item.address">{{ |
||||||
|
formatAccountHash(item.address) |
||||||
|
}}</nuxt-link> |
||||||
|
</template> |
||||||
|
<template #[`item.tx`]="{ item }"> |
||||||
|
<explorer-link :hash="item.tx" :config="config" :clip="12" /> |
||||||
|
</template> |
||||||
|
<template #[`item.amount`]="{ item }"> |
||||||
|
{{ formatReward(item.amount) }} {{ symbol }} |
||||||
|
</template> |
||||||
|
</v-data-table> |
||||||
|
</v-card> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import ExplorerLink from '~/components/ExplorerLink' |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
ExplorerLink, |
||||||
|
}, |
||||||
|
props: { |
||||||
|
payments: { |
||||||
|
type: Array, |
||||||
|
default() { |
||||||
|
return [] |
||||||
|
}, |
||||||
|
}, |
||||||
|
headers: { |
||||||
|
type: Array, |
||||||
|
default() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
text: this.$t('pages.payments.time'), |
||||||
|
align: 'start', |
||||||
|
value: 'timestamp', |
||||||
|
}, |
||||||
|
{ text: this.$t('pages.payments.address'), value: 'address' }, |
||||||
|
{ text: this.$t('pages.payments.txid'), value: 'tx' }, |
||||||
|
{ |
||||||
|
text: this.$t('pages.payments.amount'), |
||||||
|
value: 'amount', |
||||||
|
align: 'right', |
||||||
|
}, |
||||||
|
] |
||||||
|
}, |
||||||
|
}, |
||||||
|
config: { |
||||||
|
type: Object, |
||||||
|
default() { |
||||||
|
return {} |
||||||
|
}, |
||||||
|
}, |
||||||
|
noDataText: { |
||||||
|
type: String, |
||||||
|
default() { |
||||||
|
return this.$t('pages.payments.noPayments') |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
search: null, |
||||||
|
symbol: this.config.symbol, |
||||||
|
nf: new Intl.NumberFormat(this.locale, {}), |
||||||
|
dtf: new Intl.DateTimeFormat(this.locale, { |
||||||
|
year: 'numeric', |
||||||
|
month: 'numeric', |
||||||
|
day: 'numeric', |
||||||
|
hour: 'numeric', |
||||||
|
minute: 'numeric', |
||||||
|
second: 'numeric', |
||||||
|
}), |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
now() { |
||||||
|
return this.$store.state.now |
||||||
|
}, |
||||||
|
locale() { |
||||||
|
return this.$i18n.locale |
||||||
|
}, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
formatAccountHash(account) { |
||||||
|
if (account === '0x0' || !account) { |
||||||
|
return 'N/A' |
||||||
|
} |
||||||
|
const start = account.substring(0, 10) |
||||||
|
const end = account.substring(account.length - 10) |
||||||
|
return start + '...' + end |
||||||
|
}, |
||||||
|
formatReward(shannon) { |
||||||
|
return shannon / 1000000000 |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
--- |
||||||
|
title: GMiner |
||||||
|
minVer: 2.30 |
||||||
|
releases: https://github.com/develsoftware/GMinerRelease/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
gminer --algo etchash --server STRATUM_HOST --user 0xda904bc07fd95e39661941b3f6daded1b8a38c71 |
||||||
|
``` |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
--- |
||||||
|
title: lolMiner |
||||||
|
minVer: 1.12 |
||||||
|
releases: https://github.com/Lolliedieb/lolMiner-releases/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
################################# |
||||||
|
## Begin of user-editable part ## |
||||||
|
################################# |
||||||
|
|
||||||
|
POOL=STRATUM_HOST |
||||||
|
# Address to send funds to. Change this address to yours! |
||||||
|
WALLET=0xda904bc07fd95e39661941b3f6daded1b8a38c71 |
||||||
|
|
||||||
|
################################# |
||||||
|
## End of user-editable part ## |
||||||
|
################################# |
||||||
|
|
||||||
|
cd "$(dirname "$0")" |
||||||
|
|
||||||
|
./lolMiner -c ETC --pool $POOL --user $WALLET --ethstratum=ETHPROXY $@ |
||||||
|
``` |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
--- |
||||||
|
title: nanominer |
||||||
|
minVer: 1.12.0 |
||||||
|
releases: https://github.com/nanopool/nanominer/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
; Address to send funds to. Change this address to yours! |
||||||
|
wallet = 0xda904bc07fd95e39661941b3f6daded1b8a38c71 |
||||||
|
|
||||||
|
; Coin to mine. |
||||||
|
coin = ETC |
||||||
|
|
||||||
|
pool1=STRATUM_HOST |
||||||
|
``` |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
--- |
||||||
|
title: NBMiner |
||||||
|
minVer: 33.4 |
||||||
|
releases: https://github.com/NebuTech/NBMiner/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
nbminer -a etchash -o ethproxy+tcp://STRATUM_HOST -u 0xda904bc07fd95e39661941b3f6daded1b8a38c71 |
||||||
|
``` |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
--- |
||||||
|
title: SRBMiner |
||||||
|
minVer: 0.5.6 |
||||||
|
releases: https://github.com/doktor83/SRBMiner-Multi/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
SRBMiner-MULTI --disable-cpu --algorithm etchash --pool STRATUM_HOST --wallet 0xda904bc07fd95e39661941b3f6daded1b8a38c71 --gpu-boost 5 |
||||||
|
``` |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
--- |
||||||
|
title: Team Red Miner |
||||||
|
minVer: 0.7.18 |
||||||
|
releases: https://github.com/todxx/teamredminer/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
teamredminer -a etchash -o stratum+tcp://STRATUM_HOST -u 0xda904bc07fd95e39661941b3f6daded1b8a38c71 -p x |
||||||
|
``` |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
--- |
||||||
|
title: T-Rex |
||||||
|
minVer: 0.18.8 |
||||||
|
releases: https://github.com/trexminer/T-Rex/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
t-rex -a etchash -o stratum+tcp://STRATUM_HOST -u 0xda904bc07fd95e39661941b3f6daded1b8a38c71 -p x -w rig0 |
||||||
|
``` |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
--- |
||||||
|
title: GMiner |
||||||
|
minVer: 2.30 |
||||||
|
releases: https://github.com/develsoftware/GMinerRelease/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
gminer --algo etchash_test --server STRATUM_HOST --user 0xda904bc07fd95e39661941b3f6daded1b8a38c71 |
||||||
|
``` |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
--- |
||||||
|
title: lolMiner |
||||||
|
minVer: 1.12 |
||||||
|
releases: https://github.com/Lolliedieb/lolMiner-releases/releases |
||||||
|
--- |
||||||
|
|
||||||
|
``` |
||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
################################# |
||||||
|
## Begin of user-editable part ## |
||||||
|
################################# |
||||||
|
|
||||||
|
POOL=STRATUM_HOST |
||||||
|
# Address to send funds to. Change this address to yours! |
||||||
|
WALLET=0xda904bc07fd95e39661941b3f6daded1b8a38c71 |
||||||
|
|
||||||
|
################################# |
||||||
|
## End of user-editable part ## |
||||||
|
################################# |
||||||
|
|
||||||
|
cd "$(dirname "$0")" |
||||||
|
|
||||||
|
./lolMiner -c ETC --pool $POOL --user $WALLET --ecip1099-activation 84 --ethstratum=ETHPROXY $@ |
||||||
|
``` |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
{ |
||||||
|
"menu": { |
||||||
|
"home": "Home", |
||||||
|
"blocks": "Pool Blocks", |
||||||
|
"payments": "Payments", |
||||||
|
"help": "Help", |
||||||
|
"miningPool": "mining pool", |
||||||
|
"minimize": "Minimize" |
||||||
|
}, |
||||||
|
"info": { |
||||||
|
"pool": { |
||||||
|
"title": "POOL", |
||||||
|
"hashrate": "Hashrate", |
||||||
|
"lastBlock": "Last Block", |
||||||
|
"miners": "Online", |
||||||
|
"fee": "Fee" |
||||||
|
}, |
||||||
|
"network": { |
||||||
|
"title": "NETWORK", |
||||||
|
"height": "Block Height", |
||||||
|
"difficulty": "Difficulty", |
||||||
|
"hashrate": "Hashrate", |
||||||
|
"epoch": "Epoch", |
||||||
|
"dag": "DAG" |
||||||
|
}, |
||||||
|
"hide": "Hide" |
||||||
|
}, |
||||||
|
"pages": { |
||||||
|
"home": { |
||||||
|
"testnetAlert": "This pool is configured for the {title}. The {symbol} rewarded is testnet {symbol}.", |
||||||
|
"minimumPayout": "Min. payout threshold: {threshold} {symbol}.", |
||||||
|
"mode": "{mode} stable and profitable pool with regular payouts.", |
||||||
|
"poweredBy": "Powered by", |
||||||
|
"protocols": "Getwork & Stratum supported.", |
||||||
|
"account": "Account", |
||||||
|
"hashrate": "Hashrate", |
||||||
|
"lastBeat": "Last Beat", |
||||||
|
"noMiners": "No miners connected", |
||||||
|
"minersPerPage": "Miners per page", |
||||||
|
"search": "Search by account" |
||||||
|
}, |
||||||
|
"blocks": { |
||||||
|
"blocks": "Blocks", |
||||||
|
"shares": "Shares/Diff", |
||||||
|
"uncleRate": "Uncle Rate", |
||||||
|
"orphanRate": "Orphan Rate", |
||||||
|
"immature": "Immature", |
||||||
|
"newBlocks": "New Blocks", |
||||||
|
"noMatured": "No matured blocks", |
||||||
|
"noImmature": "No immature blocks", |
||||||
|
"noPending": "No pending blocks", |
||||||
|
"blocksPerPage": "Blocks per page", |
||||||
|
"search": "Search by number or hash", |
||||||
|
"blockNumber": "Block Number", |
||||||
|
"blockHash": "Block Hash", |
||||||
|
"timeFound": "Time Found", |
||||||
|
"variance": "Variance", |
||||||
|
"reward": "Reward", |
||||||
|
"type": "Type", |
||||||
|
"block": "Block", |
||||||
|
"uncle": "Uncle", |
||||||
|
"orphan": "Orphan" |
||||||
|
}, |
||||||
|
"payments": { |
||||||
|
"latestPayments": "Latest Payments", |
||||||
|
"noPayments": "No payments found", |
||||||
|
"paymentsPerPage": "Payments per page", |
||||||
|
"search": "Search by address or txn hash", |
||||||
|
"time": "Time", |
||||||
|
"address": "Address", |
||||||
|
"txid": "Tx ID", |
||||||
|
"amount": "Amount" |
||||||
|
}, |
||||||
|
"account": { |
||||||
|
"immatureBal": "IMMATURE BAL.", |
||||||
|
"pendingBal": "PENDING BAL.", |
||||||
|
"totalPaid": "TOTAL PAID", |
||||||
|
"lastShare": "LAST SHARE", |
||||||
|
"hashrate30min": "HASHRATE (30min)", |
||||||
|
"hashrate3hour": "HASHRATE (3h)", |
||||||
|
"blocksFound": "BLOCKS FOUND", |
||||||
|
"workersOnline": "WORKERS ONLINE", |
||||||
|
"roundShare": "YOUR ROUND SHARE", |
||||||
|
"info": "Your average hashrate will be smoothly adjusted until you have shares to fullfill estimation window. There are two windows, long and short, first is equal to about 30 minutes and long window is usually equal to 3 hours. Dead (sick) workers will be highlighted in a table of workers if they didn't submit a share for 1/2 of short window, so you can perform maintenance of your rigs.", |
||||||
|
"jsonApi": "Your bulk stats JSON API URL:", |
||||||
|
"workers": "Workers", |
||||||
|
"payments": "Payments", |
||||||
|
"worker": { |
||||||
|
"id": "ID", |
||||||
|
"hashrateShort": "Hashrate (rough, short average)", |
||||||
|
"hashrateLong": "Hashrate (accurate, long average)", |
||||||
|
"lastShare": "Last Share" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
{ |
||||||
|
"menu": { |
||||||
|
"home": "Casa", |
||||||
|
"blocks": "Bloques de grupo", |
||||||
|
"payments": "Pagos", |
||||||
|
"help": "Ayuda", |
||||||
|
"miningPool": "grupo de minería", |
||||||
|
"minimize": "Minimizar" |
||||||
|
}, |
||||||
|
"info": { |
||||||
|
"pool": { |
||||||
|
"title": "GRUPO", |
||||||
|
"hashrate": "Velocidad", |
||||||
|
"lastBlock": "Último Bloque", |
||||||
|
"miners": "En línea", |
||||||
|
"fee": "Cuota" |
||||||
|
}, |
||||||
|
"network": { |
||||||
|
"title": "RED", |
||||||
|
"height": "Altura del bloque", |
||||||
|
"difficulty": "Dificultad", |
||||||
|
"hashrate": "Velocidad", |
||||||
|
"epoch": "Época", |
||||||
|
"dag": "DAG" |
||||||
|
}, |
||||||
|
"hide": "Esconder" |
||||||
|
}, |
||||||
|
"pages": { |
||||||
|
"home": { |
||||||
|
"testnetAlert": "Este grupo está configurado para el {title}. El {symbol} premiado es testnet {symbol}.", |
||||||
|
"minimumPayout": "Min. umbral de pago: {threshold} {symbol}.", |
||||||
|
"mode": "{mode} Grupo estable y rentable con pagos regulares.", |
||||||
|
"poweredBy": "Energizado por", |
||||||
|
"protocols": "Compatible con Getwork y Stratum.", |
||||||
|
"account": "Cuenta", |
||||||
|
"hashrate": "Velocidad", |
||||||
|
"lastBeat": "último latido", |
||||||
|
"noMiners": "No hay mineros conectados", |
||||||
|
"minersPerPage": "Mineros por página", |
||||||
|
"search": "Buscar por cuenta" |
||||||
|
}, |
||||||
|
"blocks": { |
||||||
|
"blocks": "Bloques", |
||||||
|
"shares": "Acciones/Dificultad", |
||||||
|
"uncleRate": "Tío ocurrencia", |
||||||
|
"orphanRate": "Ocurrencia huérfana", |
||||||
|
"immature": "Inmaduro", |
||||||
|
"newBlocks": "Nuevos bloques", |
||||||
|
"noMatured": "Sin bloques maduros", |
||||||
|
"noImmature": "Sin bloques inmaduros", |
||||||
|
"noPending": "Sin bloques pendientes", |
||||||
|
"blocksPerPage": "Bloques por página", |
||||||
|
"search": "Buscar por número o hash", |
||||||
|
"blockNumber": "Número de bloque", |
||||||
|
"blockHash": "Bloquear huella digital", |
||||||
|
"timeFound": "Tiempo encontrado", |
||||||
|
"variance": "Diferencia", |
||||||
|
"reward": "Recompensa", |
||||||
|
"type": "Tipo", |
||||||
|
"block": "Bloquear", |
||||||
|
"uncle": "Tío", |
||||||
|
"orphan": "Huérfano" |
||||||
|
}, |
||||||
|
"payments": { |
||||||
|
"latestPayments": "Últimos pagos", |
||||||
|
"noPayments": "No se encontraron pagos", |
||||||
|
"paymentsPerPage": "Pagos por página", |
||||||
|
"search": "Buscar por dirección o hash txn", |
||||||
|
"time": "Hora", |
||||||
|
"address": "la dirección", |
||||||
|
"txid": "ID de transacción", |
||||||
|
"amount": "Cantidad" |
||||||
|
}, |
||||||
|
"account": { |
||||||
|
"immatureBal": "EQUILIBRIO INMATURO", |
||||||
|
"pendingBal": "EQUILIBRIO PENDIENTE", |
||||||
|
"totalPaid": "TOTAL PAGADO", |
||||||
|
"lastShare": "ÚLTIMA COMPARTIR", |
||||||
|
"hashrate30min": "VELOCIDAD (30min)", |
||||||
|
"hashrate3hour": "VELOCIDAD (3h)", |
||||||
|
"blocksFound": "BLOQUES ENCONTRADOS", |
||||||
|
"workersOnline": "TRABAJADORES EN LINEA", |
||||||
|
"roundShare": "SU PARTICIPACIÓN RONDA", |
||||||
|
"info": "Su tasa de hash promedio se ajustará sin problemas hasta que tenga acciones para completar la ventana de estimación. Hay dos ventanas, larga y corta, la primera es igual a unos 30 minutos y la ventana larga suele ser igual a 3 horas. Los trabajadores muertos (enfermos) se destacarán en una tabla de trabajadores si no enviaron una participación durante la mitad del período corto, para que pueda realizar el mantenimiento de sus equipos.", |
||||||
|
"jsonApi": "Su URL de API JSON de estadísticas masivas:", |
||||||
|
"workers": "Trabajadores", |
||||||
|
"payments": "Pagos", |
||||||
|
"worker": { |
||||||
|
"id": "ID", |
||||||
|
"hashrateShort": "Velocidad (aproximado, promedio corto)", |
||||||
|
"hashrateLong": "Velocidad (preciso, promedio largo)", |
||||||
|
"lastShare": "Último compartir" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
{ |
||||||
|
"menu": { |
||||||
|
"home": "Главная", |
||||||
|
"blocks": "Блоки бассейна", |
||||||
|
"payments": "Платежи", |
||||||
|
"help": "Помогите", |
||||||
|
"miningPool": "майнинг пул", |
||||||
|
"minimize": "Минимизировать" |
||||||
|
}, |
||||||
|
"info": { |
||||||
|
"pool": { |
||||||
|
"title": "БАССЕЙН", |
||||||
|
"hashrate": "СКОРОСТЬ", |
||||||
|
"lastBlock": "Последний блок", |
||||||
|
"miners": "В сети", |
||||||
|
"fee": "Гонорар" |
||||||
|
}, |
||||||
|
"network": { |
||||||
|
"title": "СЕТЬ", |
||||||
|
"height": "Высота блока", |
||||||
|
"difficulty": "Сложность", |
||||||
|
"hashrate": "СКОРОСТЬ", |
||||||
|
"epoch": "Эпоха", |
||||||
|
"dag": "DAG" |
||||||
|
}, |
||||||
|
"hide": "Спрятать" |
||||||
|
}, |
||||||
|
"pages": { |
||||||
|
"home": { |
||||||
|
"testnetAlert": "Этот пул настроен для {title}. Вознаграждение {symbol} - это тестовая сеть {symbol}.", |
||||||
|
"minimumPayout": "Мин. порог выплаты: {threshold} {symbol}.", |
||||||
|
"mode": "{mode} стабильный и прибыльный пул с регулярными выплатами.", |
||||||
|
"poweredBy": "Питаться от", |
||||||
|
"protocols": "Getwork & Stratum поддерживается.", |
||||||
|
"account": "Счет", |
||||||
|
"hashrate": "СКОРОСТЬ", |
||||||
|
"lastBeat": "Последний удар", |
||||||
|
"noMiners": "Майнеры не подключены", |
||||||
|
"minersPerPage": "Майнеров на страницу", |
||||||
|
"search": "Поиск по аккаунту" |
||||||
|
}, |
||||||
|
"blocks": { |
||||||
|
"blocks": "Блоки", |
||||||
|
"shares": "Доли / Сложность", |
||||||
|
"uncleRate": "Дядя Ставка", |
||||||
|
"orphanRate": "Уровень сирот", |
||||||
|
"immature": "Незрелый", |
||||||
|
"newBlocks": "Новые блоки", |
||||||
|
"noMatured": "Нет зрелых блоков", |
||||||
|
"noImmature": "Нет незрелых блоков", |
||||||
|
"noPending": "Нет ожидающих блоков", |
||||||
|
"blocksPerPage": "Блоки на страницу", |
||||||
|
"search": "Поиск по номеру или хешу", |
||||||
|
"blockNumber": "Номер блока", |
||||||
|
"blockHash": "Блокировать хеш", |
||||||
|
"timeFound": "Время найдено", |
||||||
|
"variance": "Дисперсия", |
||||||
|
"reward": "Награда", |
||||||
|
"type": "Тип", |
||||||
|
"block": "Блокировать", |
||||||
|
"uncle": "Дядя", |
||||||
|
"orphan": "Сирота" |
||||||
|
}, |
||||||
|
"payments": { |
||||||
|
"latestPayments": "Последние платежи", |
||||||
|
"noPayments": "Платежей не найдено", |
||||||
|
"paymentsPerPage": "Платежей за страницу", |
||||||
|
"search": "Поиск по адресу или txn-хешу", |
||||||
|
"time": "Время", |
||||||
|
"address": "Адрес", |
||||||
|
"txid": "номер транзакции", |
||||||
|
"amount": "Количество" |
||||||
|
}, |
||||||
|
"account": { |
||||||
|
"immatureBal": "НЕПРЕРЫВНЫЙ БАЛАНС", |
||||||
|
"pendingBal": "ОЖИДАНИЕ БАЛАНСА", |
||||||
|
"totalPaid": "ИТОГО", |
||||||
|
"lastShare": "ПОСЛЕДНЯЯ ПОДЕЛИТЬСЯ", |
||||||
|
"hashrate30min": "СКОРОСТЬ (30 минут)", |
||||||
|
"hashrate3hour": "СКОРОСТЬ (3 часа)", |
||||||
|
"blocksFound": "БЛОКИ НАЙДЕНЫ", |
||||||
|
"workersOnline": "РАБОТНИКИ ОНЛАЙН", |
||||||
|
"roundShare": "ВАША КРУГЛАЯ АКЦИЯ", |
||||||
|
"info": "Ваш средний хешрейт будет плавно регулироваться, пока у вас не будет долей для полного заполнения окна оценки. Есть два окна, длинное и короткое, первое составляет около 30 минут, а длинное окно обычно равно 3 часам. Мертвые (больные) рабочие будут выделены в таблице рабочих, если они не предоставили долю в течение 1/2 короткого периода, чтобы вы могли выполнять техническое обслуживание своих установок.", |
||||||
|
"jsonApi": "URL вашей массовой статистики JSON API:", |
||||||
|
"workers": "Рабочие", |
||||||
|
"payments": "Платежи", |
||||||
|
"worker": { |
||||||
|
"id": "Я БЫ", |
||||||
|
"hashrateShort": "Скорость (грубая, короткая средняя)", |
||||||
|
"hashrateLong": "Скорость (точная, длинная средняя)", |
||||||
|
"lastShare": "Последняя доля" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
{ |
||||||
|
"menu": { |
||||||
|
"home": "开始", |
||||||
|
"blocks": "区块", |
||||||
|
"payments": "付款方式", |
||||||
|
"help": "帮助", |
||||||
|
"miningPool": "矿池", |
||||||
|
"minimize": "最小化" |
||||||
|
}, |
||||||
|
"info": { |
||||||
|
"pool": { |
||||||
|
"title": "名称", |
||||||
|
"hashrate": "哈希率", |
||||||
|
"lastBlock": "最新区块", |
||||||
|
"miners": "矿工", |
||||||
|
"fee": "费用" |
||||||
|
}, |
||||||
|
"network": { |
||||||
|
"title": "名称", |
||||||
|
"height": "块高", |
||||||
|
"difficulty": "难度", |
||||||
|
"hashrate": "哈希率", |
||||||
|
"epoch": "Epoch", |
||||||
|
"dag": "DAG" |
||||||
|
}, |
||||||
|
"hide": "隐藏" |
||||||
|
}, |
||||||
|
"pages": { |
||||||
|
"home": { |
||||||
|
"testnetAlert": "已为{title}配置了该池。 奖励的{symbol}是测试网{symbol}。", |
||||||
|
"minimumPayout": "最低付款额度:{threshold} {symbol}。", |
||||||
|
"mode": "{mode}稳定且可盈利的定期付款池。", |
||||||
|
"poweredBy": "基于", |
||||||
|
"protocols": "支持Getwork和Stratum。", |
||||||
|
"account": "帐户", |
||||||
|
"hashrate": "哈希率", |
||||||
|
"lastBeat": "最近上线", |
||||||
|
"noMiners": "无连接矿工", |
||||||
|
"minersPerPage": "每页矿工数", |
||||||
|
"search": "搜索" |
||||||
|
}, |
||||||
|
"blocks": { |
||||||
|
"blocks": "区块", |
||||||
|
"shares": "份额", |
||||||
|
"uncleRate": "叔块率", |
||||||
|
"orphanRate": "孤块率", |
||||||
|
"immature": "待确认", |
||||||
|
"newBlocks": "新区块", |
||||||
|
"noMatured": "无已确认的区块", |
||||||
|
"noImmature": "无待确认的区块", |
||||||
|
"noPending": "无待处理的区块", |
||||||
|
"blocksPerPage": "每页块数", |
||||||
|
"search": "搜索", |
||||||
|
"blockNumber": "块号", |
||||||
|
"blockHash": "区块哈希", |
||||||
|
"timeFound": "发现时间", |
||||||
|
"variance": "回报方差", |
||||||
|
"reward": "奖励", |
||||||
|
"type": "类型", |
||||||
|
"block": "区块", |
||||||
|
"uncle": "叔块", |
||||||
|
"orphan": "孤块" |
||||||
|
}, |
||||||
|
"payments": { |
||||||
|
"latestPayments": "最新付款", |
||||||
|
"noPayments": "无付款记录", |
||||||
|
"paymentsPerPage": "每页付款数", |
||||||
|
"search": "搜索", |
||||||
|
"time": "时间", |
||||||
|
"address": "地址", |
||||||
|
"txid": "交易编号", |
||||||
|
"amount": "数量" |
||||||
|
}, |
||||||
|
"account": { |
||||||
|
"immatureBal": "未确认的余额", |
||||||
|
"pendingBal": "待确认余额", |
||||||
|
"totalPaid": "总支付", |
||||||
|
"lastShare": "最近份额", |
||||||
|
"hashrate30min": "哈希率(30分钟)", |
||||||
|
"hashrate3hour": "哈希率(3小时)", |
||||||
|
"blocksFound": "发现的块", |
||||||
|
"workersOnline": "在线矿工", |
||||||
|
"roundShare": "您的份额", |
||||||
|
"info": "您的平均哈希率将被平滑地调整,直到您有要完全满足估计值的份额为止。有长、短两个时间窗口,前者通常等于3小时,后者等于大约30分钟。列表中会显示未在短窗口的1/2时间内提交份额的矿工,以便您进行矿机维护。", |
||||||
|
"jsonApi": "您的批量统计信息JSON API URL:", |
||||||
|
"workers": "矿工", |
||||||
|
"payments": "付款方式", |
||||||
|
"worker": { |
||||||
|
"id": "ID", |
||||||
|
"hashrateShort": "哈希率(粗略,短期平均)", |
||||||
|
"hashrateLong": "哈希率(准确,长期平均)", |
||||||
|
"lastShare": "最近份额" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,17 @@ |
|||||||
|
module.exports = { |
||||||
|
moduleNameMapper: { |
||||||
|
'^@/(.*)$': '<rootDir>/$1', |
||||||
|
'^~/(.*)$': '<rootDir>/$1', |
||||||
|
'^vue$': 'vue/dist/vue.common.js', |
||||||
|
}, |
||||||
|
moduleFileExtensions: ['js', 'vue', 'json'], |
||||||
|
transform: { |
||||||
|
'^.+\\.js$': 'babel-jest', |
||||||
|
'.*\\.(vue)$': 'vue-jest', |
||||||
|
}, |
||||||
|
collectCoverage: true, |
||||||
|
collectCoverageFrom: [ |
||||||
|
'<rootDir>/components/**/*.vue', |
||||||
|
'<rootDir>/pages/**/*.vue', |
||||||
|
], |
||||||
|
} |
||||||
@ -0,0 +1,12 @@ |
|||||||
|
{ |
||||||
|
"compilerOptions": { |
||||||
|
"baseUrl": ".", |
||||||
|
"paths": { |
||||||
|
"~/*": ["./*"], |
||||||
|
"@/*": ["./*"], |
||||||
|
"~~/*": ["./*"], |
||||||
|
"@@/*": ["./*"] |
||||||
|
} |
||||||
|
}, |
||||||
|
"exclude": ["node_modules", ".nuxt", "dist"] |
||||||
|
} |
||||||
@ -0,0 +1,409 @@ |
|||||||
|
<template> |
||||||
|
<v-app> |
||||||
|
<v-navigation-drawer |
||||||
|
v-model="drawer" |
||||||
|
:mini-variant="miniVariant" |
||||||
|
mobile-breakpoint="sm" |
||||||
|
clipped |
||||||
|
fixed |
||||||
|
app |
||||||
|
> |
||||||
|
<v-list> |
||||||
|
<v-list-item |
||||||
|
v-for="(item, i) in items" |
||||||
|
:key="i" |
||||||
|
:to="item.to" |
||||||
|
router |
||||||
|
exact |
||||||
|
> |
||||||
|
<v-list-item-action> |
||||||
|
<v-icon>{{ item.icon }}</v-icon> |
||||||
|
</v-list-item-action> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title v-text="item.title" /> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
<template #append> |
||||||
|
<v-list> |
||||||
|
<v-list-item |
||||||
|
v-for="(item, index) in stats.env.extraPools" |
||||||
|
:key="index" |
||||||
|
:href="item.url" |
||||||
|
target="_blank" |
||||||
|
> |
||||||
|
<v-list-item-action size="24"> |
||||||
|
<img |
||||||
|
:src="require('~/static/' + stats.networks[item.network].icon)" |
||||||
|
style="width: 24px; max-height: 24px" |
||||||
|
/> |
||||||
|
</v-list-item-action> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
stats.networks[item.network].title |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle |
||||||
|
>{{ item.type }} |
||||||
|
{{ $t('menu.miningPool') }}</v-list-item-subtitle |
||||||
|
> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item @click.stop="miniVariant = !miniVariant"> |
||||||
|
<v-list-item-action> |
||||||
|
<v-icon |
||||||
|
>mdi-{{ `chevron-${miniVariant ? 'right' : 'left'}` }}</v-icon |
||||||
|
> |
||||||
|
</v-list-item-action> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ $t('menu.minimize') }}</v-list-item-title> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</template> |
||||||
|
</v-navigation-drawer> |
||||||
|
<v-app-bar clipped-left clipped-right fixed app> |
||||||
|
<v-app-bar-nav-icon |
||||||
|
:class="{ 'd-xs-flex': true, 'd-md-none': drawer }" |
||||||
|
@click.stop="drawer = !drawer" |
||||||
|
/> |
||||||
|
<v-spacer /> |
||||||
|
<v-toolbar-title> |
||||||
|
<v-avatar size="32"> |
||||||
|
<img :src="require('@/static/' + logo)" /> |
||||||
|
</v-avatar> |
||||||
|
{{ title }} |
||||||
|
</v-toolbar-title> |
||||||
|
<v-spacer /> |
||||||
|
<v-btn |
||||||
|
icon |
||||||
|
class="mr-1" |
||||||
|
@click.stop="$vuetify.theme.dark = !$vuetify.theme.dark" |
||||||
|
> |
||||||
|
<v-icon>mdi-theme-light-dark</v-icon> |
||||||
|
</v-btn> |
||||||
|
<v-menu offset-y> |
||||||
|
<template #activator="{ on, attrs }"> |
||||||
|
<v-btn icon v-bind="attrs" class="mr-1" v-on="on"> |
||||||
|
<v-icon>mdi-translate</v-icon> |
||||||
|
</v-btn> |
||||||
|
</template> |
||||||
|
<v-list> |
||||||
|
<v-list-item |
||||||
|
v-for="(item, index) in locales" |
||||||
|
:key="index" |
||||||
|
:disabled="item.code === $i18n.locale" |
||||||
|
@click="$i18n.setLocale(item.code)" |
||||||
|
> |
||||||
|
<v-list-item-title>{{ item.name }}</v-list-item-title> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</v-menu> |
||||||
|
<v-app-bar-nav-icon @click.stop="drawerRight = !drawerRight" /> |
||||||
|
</v-app-bar> |
||||||
|
<v-navigation-drawer |
||||||
|
v-model="drawerRight" |
||||||
|
mobile-breakpoint="sm" |
||||||
|
clipped |
||||||
|
fixed |
||||||
|
right |
||||||
|
app |
||||||
|
> |
||||||
|
<v-list dense class="ma-0 pa-0"> |
||||||
|
<v-subheader>{{ $t('info.pool.title') }}</v-subheader> |
||||||
|
<v-list-item class="stats-item ma-1 darken2"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-gauge</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('info.pool.hashrate') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
formatHashrate(stats.poolHashRate, true) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-clock-outline</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('info.pool.lastBlock') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
formatTimeSince(stats.lastBlockFound) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-pickaxe</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ $t('info.pool.miners') }}</v-list-item-title> |
||||||
|
</v-list-item-content> |
||||||
|
<v-list-item-action-text>{{ |
||||||
|
stats.minersOnline |
||||||
|
}}</v-list-item-action-text> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-cash</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ $t('info.pool.fee') }}</v-list-item-title> |
||||||
|
</v-list-item-content> |
||||||
|
<v-list-item-action-text |
||||||
|
>{{ stats.env.poolFee }}%</v-list-item-action-text |
||||||
|
> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
<v-list dense class="ma-0 pa-0"> |
||||||
|
<v-subheader text-right>{{ $t('info.network.title') }}</v-subheader> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<img :src="require('~/static/' + stats.env.network.icon)" /> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ stats.env.network.title }}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
stats.env.network.algo |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-cube-scan</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('info.network.height') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
nf.format(stats.height) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-lock</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('info.network.difficulty') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
formatHashrate(stats.difficulty, false) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-gauge</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('info.network.hashrate') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
formatHashrate(stats.networkHashrate, true) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-timer-sand</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title |
||||||
|
>{{ $t('info.network.epoch') }} ({{ |
||||||
|
stats.env.network.algo |
||||||
|
}})</v-list-item-title |
||||||
|
> |
||||||
|
<v-list-item-subtitle>{{ stats.epoch }}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="stats-item ma-1"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-chip</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ $t('info.network.dag') }}</v-list-item-title> |
||||||
|
<v-list-item-subtitle |
||||||
|
>{{ stats.dagSize }} MByte</v-list-item-subtitle |
||||||
|
> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
<template #append> |
||||||
|
<v-list> |
||||||
|
<v-list-item @click.stop="drawerRight = !drawerRight"> |
||||||
|
<v-list-item-action> |
||||||
|
<v-icon>mdi-chevron-right</v-icon> |
||||||
|
</v-list-item-action> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ $t('info.hide') }}</v-list-item-title> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</template> |
||||||
|
</v-navigation-drawer> |
||||||
|
<v-main> |
||||||
|
<v-container fluid class="pa-0"> |
||||||
|
<nuxt /> |
||||||
|
</v-container> |
||||||
|
</v-main> |
||||||
|
<v-footer :absolute="!fixed" app> |
||||||
|
<span>© {{ new Date().getFullYear() }}</span> |
||||||
|
<v-spacer /> |
||||||
|
</v-footer> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { formatDistance } from 'date-fns' |
||||||
|
|
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
drawer: true, |
||||||
|
drawerRight: true, |
||||||
|
fixed: true, |
||||||
|
miniVariant: true, |
||||||
|
title: this.$store.state.env.title, |
||||||
|
logo: this.$store.state.env.logo, |
||||||
|
nf: new Intl.NumberFormat(this.locale, {}), |
||||||
|
timer: { |
||||||
|
stats: null, |
||||||
|
miners: null, |
||||||
|
}, |
||||||
|
interval: { |
||||||
|
stats: 2000, |
||||||
|
miners: 10000, |
||||||
|
blocks: 10000, |
||||||
|
payments: 10000, |
||||||
|
}, |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
stats() { |
||||||
|
return this.$store.state |
||||||
|
}, |
||||||
|
now() { |
||||||
|
return this.$store.state.now |
||||||
|
}, |
||||||
|
locales() { |
||||||
|
return this.$i18n.locales |
||||||
|
}, |
||||||
|
darkmode: { |
||||||
|
get() { |
||||||
|
return this.$vuetify.theme.dark |
||||||
|
}, |
||||||
|
set() { |
||||||
|
this.$vuetify.theme.dark = !this.$vuetify.theme.dark |
||||||
|
}, |
||||||
|
}, |
||||||
|
items() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
icon: 'mdi-home', |
||||||
|
title: this.$t('menu.home'), |
||||||
|
to: '/', |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'mdi-cube-outline', |
||||||
|
title: this.$t('menu.blocks'), |
||||||
|
to: '/blocks', |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'mdi-send', |
||||||
|
title: this.$t('menu.payments'), |
||||||
|
to: '/payments', |
||||||
|
}, |
||||||
|
{ |
||||||
|
icon: 'mdi-help-circle-outline', |
||||||
|
title: this.$t('menu.help'), |
||||||
|
to: '/help', |
||||||
|
}, |
||||||
|
] |
||||||
|
}, |
||||||
|
locale() { |
||||||
|
return this.$i18n.locale |
||||||
|
}, |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.startSync('stats') |
||||||
|
this.startSync('miners') |
||||||
|
this.startSync('blocks') |
||||||
|
this.startSync('payments') |
||||||
|
const t = this |
||||||
|
setInterval(function () { |
||||||
|
t.$store.dispatch('now') |
||||||
|
}, 1000) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
formatHashrate(bytes, showHash) { |
||||||
|
const sizes = ['', 'K', 'M', 'G', 'T'] |
||||||
|
if (bytes === 0) { |
||||||
|
if (showHash) { |
||||||
|
return '0 H' |
||||||
|
} |
||||||
|
return '0' |
||||||
|
} |
||||||
|
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000))) |
||||||
|
if (i === 0) { |
||||||
|
return bytes + ' ' + sizes[i] |
||||||
|
} |
||||||
|
let unit = ' ' + sizes[i] |
||||||
|
if (showHash) { |
||||||
|
unit = ' ' + sizes[i] + 'H' |
||||||
|
} |
||||||
|
return (bytes / 1000 ** i).toFixed(3) + unit |
||||||
|
}, |
||||||
|
startSync(store) { |
||||||
|
const self = this |
||||||
|
this.timer[store] = null |
||||||
|
this.$store.dispatch(store) |
||||||
|
this.timer[store] = setInterval(function () { |
||||||
|
self.$store.dispatch(store) |
||||||
|
}, this.interval[store]) |
||||||
|
}, |
||||||
|
stopSync(store) { |
||||||
|
clearInterval(this.timer[store]) |
||||||
|
this.timer[store] = null |
||||||
|
}, |
||||||
|
formatTimeSince(time) { |
||||||
|
return formatDistance(new Date(time * 1000), this.now, { |
||||||
|
addSuffix: true, |
||||||
|
includeSeconds: true, |
||||||
|
}) |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.stats-item { |
||||||
|
background-color: var(--v-secondary-base) !important; |
||||||
|
border-bottom-left-radius: 32px !important; |
||||||
|
border-top-left-radius: 32px !important; |
||||||
|
} |
||||||
|
</style> |
||||||
|
|
||||||
|
<style lang="scss"> |
||||||
|
::-webkit-scrollbar { |
||||||
|
width: 6px; /* for vertical scrollbars */ |
||||||
|
height: 6px; /* for horizontal scrollbars */ |
||||||
|
border-radius: 3px; |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-scrollbar-track { |
||||||
|
background: var(--v-secondary-base) !important; |
||||||
|
} |
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb { |
||||||
|
background: var(--v-primary-base) !important; |
||||||
|
border-radius: 3px; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
<template> |
||||||
|
<v-app dark> |
||||||
|
<h1 v-if="error.statusCode === 404"> |
||||||
|
{{ pageNotFound }} |
||||||
|
</h1> |
||||||
|
<h1 v-else> |
||||||
|
{{ otherError }} |
||||||
|
</h1> |
||||||
|
<NuxtLink to="/"> Home page </NuxtLink> |
||||||
|
</v-app> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
export default { |
||||||
|
layout: 'empty', |
||||||
|
props: { |
||||||
|
error: { |
||||||
|
type: Object, |
||||||
|
default: null, |
||||||
|
}, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
pageNotFound: '404 Not Found', |
||||||
|
otherError: 'An error occurred', |
||||||
|
} |
||||||
|
}, |
||||||
|
head() { |
||||||
|
const title = |
||||||
|
this.error.statusCode === 404 ? this.pageNotFound : this.otherError |
||||||
|
return { |
||||||
|
title, |
||||||
|
} |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style scoped> |
||||||
|
h1 { |
||||||
|
font-size: 20px; |
||||||
|
} |
||||||
|
</style> |
||||||
@ -0,0 +1,114 @@ |
|||||||
|
// import colors from 'vuetify/es5/util/colors'
|
||||||
|
import config from './params/config.json' |
||||||
|
|
||||||
|
export default { |
||||||
|
// Disable server-side rendering (https://go.nuxtjs.dev/ssr-mode)
|
||||||
|
ssr: false, |
||||||
|
|
||||||
|
// Target (https://go.nuxtjs.dev/config-target)
|
||||||
|
target: 'static', |
||||||
|
|
||||||
|
// Global page headers (https://go.nuxtjs.dev/config-head)
|
||||||
|
head: { |
||||||
|
titleTemplate: '%s', |
||||||
|
title: config.title, |
||||||
|
meta: [ |
||||||
|
{ charset: 'utf-8' }, |
||||||
|
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }, |
||||||
|
{ hid: 'description', name: 'description', content: config.description }, |
||||||
|
], |
||||||
|
link: [{ rel: 'icon', type: 'image/x-icon', href: '/' + config.favicon }], |
||||||
|
}, |
||||||
|
|
||||||
|
// Global CSS (https://go.nuxtjs.dev/config-css)
|
||||||
|
css: ['~/scss/main.scss'], |
||||||
|
|
||||||
|
// Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
|
||||||
|
plugins: [], |
||||||
|
|
||||||
|
// Auto import components (https://go.nuxtjs.dev/config-components)
|
||||||
|
components: true, |
||||||
|
|
||||||
|
// Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
|
||||||
|
buildModules: [ |
||||||
|
// https://github.com/nuxt-community/eslint-module
|
||||||
|
'@nuxtjs/eslint-module', |
||||||
|
// https://go.nuxtjs.dev/vuetify
|
||||||
|
'@nuxtjs/vuetify', |
||||||
|
], |
||||||
|
|
||||||
|
// Modules (https://go.nuxtjs.dev/config-modules)
|
||||||
|
modules: [ |
||||||
|
// https://go.nuxtjs.dev/axios
|
||||||
|
'@nuxtjs/axios', |
||||||
|
// https://go.nuxtjs.dev/pwa
|
||||||
|
'@nuxtjs/pwa', |
||||||
|
// https://go.nuxtjs.dev/content
|
||||||
|
'@nuxt/content', |
||||||
|
// https://i18n.nuxtjs.org/
|
||||||
|
'nuxt-i18n', |
||||||
|
], |
||||||
|
|
||||||
|
// Axios module configuration (https://go.nuxtjs.dev/config-axios)
|
||||||
|
axios: {}, |
||||||
|
|
||||||
|
// Content module configuration (https://go.nuxtjs.dev/config-content)
|
||||||
|
content: {}, |
||||||
|
|
||||||
|
// Vuetify module configuration (https://go.nuxtjs.dev/config-vuetify)
|
||||||
|
vuetify: { |
||||||
|
customVariables: ['~/assets/variables.scss'], |
||||||
|
theme: config.theme, |
||||||
|
}, |
||||||
|
|
||||||
|
// i18n module configuration (https://i18n.nuxtjs.org/basic-usage)
|
||||||
|
i18n: { |
||||||
|
locales: [ |
||||||
|
{ |
||||||
|
code: 'en', |
||||||
|
name: 'English', |
||||||
|
}, |
||||||
|
{ |
||||||
|
code: 'es', |
||||||
|
name: 'Español', |
||||||
|
}, |
||||||
|
{ |
||||||
|
code: 'ru', |
||||||
|
name: 'Pусский', |
||||||
|
}, |
||||||
|
{ |
||||||
|
code: 'zh', |
||||||
|
name: '中文', |
||||||
|
}, |
||||||
|
], |
||||||
|
strategy: 'no_prefix', |
||||||
|
detectBrowserLanguage: { |
||||||
|
useCookie: true, |
||||||
|
cookieKey: 'core_pool_i18n_redirected', |
||||||
|
fallbackLocale: config.i18n.fallback || 'en', |
||||||
|
alwaysRedirect: true, |
||||||
|
onlyOnRoot: true, |
||||||
|
}, |
||||||
|
defaultLocale: config.i18n.default || 'en', |
||||||
|
vueI18n: { |
||||||
|
fallbackLocale: config.i18n.fallback || 'en', |
||||||
|
messages: { |
||||||
|
en: require('./i18n/en.json'), |
||||||
|
es: require('./i18n/es.json'), |
||||||
|
ru: require('./i18n/ru.json'), |
||||||
|
zh: require('./i18n/zh.json'), |
||||||
|
}, |
||||||
|
}, |
||||||
|
}, |
||||||
|
|
||||||
|
// Build Configuration (https://go.nuxtjs.dev/config-build)
|
||||||
|
build: {}, |
||||||
|
|
||||||
|
// hooks
|
||||||
|
hooks: { |
||||||
|
'content:file:beforeParse': (file) => { |
||||||
|
if (file.extension !== '.md') return |
||||||
|
file.data = file.data.replace(/STRATUM_HOST/g, config.stratum) |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
{ |
||||||
|
"name": "vue-core-pool", |
||||||
|
"version": "1.0.0", |
||||||
|
"private": true, |
||||||
|
"scripts": { |
||||||
|
"dev": "nuxt", |
||||||
|
"build": "nuxt build", |
||||||
|
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .", |
||||||
|
"lint-fix": "eslint --ext .js,.vue --ignore-path .gitignore --fix .", |
||||||
|
"start": "nuxt start", |
||||||
|
"generate": "nuxt generate", |
||||||
|
"test": "jest", |
||||||
|
"prepare": "husky install" |
||||||
|
}, |
||||||
|
"dependencies": { |
||||||
|
"@nuxt/content": "^1.14.0", |
||||||
|
"@nuxtjs/axios": "^5.13.6", |
||||||
|
"@nuxtjs/pwa": "^3.3.5", |
||||||
|
"consola": "^2.15.3", |
||||||
|
"core-js": "^3.12.1", |
||||||
|
"date-fns": "^2.23.0", |
||||||
|
"nuxt": "^2.15.6", |
||||||
|
"nuxt-i18n": "^6.27.0" |
||||||
|
}, |
||||||
|
"devDependencies": { |
||||||
|
"@nuxtjs/eslint-config": "^6.0.0", |
||||||
|
"@nuxtjs/eslint-module": "^3.0.2", |
||||||
|
"@nuxtjs/vuetify": "^1.12.1", |
||||||
|
"@vue/test-utils": "^1.2.0", |
||||||
|
"babel-core": "7.0.0-bridge.0", |
||||||
|
"babel-eslint": "^10.1.0", |
||||||
|
"babel-jest": "^26.5.0", |
||||||
|
"eslint": "^7.27.0", |
||||||
|
"eslint-config-prettier": "^8.3.0", |
||||||
|
"eslint-plugin-nuxt": "^2.0.0", |
||||||
|
"eslint-plugin-prettier": "^3.4.0", |
||||||
|
"husky": "^6.0.0", |
||||||
|
"jest": "^26.5.0", |
||||||
|
"prettier": "^2.4.1", |
||||||
|
"vue-jest": "^3.0.4" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,312 @@ |
|||||||
|
<template> |
||||||
|
<v-col cols="12" class="pa-0"> |
||||||
|
<v-row no-gutters class="border-bottom"> |
||||||
|
<v-col cols="12" md="4" sm="4" xs="12"> |
||||||
|
<v-list dense> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-cloud-outline</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.immatureBal') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle> |
||||||
|
{{ formatEther(data.stats.immature) }} {{ config.symbol }} |
||||||
|
</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-bank</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.pendingBal') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle> |
||||||
|
{{ formatEther(data.stats.balance) }} {{ config.symbol }} |
||||||
|
</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-cash</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.totalPaid') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle |
||||||
|
>{{ formatEther(data.stats.paid) }} |
||||||
|
{{ config.symbol }}</v-list-item-subtitle |
||||||
|
> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</v-col> |
||||||
|
<v-col cols="12" md="4" sm="4" xs="12"> |
||||||
|
<v-list dense> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-cube-send</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.lastShare') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
formatTimeSince(data.stats.lastShare) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-gauge-full</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.hashrate30min') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle |
||||||
|
>{{ formatHashrate(data.currentHashrate, true) }} |
||||||
|
</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-gauge-full</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.hashrate3hour') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle |
||||||
|
>{{ formatHashrate(data.hashrate, true) }} |
||||||
|
</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</v-col> |
||||||
|
<v-col cols="12" md="4" sm="4" xs="12"> |
||||||
|
<v-list dense> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-cube-scan</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.blocksFound') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
nf.format(data.stats.blocksFound) |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-pickaxe</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.workersOnline') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
data.workersOnline |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
<v-list-item class="border-right"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<v-icon>mdi-clock-outline</v-icon> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
$t('pages.account.roundShare') |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle |
||||||
|
>{{ data.roundShares }}% |
||||||
|
</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</v-col> |
||||||
|
</v-row> |
||||||
|
<v-alert tile dismissible type="info"> |
||||||
|
{{ $t('pages.account.info') }} |
||||||
|
</v-alert> |
||||||
|
<v-alert tile dismissible type="info"> |
||||||
|
{{ $t('pages.account.jsonApi') }} |
||||||
|
<a |
||||||
|
:href=" |
||||||
|
config.api + '/accounts/0xda904bc07fd95e39661941b3f6daded1b8a38c71' |
||||||
|
" |
||||||
|
target="_blank" |
||||||
|
style="color: #fff" |
||||||
|
> |
||||||
|
{{ |
||||||
|
config.api + '/accounts/0xda904bc07fd95e39661941b3f6daded1b8a38c71' |
||||||
|
}} |
||||||
|
</a> |
||||||
|
</v-alert> |
||||||
|
<v-tabs v-model="tab" grow> |
||||||
|
<v-tab> |
||||||
|
{{ $t('pages.account.workers') |
||||||
|
}}<v-chip label x-small class="ml-2">{{ data.workersTotal }}</v-chip> |
||||||
|
</v-tab> |
||||||
|
<v-tab> |
||||||
|
{{ $t('pages.account.payments') |
||||||
|
}}<v-chip label x-small class="ml-2">{{ data.paymentsTotal }}</v-chip> |
||||||
|
</v-tab> |
||||||
|
</v-tabs> |
||||||
|
<v-tabs-items v-model="tab"> |
||||||
|
<v-tab-item> |
||||||
|
<v-simple-table fixed-header> |
||||||
|
<template #default> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th class="text-left">{{ $t('pages.account.worker.id') }}</th> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.account.worker.hashrateShort') }} |
||||||
|
</th> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.account.worker.hashrateLong') }} |
||||||
|
</th> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.account.worker.lastShare') }} |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr v-for="(item, index) in data.workers" :key="index"> |
||||||
|
<td>{{ index }}</td> |
||||||
|
<td>{{ formatHashrate(item.hr, true) }}</td> |
||||||
|
<td>{{ formatHashrate(item.hr2, true) }}</td> |
||||||
|
<td>{{ formatTimeSince(item.lastBeat) }}</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</template> |
||||||
|
</v-simple-table> |
||||||
|
</v-tab-item> |
||||||
|
<v-tab-item> |
||||||
|
<payments-table |
||||||
|
:payments="data.payments" |
||||||
|
:headers="payoutHeaders" |
||||||
|
:config="config" |
||||||
|
:no-data-text="$t('pages.payments.noPayments')" |
||||||
|
/> |
||||||
|
</v-tab-item> |
||||||
|
</v-tabs-items> |
||||||
|
</v-col> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import axios from 'axios' |
||||||
|
import { formatDistance } from 'date-fns' |
||||||
|
import PaymentsTable from '~/components/tables/Payments' |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
PaymentsTable, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
id: this.$route.params.id, |
||||||
|
errors: [], |
||||||
|
tab: null, |
||||||
|
data: { |
||||||
|
workers: {}, |
||||||
|
workersOffline: 0, |
||||||
|
workersOnline: 0, |
||||||
|
workersTotal: 0, |
||||||
|
roundShares: 0, |
||||||
|
paymentsTotal: 0, |
||||||
|
payments: null, |
||||||
|
hashrate: 0, |
||||||
|
currentHashrate: 0, |
||||||
|
stats: { |
||||||
|
balance: 0, |
||||||
|
blocksFound: 0, |
||||||
|
immature: 0, |
||||||
|
lastShare: 0, |
||||||
|
paid: 0, |
||||||
|
pending: 0, |
||||||
|
}, |
||||||
|
}, |
||||||
|
payoutHeaders: [ |
||||||
|
{ |
||||||
|
text: this.$t('pages.payments.time'), |
||||||
|
align: 'start', |
||||||
|
value: 'timestamp', |
||||||
|
}, |
||||||
|
{ text: this.$t('pages.payments.txid'), value: 'tx' }, |
||||||
|
{ |
||||||
|
text: this.$t('pages.payments.amount'), |
||||||
|
value: 'amount', |
||||||
|
align: 'right', |
||||||
|
}, |
||||||
|
], |
||||||
|
nf: new Intl.NumberFormat(this.locale, {}), |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
now() { |
||||||
|
return this.$store.state.now |
||||||
|
}, |
||||||
|
config() { |
||||||
|
return this.$store.state.env |
||||||
|
}, |
||||||
|
locale() { |
||||||
|
return this.$i18n.locale |
||||||
|
}, |
||||||
|
}, |
||||||
|
created() { |
||||||
|
this.fetchData(this.id) |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
async fetchData(address) { |
||||||
|
try { |
||||||
|
const { data } = await axios.get( |
||||||
|
this.config.api + '/accounts/' + address |
||||||
|
) |
||||||
|
if (data) { |
||||||
|
this.data = data |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
this.errors.push(error) |
||||||
|
} |
||||||
|
}, |
||||||
|
formatTimeSince(time) { |
||||||
|
return formatDistance(new Date(time * 1000), this.now, { |
||||||
|
addSuffix: true, |
||||||
|
includeSeconds: true, |
||||||
|
}) |
||||||
|
}, |
||||||
|
formatHashrate(bytes, showHash) { |
||||||
|
const sizes = ['', 'K', 'M', 'G', 'T'] |
||||||
|
if (bytes === 0) { |
||||||
|
return 'n/a' |
||||||
|
} |
||||||
|
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000))) |
||||||
|
if (i === 0) { |
||||||
|
return bytes + ' ' + sizes[i] |
||||||
|
} |
||||||
|
let unit = ' ' + sizes[i] |
||||||
|
if (showHash) { |
||||||
|
unit = ' ' + sizes[i] + 'H' |
||||||
|
} |
||||||
|
return (bytes / 1000 ** i).toFixed(3) + unit |
||||||
|
}, |
||||||
|
formatEther(shannon) { |
||||||
|
const ether = shannon / 1000000000 |
||||||
|
// format nicely without losing precision |
||||||
|
const split = ether.toString().split('.') |
||||||
|
if (split.length > 1) { |
||||||
|
return this.nf.format(split[0]) + '.' + split[1] |
||||||
|
} else { |
||||||
|
return this.nf.format(ether) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,117 @@ |
|||||||
|
<template> |
||||||
|
<v-row justify="center" align="center" no-gutters> |
||||||
|
<v-col cols="12" class="pa-0"> |
||||||
|
<v-card tile flat style="margin-bottom: 1px solid #2e2e2e"> |
||||||
|
<v-simple-table> |
||||||
|
<template #default> |
||||||
|
<thead> |
||||||
|
<tr> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.blocks.blocks') }} |
||||||
|
</th> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.blocks.shares') }} |
||||||
|
</th> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.blocks.uncleRate') }} |
||||||
|
</th> |
||||||
|
<th class="text-left"> |
||||||
|
{{ $t('pages.blocks.orphanRate') }} |
||||||
|
</th> |
||||||
|
</tr> |
||||||
|
</thead> |
||||||
|
<tbody> |
||||||
|
<tr v-for="(item, key) in blocks.luck" :key="key"> |
||||||
|
<td>{{ key }}</td> |
||||||
|
<td>{{ nf.format(item.luck.toFixed(2)) }}%</td> |
||||||
|
<td>{{ nf.format((item.uncleRate * 100).toFixed(2)) }}%</td> |
||||||
|
<td>{{ nf.format((item.orphanRate * 100).toFixed(2)) }}%</td> |
||||||
|
</tr> |
||||||
|
</tbody> |
||||||
|
</template> |
||||||
|
</v-simple-table> |
||||||
|
</v-card> |
||||||
|
<v-card tile flat> |
||||||
|
<v-tabs v-model="tab" background-color="transparent" grow> |
||||||
|
<v-tab |
||||||
|
>{{ $t('pages.blocks.blocks') |
||||||
|
}}<v-chip label small color="success" class="ml-2">{{ |
||||||
|
blocks.maturedTotal |
||||||
|
}}</v-chip></v-tab |
||||||
|
> |
||||||
|
<v-tab |
||||||
|
>{{ $t('pages.blocks.immature') |
||||||
|
}}<v-chip label small color="warning" class="ml-2">{{ |
||||||
|
blocks.immatureTotal |
||||||
|
}}</v-chip></v-tab |
||||||
|
> |
||||||
|
<v-tab |
||||||
|
>{{ $t('pages.blocks.newBlocks') |
||||||
|
}}<v-chip label small color="info" class="ml-2">{{ |
||||||
|
blocks.candidatesTotal |
||||||
|
}}</v-chip></v-tab |
||||||
|
> |
||||||
|
</v-tabs> |
||||||
|
<v-tabs-items v-model="tab"> |
||||||
|
<v-tab-item> |
||||||
|
<blocks-table |
||||||
|
:blocks="matured" |
||||||
|
:config="config" |
||||||
|
:no-data-text="$t('pages.blocks.noMatured')" |
||||||
|
/> |
||||||
|
</v-tab-item> |
||||||
|
<v-tab-item> |
||||||
|
<blocks-table |
||||||
|
:blocks="immature" |
||||||
|
:config="config" |
||||||
|
:no-data-text="$t('pages.blocks.noImmature')" |
||||||
|
/> |
||||||
|
</v-tab-item> |
||||||
|
<v-tab-item> |
||||||
|
<blocks-table |
||||||
|
:blocks="candidates" |
||||||
|
:config="config" |
||||||
|
:no-data-text="$t('pages.blocks.noPending')" |
||||||
|
/> |
||||||
|
</v-tab-item> |
||||||
|
</v-tabs-items> |
||||||
|
</v-card> |
||||||
|
</v-col> |
||||||
|
</v-row> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import BlocksTable from '~/components/tables/Blocks' |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
BlocksTable, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
tab: null, |
||||||
|
nf: new Intl.NumberFormat(this.locale, {}), |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
blocks() { |
||||||
|
return this.$store.state.blocks |
||||||
|
}, |
||||||
|
matured() { |
||||||
|
return this.$store.state.blocks?.matured || [] |
||||||
|
}, |
||||||
|
immature() { |
||||||
|
return this.$store.state.blocks?.immature || [] |
||||||
|
}, |
||||||
|
candidates() { |
||||||
|
return this.$store.state.blocks?.candidates || [] |
||||||
|
}, |
||||||
|
config() { |
||||||
|
return this.$store.state.env |
||||||
|
}, |
||||||
|
locale() { |
||||||
|
return this.$i18n.locale |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,109 @@ |
|||||||
|
<template> |
||||||
|
<v-row justify="center" align="center"> |
||||||
|
<v-col cols="12" sm="12" md="12"> |
||||||
|
<v-row no-gutters class="px-4"> |
||||||
|
<v-alert type="info" class="w-100 mb-0"> |
||||||
|
Change the address in the examples below to YOUR address before |
||||||
|
starting your miner. |
||||||
|
</v-alert> |
||||||
|
</v-row> |
||||||
|
<v-row no-gutters class="px-4"> |
||||||
|
<v-col cols="12" sm="12" md="12"> |
||||||
|
<v-card |
||||||
|
v-for="(miner, index) in miners" |
||||||
|
:key="index" |
||||||
|
tile |
||||||
|
class="my-2" |
||||||
|
> |
||||||
|
<v-card-title class="headline ma-0"> |
||||||
|
{{ miner.title }} |
||||||
|
<v-spacer /> |
||||||
|
<a class="pa-0" :href="miner.releases" target="_blank"> |
||||||
|
<v-btn color="primary" label> |
||||||
|
{{ miner.minVer }}+ |
||||||
|
<v-icon class="ml-2" small>mdi-download</v-icon> |
||||||
|
</v-btn> |
||||||
|
</a> |
||||||
|
</v-card-title> |
||||||
|
<v-card-text class="pa-0"> |
||||||
|
<article> |
||||||
|
<nuxt-content |
||||||
|
:document="miner" |
||||||
|
:class="{ 'code-lightmode': !darkmode }" |
||||||
|
/> |
||||||
|
</article> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
</v-col> |
||||||
|
</v-row> |
||||||
|
</v-col> |
||||||
|
</v-row> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
// import config here as 'this' context within asyncData is not the 'this' we are looking for |
||||||
|
import config from '~/params/config.json' |
||||||
|
|
||||||
|
export default { |
||||||
|
async asyncData({ $content }) { |
||||||
|
const network = config.network |
||||||
|
const pathPrefix = 'help/miners/' + network |
||||||
|
const miners = [] |
||||||
|
const supportsClassic = [ |
||||||
|
'lolminer', |
||||||
|
'nanominer', |
||||||
|
'trex', |
||||||
|
'nbminer', |
||||||
|
'gminer', |
||||||
|
'teamred', |
||||||
|
'srbminer', |
||||||
|
] |
||||||
|
const supportsMordor = ['lolminer', 'gminer'] |
||||||
|
|
||||||
|
if (network === 'mordor') { |
||||||
|
for (const miner of supportsMordor) { |
||||||
|
const doc = await $content(pathPrefix + '/' + miner).fetch() |
||||||
|
miners.push(doc) |
||||||
|
} |
||||||
|
} else { |
||||||
|
for (const miner of supportsClassic) { |
||||||
|
const doc = await $content(pathPrefix + '/' + miner).fetch() |
||||||
|
miners.push(doc) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// shuffle miners array to avoid an ordering bias |
||||||
|
let currentIndex = miners.length |
||||||
|
let temporaryValue |
||||||
|
let randomIndex |
||||||
|
|
||||||
|
// While there remain elements to shuffle... |
||||||
|
while (currentIndex !== 0) { |
||||||
|
// Pick a remaining element... |
||||||
|
randomIndex = Math.floor(Math.random() * currentIndex) |
||||||
|
currentIndex -= 1 |
||||||
|
|
||||||
|
// And swap it with the current element. |
||||||
|
temporaryValue = miners[currentIndex] |
||||||
|
miners[currentIndex] = miners[randomIndex] |
||||||
|
miners[randomIndex] = temporaryValue |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
miners, |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
darkmode() { |
||||||
|
return this.$vuetify.theme.dark |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
|
|
||||||
|
<style lang="scss" scoped> |
||||||
|
.v-card__title { |
||||||
|
background-color: var(--v-secondary-base) !important; |
||||||
|
} |
||||||
|
</style> |
||||||
|
> |
||||||
@ -0,0 +1,200 @@ |
|||||||
|
<template> |
||||||
|
<v-row justify="center" align="center" no-gutters class="pa-0"> |
||||||
|
<v-col cols="12" class="pa-0"> |
||||||
|
<v-card flat tile class="mb-0"> |
||||||
|
<v-img |
||||||
|
height="200" |
||||||
|
:src="require('~/static/' + config.banner)" |
||||||
|
gradient="to top right, rgba(0,0,0,.9), rgba(255,255,201,.33)" |
||||||
|
class="white--text align-end" |
||||||
|
> |
||||||
|
<v-card-title> |
||||||
|
<v-list style="background-color: rgba(0, 0, 0, 0)"> |
||||||
|
<v-list-item style="background-color: rgba(0, 0, 0, 0)"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<img :src="require('~/static/' + config.logo)" /> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title class="white--text">{{ |
||||||
|
config.title |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle class="white--text">{{ |
||||||
|
config.description |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
</v-card-title> |
||||||
|
</v-img> |
||||||
|
<v-alert |
||||||
|
v-if="network.testnet" |
||||||
|
outlined |
||||||
|
text |
||||||
|
dismissible |
||||||
|
tile |
||||||
|
type="warning" |
||||||
|
class="w-100 mb-0" |
||||||
|
> |
||||||
|
{{ |
||||||
|
$tc('pages.home.testnetAlert', 0, { |
||||||
|
title: config.network.title, |
||||||
|
symbol: config.network.symbol, |
||||||
|
}) |
||||||
|
}} |
||||||
|
</v-alert> |
||||||
|
<v-card-text class="py-1"> |
||||||
|
<v-list style="background-color: rgba(0, 0, 0, 0)"> |
||||||
|
<v-list-item style="background-color: rgba(0, 0, 0, 0)"> |
||||||
|
<v-list-item-avatar> |
||||||
|
<img :src="require('~/static/' + config.network.icon)" /> |
||||||
|
</v-list-item-avatar> |
||||||
|
<v-list-item-content> |
||||||
|
<v-list-item-title>{{ |
||||||
|
config.network.title |
||||||
|
}}</v-list-item-title> |
||||||
|
<v-list-item-subtitle>{{ |
||||||
|
config.network.algo |
||||||
|
}}</v-list-item-subtitle> |
||||||
|
</v-list-item-content> |
||||||
|
</v-list-item> |
||||||
|
</v-list> |
||||||
|
<ul> |
||||||
|
<li> |
||||||
|
{{ |
||||||
|
$tc('pages.home.minimumPayout', 0, { |
||||||
|
threshold: config.payoutThreshold, |
||||||
|
symbol: config.network.symbol, |
||||||
|
}) |
||||||
|
}} |
||||||
|
</li> |
||||||
|
<li>{{ $tc('pages.home.mode', 0, { mode: config.mode }) }}</li> |
||||||
|
<li> |
||||||
|
{{ $t('pages.home.poweredBy') }} |
||||||
|
<a href="https://github.com/etclabscore/core-pool" target="_blank" |
||||||
|
>core-pool</a |
||||||
|
>. |
||||||
|
</li> |
||||||
|
<li>{{ $t('pages.home.protocols') }}</li> |
||||||
|
</ul> |
||||||
|
</v-card-text> |
||||||
|
</v-card> |
||||||
|
<v-card flat tile> |
||||||
|
<v-card-title> |
||||||
|
<v-text-field |
||||||
|
v-model="search" |
||||||
|
append-icon="mdi-magnify" |
||||||
|
:label="$t('pages.home.search')" |
||||||
|
single-line |
||||||
|
outlined |
||||||
|
hide-details |
||||||
|
></v-text-field> |
||||||
|
</v-card-title> |
||||||
|
<v-data-table |
||||||
|
dense |
||||||
|
flat |
||||||
|
:headers="headers" |
||||||
|
:items="miners" |
||||||
|
:search="search" |
||||||
|
:footer-props="{ |
||||||
|
itemsPerPageText: $t('pages.home.minersPerPage'), |
||||||
|
itemsPerPageOptions: [25, 50, 100], |
||||||
|
}" |
||||||
|
:options="{ itemsPerPage: 25 }" |
||||||
|
:items-per-page="-1" |
||||||
|
:no-data-text="$t('pages.home.noMiners')" |
||||||
|
> |
||||||
|
<template #[`item.account`]="{ item }"> |
||||||
|
<nuxt-link :to="'/account/' + item.account">{{ |
||||||
|
formatAccountHash(item.account) |
||||||
|
}}</nuxt-link> |
||||||
|
</template> |
||||||
|
<template #[`item.hashrate`]="{ item }"> |
||||||
|
{{ formatHashrate(item.hashrate, true) }} |
||||||
|
</template> |
||||||
|
<template #[`item.lastBeat`]="{ item }"> |
||||||
|
{{ formatLastBeat(item.lastBeat) }} |
||||||
|
</template> |
||||||
|
</v-data-table> |
||||||
|
</v-card> |
||||||
|
</v-col> |
||||||
|
</v-row> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import { formatDistance } from 'date-fns' |
||||||
|
|
||||||
|
export default { |
||||||
|
data() { |
||||||
|
return { |
||||||
|
search: '', |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
headers() { |
||||||
|
return [ |
||||||
|
{ |
||||||
|
text: this.$t('pages.home.account'), |
||||||
|
align: 'start', |
||||||
|
value: 'account', |
||||||
|
}, |
||||||
|
{ text: this.$t('pages.home.hashrate'), value: 'hashrate' }, |
||||||
|
{ |
||||||
|
text: this.$t('pages.home.lastBeat'), |
||||||
|
align: 'right', |
||||||
|
value: 'lastBeat', |
||||||
|
}, |
||||||
|
] |
||||||
|
}, |
||||||
|
miners() { |
||||||
|
const obj = this.$store.state.miners |
||||||
|
const arr = [] |
||||||
|
for (const miner in obj) { |
||||||
|
arr.push({ |
||||||
|
account: miner, |
||||||
|
hashrate: obj[miner].hr, |
||||||
|
lastBeat: obj[miner].lastBeat * 1000, |
||||||
|
offline: obj[miner.offline], |
||||||
|
}) |
||||||
|
} |
||||||
|
return arr |
||||||
|
}, |
||||||
|
config() { |
||||||
|
return this.$store.state.env |
||||||
|
}, |
||||||
|
network() { |
||||||
|
return this.$store.state.env.network |
||||||
|
}, |
||||||
|
now() { |
||||||
|
return this.$store.state.now |
||||||
|
}, |
||||||
|
}, |
||||||
|
methods: { |
||||||
|
formatHashrate(bytes, showHash) { |
||||||
|
const sizes = ['', 'K', 'M', 'G', 'T'] |
||||||
|
if (bytes === 0) { |
||||||
|
return 'n/a' |
||||||
|
} |
||||||
|
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000))) |
||||||
|
if (i === 0) { |
||||||
|
return bytes + ' ' + sizes[i] |
||||||
|
} |
||||||
|
let unit = ' ' + sizes[i] |
||||||
|
if (showHash) { |
||||||
|
unit = ' ' + sizes[i] + 'H' |
||||||
|
} |
||||||
|
return (bytes / 1000 ** i).toFixed(3) + unit |
||||||
|
}, |
||||||
|
formatAccountHash(account) { |
||||||
|
const start = account.substring(0, 10) |
||||||
|
const end = account.substring(account.length - 10) |
||||||
|
return start + '...' + end |
||||||
|
}, |
||||||
|
formatLastBeat(time) { |
||||||
|
return formatDistance(new Date(time), this.now, { |
||||||
|
addSuffix: true, |
||||||
|
includeSeconds: true, |
||||||
|
}) |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
<template> |
||||||
|
<v-row justify="center" align="center" no-gutters> |
||||||
|
<v-col cols="12" class="pa-0"> |
||||||
|
<v-card tile flat> |
||||||
|
<v-tabs v-model="tab" background-color="transparent"> |
||||||
|
<v-tab>{{ $t('pages.payments.latestPayments') }}</v-tab> |
||||||
|
</v-tabs> |
||||||
|
<v-tabs-items v-model="tab"> |
||||||
|
<v-tab-item> |
||||||
|
<payments-table |
||||||
|
:payments="payments" |
||||||
|
:config="config" |
||||||
|
:no-data-text="$t('pages.payments.noPayments')" |
||||||
|
/> |
||||||
|
</v-tab-item> |
||||||
|
</v-tabs-items> |
||||||
|
</v-card> |
||||||
|
</v-col> |
||||||
|
</v-row> |
||||||
|
</template> |
||||||
|
|
||||||
|
<script> |
||||||
|
import PaymentsTable from '~/components/tables/Payments' |
||||||
|
|
||||||
|
export default { |
||||||
|
components: { |
||||||
|
PaymentsTable, |
||||||
|
}, |
||||||
|
data() { |
||||||
|
return { |
||||||
|
tab: null, |
||||||
|
nf: new Intl.NumberFormat(this.locale, {}), |
||||||
|
} |
||||||
|
}, |
||||||
|
computed: { |
||||||
|
payments() { |
||||||
|
return this.$store.state.payments?.payments |
||||||
|
}, |
||||||
|
config() { |
||||||
|
return this.$store.state.env |
||||||
|
}, |
||||||
|
locale() { |
||||||
|
return this.$i18n.locale |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
</script> |
||||||
@ -0,0 +1,93 @@ |
|||||||
|
## config.json |
||||||
|
|
||||||
|
Copy ~/params/example.config.json to ~/params/config.json |
||||||
|
|
||||||
|
### example config.json |
||||||
|
|
||||||
|
```javascript |
||||||
|
{ |
||||||
|
"title": "core-pool", |
||||||
|
"description": "vue based frontend for core-pool", |
||||||
|
"logo": "etc.svg", |
||||||
|
"favicon": "favicon.png", |
||||||
|
"url": "http://127.0.0.1:3000", |
||||||
|
"api": "http://127.0.0.1:8080", |
||||||
|
"stratum": "127.0.0.1:8008", |
||||||
|
"network": "classic", |
||||||
|
"explorer": { |
||||||
|
"url": "https://blockscout.com", |
||||||
|
"type": "blockscout" |
||||||
|
}, |
||||||
|
"poolFee": "1", |
||||||
|
"payoutThreshold": "0.5", |
||||||
|
"theme": { |
||||||
|
"dark": true, |
||||||
|
"themes": { |
||||||
|
"dark": { |
||||||
|
"primary": "#1976D2", |
||||||
|
"secondary": "#424242", |
||||||
|
"accent": "#82B1FF", |
||||||
|
"error": "#FF5252", |
||||||
|
"info": "#2196F3", |
||||||
|
"success": "#4CAF50", |
||||||
|
"warning": "#FFC107", |
||||||
|
"borders": "#2E2E2E" |
||||||
|
}, |
||||||
|
"light": { |
||||||
|
"primary": "#1976D2", |
||||||
|
"secondary": "#F5F5F5", |
||||||
|
"accent": "#82B1FF", |
||||||
|
"error": "#FF5252", |
||||||
|
"info": "#2196F3", |
||||||
|
"success": "#4CAF50", |
||||||
|
"warning": "#FFC107", |
||||||
|
"borders": "#E1E1E1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"options": { |
||||||
|
"customProperties": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"i18n": { |
||||||
|
"default": "en", |
||||||
|
"fallback": "en" |
||||||
|
}, |
||||||
|
"extraPools": [] |
||||||
|
} |
||||||
|
``` |
||||||
|
|
||||||
|
## images/icons |
||||||
|
|
||||||
|
To avoid future merge conflicts dont replace the existing icon/image files, add new ones alongside and update the config. Images/icons can be found in the ~/static directory. |
||||||
|
|
||||||
|
## network |
||||||
|
|
||||||
|
`classic`, `mordor`, `ethereum` or `ubiq` |
||||||
|
|
||||||
|
blocktimes, epochLength, icon, title, algo are set based on network, these values can be found in ~/params/networks.json |
||||||
|
|
||||||
|
## explorer type |
||||||
|
|
||||||
|
`expedition`, `blockscout`, `etherscan` or `spectrum` |
||||||
|
|
||||||
|
## theme |
||||||
|
|
||||||
|
`dark`: If true pool interface defaults to darkmode. |
||||||
|
|
||||||
|
Colors for each theme (dark/light) can be configured via config.json, see: https://vuetifyjs.com/en/features/theme for additional options. |
||||||
|
|
||||||
|
Addtional customizations/overrides can be done via ~/assets/variables.scss, see: https://vuetifyjs.com/en/features/sass-variables/ for more info. |
||||||
|
|
||||||
|
## extraPools |
||||||
|
|
||||||
|
Custom menu links to additional pool instances can easily be configured via the config, simply define any additional pools as follows |
||||||
|
|
||||||
|
``` |
||||||
|
"extraPools": [ |
||||||
|
{ "network": "ethereum", "url": "https://ethereum.pool.octano.dev", "type": "PROP" }, |
||||||
|
{ "network": "ubiq", "url": "https://ubiq.pool.octano.dev", "type": "PPLNS" }, |
||||||
|
{ "network": "classic", "url": "https://classic.pool.octano.dev", "type": "SOLO" } |
||||||
|
] |
||||||
|
``` |
||||||
|
|
||||||
|
Network must be a supported support key. Define any new networks in ~/params/networks.json (and submit a PR). |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
{ |
||||||
|
"title": "core-pool", |
||||||
|
"description": "vue based frontend for core-pool", |
||||||
|
"logo": "etc.svg", |
||||||
|
"favicon": "favicon.png", |
||||||
|
"banner": "banner.jpg", |
||||||
|
"url": "http://127.0.0.1:3000", |
||||||
|
"api": "http://127.0.0.1:8080", |
||||||
|
"stratum": "127.0.0.1:8008", |
||||||
|
"network": "classic", |
||||||
|
"explorer": { |
||||||
|
"url": "https://blockscout.com", |
||||||
|
"type": "blockscout" |
||||||
|
}, |
||||||
|
"poolFee": "1", |
||||||
|
"payoutThreshold": "0.5", |
||||||
|
"mode": "PROP", |
||||||
|
"theme": { |
||||||
|
"dark": true, |
||||||
|
"themes": { |
||||||
|
"dark": { |
||||||
|
"primary": "#1976D2", |
||||||
|
"secondary": "#424242", |
||||||
|
"accent": "#82B1FF", |
||||||
|
"error": "#FF5252", |
||||||
|
"info": "#2196F3", |
||||||
|
"success": "#4CAF50", |
||||||
|
"warning": "#FFC107", |
||||||
|
"borders": "#2E2E2E" |
||||||
|
}, |
||||||
|
"light": { |
||||||
|
"primary": "#1976D2", |
||||||
|
"secondary": "#F5F5F5", |
||||||
|
"accent": "#82B1FF", |
||||||
|
"error": "#FF5252", |
||||||
|
"info": "#2196F3", |
||||||
|
"success": "#4CAF50", |
||||||
|
"warning": "#FFC107", |
||||||
|
"borders": "#E1E1E1" |
||||||
|
} |
||||||
|
}, |
||||||
|
"options": { |
||||||
|
"customProperties": true |
||||||
|
} |
||||||
|
}, |
||||||
|
"i18n": { |
||||||
|
"default": "en", |
||||||
|
"fallback": "en" |
||||||
|
}, |
||||||
|
"extraPools": [] |
||||||
|
} |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
{ |
||||||
|
"classic": { |
||||||
|
"title": "Ethereum Classic", |
||||||
|
"symbol": "ETC", |
||||||
|
"icon": "etc.svg", |
||||||
|
"blockTime": 13.2, |
||||||
|
"epochLength": 60000, |
||||||
|
"algo": "etchash" |
||||||
|
}, |
||||||
|
"mordor": { |
||||||
|
"title": "Mordor Testnet", |
||||||
|
"symbol": "ETC", |
||||||
|
"icon": "etc.svg", |
||||||
|
"blockTime": 13.2, |
||||||
|
"epochLength": 60000, |
||||||
|
"algo": "etchash", |
||||||
|
"testnet": true |
||||||
|
}, |
||||||
|
"ethereum": { |
||||||
|
"title": "Ethereum Mainnet", |
||||||
|
"symbol": "ETH", |
||||||
|
"icon": "eth.png", |
||||||
|
"blockTime": 13.2, |
||||||
|
"epochLength": 30000, |
||||||
|
"algo": "ethash" |
||||||
|
}, |
||||||
|
"ubiq": { |
||||||
|
"title": "Ubiq Mainnet", |
||||||
|
"symbol": "UBQ", |
||||||
|
"icon": "ubq.svg", |
||||||
|
"blockTime": 88, |
||||||
|
"epochLength": 30000, |
||||||
|
"algo": "ubqhash" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
# PLUGINS |
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.** |
||||||
|
|
||||||
|
This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. |
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). |
||||||
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 253 KiB |
@ -0,0 +1,62 @@ |
|||||||
|
@import url('https://fonts.googleapis.com/css?family=Ubuntu+Mono&display=swap'); |
||||||
|
|
||||||
|
a { |
||||||
|
text-decoration: none; |
||||||
|
} |
||||||
|
|
||||||
|
.v-application { |
||||||
|
font-family: Ubuntu Mono, monospace !important; |
||||||
|
font-style: normal; |
||||||
|
font-variant: normal; |
||||||
|
} |
||||||
|
|
||||||
|
.w-100 { |
||||||
|
width: 100% !important; |
||||||
|
} |
||||||
|
|
||||||
|
.h-100 { |
||||||
|
height: calc(100vh - 80px) |
||||||
|
} |
||||||
|
|
||||||
|
.bg-transparent { |
||||||
|
background-color: $transparent !important; |
||||||
|
} |
||||||
|
|
||||||
|
.bb-1 { |
||||||
|
border-bottom: 1px solid $grey3 !important; |
||||||
|
} |
||||||
|
|
||||||
|
.nuxt-content-highlight pre { |
||||||
|
background-color: $transparent !important; |
||||||
|
border: none; |
||||||
|
} |
||||||
|
|
||||||
|
.nuxt-content-highlight pre code { |
||||||
|
background-color:$transparent !important; |
||||||
|
text-shadow: none !important; |
||||||
|
} |
||||||
|
|
||||||
|
.theme--dark.v-application { |
||||||
|
background-color: #1E1E1E !important; |
||||||
|
} |
||||||
|
|
||||||
|
// scrollbars |
||||||
|
|
||||||
|
::-webkit-scrollbar { |
||||||
|
width: 6px; /* for vertical scrollbars */ |
||||||
|
height: 6px; /* for horizontal scrollbars */ |
||||||
|
} |
||||||
|
::-webkit-scrollbar-track { |
||||||
|
background: var(--v-borders-base) !important; |
||||||
|
z-index: 4 !important |
||||||
|
} |
||||||
|
::-webkit-scrollbar-thumb { |
||||||
|
background: var(--v-primary-base) !important; |
||||||
|
} |
||||||
|
|
||||||
|
// firefox scrollbar z-index fix |
||||||
|
.ff-scrollbar-fix { |
||||||
|
transform: translate3d(0, 0, 0); |
||||||
|
scrollbar-color: var(--v-primary-base) var(--v-borders-base); |
||||||
|
scrollbar-width: thin; |
||||||
|
} |
||||||
@ -0,0 +1,11 @@ |
|||||||
|
$grey1: #111 !default; |
||||||
|
$grey2: #222 !default; |
||||||
|
$grey3: #333 !default; |
||||||
|
$grey4: #444 !default; |
||||||
|
$grey5: #555 !default; |
||||||
|
|
||||||
|
$greyLight: #e6e6e6 !default; |
||||||
|
|
||||||
|
$transparent: rgba(0,0,0,0); |
||||||
|
|
||||||
|
@import 'custom'; |
||||||
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
@ -0,0 +1,122 @@ |
|||||||
|
import axios from 'axios' |
||||||
|
import consola from 'consola' |
||||||
|
import config from '@/params/config.json' |
||||||
|
import networks from '@/params/networks.json' |
||||||
|
|
||||||
|
const TARGET_TIME = networks[config.network].blockTime |
||||||
|
const EPOCH_LENGTH = networks[config.network].epochLength |
||||||
|
const API_URL = config.api + '/api' |
||||||
|
|
||||||
|
export const state = () => ({ |
||||||
|
env: { |
||||||
|
title: config.title, |
||||||
|
description: config.description, |
||||||
|
logo: config.logo, |
||||||
|
favicon: config.favicon, |
||||||
|
banner: config.banner, |
||||||
|
url: config.url, |
||||||
|
api: API_URL, |
||||||
|
network: networks[config.network], |
||||||
|
stratum: config.stratum, |
||||||
|
symbol: networks[config.network].symbol, |
||||||
|
explorer: config.explorer, |
||||||
|
poolFee: config.poolFee, |
||||||
|
payoutThreshold: config.payoutThreshold, |
||||||
|
extraPools: config.extraPools, |
||||||
|
mode: config.mode, |
||||||
|
}, |
||||||
|
networks, |
||||||
|
minersOnline: 0, |
||||||
|
poolHashRate: 0, |
||||||
|
lastBlockFound: 0, |
||||||
|
roundShares: 0, |
||||||
|
height: 0, |
||||||
|
difficulty: 0, |
||||||
|
networkHashrate: 0, |
||||||
|
miners: {}, |
||||||
|
blocks: {}, |
||||||
|
payments: {}, |
||||||
|
epoch: 0, |
||||||
|
dagSize: 0, // in MB
|
||||||
|
now: Date.now(), // global now Date for time since calcs
|
||||||
|
}) |
||||||
|
|
||||||
|
export const mutations = { |
||||||
|
SET_STATS(state, info) { |
||||||
|
state.minersOnline = info.minersOnline | state.minersOnline |
||||||
|
state.poolHashRate = info.poolHashRate | state.poolHashRate |
||||||
|
state.lastBlockFound = info.lastBlockFound | state.lastBlockFound |
||||||
|
state.roundShares = info.roundShares | state.roundShares |
||||||
|
state.poolFee = info.poolFee | state.poolFee |
||||||
|
state.height = info.height | state.height |
||||||
|
state.difficulty = info.difficulty | state.difficulty |
||||||
|
state.networkHashrate = state.difficulty / TARGET_TIME |
||||||
|
state.epoch = Math.trunc(info.height / EPOCH_LENGTH) |
||||||
|
state.dagSize = 1024 + 8 * state.epoch |
||||||
|
}, |
||||||
|
SET_MINERS(state, miners) { |
||||||
|
state.miners = miners |
||||||
|
}, |
||||||
|
SET_BLOCKS(state, blocks) { |
||||||
|
state.blocks = blocks |
||||||
|
}, |
||||||
|
SET_PAYMENTS(state, txns) { |
||||||
|
state.payments = txns |
||||||
|
}, |
||||||
|
SET_NOW(state, now) { |
||||||
|
state.now = now |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export const actions = { |
||||||
|
async stats({ commit }) { |
||||||
|
try { |
||||||
|
const { data } = await axios.get(API_URL + '/stats') |
||||||
|
if (data) { |
||||||
|
const info = { |
||||||
|
minersOnline: data.minersTotal, |
||||||
|
poolHashRate: data.hashrate, |
||||||
|
height: data.nodes[0].height, |
||||||
|
difficulty: data.nodes[0].difficulty, |
||||||
|
lastBlockFound: data.stats.lastBlockFound, |
||||||
|
} |
||||||
|
commit('SET_STATS', info) |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
consola.error(new Error(error)) |
||||||
|
} |
||||||
|
}, |
||||||
|
async miners({ commit }) { |
||||||
|
try { |
||||||
|
const { data } = await axios.get(API_URL + '/miners') |
||||||
|
if (data) { |
||||||
|
commit('SET_MINERS', data.miners) |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
consola.error(new Error(error)) |
||||||
|
} |
||||||
|
}, |
||||||
|
async blocks({ commit }) { |
||||||
|
try { |
||||||
|
const { data } = await axios.get(API_URL + '/blocks') |
||||||
|
if (data) { |
||||||
|
commit('SET_BLOCKS', data) |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
consola.error(new Error(error)) |
||||||
|
} |
||||||
|
}, |
||||||
|
async payments({ commit }) { |
||||||
|
try { |
||||||
|
const { data } = await axios.get(API_URL + '/payments') |
||||||
|
if (data) { |
||||||
|
commit('SET_PAYMENTS', data) |
||||||
|
} |
||||||
|
} catch (error) { |
||||||
|
consola.error(new Error(error)) |
||||||
|
} |
||||||
|
}, |
||||||
|
now({ commit }) { |
||||||
|
commit('SET_NOW', Date.now()) |
||||||
|
}, |
||||||
|
} |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
// Libraries
|
||||||
|
import Vue from 'vue' |
||||||
|
import Vuetify from 'vuetify' |
||||||
|
|
||||||
|
// components
|
||||||
|
import ExplorerLink from '@/components/ExplorerLink.vue' |
||||||
|
|
||||||
|
import { mount, createLocalVue } from '@vue/test-utils' |
||||||
|
|
||||||
|
Vue.use(Vuetify) |
||||||
|
|
||||||
|
const localVue = createLocalVue() |
||||||
|
|
||||||
|
describe('ExplorerLink.vue', () => { |
||||||
|
let vuetify |
||||||
|
|
||||||
|
beforeEach(() => { |
||||||
|
vuetify = new Vuetify() |
||||||
|
}) |
||||||
|
|
||||||
|
it('is a Vue instance', () => { |
||||||
|
const wrapper = mount(ExplorerLink, { |
||||||
|
localVue, |
||||||
|
vuetify, |
||||||
|
propsData: { |
||||||
|
config: { |
||||||
|
network: 'classic', |
||||||
|
explorer: { |
||||||
|
url: 'https://blockscout.com', |
||||||
|
type: 'blockscout', |
||||||
|
}, |
||||||
|
symbol: 'ETC', |
||||||
|
}, |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
|
expect(wrapper.vm).toBeTruthy() |
||||||
|
}) |
||||||
|
}) |
||||||
Loading…
Reference in new issue