Merge branch 'master' into patch-1
7
.github/workflows/mainnet-deploy.yaml
vendored
@ -12,13 +12,14 @@ jobs:
|
||||
name: Ping deploy
|
||||
runs-on: mainnet
|
||||
steps:
|
||||
- name: print
|
||||
run: echo ${GITHUB_REF#refs/heads/}
|
||||
- name: Environment
|
||||
run: export NODE_OPTIONS="--max_old_space_size=4096"
|
||||
|
||||
- name: Git Checkout Latest
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install
|
||||
run: yarn install
|
||||
run: yarn install --ignore-engines
|
||||
|
||||
- name: Build
|
||||
run: yarn run vue-cli-service build
|
||||
|
2
.gitignore
vendored
@ -32,3 +32,5 @@ yarn-error.log*
|
||||
.yarn/
|
||||
.yarnrc.yml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
pkg/
|
||||
|
14
README.md
@ -15,22 +15,24 @@
|
||||
|
||||
</div>
|
||||
|
||||
Ping Explorer is a light explorer for Cosmos-based Blockchains. https://ping.pub .
|
||||
`Ping Dashboard` is a light explorer for Cosmos-based Blockchains. https://ping.pub .
|
||||
|
||||
## What is the difference between Ping explorer and other explorers?
|
||||
|
||||
Ping Explorer is designed to explore blockchain data as real as possible, therefore there is no cache, no pre-processing. Ping Explorer does not cache/save blockchain data on its server. Ping Explorer only fetch data from Cosmos full node via LCD/RPC endpoints. We call it "Light Explorer".
|
||||
`Ping Dashboard` is designed to explore blockchain data as real as possible, therefore there is no cache, no pre-processing. `Ping Dashboard` only fetch data from Cosmos full node via LCD/RPC endpoints. We call it "Light Explorer".
|
||||
|
||||
## Do you want to list your blockchain on ping.pub?
|
||||
|
||||
Pull your request [here](./src/chains), We will add your chains as soon as possible. It is **FREE** (You must have 10+ independent validators on your chain).
|
||||
Submit your pull request [here](./src/chains), We will add your chains as soon as possible. It is **FREE** (You must have 10+ independent validators on your chain).
|
||||
|
||||
We remain neutral to all chains, and we do not comment on their market prospects, technical risks, or investment risks. The only condition we list on ping.pub is if there are ten validators, and we cannot determine if these validators are controlled by the same entity.
|
||||
|
||||
## Why Ping explorer use official/trusted third party public LCD/rpc server?
|
||||
|
||||
We have two considerations:
|
||||
There are two main reasons:
|
||||
|
||||
- Trust, In decentralize system, everything controlled by one single team/organization could be risks. So we decided to co-build with the community.
|
||||
- Limited Resources: ` Ping Dashboard ` will list hundreds cosmos-based blockchains in the future, it's impossible for our team to run validators or fullnodes for all of those chains.
|
||||
- Trust, in a decentralized system, anything controlled by one entity cannot be trusted. So we decided to build with the community.
|
||||
- Limited resources: `Ping Dashboard` will list hundreds of cosmos-based blockchains in the future, and it is impossible for our team to run validators or full nodes for all of them.
|
||||
|
||||
|
||||
## Donation
|
||||
|
BIN
public/logos/c4e.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
public/logos/cronos.png
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
public/logos/game_of_chain.jpeg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/logos/mars.jpg
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
public/logos/mars.png
Normal file
After Width: | Height: | Size: 257 KiB |
BIN
public/logos/planq.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
public/logos/quasar.png
Normal file
After Width: | Height: | Size: 12 KiB |
@ -31,7 +31,7 @@
|
||||
{{ chainname }}
|
||||
</b-breadcrumb-item>
|
||||
<b-breadcrumb-item
|
||||
v-for="item in $route.meta.breadcrumb"
|
||||
v-for="item in breadcrumb"
|
||||
:key="item.text"
|
||||
:active="item.active"
|
||||
:to="item.to"
|
||||
@ -75,6 +75,14 @@ export default {
|
||||
chainname() {
|
||||
return this.$store?.state?.chains?.selected?.chain_name
|
||||
},
|
||||
/**
|
||||
* Invoke `route.meta.breadcrumb($route)` if breadcrumb is callable.
|
||||
*/
|
||||
breadcrumb() {
|
||||
const { breadcrumb } = this.$route.meta
|
||||
const breadcrumbIsCallable = typeof breadcrumb === 'function'
|
||||
return breadcrumbIsCallable ? breadcrumb(this.$route) : breadcrumb
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -1,53 +1,53 @@
|
||||
export default () => ([
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'dashboard',
|
||||
title: 'dashboard.dashboard',
|
||||
route: 'dashboard',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'blocks',
|
||||
title: 'dashboard.blocks',
|
||||
route: 'blocks',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'staking',
|
||||
title: 'dashboard.staking',
|
||||
route: 'staking',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'governance',
|
||||
title: 'dashboard.governance',
|
||||
route: 'governance',
|
||||
exclude: 'emoney',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'uptime',
|
||||
title: 'dashboard.uptime',
|
||||
route: 'uptime',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'parameters',
|
||||
title: 'dashboard.parameters',
|
||||
route: 'parameters',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'statesync',
|
||||
title: 'dashboard.statesync',
|
||||
route: 'statesync',
|
||||
},
|
||||
{
|
||||
scope: 'normal',
|
||||
title: 'consensus',
|
||||
title: 'dashboard.consensus',
|
||||
route: 'consensus',
|
||||
},
|
||||
{
|
||||
scope: 'cos-mos',
|
||||
title: 'gravity',
|
||||
title: 'dashboard.gravity',
|
||||
route: 'gravity',
|
||||
},
|
||||
{
|
||||
scope: 'osmosis',
|
||||
title: 'trade',
|
||||
title: 'dashboard.trade',
|
||||
route: 'osmosis-trade',
|
||||
},
|
||||
])
|
||||
|
@ -22,3 +22,28 @@
|
||||
.progress {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
||||
.scale {
|
||||
width: 100%;
|
||||
height: 3em;
|
||||
position: relative;
|
||||
/* margin: 30px; // */
|
||||
}
|
||||
.box {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding-top: 0.5em;
|
||||
/* opacity: 0.7; /**/
|
||||
background: transparent;
|
||||
}
|
||||
.overlay {
|
||||
z-index: 9;
|
||||
width: 2px;
|
||||
border-right-color: green;
|
||||
border-right-width: 2px;
|
||||
border-right-style: dotted;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"chain_name": "agoric",
|
||||
"api": [
|
||||
"https://api.agoric.sgtstake.com",
|
||||
"https://agoric-api.polkachu.com",
|
||||
"https://api-agoric.nodes.guru",
|
||||
"https://agoric.stakesystems.io",
|
||||
|
@ -4,7 +4,7 @@
|
||||
"api": ["https://rest.getbze.com"],
|
||||
"rpc": ["https://rpc-1.getbze.com:443","https://rpc-2.getbze.com:443"],
|
||||
"snapshot_provider": ["a9fac0534bd6853f5810fdc692564967bd01b1fe@rpc-1.getbze.com:26656"],
|
||||
"sdk_version": "0.44.3",
|
||||
"sdk_version": "0.45.9",
|
||||
"coin_type": "370",
|
||||
"min_tx_fee": "8000",
|
||||
"addr_prefix": "bze",
|
||||
|
@ -6,7 +6,7 @@
|
||||
"snapshot_provider": "29edc55748bc341224f711a05cb0a9f6d73b4da3@bitcanna.rpc.ping.pub:26656",
|
||||
"sdk_version": "0.45.10",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "8000",
|
||||
"min_tx_fee": "420",
|
||||
"assets": [{
|
||||
"base": "ubcna",
|
||||
"symbol": "BCNA",
|
||||
|
16
src/chains/mainnet/chain4energy.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"chain_name": "chain4energy",
|
||||
"api": ["https://lcd.c4e.io"],
|
||||
"rpc": ["https://rpc.c4e.io:443", "https://rpc.c4e.io:443"],
|
||||
"sdk_version": "0.45.5",
|
||||
"coin_type": "4444",
|
||||
"min_tx_fee": "3000",
|
||||
"addr_prefix": "c4e",
|
||||
"logo": "/logos/c4e.png",
|
||||
"assets": [{
|
||||
"base": "uc4e",
|
||||
"symbol": "C4E",
|
||||
"exponent": "6",
|
||||
"logo": "/logos/c4e.png"
|
||||
}]
|
||||
}
|
17
src/chains/mainnet/cronos.json
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
{
|
||||
"chain_name": "cronos",
|
||||
"api": ["https://rest.cronos.org"],
|
||||
"rpc": ["https://rpc.cronos.org:443"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.11",
|
||||
"coin_type": "60",
|
||||
"min_tx_fee": "5000000000000000",
|
||||
"addr_prefix": "crc",
|
||||
"logo": "/logos/cronos.png",
|
||||
"assets": [{
|
||||
"base": "basecro",
|
||||
"symbol": "CRO",
|
||||
"exponent": "18"
|
||||
}]
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"chain_name": "injective",
|
||||
"api": "https://lcd.injective.network",
|
||||
"rpc": ["https://injective-rpc.api.chainlayer.network:443", "https://injective-rpc.api.chainlayer.network:443"],
|
||||
"api": ["https://lcd.injective.network", "https://injective-api.polkachu.com"],
|
||||
"rpc": ["https://tm.injective.network", "https://injective-rpc.polkachu.com"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "v0.45.5",
|
||||
"coin_type": "60",
|
||||
@ -9,6 +9,12 @@
|
||||
"addr_prefix": "inj",
|
||||
"excludes": "",
|
||||
"logo": "/logos/injective.jpg",
|
||||
"keplr_features": ["ibc-transfer", "ibc-go", "eth-address-gen", "eth-key-sign"],
|
||||
"keplr_price_step": {
|
||||
"low": 100000000000,
|
||||
"average": 200000000000,
|
||||
"high": 30000000000000
|
||||
},
|
||||
"assets": [{
|
||||
"base": "inj",
|
||||
"symbol": "INJ",
|
||||
|
@ -1,18 +1,28 @@
|
||||
{
|
||||
"chain_name": "jackal",
|
||||
"coingecko": "",
|
||||
"api": ["https://api.jackalprotocol.com", "https://jackal-api.polkachu.com","https://api.jackal.nodestake.top"],
|
||||
"rpc": ["https://rpc.jackalprotocol.com", "https://jackal-rpc.polkachu.com","https://rpc.jackal.nodestake.top"],
|
||||
"coingecko": "jackal-protocol",
|
||||
"api": [
|
||||
"https://api.jackalprotocol.com",
|
||||
"https://jackal-api.polkachu.com",
|
||||
"https://api.jackal.nodestake.top"
|
||||
],
|
||||
"rpc": [
|
||||
"https://rpc.jackalprotocol.com",
|
||||
"https://jackal-rpc.polkachu.com",
|
||||
"https://rpc.jackal.nodestake.top"
|
||||
],
|
||||
"snapshot_provider": "",
|
||||
"coin_type": "118",
|
||||
"sdk_version": "0.45.9",
|
||||
"sdk_version": "0.45.11",
|
||||
"addr_prefix": "jkl",
|
||||
"logo": "/logos/jackal.png",
|
||||
"assets": [{
|
||||
"base": "ujkl",
|
||||
"symbol": "JKL",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "jackal",
|
||||
"logo": "/logos/jackal.png"
|
||||
}]
|
||||
"assets": [
|
||||
{
|
||||
"base": "ujkl",
|
||||
"symbol": "JKL",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "jackal",
|
||||
"logo": "/logos/jackal.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"chain_name": "lumenx",
|
||||
"coingecko": "",
|
||||
"api": "https://api.helios-1.lumenex.io",
|
||||
"rpc": ["https://rpc.helios-1.lumenex.io:443","http://node4.lumenex.io:26657"],
|
||||
"api": ["https://api.lumenx.chaintools.tech:443","https://api-lumenx.cryptonet.pl:443"],
|
||||
"rpc": ["https://rpc.lumenx.chaintools.tech:443","https://rpc-lumenx.cryptonet.pl:443"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.5",
|
||||
"coin_type": "118",
|
||||
|
29
src/chains/mainnet/mars.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"chain_name": "mars",
|
||||
"coingecko": "",
|
||||
"api": [
|
||||
"https://rest.marsprotocol.io",
|
||||
"https://mars-api.polkachu.com",
|
||||
"https://rest.cosmos.directory/mars"
|
||||
],
|
||||
"rpc": [
|
||||
"https://rpc.marsprotocol.io",
|
||||
"https://mars-rpc.polkachu.com",
|
||||
"https://rpc.marsprotocol.io",
|
||||
"https://rpc.cosmos.directory/mars"
|
||||
],
|
||||
"snapshot_provider": "",
|
||||
"coin_type": "118",
|
||||
"sdk_version": "0.46.8",
|
||||
"addr_prefix": "mars",
|
||||
"logo": "/logos/mars.png",
|
||||
"assets": [
|
||||
{
|
||||
"base": "umars",
|
||||
"symbol": "MARS",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/mars.png"
|
||||
}
|
||||
]
|
||||
}
|
19
src/chains/mainnet/planq.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"chain_name": "planq",
|
||||
"api": ["https://rest.planq.network"],
|
||||
"rpc": ["https://rpc.planq.network"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.46.3",
|
||||
"coin_type": "60",
|
||||
"min_tx_fee": "5000000000000000",
|
||||
"addr_prefix": "plq",
|
||||
"logo": "/logos/planq.png",
|
||||
"keplr_features": ["ibc-transfer", "ibc-go", "eth-address-gen", "eth-key-sign"],
|
||||
"assets": [{
|
||||
"base": "aplanq",
|
||||
"symbol": "planq",
|
||||
"exponent": "18",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/planq.png"
|
||||
}]
|
||||
}
|
20
src/chains/mainnet/quicksilver.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"chain_name": "quicksilver",
|
||||
"coingecko": "",
|
||||
"api": ["https://quicksilver-api.polkachu.com", "https://api-quicksilver.nodeist.net"],
|
||||
"rpc": ["https://quicksilver-rpc.polkachu.com", "https://rpc-quicksilver.nodeist.net"],
|
||||
"sdk_version": "0.46.7",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "8000",
|
||||
"addr_prefix": "quick",
|
||||
"logo": "/logos/quicksilver.png",
|
||||
"assets": [
|
||||
{
|
||||
"base": "uqck",
|
||||
"symbol": "QCK",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/quicksilver.png"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"chain_name": "rebus",
|
||||
"api": ["https://api.mainnet.rebus.money:1317", "https://rebus.api.kjnodes.com"],
|
||||
"rpc": ["https://api.mainnet.rebus.money:26657", "https://rebus.rpc.kjnodes.com:443"],
|
||||
"api": ["https://api.mainnet.rebus.money:1317","https://api.rebus.nodestake.top"],
|
||||
"rpc": ["https://api.mainnet.rebus.money:26657","https://rpc.rebus.nodestake.top"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.6",
|
||||
"coin_type": "118",
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"chain_name": "secret",
|
||||
"coingecko": "secret",
|
||||
"api": ["https://api.roninventures.io","https://api.scrt.network"],
|
||||
"rpc": ["http://beta-api.scrt.network:26657", "https://api.scrt.network:443"],
|
||||
"api": ["https://lcd.spartanapi.dev", "https://secretnetwork-lcd.stakely.io"],
|
||||
"rpc": ["https://rpc.spartanapi.dev", "https://secretnetwork-rpc.stakely.io"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.4",
|
||||
"coin_type": "529",
|
||||
|
@ -2,10 +2,10 @@
|
||||
{
|
||||
"chain_name": "shentu",
|
||||
"coingecko": "certik",
|
||||
"api": ["https://certik-api.polkachu.com/", "https://shentu-api.panthea.eu", "https://chainfull.noopsbycertik.com"],
|
||||
"rpc": ["https://certik-rpc.polkachu.com:443", "https://shentu-rpc.panthea.eu:443"],
|
||||
"api": ["https://certik-api.polkachu.com", "https://chainfull.noopsbycertik.com"],
|
||||
"rpc": ["https://certik-rpc.polkachu.com:443"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.4",
|
||||
"sdk_version": "0.45.9",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "8000",
|
||||
"addr_prefix": "certik",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"chain_name": "teritori",
|
||||
"api": ["https://rest.mainnet.teritori.com", "https://teritori.api.kjnodes.com"],
|
||||
"rpc": ["https://rpc.mainnet.teritori.com", "https://teritori.rpc.kjnodes.com:443"],
|
||||
"api": ["https://rest.mainnet.teritori.com","https://api.teritori.nodestake.top"],
|
||||
"rpc": ["https://rpc.mainnet.teritori.com","https://rpc.teritori.nodestake.top"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.4",
|
||||
"coin_type": "118",
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"chain_name": "vidulum",
|
||||
"coingecko": "vidulum",
|
||||
"api": ["https://mainnet-lcd.vidulum.app", "https://api-vidulum-ia.cosmosia.notional.ventures", "https://rest.rpc.erialos.me"],
|
||||
"rpc": ["https://trpc.rpc.erialos.me:443","https://rpc-vidulum-ia.cosmosia.notional.ventures:443", "https://mainnet-rpc.vidulum.app:443"],
|
||||
"snapshot_provider": "c32903505e9ab811ac46306d2913c98ccf4883ce@rpc.erialos.me:26656",
|
||||
"api": ["https://mainnet-lcd.vidulum.app", "https://api-vidulum-ia.cosmosia.notional.ventures"],
|
||||
"rpc": ["https://mainnet-rpc.vidulum.app:443", "https://rpc-vidulum-ia.cosmosia.notional.ventures:443"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.9",
|
||||
"coin_type": "370",
|
||||
"min_tx_fee": "8000",
|
||||
|
20
src/chains/testnet/apollo.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"chain_name": "apollo",
|
||||
"provider_chain": {
|
||||
"api": "https://rest.provider-sentry-01.goc.earthball.xyz"
|
||||
},
|
||||
"api": ["https://apollo.api.ping.pub"],
|
||||
"rpc": [],
|
||||
"sdk_version": "0.45.7",
|
||||
"coin_type": 118,
|
||||
"min_tx_fee": "0",
|
||||
"addr_prefix": "cosmos",
|
||||
"logo": "/logos/game_of_chain.jpeg",
|
||||
"assets": [{
|
||||
"base": "upol",
|
||||
"symbol": "POL",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/game_of_chain.jpeg"
|
||||
}]
|
||||
}
|
19
src/chains/testnet/canto.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"chain_name": "canto",
|
||||
"api": ["https://canto-testnet.ansybl.io/api"],
|
||||
"rpc": ["https://canto-testnet.ansybl.io/rpc"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.6",
|
||||
"coin_type": "60",
|
||||
"min_tx_fee": "800",
|
||||
"addr_prefix": "canto",
|
||||
"logo": "/logos/canto.png",
|
||||
"assets": [
|
||||
{
|
||||
"base": "acanto",
|
||||
"symbol": "CANTO",
|
||||
"exponent": "18"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
19
src/chains/testnet/celestia.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"chain_name": "celestia",
|
||||
"coingecko": "",
|
||||
"api": ["https://celestia-testnet-api.polkachu.com"],
|
||||
"rpc": ["https://celestia-testnet-rpc.polkachu.com"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.46.0",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "800",
|
||||
"addr_prefix": "celestia",
|
||||
"logo": "/logos/celestia.png",
|
||||
"assets": [{
|
||||
"base": "utia",
|
||||
"symbol": "TIA",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/celestia.png"
|
||||
}]
|
||||
}
|
@ -1,7 +1,17 @@
|
||||
{
|
||||
"chain_name": "cosmos-vega",
|
||||
"api":"https://vega.api.ping.pub",
|
||||
"sdk_version": "0.42.9",
|
||||
"chain_name": "cosmos",
|
||||
"api": ["https://vega.api.ping.pub", "https://rest.seed-01.theta-testnet.polypore.xyz", "https://rest.seed-02.theta-testnet.polypore.xyz"],
|
||||
"rpc": ["https://rpc.seed-01.theta-testnet.polypore.xyz", "https://rpc.seed-02.theta-testnet.polypore.xyz"],
|
||||
"sdk_version": "0.45.1",
|
||||
"coin_type": "118",
|
||||
"min_tx_fee": "800",
|
||||
"addr_prefix": "cosmos",
|
||||
"logo": "https://dl.airtable.com/.attachments/e54f814bba8c0f9af8a3056020210de0/2d1155fb/cosmos-hub.svg"
|
||||
}
|
||||
"logo": "/logos/cosmos.svg",
|
||||
"assets": [{
|
||||
"base": "uatom",
|
||||
"symbol": "ATOM",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "cosmos",
|
||||
"logo": "/logos/cosmos.svg"
|
||||
}]
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
"min_tx_fee": "3000000000000000",
|
||||
"addr_prefix": "evmos",
|
||||
"logo": "/logos/evmos.jpeg",
|
||||
"keplr_features": ["ibc-transfer", "ibc-go", "eth-address-gen", "eth-key-sign"],
|
||||
"assets": [{
|
||||
"base": "atevmos",
|
||||
"symbol": "TEVMOS",
|
||||
|
20
src/chains/testnet/hero.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"chain_name": "hero",
|
||||
"provider_chain": {
|
||||
"api": "https://rest.provider-sentry-01.goc.earthball.xyz"
|
||||
},
|
||||
"api": ["https://api-c.hero.nodestake.top"],
|
||||
"rpc": ["https://rpc-c.hero.nodestake.top"],
|
||||
"sdk_version": "0.45.7",
|
||||
"coin_type": 118,
|
||||
"min_tx_fee": "0",
|
||||
"addr_prefix": "cosmos",
|
||||
"logo": "/logos/game_of_chain.jpeg",
|
||||
"assets": [{
|
||||
"base": "uhero",
|
||||
"symbol": "HERO",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/game_of_chain.jpeg"
|
||||
}]
|
||||
}
|
@ -1,17 +1,23 @@
|
||||
{
|
||||
"chain_name": "jackal",
|
||||
"coingecko": "jackal",
|
||||
"api": "https://testnet-api.jackalprotocol.com",
|
||||
"rpc": "https://testnet-rpc.jackalprotocol.com",
|
||||
"coingecko": "jackal_protocol",
|
||||
"api": [
|
||||
"https://testnet-api.jackalprotocol.com"
|
||||
],
|
||||
"rpc": [
|
||||
"https://testnet-rpc.jackalprotocol.com"
|
||||
],
|
||||
"coin_type": "118",
|
||||
"sdk_version": "0.45.9",
|
||||
"addr_prefix": "jkl",
|
||||
"sdk_version": "0.45.11",
|
||||
"addr_prefix": "jkl",
|
||||
"logo": "/logos/jackal.png",
|
||||
"assets": [{
|
||||
"base": "ujkl",
|
||||
"symbol": "JKL",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "jackal",
|
||||
"logo": "/logos/jackal.png"
|
||||
}]
|
||||
}
|
||||
"assets": [
|
||||
{
|
||||
"base": "ujkl",
|
||||
"symbol": "JKL",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "jackal-protocol",
|
||||
"logo": "/logos/jackal.png"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"chain_name": "osmosis",
|
||||
"coingecko": "osmosis",
|
||||
"api": ["https://testnet-rest.osmosis.zone", "https://lcd.osmo-test.ccvalidators.com", "https://osmosistest-lcd.quickapi.com"],
|
||||
"rpc": ["https://testnet-rpc.osmosis.zone:443", "https://rpc.osmo-test.ccvalidators.com:443"," https://osmosistest-rpc.quickapi.com:443"],
|
||||
"api": ["https://lcd-test.osmosis.zone", "https://lcd.osmo-test.ccvalidators.com", "https://osmosistest-lcd.quickapi.com"],
|
||||
"rpc": ["https://rpc-test.osmosis.zone", "https://testnet-rpc.osmosis.zone:443", "https://rpc.osmo-test.ccvalidators.com:443"," https://osmosistest-rpc.quickapi.com:443"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.44.5",
|
||||
"coin_type": "118",
|
||||
|
17
src/chains/testnet/provider.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"chain_name": "provider",
|
||||
"api": ["https://rest.provider-sentry-01.goc.earthball.xyz","https://rest.provider-sentry-02.goc.earthball.xyz"],
|
||||
"rpc": ["https://rpc.provider-sentry-01.goc.earthball.xyz"],
|
||||
"sdk_version": "0.45.7",
|
||||
"coin_type": 118,
|
||||
"min_tx_fee": "0",
|
||||
"addr_prefix": "cosmos",
|
||||
"logo": "/logos/game_of_chain.jpeg",
|
||||
"assets": [{
|
||||
"base": "uprov",
|
||||
"symbol": "PROV",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/game_of_chain.jpeg"
|
||||
}]
|
||||
}
|
20
src/chains/testnet/quasar.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"chain_name": "quasar",
|
||||
"coingecko": "",
|
||||
"api": ["https://quasar-testnet-api.polkachu.com", "https://lcd-office.cosmostation.io/quasar-testnet"],
|
||||
"rpc": ["https://quasar-testnet-rpc.polkachu.com", "https://rpc-office.cosmostation.io/quasar-testnet", "https://questnet.quasar-finance.rhinostake.com"],
|
||||
"sdk_version": "0.45.6",
|
||||
"coin_type": 118,
|
||||
"min_tx_fee": "8000",
|
||||
"addr_prefix": "quasar",
|
||||
"logo": "/logos/quasar.png",
|
||||
"assets": [
|
||||
{
|
||||
"base": "uqsr",
|
||||
"symbol": "QSR",
|
||||
"exponent": 6,
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/quasar.png"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"chain_name": "secret",
|
||||
"coingecko": "secret",
|
||||
"api": ["https://api.pulsar.scrttestnet.com","https://lcd.testnet.secretsaturn.net", "https://testnet-api.roninventures.io", "https://pulsar-2.api.trivium.network:1317"],
|
||||
"rpc": ["https://rpc.pulsar.scrttestnet.com", "https://rpc.testnet.secretsaturn.net", "https://testnet-rpc.roninventures.io", "https://pulsar-2.api.trivium.network:26657"],
|
||||
"api": ["https://api.pulsar.scrttestnet.com","https://lcd.testnet.secretsaturn.net", "https://pulsar-2.api.trivium.network:1317"],
|
||||
"rpc": ["https://rpc.pulsar.scrttestnet.com", "https://rpc.testnet.secretsaturn.net", "https://pulsar-2.api.trivium.network:26657"],
|
||||
"snapshot_provider": "",
|
||||
"sdk_version": "0.45.4",
|
||||
"coin_type": "529",
|
||||
|
20
src/chains/testnet/sputnik.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"chain_name": "sputnik",
|
||||
"provider_chain": {
|
||||
"api": "https://rest.provider-sentry-01.goc.earthball.xyz"
|
||||
},
|
||||
"api": ["https://sputnik.api.ping.pub"],
|
||||
"rpc": [],
|
||||
"sdk_version": "0.45.7",
|
||||
"coin_type": 118,
|
||||
"min_tx_fee": "0",
|
||||
"addr_prefix": "cosmos",
|
||||
"logo": "/logos/game_of_chain.jpeg",
|
||||
"assets": [{
|
||||
"base": "unik",
|
||||
"symbol": "NIK",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "",
|
||||
"logo": "/logos/game_of_chain.jpeg"
|
||||
}]
|
||||
}
|
@ -2,64 +2,150 @@
|
||||
"message": {
|
||||
|
||||
},
|
||||
"cosmos": "Cosmos Hub",
|
||||
"kava": "Kava",
|
||||
"akash-network": "Akash Decloud",
|
||||
"iris-network": "IRIS Hub",
|
||||
"crypto-com-chain": "Crypto.org",
|
||||
"osmosis": "Osmosis",
|
||||
"okexchain": "OKEX Chain",
|
||||
"band-protocol": "Band Protocol",
|
||||
"terra-luna": "Terra",
|
||||
"persistence": "Persistence",
|
||||
"regen": "Regen Network",
|
||||
"secret": "Secret Network",
|
||||
"desmos": "Desmos",
|
||||
"juno": "Juno",
|
||||
"certik": "Certik",
|
||||
"sentinel": "Sentinel",
|
||||
"sifchain": "Sifchain",
|
||||
"starname": "Starname",
|
||||
"bitsong": "BitSong",
|
||||
"e-money": "E-Money",
|
||||
"omniflix": "OmniFlix",
|
||||
"likecoin": "LikeCoin",
|
||||
"stargaze": "Stargaze",
|
||||
"injective": "Injective Protocal",
|
||||
"vidulum": "Vidulum",
|
||||
"kichain": "KI Chain",
|
||||
"genesisL1": "Genesis L1",
|
||||
"microtick": "Microtick",
|
||||
"odin": "ODIN",
|
||||
"chihuahua": "CHIHUAHUA",
|
||||
|
||||
"staking": "Staking",
|
||||
"governance": "Governance",
|
||||
"summary": "Summary",
|
||||
"blocks": "Blocks / Transactions",
|
||||
"blockchains": "Blockchains",
|
||||
"uptime": "Uptime",
|
||||
"statesync": "State Sync",
|
||||
"trade": "Trade",
|
||||
|
||||
"gravity": "Gravity(WIP)",
|
||||
"pools": "Pools(WIP)",
|
||||
"chains": {
|
||||
"cosmos": "Cosmos Hub",
|
||||
"kava": "Kava",
|
||||
"akash-network": "Akash Decloud",
|
||||
"iris-network": "IRIS Hub",
|
||||
"crypto-com-chain": "Crypto.org",
|
||||
"osmosis": "Osmosis",
|
||||
"okexchain": "OKEX Chain",
|
||||
"band-protocol": "Band Protocol",
|
||||
"terra-luna": "Terra",
|
||||
"persistence": "Persistence",
|
||||
"regen": "Regen Network",
|
||||
"secret": "Secret Network",
|
||||
"desmos": "Desmos",
|
||||
"juno": "Juno",
|
||||
"certik": "Certik",
|
||||
"sentinel": "Sentinel",
|
||||
"sifchain": "Sifchain",
|
||||
"starname": "Starname",
|
||||
"bitsong": "BitSong",
|
||||
"e-money": "E-Money",
|
||||
"omniflix": "OmniFlix",
|
||||
"likecoin": "LikeCoin",
|
||||
"stargaze": "Stargaze",
|
||||
"injective": "Injective Protocal",
|
||||
"vidulum": "Vidulum",
|
||||
"kichain": "KI Chain",
|
||||
"genesisL1": "Genesis L1",
|
||||
"microtick": "Microtick",
|
||||
"odin": "ODIN",
|
||||
"chihuahua": "CHIHUAHUA",
|
||||
|
||||
"proposal_id": "Proposal ID",
|
||||
"proposal_type": "Proposal Type",
|
||||
"proposal_proposer": "Proposer",
|
||||
"proposal_submit_time": "Submited Time",
|
||||
"proposal_voting_start_time": "Voting Begin Time",
|
||||
"proposal_voting_end_time": "Voting End Time",
|
||||
"proposal_description": "Description",
|
||||
"proposal_content": "Content",
|
||||
"proposal_total_deposit": "Total Deposit",
|
||||
"voting_time": "Voting Time",
|
||||
"upgrade_time": "Estimated Upgrade Time:",
|
||||
"gravity": "Gravity(WIP)",
|
||||
"pools": "Pools(WIP)"
|
||||
},
|
||||
|
||||
"btn_vote": "Vote",
|
||||
"btn_deposit": "Deposit",
|
||||
"btn_detail": "Detail",
|
||||
"btn_back_list": "Back To List"
|
||||
|
||||
"dashboard": {
|
||||
"dashboard": "Dashboard",
|
||||
"staking": "Staking",
|
||||
"governance": "Governance",
|
||||
"summary": "Summary",
|
||||
"blocks": "Blocks / Transactions",
|
||||
"blockchains": "Blockchains",
|
||||
"uptime": "Uptime",
|
||||
"statesync": "State Sync",
|
||||
"trade": "Trade",
|
||||
"parameters": "Parameters",
|
||||
"consensus": "consensus",
|
||||
"no_new_blocks": "No new blocks have been produced since ",
|
||||
"active_props": "Active Proposals",
|
||||
"proposal_votes_yes": "voters voted Yes",
|
||||
"proposal_votes_no": "voters voted No",
|
||||
"proposal_votes_nwv": "voters voted No With Veto",
|
||||
"proposal_votes_abstain": "voters voted Abstain",
|
||||
"no_active_prop": "No active proposal!",
|
||||
"browse": "Browse all",
|
||||
"assets": "Assets",
|
||||
"more": "More",
|
||||
"not_conn": "Not Connected?",
|
||||
"delegate": "Delegate",
|
||||
"redelegate": "Redelegate",
|
||||
"unbond": "Unbond",
|
||||
"withdraw_reward": "Withdraw Rewards",
|
||||
"unbonding_token": "Unbonding Tokens",
|
||||
"send": "Send",
|
||||
"receive": "Receive",
|
||||
"connect_wal": "Connect Wallet"
|
||||
},
|
||||
|
||||
"governanceProposal": {
|
||||
"proposal_id": "Proposal ID",
|
||||
"proposal_type": "Proposal Type",
|
||||
"proposal_proposer": "Proposer",
|
||||
"proposal_submit_time": "Submitted Time",
|
||||
"proposal_voting_start_time": "Voting Begin Time",
|
||||
"proposal_voting_end_time": "Voting End Time",
|
||||
"proposal_description": "Description",
|
||||
"proposal_content": "Content",
|
||||
"proposal_total_deposit": "Total Deposit",
|
||||
"proposal_deposits": "Deposits",
|
||||
"voting_time": "Voting Time",
|
||||
"upgrade_time": "Estimated Upgrade Time:",
|
||||
|
||||
"btn_vote": "Vote",
|
||||
"btn_deposit": "Deposit",
|
||||
"btn_detail": "Detail",
|
||||
"btn_back_list": "Back To List",
|
||||
|
||||
"proposal_status": "Status",
|
||||
"proposal_status_deposit": "Deposit",
|
||||
"proposal_status_voting": "Voting",
|
||||
"proposal_status_passed": "Passed",
|
||||
"proposal_status_rejected": "Rejected",
|
||||
"proposal_status_start_date": "Start Date",
|
||||
"proposal_status_end_date": "End Date",
|
||||
"proposal_votes": "Votes",
|
||||
"proposal_votes_yes": "voted Yes",
|
||||
"proposal_votes_no": "voted No",
|
||||
"proposal_votes_nwv": "voted No With Veto",
|
||||
"proposal_votes_abstain": "voted Abstain",
|
||||
"proposal_votes_load": "Load More Votes"
|
||||
},
|
||||
"parameters" : {
|
||||
"no_blocks_produced" : "No new blocks have been produced since ",
|
||||
"app_ver": "Application Version",
|
||||
"node_info": "Node Information"
|
||||
},
|
||||
"uptimeMyChainBlocks" : {
|
||||
"height": "Height:",
|
||||
"no_blocks_produced" : "No new blocks have been produced since ",
|
||||
"not_active": "Your node is out of active validator set"
|
||||
},
|
||||
"walletAccountDetail": {
|
||||
"address": "Address:",
|
||||
"assets": "Assets",
|
||||
"transfer": "Transfer",
|
||||
"ibc_transfer": "IBC Transfer",
|
||||
"total": "Total: ",
|
||||
"unbonding": "Unbonding Tokens",
|
||||
"from": "From: ",
|
||||
"delegation": "Delegation",
|
||||
"delegate": "Delegate",
|
||||
"withdraw": " Withdraw Rewards",
|
||||
"acct_type": "Account Type",
|
||||
"acct_num": "Account Number",
|
||||
"seq": "Sequence",
|
||||
"pub_key": "Public Key",
|
||||
"orig_vest": "Original Vesting",
|
||||
"delegated_free": "Delegated Free",
|
||||
"delegated_vest": "Delegated Vesting",
|
||||
"vest_time": "Vesting Time",
|
||||
"vest_period": "Vesting Periods",
|
||||
"length": "Length",
|
||||
"amount": "Amount",
|
||||
"end_time": "End Time",
|
||||
"acct_not_found": "Account not found",
|
||||
"opps": "Oops!",
|
||||
"back_home": "Back to home"
|
||||
},
|
||||
"uptimeMyValidators": {
|
||||
"tips": "Tips",
|
||||
"two_ways": "There are two ways to monitor your validators:",
|
||||
"pin": "Pin a validator on Uptime pages.",
|
||||
"link": "Specify parameters like following:"
|
||||
}
|
||||
}
|
||||
|
@ -84,9 +84,9 @@
|
||||
<!-- <dark-Toggler class="d-none d-lg-block" /> -->
|
||||
<!-- Right Col -->
|
||||
<b-navbar-nav class="nav align-items-center ml-auto">
|
||||
<dark-Toggler class="d-none d-lg-block" />
|
||||
<dark-Toggler />
|
||||
<search-bar />
|
||||
<locale />
|
||||
<locale class="d-none" />
|
||||
<b-dropdown
|
||||
class="ml-1"
|
||||
variant="link"
|
||||
|
@ -9,16 +9,16 @@ export default class ProposalTally {
|
||||
}
|
||||
|
||||
init(element, total) {
|
||||
const subtotal = Number(element.yes) + Number(element.no) + Number(element.abstain) + Number(element.no_with_veto)
|
||||
const subtotal = Number(element.yes || element.yes_count) + Number(element.no || element.no_count) + Number(element.abstain || element.abstain_count) + Number(element.no_with_veto || element.no_with_veto_count)
|
||||
if (total < 1) {
|
||||
this.total = subtotal + 1
|
||||
} else {
|
||||
this.total = total
|
||||
}
|
||||
this.yes = Number(element.yes) / this.total
|
||||
this.no = Number(element.no) / this.total
|
||||
this.veto = Number(element.no_with_veto) / this.total
|
||||
this.abstain = Number(element.abstain) / this.total
|
||||
this.yes = Number(element.yes || element.yes_count) / this.total
|
||||
this.no = Number(element.no || element.no_count) / this.total
|
||||
this.veto = Number(element.no_with_veto || element.no_with_veto_count) / this.total
|
||||
this.abstain = Number(element.abstain || element.abstain_count) / this.total
|
||||
this.turnout = subtotal / this.total
|
||||
return this
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ export default class Proposal {
|
||||
this.voting_start_time = '0000-00-00'
|
||||
this.total_deposit = '-'
|
||||
this.contents = null
|
||||
this.metadata = {}
|
||||
}
|
||||
|
||||
init(element, total) {
|
||||
@ -29,7 +30,7 @@ export default class Proposal {
|
||||
this.voting_start_time = element.voting_start_time
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
this.total_deposit = element.total_deposit[0]
|
||||
this.contents = element.content.value || element.content
|
||||
if (element.content) this.contents = element.content.value || element.content
|
||||
if (this.contents) {
|
||||
this.title = this.contents.title
|
||||
this.description = this.contents.description
|
||||
@ -38,6 +39,7 @@ export default class Proposal {
|
||||
this.type = element.content['@type']
|
||||
}
|
||||
}
|
||||
this.metadata = element.metadata
|
||||
return this
|
||||
}
|
||||
|
||||
@ -51,6 +53,12 @@ export default class Proposal {
|
||||
|
||||
versionFixed(ver) {
|
||||
if (compareVersions(ver, '0.46') >= 0) {
|
||||
if (this.element.messages) [this.contents] = this.element.messages
|
||||
if (this.contents) this.type = this.contents['@type']
|
||||
if (this.contents['@type'] === '/cosmos.gov.v1.MsgExecLegacyContent') {
|
||||
this.title = this.contents.content.title
|
||||
this.description = this.contents.content.description
|
||||
}
|
||||
if (this.element.metadata) {
|
||||
this.title = this.element.metadata.title || this.element.metadata
|
||||
this.description = this.element.metadata.description || this.element.metadata
|
||||
|
@ -46,6 +46,7 @@ export default class WrapStdTx {
|
||||
self.tx = StdTx.create(element.tx, version)
|
||||
self.raw_log = element.tx_response.raw_log
|
||||
}
|
||||
self.element = element
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +128,8 @@ export default class ChainFetch {
|
||||
// return ret
|
||||
// })
|
||||
return Promise.all([
|
||||
this.get(`/cosmos/distribution/v1beta1/validators/${address}/commission`),
|
||||
this.get(`/cosmos/distribution/v1beta1/validators/${address}/outstanding_rewards`),
|
||||
this.get(`/cosmos/distribution/v1beta1/validators/${address}/commission`, null, true),
|
||||
this.get(`/cosmos/distribution/v1beta1/validators/${address}/outstanding_rewards`, null, true),
|
||||
]).then(data => {
|
||||
const ret = ValidatorDistribution.create({
|
||||
operator_address: address,
|
||||
@ -145,6 +145,9 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getBankTotal(denom) {
|
||||
if (compareVersions(this.config.sdk_version, '0.46.2') > 0) {
|
||||
return this.get(`/cosmos/bank/v1beta1/supply/by_denom?denom=${denom}`).then(data => commonProcess(data).amount)
|
||||
}
|
||||
if (compareVersions(this.config.sdk_version, '0.40') < 0) {
|
||||
return this.get(`/supply/total/${denom}`).then(data => ({ amount: commonProcess(data), denom }))
|
||||
}
|
||||
@ -159,7 +162,7 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getStakingPool() {
|
||||
return this.get('/cosmos/staking/v1beta1/pool').then(data => new StakingPool().init(commonProcess(data.pool)))
|
||||
return this.get('/cosmos/staking/v1beta1/pool', null, true).then(data => new StakingPool().init(commonProcess(data.pool)))
|
||||
}
|
||||
|
||||
async getMintingInflation() {
|
||||
@ -176,14 +179,14 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getStakingParameters() {
|
||||
return this.get('/cosmos/staking/v1beta1/params').then(data => {
|
||||
return this.get('/cosmos/staking/v1beta1/params', null, true).then(data => {
|
||||
this.getSelectedConfig()
|
||||
return StakingParameters.create(commonProcess(data.params), this.config.chain_name)
|
||||
})
|
||||
}
|
||||
|
||||
async getValidatorList(config = null) {
|
||||
return this.get('/cosmos/staking/v1beta1/validators?pagination.limit=200&status=BOND_STATUS_BONDED', config).then(data => {
|
||||
return this.get('/cosmos/staking/v1beta1/validators?pagination.limit=200&status=BOND_STATUS_BONDED', config, true).then(data => {
|
||||
const vals = commonProcess(data.validators).map(i => new Validator().init(i))
|
||||
try {
|
||||
localStorage.setItem(`validators-${this.config.chain_name}`, JSON.stringify(vals))
|
||||
@ -203,7 +206,7 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getValidatorUnbondedList() {
|
||||
return this.get('/cosmos/staking/v1beta1/validators?pagination.limit=100&status=BOND_STATUS_UNBONDED').then(data => {
|
||||
return this.get('/cosmos/staking/v1beta1/validators?pagination.limit=100&status=BOND_STATUS_UNBONDED', null, true).then(data => {
|
||||
const result = commonProcess(data.validators)
|
||||
const vals = result.validators ? result.validators : result
|
||||
return vals.map(i => new Validator().init(i))
|
||||
@ -211,7 +214,7 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getValidatorListByStatus(status) {
|
||||
return this.get(`/cosmos/staking/v1beta1/validators?status=${status}&pagination.limit=500`).then(data => {
|
||||
return this.get(`/cosmos/staking/v1beta1/validators?status=${status}&pagination.limit=500`, null, true).then(data => {
|
||||
const result = commonProcess(data)
|
||||
const vals = result.validators ? result.validators : result
|
||||
return vals.map(i => new Validator().init(i))
|
||||
@ -223,7 +226,7 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getStakingValidator(address) {
|
||||
return this.get(`/cosmos/staking/v1beta1/validators/${address}`).then(data => new Validator().init(commonProcess(data).validator))
|
||||
return this.get(`/cosmos/staking/v1beta1/validators/${address}`, null, true).then(data => new Validator().init(commonProcess(data).validator))
|
||||
}
|
||||
|
||||
async getSlashingParameters() {
|
||||
@ -277,27 +280,39 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getDistributionParameters() {
|
||||
return this.get('/cosmos/distribution/v1beta1/params').then(data => commonProcess(data.params))
|
||||
return this.get('/cosmos/distribution/v1beta1/params', null, true).then(data => commonProcess(data.params))
|
||||
}
|
||||
|
||||
async getGovernanceParameterDeposit() {
|
||||
return this.get('/cosmos/gov/v1beta1/params/deposit').then(data => commonProcess(data.deposit_params))
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/params/deposit`).then(data => commonProcess(data.deposit_params))
|
||||
}
|
||||
|
||||
async getGovernanceParameterTallying() {
|
||||
return this.get('/cosmos/gov/v1beta1/params/tallying').then(data => commonProcess(data.tally_params))
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/params/tallying`).then(data => commonProcess(data.tally_params))
|
||||
}
|
||||
|
||||
async getGovernanceParameterVoting() {
|
||||
return this.get('/cosmos/gov/v1beta1/params/voting').then(data => commonProcess(data.voting_params))
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/params/voting`).then(data => commonProcess(data.voting_params))
|
||||
}
|
||||
|
||||
async getGovernanceTally(pid, total, conf) {
|
||||
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/tally`, conf).then(data => new ProposalTally().init(commonProcess(data).tally, total))
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/proposals/${pid}/tally`, conf).then(data => new ProposalTally().init(commonProcess(data).tally, total))
|
||||
}
|
||||
|
||||
getGovernance(pid) {
|
||||
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}`).then(data => {
|
||||
if (this.config.chain_name === 'shentu') {
|
||||
return this.get(`/shentu/gov/v1alpha1/proposals/${pid}`).then(data => {
|
||||
const p = new Proposal().init(commonProcess(data).proposal, 0)
|
||||
return p
|
||||
})
|
||||
}
|
||||
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/proposals/${pid}`).then(data => {
|
||||
const p = new Proposal().init(commonProcess(data).proposal, 0)
|
||||
p.versionFixed(this.config.sdk_version)
|
||||
return p
|
||||
@ -305,20 +320,22 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getGovernanceProposer(pid) {
|
||||
if (this.config.chain_name === 'certik') {
|
||||
if (this.config.chain_name === 'shentu') {
|
||||
return this.get(`/shentu/gov/v1alpha1/${pid}/proposer`).then(data => new Proposer().init(commonProcess(data)))
|
||||
}
|
||||
return this.get(`/gov/proposals/${pid}/proposer`).then(data => new Proposer().init(commonProcess(data)))
|
||||
}
|
||||
|
||||
async getGovernanceDeposits(pid) {
|
||||
if (this.config.chain_name === 'certik') {
|
||||
if (this.config.chain_name === 'shentu') {
|
||||
return this.get(`/shentu/gov/v1alpha1/proposals/${pid}/deposits`).then(data => {
|
||||
const result = commonProcess(data)
|
||||
return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result
|
||||
})
|
||||
}
|
||||
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/deposits`).then(data => {
|
||||
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/proposals/${pid}/deposits`).then(data => {
|
||||
const result = commonProcess(data)
|
||||
return Array.isArray(result) ? result.reverse().map(d => new Deposit().init(d)) : result
|
||||
})
|
||||
@ -334,12 +351,15 @@ export default class ChainFetch {
|
||||
if (this.config.chain_name === 'shentu') {
|
||||
return this.get(`/shentu/gov/v1alpha1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
|
||||
}
|
||||
return this.get(`/cosmos/gov/v1beta1/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
return this.get(`/cosmos/gov/${ver}/proposals/${pid}/votes?pagination.key=${encodeURIComponent(next)}&pagination.limit=${limit}&pagination.reverse=true`)
|
||||
}
|
||||
|
||||
async getGovernanceListByStatus(status, chain = null) {
|
||||
const conf = chain || this.config
|
||||
const url = conf.chain_name === 'shentu' ? `/shentu/gov/v1alpha1/proposals?pagination.limit=100&proposal_status=${status}` : `/cosmos/gov/v1beta1/proposals?pagination.limit=100&proposal_status=${status}`
|
||||
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
const url = conf.chain_name === 'shentu' ? `/shentu/gov/v1alpha1/proposals?pagination.limit=100&proposal_status=${status}` : `/cosmos/gov/${ver}/proposals?pagination.limit=100&proposal_status=${status}`
|
||||
return this.get(url, conf).then(data => {
|
||||
let proposals = commonProcess(data)
|
||||
if (Array.isArray(proposals.proposals)) {
|
||||
@ -361,9 +381,10 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getGovernanceProposalVote(pid, voter, chain) {
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
const url = this.config.chain_name === 'shentu'
|
||||
? `/shentu/gov/v1alpha1/proposals/${pid}/votes/${voter}`
|
||||
: `/cosmos/gov/v1beta1/proposals/${pid}/votes/${voter}`
|
||||
: `/cosmos/gov/${ver}/proposals/${pid}/votes/${voter}`
|
||||
return this.get(url, chain).then(data => {
|
||||
if (data.code === 3) {
|
||||
throw new Error('not found')
|
||||
@ -379,9 +400,10 @@ export default class ChainFetch {
|
||||
|
||||
async getGovernanceList(next = '', chain = null) {
|
||||
const key = next || ''
|
||||
const ver = compareVersions(this.config.sdk_version, '0.46.5') < 0 ? 'v1beta1' : 'v1'
|
||||
const url = this.config.chain_name === 'shentu'
|
||||
? `/shentu/gov/v1alpha1/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}`
|
||||
: `/cosmos/gov/v1beta1/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}`
|
||||
: `/cosmos/gov/${ver}/proposals?pagination.limit=20&pagination.reverse=true&pagination.key=${key}`
|
||||
return this.get(url, chain).then(data => {
|
||||
let proposals = commonProcess(data)
|
||||
if (Array.isArray(proposals.proposals)) {
|
||||
@ -415,22 +437,22 @@ export default class ChainFetch {
|
||||
|
||||
async getStakingReward(address, config = null) {
|
||||
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
|
||||
return this.get(`/distribution/delegators/${address}/rewards`, config).then(data => commonProcess(data))
|
||||
return this.get(`/distribution/delegators/${address}/rewards`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/rewards`, config).then(data => commonProcess(data))
|
||||
return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/rewards`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
|
||||
async getValidatorSlashs(address, config = null) {
|
||||
return this.get(`/cosmos/distribution/v1beta1/validators//${address}/slashes`, config).then(data => commonProcess(data))
|
||||
return this.get(`/cosmos/distribution/v1beta1/validators/${address}/slashes`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
|
||||
async getStakingValidators(address) {
|
||||
return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/validators?pagination.size=200`).then(data => commonProcess(data.validators))
|
||||
return this.get(`/cosmos/distribution/v1beta1/delegators/${address}/validators?pagination.size=200`, null, true).then(data => commonProcess(data.validators))
|
||||
}
|
||||
|
||||
async getStakingDelegations(address, config = null) {
|
||||
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
|
||||
return this.get(`/staking/delegators/${address}/delegations`, config).then(data => commonProcess(data).map(x => {
|
||||
return this.get(`/staking/delegators/${address}/delegations`, config, true).then(data => commonProcess(data).map(x => {
|
||||
const xh = x
|
||||
if (!xh.delegation) {
|
||||
xh.delegation = {
|
||||
@ -441,21 +463,21 @@ export default class ChainFetch {
|
||||
return xh
|
||||
}))
|
||||
}
|
||||
return this.get(`/cosmos/staking/v1beta1/delegations/${address}`, config).then(data => commonProcess(data))
|
||||
return this.get(`/cosmos/staking/v1beta1/delegations/${address}`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
|
||||
async getStakingRedelegations(address, config = null) {
|
||||
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
|
||||
return this.get(`/staking/redelegations?delegator=${address}`, config).then(data => commonProcess(data))
|
||||
return this.get(`/staking/redelegations?delegator=${address}`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
return this.get(`/cosmos/staking/v1beta1/delegators/${address}/redelegations`, config).then(data => commonProcess(data))
|
||||
return this.get(`/cosmos/staking/v1beta1/delegators/${address}/redelegations`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
|
||||
async getStakingUnbonding(address, config = null) {
|
||||
if (compareVersions(config ? config.sdk_version : this.config.sdk_version, '0.40') < 0) {
|
||||
return this.get(`/staking/delegators/${address}/unbonding_delegations`, config).then(data => commonProcess(data))
|
||||
return this.get(`/staking/delegators/${address}/unbonding_delegations`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
return this.get(`/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations`, config).then(data => commonProcess(data))
|
||||
return this.get(`/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations`, config, true).then(data => commonProcess(data))
|
||||
}
|
||||
|
||||
async getBankBalances(address, config = null) {
|
||||
@ -463,7 +485,7 @@ export default class ChainFetch {
|
||||
}
|
||||
|
||||
async getCommunityPool(config = null) {
|
||||
return this.get('/cosmos/distribution/v1beta1/community_pool', config).then(data => commonProcess(data))
|
||||
return this.get('/cosmos/distribution/v1beta1/community_pool', config, true).then(data => commonProcess(data))
|
||||
}
|
||||
|
||||
async getAllIBCDenoms(config = null) {
|
||||
@ -589,15 +611,17 @@ export default class ChainFetch {
|
||||
return response.json() // parses JSON response into native JavaScript objects
|
||||
}
|
||||
|
||||
async get(url, config = null) {
|
||||
async get(url, config = null, fetch_on_provider = false) {
|
||||
if (!config) {
|
||||
this.getSelectedConfig()
|
||||
}
|
||||
const conf = config || this.config
|
||||
if (fetch_on_provider && conf.provider_chain) {
|
||||
return fetch(`${conf.provider_chain.api}${url}`).then(response => response.json())
|
||||
}
|
||||
const finalurl = (Array.isArray(conf.api) ? conf.api[this.getApiIndex(config)] : conf.api) + url
|
||||
// finalurl = finalurl.replaceAll('v1beta1', this.getEndpointVersion())
|
||||
const ret = await fetch(finalurl).then(response => response.json())
|
||||
return ret
|
||||
return fetch(finalurl).then(response => response.json())
|
||||
}
|
||||
|
||||
getApiIndex(config = null) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {
|
||||
Bech32, fromBase64, fromBech32, fromHex, toBase64, toBech32, toHex,
|
||||
fromBase64, fromBech32, fromHex, toBase64, toBech32, toHex,
|
||||
} from '@cosmjs/encoding'
|
||||
import { sha256, stringToPath } from '@cosmjs/crypto'
|
||||
// ledger
|
||||
@ -82,20 +82,26 @@ export async function connectLedger(transport = 'usb') {
|
||||
return new CosmosApp(trans)
|
||||
}
|
||||
|
||||
export function operatorAddressToAccount(operAddress) {
|
||||
const { prefix, data } = Bech32.decode(operAddress)
|
||||
if (prefix === 'iva') { // handle special cases
|
||||
return Bech32.encode('iaa', data)
|
||||
}
|
||||
if (prefix === 'crocncl') { // handle special cases
|
||||
return Bech32.encode('cro', data)
|
||||
}
|
||||
return Bech32.encode(prefix.replace('valoper', ''), data)
|
||||
export function valoperToPrefix(valoper) {
|
||||
const prefixIndex = valoper.indexOf('valoper')
|
||||
if (prefixIndex === -1) return null
|
||||
return valoper.slice(0, prefixIndex)
|
||||
}
|
||||
|
||||
// TODO, not tested
|
||||
export function pubkeyToAccountAddress(pubkey, prefix) {
|
||||
return Bech32.encode(prefix, pubkey, 40)
|
||||
export function operatorAddressToAccount(operAddress) {
|
||||
const { prefix, data } = fromBech32(operAddress)
|
||||
if (prefix === 'iva') { // handle special cases
|
||||
return toBech32('iaa', data)
|
||||
}
|
||||
if (prefix === 'crocncl') { // handle special cases
|
||||
return toBech32('cro', data)
|
||||
}
|
||||
return toBech32(prefix.replace('valoper', ''), data)
|
||||
}
|
||||
|
||||
export function pubKeyToValcons(pubkey, prefix) {
|
||||
const addressData = sha256(fromBase64(pubkey.key)).slice(0, 20)
|
||||
return toBech32(`${prefix}valcons`, addressData)
|
||||
}
|
||||
|
||||
export function toETHAddress(cosmosAddress) {
|
||||
|
@ -249,16 +249,16 @@ const router = new VueRouter({
|
||||
component: () => import('@/views/StakingValidator.vue'),
|
||||
meta: {
|
||||
pageTitle: 'Staking Validator',
|
||||
breadcrumb: [
|
||||
breadcrumb: route => ([
|
||||
{
|
||||
text: 'Staking',
|
||||
active: true,
|
||||
to: `/${route.params.chain}/staking`,
|
||||
},
|
||||
{
|
||||
text: 'Validator',
|
||||
active: true,
|
||||
},
|
||||
],
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -317,16 +317,16 @@ const router = new VueRouter({
|
||||
component: () => import('@/views/Block.vue'),
|
||||
meta: {
|
||||
pageTitle: 'Block',
|
||||
breadcrumb: [
|
||||
breadcrumb: route => ([
|
||||
{
|
||||
text: 'Blocks',
|
||||
active: true,
|
||||
to: `/${route.params.chain}/blocks`,
|
||||
},
|
||||
{
|
||||
text: 'Block',
|
||||
active: true,
|
||||
},
|
||||
],
|
||||
]),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -273,8 +273,9 @@ export default {
|
||||
return i
|
||||
}
|
||||
const txt = text.substring(text.indexOf(':') + 1, text.indexOf(' '))
|
||||
const sig = text.split(' ')
|
||||
const val = this.vals.find(x => x.hex.startsWith(txt))
|
||||
return val?.description?.moniker || txt
|
||||
return `${val?.description?.moniker || txt} - ${sig[2]}`
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
:show="syncing"
|
||||
>
|
||||
<div class="alert-body">
|
||||
<span>No new blocks have been produced since <strong>{{ latestTime }}</strong> </span>
|
||||
<span>{{ $t('dashboard.no_new_blocks') }}<strong>{{ latestTime }}</strong> </span>
|
||||
</div>
|
||||
</b-alert>
|
||||
|
||||
@ -90,40 +90,162 @@
|
||||
</b-row>
|
||||
<b-card no-body>
|
||||
<b-card-header>
|
||||
<b-card-title>Active Proposals</b-card-title>
|
||||
<b-card-title>{{ $t('dashboard.active_props') }}</b-card-title>
|
||||
</b-card-header>
|
||||
<b-card-body>
|
||||
<b-media
|
||||
<b-row
|
||||
v-for="prop in proprosals2"
|
||||
:key="prop.id"
|
||||
no-body
|
||||
class="mb-1"
|
||||
>
|
||||
<b-media-aside
|
||||
v-b-modal.operation-modal
|
||||
@click="selectProposal('Vote',prop.id, prop.title)"
|
||||
<b-col
|
||||
md="6"
|
||||
sm="12"
|
||||
>
|
||||
<b-avatar
|
||||
rounded
|
||||
size="42"
|
||||
:variant="myVotes[prop.id] ? 'light-primary': 'primary'"
|
||||
<b-media
|
||||
no-body
|
||||
class="mb-1"
|
||||
>
|
||||
{{ myVotes[prop.id] || 'Vote' }}
|
||||
</b-avatar>
|
||||
</b-media-aside>
|
||||
<b-link :to="`./${chain}/gov/${prop.id}`">
|
||||
<b-media-body class="d-flex flex-column justify-content-center">
|
||||
<h6 class="transaction-title">
|
||||
{{ prop.id }}. {{ prop.title }}
|
||||
</h6>
|
||||
<small>{{ formatType(prop.contents['@type']) }} {{ formatEnding(prop.voting_end_time) }}</small>
|
||||
</b-media-body>
|
||||
</b-link>
|
||||
</b-media>
|
||||
<b-media-aside
|
||||
@click="showDetail(prop.id)"
|
||||
>
|
||||
<b-avatar
|
||||
rounded
|
||||
size="42"
|
||||
variant="light-primary"
|
||||
>
|
||||
{{ prop.id }}
|
||||
</b-avatar>
|
||||
</b-media-aside>
|
||||
<b-link :to="`./${chain}/gov/${prop.id}`">
|
||||
<b-media-body class="d-flex flex-column justify-content-center">
|
||||
<h6 class="transaction-title">
|
||||
<b-badge
|
||||
pill
|
||||
variant="light-primary"
|
||||
>
|
||||
{{ formatType(prop.contents['@type']) }}
|
||||
</b-badge>{{ prop.title }}
|
||||
</h6>
|
||||
<small>will {{ caculateTallyResult(prop.tally) }} {{ formatEnding(prop.voting_end_time) }}</small>
|
||||
</b-media-body>
|
||||
</b-link>
|
||||
</b-media>
|
||||
</b-col>
|
||||
<b-col
|
||||
md="6"
|
||||
sm="12"
|
||||
>
|
||||
<b-row>
|
||||
<b-col cols="8">
|
||||
<div class="scale">
|
||||
<div class="box">
|
||||
<b-progress
|
||||
:max="totalPower? 100 * (totalPower/prop.tally.total) :100"
|
||||
height="2rem"
|
||||
show-progress
|
||||
class="font-small-1"
|
||||
>
|
||||
<b-progress-bar
|
||||
:id="'vote-yes'+prop.id"
|
||||
variant="success"
|
||||
:value="percent(prop.tally.yes)"
|
||||
show-progress
|
||||
:label="`${percent(prop.tally.yes).toFixed()}%`"
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+prop.id"
|
||||
variant="danger"
|
||||
:value="percent(prop.tally.no)"
|
||||
:label="`${percent(prop.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+prop.id"
|
||||
class="bg-danger bg-darken-4"
|
||||
:value="percent(prop.tally.veto)"
|
||||
:label="`${percent(prop.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-abstain'+prop.id"
|
||||
variant="secondary"
|
||||
:value="percent(prop.tally.abstain)"
|
||||
:label="`${percent(prop.tally.abstain).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
</b-progress>
|
||||
</div>
|
||||
<div
|
||||
v-b-tooltip.hover
|
||||
title="Threshold"
|
||||
class="box overlay"
|
||||
:style="`left:${scaleWidth(prop)}%;`"
|
||||
/>
|
||||
<div
|
||||
v-if="tallyParam"
|
||||
v-b-tooltip.hover
|
||||
title="Quorum"
|
||||
class="box overlay"
|
||||
:style="`left:${Number(tallyParam.quorum) * 100}%; border-color:black`"
|
||||
/>
|
||||
</div>
|
||||
<b-tooltip
|
||||
:target="'vote-yes'+prop.id"
|
||||
>
|
||||
{{ percent(prop.tally.yes) }}% {{ $t('dashboard.proposal_votes_yes') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+prop.id"
|
||||
>
|
||||
{{ percent(prop.tally.no) }}% {{ $t('dashboard.proposal_votes_no') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+prop.id"
|
||||
>
|
||||
{{ percent(prop.tally.veto) }}% {{ $t('dashboard.proposal_votes_nwv') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+prop.id"
|
||||
>
|
||||
{{ percent(prop.tally.abstain) }}% {{ $t('dashboard.proposal_votes_abstain') }}
|
||||
</b-tooltip>
|
||||
</b-col>
|
||||
<b-col
|
||||
cols="4"
|
||||
style="padding-top: 0.5em"
|
||||
>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
variant="primary"
|
||||
size="sm"
|
||||
class="mb-2"
|
||||
@click="selectProposal('Vote',prop.id, prop.title)"
|
||||
>
|
||||
{{ myVotes[prop.id] ? `${myVotes[prop.id]}`: 'Vote' }}
|
||||
</b-button>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-col>
|
||||
<b-col
|
||||
cols="12"
|
||||
:class="detailId === prop.id? 'd-block': 'd-none'"
|
||||
>
|
||||
<b-card
|
||||
border-variant="primary"
|
||||
bg-variant="transparent"
|
||||
class="shadow-none"
|
||||
style="max-height:350px;overflow: auto;"
|
||||
>
|
||||
<VueMarkdown class="pb-1">
|
||||
{{ addNewLine(prop.description) }}
|
||||
</VueMarkdown>
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<div v-if="proprosals2.length === 0">
|
||||
No active proposal!
|
||||
{{ $t('dashboard.no_active_prop') }}
|
||||
<b-link :to="`./${chain}/gov`">
|
||||
Browse all
|
||||
{{ $t('dashboard.browse') }}
|
||||
</b-link>
|
||||
</div>
|
||||
</b-card-body>
|
||||
@ -133,20 +255,20 @@
|
||||
bg-variant="transparent"
|
||||
class="shadow-none"
|
||||
>
|
||||
<b-card-title class="d-flex justify-content-between">
|
||||
<span>{{ walletName }} Assets </span>
|
||||
<b-card-title class="d-flex justify-content-between text-capitalize">
|
||||
<span>{{ walletName }} {{ $t('dashboard.assets') }} </span>
|
||||
<small>
|
||||
<b-link
|
||||
v-if="address"
|
||||
:to="`./${chain}/account/${address}`"
|
||||
>
|
||||
More
|
||||
{{ $t('dashboard.more') }}
|
||||
</b-link>
|
||||
<b-link
|
||||
v-else
|
||||
:to="`/wallet/accounts`"
|
||||
>
|
||||
Not connected?
|
||||
{{ $t('dashboard.not_conn') }}
|
||||
</b-link>
|
||||
</small>
|
||||
</b-card-title>
|
||||
@ -211,6 +333,7 @@
|
||||
<!-- size -->
|
||||
<b-button-group
|
||||
size="sm"
|
||||
class="d-none"
|
||||
>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
@ -240,18 +363,41 @@
|
||||
<feather-icon icon="LogOutIcon" />
|
||||
</b-button>
|
||||
</b-button-group>
|
||||
<b-dropdown
|
||||
v-b-modal.operation-modal
|
||||
split
|
||||
variant="outline-primary"
|
||||
text="Delegate"
|
||||
class="mr-1"
|
||||
size="sm"
|
||||
@click="selectDelegation(data,'Delegate')"
|
||||
>
|
||||
<template #button-content>
|
||||
{{ $t('dashboard.delegate') }}
|
||||
</template>
|
||||
<b-dropdown-item
|
||||
v-b-modal.operation-modal
|
||||
@click="selectDelegation(data,'Redelegate')"
|
||||
>
|
||||
{{ $t('dashboard.redelegate') }}
|
||||
</b-dropdown-item>
|
||||
<b-dropdown-item
|
||||
v-b-modal.operation-modal
|
||||
@click="selectDelegation(data,'Unbond')"
|
||||
>
|
||||
{{ $t('dashboard.unbond') }}
|
||||
</b-dropdown-item>
|
||||
</b-dropdown>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
variant="outline-primary"
|
||||
size="sm"
|
||||
@click="selectWithdraw()"
|
||||
>
|
||||
{{ $t('dashboard.withdraw_reward') }}
|
||||
</b-button>
|
||||
</template>
|
||||
</b-table>
|
||||
<b-card-footer class="text-right">
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
variant="outline-primary"
|
||||
@click="selectWithdraw()"
|
||||
>
|
||||
<feather-icon icon="AwardIcon" />
|
||||
Widthdraw Rewards
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
@ -260,7 +406,7 @@
|
||||
<b-col>
|
||||
<b-card>
|
||||
<b-card-header class="pt-0 pl-0 pr-0">
|
||||
<b-card-title>Unbonding Tokens</b-card-title>
|
||||
<b-card-title>{{ $t('dashboard.unbonding_token') }}</b-card-title>
|
||||
</b-card-header>
|
||||
<b-card-body class="pl-0 pr-0">
|
||||
<b-row
|
||||
@ -307,7 +453,7 @@
|
||||
@click="selectSend()"
|
||||
>
|
||||
<feather-icon icon="SendIcon" />
|
||||
Send
|
||||
{{ $t('dashboard.send') }}
|
||||
</b-button>
|
||||
</b-col>
|
||||
<b-col cols="6">
|
||||
@ -319,7 +465,7 @@
|
||||
<feather-icon
|
||||
icon="PlusCircleIcon"
|
||||
/>
|
||||
Receive
|
||||
{{ $t('dashboard.receive') }}
|
||||
</b-button>
|
||||
</b-col>
|
||||
</b-row>
|
||||
@ -327,7 +473,7 @@
|
||||
<router-link to="/wallet/import">
|
||||
<b-card class="addzone text-center">
|
||||
<feather-icon icon="PlusIcon" />
|
||||
Connect Wallet
|
||||
{{ $t('dashboard.connect_wal') }}
|
||||
</b-card>
|
||||
</router-link>
|
||||
<operation-modal
|
||||
@ -337,21 +483,24 @@
|
||||
:proposal-id="selectedProposalId"
|
||||
:proposal-title="selectedTitle"
|
||||
/>
|
||||
<div id="txevent" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
BRow, BCol, BAlert, BCard, BTable, BFormCheckbox, BCardHeader, BCardTitle, BMedia, BMediaAside, BMediaBody, BAvatar,
|
||||
BCardBody, BLink, BButtonGroup, BButton, BTooltip, VBModal, VBTooltip, BCardFooter,
|
||||
BCardBody, BLink, BButtonGroup, BButton, BTooltip, VBModal, VBTooltip, BCardFooter, BProgress, BProgressBar, BBadge,
|
||||
BDropdown, BDropdownItem,
|
||||
} from 'bootstrap-vue'
|
||||
import {
|
||||
formatNumber, formatTokenAmount, isToken, percent, timeIn, toDay, toDuration, tokenFormatter, getLocalAccounts,
|
||||
getStakingValidatorOperator,
|
||||
getStakingValidatorOperator, formatToken,
|
||||
} from '@/libs/utils'
|
||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
||||
import Ripple from 'vue-ripple-directive'
|
||||
import dayjs from 'dayjs'
|
||||
import VueMarkdown from 'vue-markdown'
|
||||
import ParametersModuleComponent from './components/parameters/ParametersModuleComponent.vue'
|
||||
import DashboardCardHorizontal from './components/dashboard/DashboardCardHorizontal.vue'
|
||||
import DashboardCardVertical from './components/dashboard/DashboardCardVertical.vue'
|
||||
@ -364,6 +513,8 @@ export default {
|
||||
BButtonGroup,
|
||||
BTooltip,
|
||||
BButton,
|
||||
BDropdown,
|
||||
BDropdownItem,
|
||||
BRow,
|
||||
BCol,
|
||||
BAlert,
|
||||
@ -378,6 +529,10 @@ export default {
|
||||
BCardBody,
|
||||
BLink,
|
||||
BCardFooter,
|
||||
BProgress,
|
||||
BProgressBar,
|
||||
VueMarkdown,
|
||||
BBadge,
|
||||
|
||||
OperationModal,
|
||||
ParametersModuleComponent,
|
||||
@ -393,6 +548,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
detailId: 0,
|
||||
fields: ['validator', 'delegation', 'rewards', 'action'],
|
||||
delegations: [],
|
||||
rewards: [],
|
||||
@ -414,6 +570,8 @@ export default {
|
||||
selectedProposalId: 0,
|
||||
selectedTitle: '',
|
||||
operationModalType: '',
|
||||
tallyParam: null,
|
||||
totalPower: 0,
|
||||
voteColors: {
|
||||
YES: 'success',
|
||||
NO: 'warning',
|
||||
@ -450,10 +608,12 @@ export default {
|
||||
stakingList() {
|
||||
return this.delegations.map(x => {
|
||||
const rewards = this.rewards.find(r => r.validator_address === x.delegation.validator_address)
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
const decimal = conf.assets[0].exponent || '6'
|
||||
return {
|
||||
valAddress: x.delegation.validator_address,
|
||||
validator: getStakingValidatorOperator(this.$store.state.chains.selected.chain_name, x.delegation.validator_address),
|
||||
delegation: this.formatToken([x.balance]),
|
||||
delegation: formatToken(x.balance, {}, decimal),
|
||||
rewards: rewards ? this.formatToken(rewards.reward) : '',
|
||||
action: '',
|
||||
}
|
||||
@ -461,9 +621,29 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$http.getGovernanceListByStatus(2).then(res => {
|
||||
this.proposals = res.proposals
|
||||
this.$http.getStakingParameters().then(res => {
|
||||
Promise.all([this.$http.getStakingPool(), this.$http.getBankTotal(res.bond_denom)])
|
||||
.then(pool => {
|
||||
this.supply = `${formatNumber(formatTokenAmount(pool[1].amount, 2, res.bond_denom, false), true, 2)}`
|
||||
this.bonded = `${formatNumber(formatTokenAmount(pool[0].bondedToken, 2, res.bond_denom, false), true, 2)}`
|
||||
this.ratio = `${percent(pool[0].bondedToken / pool[1].amount)}%`
|
||||
this.totalPower = pool[0].bondedToken
|
||||
})
|
||||
})
|
||||
|
||||
this.$http.getGovernanceListByStatus(2).then(gov => {
|
||||
this.proposals = gov.proposals
|
||||
this.proposals.forEach(p => {
|
||||
this.$http.getGovernanceTally(p.id, 0).then(update => {
|
||||
// const p2 = p
|
||||
// p2.tally = update
|
||||
// this.proposals.push(p2)
|
||||
// this.proposals.sort((a, b) => a.id - b.id)
|
||||
this.$set(p, 'tally', update)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
this.$http.getLatestBlock().then(res => {
|
||||
this.height = res.block.header.height
|
||||
if (timeIn(res.block.header.time, 3, 'm')) {
|
||||
@ -475,19 +655,14 @@ export default {
|
||||
this.validators = res.block.last_commit.signatures.length
|
||||
})
|
||||
|
||||
this.$http.getStakingParameters().then(res => {
|
||||
Promise.all([this.$http.getStakingPool(), this.$http.getBankTotal(res.bond_denom)])
|
||||
.then(pool => {
|
||||
this.supply = `${formatNumber(formatTokenAmount(pool[1].amount, 2, res.bond_denom, false), true, 2)}`
|
||||
this.bonded = `${formatNumber(formatTokenAmount(pool[0].bondedToken, 2, res.bond_denom, false), true, 2)}`
|
||||
this.ratio = `${percent(pool[0].bondedToken / pool[1].amount)}%`
|
||||
})
|
||||
})
|
||||
|
||||
this.$http.getCommunityPool().then(res => {
|
||||
this.communityPool = this.formatToken(res.pool)
|
||||
})
|
||||
|
||||
this.$http.getGovernanceParameterTallying().then(res => {
|
||||
this.tallyParam = res
|
||||
})
|
||||
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
if (conf.excludes && conf.excludes.indexOf('mint') > -1) {
|
||||
this.inflation = '-'
|
||||
@ -499,7 +674,39 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const elem = document.getElementById('txevent')
|
||||
elem.addEventListener('txcompleted', () => {
|
||||
const key = this.$store?.state?.chains?.defaultWallet
|
||||
if (key) {
|
||||
const accounts = getLocalAccounts() || {}
|
||||
const account = Object.entries(accounts)
|
||||
.map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.$store.state.chains.selected.chain_name) }))
|
||||
.filter(v => v.address)
|
||||
.find(x => x.wallet === key)
|
||||
if (account) {
|
||||
this.fetchAccount(account.address.addr)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
caculateTallyResult(tally) {
|
||||
if (this.tallyParam && tally && this.totalPower > 0) {
|
||||
if (tally.veto < Number(this.tallyParam.veto_threshold)
|
||||
&& tally.yes > Number(this.tallyParam.threshold)
|
||||
&& tally.total / this.totalPower > Number(this.tallyParam.quorum)) {
|
||||
return 'pass'
|
||||
}
|
||||
}
|
||||
return 'be rejected'
|
||||
},
|
||||
scaleWidth(p) {
|
||||
if (this.tallyParam) {
|
||||
return Number(this.tallyParam.quorum) * Number(this.tallyParam.threshold) * (1 - p.tally.abstain) * 100
|
||||
}
|
||||
return 50
|
||||
},
|
||||
selectProposal(modal, pid, title) {
|
||||
this.operationModalType = modal
|
||||
this.selectedProposalId = Number(pid)
|
||||
@ -609,6 +816,13 @@ export default {
|
||||
return { title: this.convert(data[k]), subtitle: k }
|
||||
})
|
||||
},
|
||||
addNewLine(value) {
|
||||
return value ? value.replace(/(?:\\[rn])+/g, '\n') : '-'
|
||||
},
|
||||
percent: v => percent(v),
|
||||
processBarLength(v) {
|
||||
return percent(v)
|
||||
},
|
||||
formatDate: v => dayjs(v).format('YYYY-MM-DD HH:mm:ss'),
|
||||
convert(v) {
|
||||
if (typeof v === 'object') {
|
||||
@ -633,6 +847,13 @@ export default {
|
||||
}
|
||||
return v
|
||||
},
|
||||
showDetail(id) {
|
||||
if (this.detailId !== id) {
|
||||
this.detailId = id
|
||||
} else {
|
||||
this.detailId = 0
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -7,7 +7,11 @@
|
||||
lg="6"
|
||||
md="12"
|
||||
>
|
||||
<proposal-summary-component :p="p" />
|
||||
<proposal-summary-component
|
||||
:p="p"
|
||||
:total-power="totalPower"
|
||||
:tally-param="tallyParam"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row v-if="next">
|
||||
@ -64,9 +68,14 @@ export default {
|
||||
max: 1,
|
||||
operationModalType: '',
|
||||
next: '',
|
||||
totalPower: 0,
|
||||
tallyParam: null,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$http.getGovernanceParameterTallying().then(res => {
|
||||
this.tallyParam = res
|
||||
})
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
@ -81,9 +90,10 @@ export default {
|
||||
},
|
||||
updateTally(res) {
|
||||
this.$http.getStakingPool().then(pool => {
|
||||
this.totalPower = pool.bondedToken
|
||||
const voting = res.filter(i => i.status === 2)
|
||||
if (voting.length > 0) {
|
||||
voting.forEach(p => this.$http.getGovernanceTally(p.id, pool.bondedToken).then(update => {
|
||||
voting.forEach(p => this.$http.getGovernanceTally(p.id, 0).then(update => {
|
||||
this.$set(p, 'tally', update)
|
||||
}))
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
variant="light-info"
|
||||
class="text-right"
|
||||
>
|
||||
Deposit
|
||||
{{$t('governanceProposal.proposal_status_deposit')}}
|
||||
</b-badge>
|
||||
<b-badge
|
||||
v-if="proposal.status == 2"
|
||||
@ -20,7 +20,7 @@
|
||||
variant="light-primary"
|
||||
class="text-right"
|
||||
>
|
||||
Voting
|
||||
{{$t('governanceProposal.proposal_status_voting')}}
|
||||
</b-badge>
|
||||
<b-badge
|
||||
v-if="proposal.status == 3"
|
||||
@ -28,7 +28,7 @@
|
||||
variant="light-success"
|
||||
class="text-right"
|
||||
>
|
||||
Passed
|
||||
{{$t('governanceProposal.proposal_status_passed')}}
|
||||
</b-badge>
|
||||
<b-badge
|
||||
v-if="proposal.status == 4"
|
||||
@ -36,12 +36,17 @@
|
||||
variant="light-danger"
|
||||
class="text-right"
|
||||
>
|
||||
Rejected
|
||||
{{$t('governanceProposal.proposal_status_rejected')}}
|
||||
</b-badge>
|
||||
{{ proposal.title }}
|
||||
</b-card-title>
|
||||
</b-card-header>
|
||||
<b-card-body>
|
||||
<div>
|
||||
<object-field-component
|
||||
:tablefield="proposal.contents"
|
||||
:small="false"
|
||||
/></div>
|
||||
<b-table-simple
|
||||
stacked="sm"
|
||||
hover
|
||||
@ -50,38 +55,46 @@
|
||||
<tbody>
|
||||
<b-tr>
|
||||
<b-td style="text-transform: capitalize; vertical-align: top; width:200px">
|
||||
{{ $t('proposal_proposer') }}
|
||||
</b-td><b-td><router-link :to="`../account/${proposer.proposer}`">
|
||||
{{ formatAddress(proposer.proposer) }}
|
||||
</router-link> </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td>
|
||||
{{ $t('proposal_total_deposit') }}
|
||||
{{ $t('governanceProposal.proposal_total_deposit') }}
|
||||
</b-td><b-td>{{ formatToken(proposal.total_deposit) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td>
|
||||
{{ $t('proposal_submit_time') }}
|
||||
{{ $t('governanceProposal.proposal_submit_time') }}
|
||||
</b-td><b-td>{{ formatDate(proposal.submit_time) }}</b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td>
|
||||
{{ $t('voting_time') }}
|
||||
{{ $t('governanceProposal.voting_time') }}
|
||||
</b-td><b-td>{{ formatDate(proposal.voting_start_time) }} - {{ formatDate(proposal.voting_end_time) }}</b-td>
|
||||
</b-tr>
|
||||
<b-tr v-if="proposal.metadata">
|
||||
<b-td>
|
||||
Metadata
|
||||
</b-td><b-td>{{ proposal.metadata }}</b-td>
|
||||
</b-tr>
|
||||
</tbody>
|
||||
</b-table-simple>
|
||||
<div>
|
||||
<object-field-component
|
||||
:tablefield="proposal.contents"
|
||||
:small="false"
|
||||
/></div>
|
||||
<b-table-simple v-if="proposal.type.indexOf('SoftwareUpgrade') > 0">
|
||||
<b-tr>
|
||||
<b-td class="text-center">
|
||||
{{ $t('upgrade_time') }} {{ upgradeTime }}
|
||||
{{ $t('governanceProposal.upgrade_time') }} {{ upgradeTime }}
|
||||
<flip-countdown :deadline="upgradeTime" />
|
||||
<b-input-group prepend="Estimated by block time: ">
|
||||
<b-form-select v-model="blocktime">
|
||||
<b-form-select-option value="7">
|
||||
7s
|
||||
</b-form-select-option>
|
||||
<b-form-select-option value="6">
|
||||
6s
|
||||
</b-form-select-option>
|
||||
<b-form-select-option value="2">
|
||||
2s
|
||||
</b-form-select-option>
|
||||
<b-form-select-option value="1">
|
||||
1s
|
||||
</b-form-select-option>
|
||||
</b-form-select></b-input-group>
|
||||
</b-td>
|
||||
</b-tr>
|
||||
</b-table-simple>
|
||||
@ -91,7 +104,7 @@
|
||||
<b-button
|
||||
variant="outline-primary"
|
||||
>
|
||||
{{ $t('btn_back_list') }}
|
||||
{{ $t('governanceProposal.btn_back_list') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
<b-button
|
||||
@ -101,94 +114,106 @@
|
||||
class="btn float-right mg-2"
|
||||
@click="openModal('Vote')"
|
||||
>
|
||||
{{ $t('btn_vote') }}
|
||||
{{ $t('governanceProposal.btn_vote') }}
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</b-card>
|
||||
<b-card no-body>
|
||||
<b-card-header>
|
||||
<b-card-title>
|
||||
Votes
|
||||
{{ $t('governanceProposal.proposal_votes') }}
|
||||
</b-card-title>
|
||||
</b-card-header>
|
||||
<b-card-body>
|
||||
<b-progress
|
||||
:max="100"
|
||||
height="2rem"
|
||||
class="mb-2"
|
||||
show-progress
|
||||
>
|
||||
<b-progress-bar
|
||||
:id="'vote-yes'+proposal.id"
|
||||
variant="success"
|
||||
:value="percent(proposal.tally.yes)"
|
||||
:label="`${percent(proposal.tally.yes).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+proposal.id"
|
||||
variant="warning"
|
||||
:value="percent(proposal.tally.no)"
|
||||
:label="`${percent(proposal.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+proposal.id"
|
||||
variant="danger"
|
||||
:value="percent(proposal.tally.veto)"
|
||||
:label="`${percent(proposal.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-abstain'+proposal.id"
|
||||
variant="secondary"
|
||||
:value="percent(proposal.tally.abstain)"
|
||||
:label="`${percent(proposal.tally.abstain).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
</b-progress>
|
||||
<b-tooltip
|
||||
:target="'vote-yes'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.yes) }}% voted Yes
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.no) }}% voted No
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.veto) }}% voted No With Veto
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.abstain) }}% voted Abstain
|
||||
</b-tooltip>
|
||||
<b-table
|
||||
v-if="votes.votes && votes.votes.length > 0"
|
||||
stacked="sm"
|
||||
:fields="votes_fields"
|
||||
:items="votes.votes"
|
||||
striped
|
||||
>
|
||||
<template #cell(voter)="data">
|
||||
<router-link :to="`../account/${data.item.voter}`">
|
||||
{{ formatAddress(data.item.voter) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</b-table>
|
||||
<div
|
||||
v-if="next"
|
||||
class="addzone text-center pt-50 pb-50 bg-transparent text-primary"
|
||||
@click="loadVotes()"
|
||||
>
|
||||
<feather-icon icon="PlusIcon" />
|
||||
Load More Votes
|
||||
</div>
|
||||
</b-card-body>
|
||||
<div>
|
||||
<div class="scale">
|
||||
<div class="box">
|
||||
<b-progress
|
||||
:max="totalPower && proposal.status ===2? 100 * (totalPower/proposal.tally.total) :100"
|
||||
height="2rem"
|
||||
class="mb-2"
|
||||
show-progress
|
||||
>
|
||||
<b-progress-bar
|
||||
:id="'vote-yes'+proposal.id"
|
||||
variant="success"
|
||||
:value="percent(proposal.tally.yes)"
|
||||
:label="`${percent(proposal.tally.yes).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+proposal.id"
|
||||
variant="danger"
|
||||
:value="percent(proposal.tally.no)"
|
||||
:label="`${percent(proposal.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+proposal.id"
|
||||
class="bg-danger bg-darken-4"
|
||||
:value="percent(proposal.tally.veto)"
|
||||
:label="`${percent(proposal.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-abstain'+proposal.id"
|
||||
variant="secondary"
|
||||
:value="percent(proposal.tally.abstain)"
|
||||
:label="`${percent(proposal.tally.abstain).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
</b-progress>
|
||||
<b-tooltip
|
||||
:target="'vote-yes'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.yes) }}% {{ $t('governanceProposal.proposal_votes_yes') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.no) }}% {{ $t('governanceProposal.proposal_votes_no') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.veto) }}% voted {{ $t('governanceProposal.proposal_votes_nwv') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.abstain) }}% {{ $t('governanceProposal.proposal_votes_abstain') }}
|
||||
</b-tooltip>
|
||||
|
||||
<div
|
||||
v-if="tallyParam"
|
||||
title="Threshold"
|
||||
class="box overlay"
|
||||
:style="`left:${scaleWidth(proposal)}%;`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<b-table
|
||||
v-if="votes.votes && votes.votes.length > 0"
|
||||
stacked="sm"
|
||||
:fields="votes_fields"
|
||||
:items="votes.votes"
|
||||
striped
|
||||
>
|
||||
<template #cell(voter)="data">
|
||||
<router-link :to="`../account/${data.item.voter}`">
|
||||
{{ formatAddress(data.item.voter) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</b-table>
|
||||
<div
|
||||
v-if="next"
|
||||
class="addzone text-center pt-50 pb-50 bg-transparent text-primary"
|
||||
@click="loadVotes()"
|
||||
>
|
||||
<feather-icon icon="PlusIcon" />
|
||||
{{ $t('governanceProposal.proposal_votes_load') }}
|
||||
</div>
|
||||
</div></b-card-body>
|
||||
</b-card>
|
||||
<b-card
|
||||
v-if="proposal.total_deposit"
|
||||
@ -196,7 +221,7 @@
|
||||
>
|
||||
<b-card-header>
|
||||
<b-card-title>
|
||||
Deposits ({{ formatToken(proposal.total_deposit) }})
|
||||
{{ $t('governanceProposal.proposal_deposits') }} ({{ formatToken(proposal.total_deposit) }})
|
||||
</b-card-title>
|
||||
</b-card-header>
|
||||
<b-card-body>
|
||||
@ -219,7 +244,7 @@
|
||||
<b-button
|
||||
variant="outline-primary"
|
||||
>
|
||||
{{ $t('btn_back_list') }}
|
||||
{{ $t('governanceProposal.btn_back_list') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
<b-button
|
||||
@ -229,7 +254,7 @@
|
||||
class="btn float-right mg-2"
|
||||
@click="openModal('GovDeposit')"
|
||||
>
|
||||
{{ $t('btn_deposit') }}
|
||||
{{ $t('governanceProposal.btn_deposit') }}
|
||||
</b-button>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
@ -238,7 +263,7 @@
|
||||
class="btn float-right mg-2 mr-1"
|
||||
@click="openModal('Vote')"
|
||||
>
|
||||
{{ $t('btn_vote') }}
|
||||
{{ $t('governanceProposal.btn_vote') }}
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</b-card>
|
||||
@ -253,7 +278,7 @@
|
||||
<script>
|
||||
import {
|
||||
BCard, BCardBody, BCardFooter, BButton, BTable, BTableSimple, BTr, BTd, BCardTitle, BCardHeader,
|
||||
BProgressBar, BProgress, BTooltip, BBadge,
|
||||
BProgressBar, BProgress, BTooltip, BBadge, BFormSelect, BFormSelectOption, BInputGroup, BInputGroupPrepend,
|
||||
} from 'bootstrap-vue'
|
||||
import FlipCountdown from 'vue2-flip-countdown'
|
||||
// import fetch from 'node-fetch'
|
||||
@ -284,16 +309,23 @@ export default {
|
||||
BProgress,
|
||||
BTooltip,
|
||||
BBadge,
|
||||
BFormSelect,
|
||||
BFormSelectOption,
|
||||
BInputGroup,
|
||||
BInputGroupPrepend,
|
||||
ObjectFieldComponent,
|
||||
FlipCountdown,
|
||||
OperationModal,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
blocktime: 6,
|
||||
tallyParam: null,
|
||||
latest: {},
|
||||
next: null,
|
||||
proposal: new Proposal(),
|
||||
proposer: new Proposer(),
|
||||
totalPower: 0,
|
||||
deposits: [],
|
||||
votes: [],
|
||||
operationModalType: '',
|
||||
@ -346,7 +378,7 @@ export default {
|
||||
if (Number(this.proposal?.contents.plan.height || 0) > 0 && this.latest?.block) {
|
||||
const blocks = Number(this.proposal.contents.plan.height) - Number(this.latest.block?.header?.height || 0)
|
||||
if (blocks > 0) {
|
||||
const endtime = dayjs().add(blocks * 6, 'second').format('YYYY-MM-DD HH:mm:ss')
|
||||
const endtime = dayjs().add(blocks * this.blocktime, 'second').format('YYYY-MM-DD HH:mm:ss')
|
||||
return endtime
|
||||
}
|
||||
}
|
||||
@ -356,6 +388,9 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$http.getGovernanceParameterTallying().then(res => {
|
||||
this.tallyParam = res
|
||||
})
|
||||
const pid = this.$route.params.proposalid
|
||||
if (this.$route.query.from) {
|
||||
this.from = this.$route.query.from
|
||||
@ -368,7 +403,8 @@ export default {
|
||||
this.$http.getGovernance(pid).then(p => {
|
||||
if (p.status === 2) {
|
||||
this.$http.getStakingPool().then(pool => {
|
||||
this.$http.getGovernanceTally(pid, pool.bondedToken).then(t => p.updateTally(t))
|
||||
this.totalPower = pool.bondedToken
|
||||
this.$http.getGovernanceTally(pid, 0).then(t => p.updateTally(t))
|
||||
})
|
||||
}
|
||||
this.proposal = p
|
||||
@ -377,10 +413,9 @@ export default {
|
||||
if (!getCachedValidators()) {
|
||||
this.$http.getValidatorList()
|
||||
}
|
||||
|
||||
this.$http.getGovernanceProposer(pid).then(res => {
|
||||
this.proposer = res
|
||||
})
|
||||
// this.$http.getGovernanceProposer(pid).then(res => {
|
||||
// this.proposer = res
|
||||
// })
|
||||
this.$http.getGovernanceDeposits(pid).then(res => {
|
||||
this.deposits = res
|
||||
}).catch(() => {})
|
||||
@ -390,6 +425,15 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
scaleWidth(p) {
|
||||
if (this.tallyParam) {
|
||||
if (p.status === 2) {
|
||||
return Number(this.tallyParam.quorum) * Number(this.tallyParam.threshold) * (1 - p.tally.abstain) * 100
|
||||
}
|
||||
return Number(this.tallyParam.threshold) * (1 - p.tally.abstain) * 100
|
||||
}
|
||||
return 50
|
||||
},
|
||||
percent: v => percent(v),
|
||||
formatDate: v => dayjs(v).format('YYYY-MM-DD HH:mm'),
|
||||
formatToken: v => tokenFormatter(v, {}),
|
||||
|
@ -5,7 +5,7 @@
|
||||
:show="syncing"
|
||||
>
|
||||
<div class="alert-body">
|
||||
<span>No new blocks have been produced since <strong>{{ latestTime }}</strong> </span>
|
||||
<span>{{$t('parameters.no_blocks_produced')}}<strong>{{ latestTime }}</strong> </span>
|
||||
</div>
|
||||
</b-alert>
|
||||
<b-row>
|
||||
@ -38,11 +38,15 @@
|
||||
<parameters-module-component :data="slashing" />
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-card title="Application Version">
|
||||
<object-field-component :tablefield="appVersion" />
|
||||
<b-card>
|
||||
<b-card-title class="card-title"><h4>{{$t('parameters.app_ver')}}</h4></b-card-title>
|
||||
<b-card><object-field-component :tablefield="appVersion" /></b-card>
|
||||
</b-card>
|
||||
<b-card title="Node Information">
|
||||
<object-field-component :tablefield="nodeVersion" />
|
||||
<b-card>
|
||||
<b-card-title class="card-title">
|
||||
<h4>{{$t('parameters.node_info')}}</h4>
|
||||
</b-card-title>
|
||||
<b-card><object-field-component :tablefield="nodeVersion" /></b-card>
|
||||
</b-card>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -468,11 +468,10 @@ export default {
|
||||
if (this.selectedStatus === 'inactive') return 'primary'
|
||||
const { index, item } = data
|
||||
if (index === 0) {
|
||||
window.sum = item.tokens
|
||||
} else {
|
||||
window.sum += item.tokens
|
||||
window.sum = 0
|
||||
}
|
||||
const rank = window.sum / this.stakingPool
|
||||
window.sum += item.tokens // sum up after the calculating.
|
||||
if (rank < 0.333) {
|
||||
return 'danger'
|
||||
}
|
||||
|
@ -224,6 +224,7 @@
|
||||
:operator-address="validator.operator_address"
|
||||
:consensus-pubkey="validator.consensus_pubkey"
|
||||
:account-address="accountAddress"
|
||||
:valcons-address="valconsAddress"
|
||||
/>
|
||||
</b-col>
|
||||
</b-row>
|
||||
@ -273,7 +274,7 @@ import {
|
||||
} from 'bootstrap-vue'
|
||||
|
||||
import {
|
||||
percent, formatToken, StakingParameters, Validator, operatorAddressToAccount, consensusPubkeyToHexAddress, toDay, abbrMessage, abbrAddress,
|
||||
percent, formatToken, StakingParameters, Validator, operatorAddressToAccount, consensusPubkeyToHexAddress, toDay, abbrMessage, abbrAddress, valoperToPrefix, pubKeyToValcons,
|
||||
} from '@/libs/utils'
|
||||
import { keybase } from '@/libs/fetch'
|
||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
||||
@ -314,6 +315,7 @@ export default {
|
||||
latestHeight: 0,
|
||||
accountAddress: '-',
|
||||
hexAddress: '-',
|
||||
valconsAddress: '-',
|
||||
stakingPool: {},
|
||||
mintInflation: 0,
|
||||
stakingParameter: new StakingParameters(),
|
||||
@ -384,8 +386,10 @@ export default {
|
||||
return percent(value)
|
||||
},
|
||||
processAddress(operAddress, consensusPubkey) {
|
||||
const prefix = valoperToPrefix(operAddress)
|
||||
this.accountAddress = operatorAddressToAccount(operAddress)
|
||||
this.hexAddress = consensusPubkeyToHexAddress(consensusPubkey)
|
||||
this.valconsAddress = pubKeyToValcons(consensusPubkey, prefix)
|
||||
this.$http.getStakingDelegatorDelegation(this.accountAddress, operAddress).then(d => {
|
||||
this.selfDelegation = d
|
||||
})
|
||||
|
@ -13,7 +13,7 @@
|
||||
</b-alert>
|
||||
<b-card
|
||||
v-if="error===null"
|
||||
title="Basic"
|
||||
title="Summary"
|
||||
class="text-truncate"
|
||||
>
|
||||
<object-field-component
|
||||
@ -46,7 +46,8 @@
|
||||
variant="light-danger"
|
||||
>
|
||||
Failed
|
||||
</b-badge><b v-if="tx.code > 0"> {{ tx.raw_log }}</b> </b-td>
|
||||
</b-badge>
|
||||
</b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td>
|
||||
@ -85,26 +86,30 @@
|
||||
</b-table-simple>
|
||||
</b-card>
|
||||
|
||||
<b-card
|
||||
v-if="tx.tx.messages"
|
||||
:title="`Messages (total: ${tx.tx.messages.length})`"
|
||||
no-body
|
||||
>
|
||||
<b-card v-if="tx.tx.messages">
|
||||
<b-card-title>Messages (total: {{ tx.tx.messages.length }})</b-card-title>
|
||||
<b-card-body
|
||||
v-for="(item, i) in tx.tx.messages "
|
||||
id="message"
|
||||
:key="i"
|
||||
class="message"
|
||||
class="message px-0"
|
||||
>
|
||||
<object-field-component :tablefield="item" />
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
|
||||
<b-card
|
||||
v-if="tx.element"
|
||||
title="Details"
|
||||
>
|
||||
<object-field-component :tablefield="tx.element.tx_response" />
|
||||
</b-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
BCard, BTableSimple, BTr, BTd, BBadge, BCardBody, BAlert,
|
||||
BCard, BTableSimple, BTr, BTd, BBadge, BCardBody, BAlert, BCardTitle,
|
||||
} from 'bootstrap-vue'
|
||||
import { toDay, tokenFormatter } from '@/libs/utils'
|
||||
import ObjectFieldComponent from './components/ObjectFieldComponent.vue'
|
||||
@ -113,6 +118,7 @@ export default {
|
||||
components: {
|
||||
BAlert,
|
||||
BCard,
|
||||
BCardTitle,
|
||||
BCardBody,
|
||||
BTableSimple,
|
||||
BTr,
|
||||
|
@ -277,25 +277,20 @@ export default {
|
||||
})
|
||||
return Object.values(valCounter).sort((a, b) => b.counter - a.counter)
|
||||
},
|
||||
h() {
|
||||
return this.height
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const cached = JSON.parse(getCachedValidators(this.$route.params.chain))
|
||||
if (cached) {
|
||||
this.validators = cached
|
||||
}
|
||||
this.fetchMissingInfo()
|
||||
this.$http.getValidatorList().then(res => {
|
||||
this.validators = res
|
||||
})
|
||||
this.$http.getSlashingSigningInfo().then(res => {
|
||||
if (res.info) {
|
||||
res.info.forEach(x => {
|
||||
if (x.address) {
|
||||
const hex = toBase64(fromBech32(x.address).data)
|
||||
this.missing[hex] = x
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
this.initBlocks()
|
||||
},
|
||||
beforeDestroy() {
|
||||
@ -304,6 +299,18 @@ export default {
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
fetchMissingInfo() {
|
||||
this.$http.getSlashingSigningInfo().then(res => {
|
||||
if (res.info) {
|
||||
res.info.forEach(x => {
|
||||
if (x.address) {
|
||||
const hex = toBase64(fromBech32(x.address).data)
|
||||
this.missing[hex] = x
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
pinValidator() {
|
||||
localStorage.setItem('pinned', this.pinned)
|
||||
},
|
||||
@ -319,13 +326,15 @@ export default {
|
||||
const blocks = []
|
||||
// update height
|
||||
let promise = Promise.resolve()
|
||||
for (let i = height - 1; i > height - 50; i -= 1) {
|
||||
for (let i = height - 1; i > height - 48; i -= 1) {
|
||||
blocks.unshift({ sigs: {}, height: i > 0 ? i : 0 })
|
||||
if (i > height - 48 && i > 0) {
|
||||
promise = promise.then(() => new Promise(resolve => {
|
||||
promise = promise.then(() => new Promise(resolve => {
|
||||
if (i > this.blocks[0].height && i > 0) { // filter useless loading
|
||||
this.fetch_status(i, resolve)
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
const sigs = this.initColor()
|
||||
@ -386,7 +395,10 @@ export default {
|
||||
res.block.last_commit.signatures.forEach(x => {
|
||||
if (x.validator_address) sigs[x.validator_address] = 'bg-success'
|
||||
})
|
||||
this.height = res.block.header.height
|
||||
this.height = Number(res.block.header.height)
|
||||
if (this.height % 100 === 0) { // update the missing number each 100
|
||||
this.fetchMissingInfo()
|
||||
}
|
||||
const block = this.blocks.find(b => b.height === res.block.last_commit.height)
|
||||
if (typeof block === 'undefined') { // mei
|
||||
// this.$set(block, 0, typeof sigs !== 'undefined')
|
||||
|
@ -2,21 +2,21 @@
|
||||
<div class="px-0">
|
||||
<b-card>
|
||||
<b-card-title class="d-flex justify-content-between">
|
||||
<span class="text-uppercase"> {{ chain }} </span><small class="text-right"> Height: {{ height }} </small>
|
||||
<span class="text-uppercase"> {{ chain }} </span><small class="text-right"> {{$t('uptimeMyChainBlocks.height')}} {{ height }} </small>
|
||||
</b-card-title>
|
||||
<b-alert
|
||||
variant="danger"
|
||||
:show="syncing"
|
||||
>
|
||||
<div class="alert-body">
|
||||
<span>No new blocks have been produced since <strong>{{ latestTime }}</strong> </span>
|
||||
<span>{{$t('uptimeMyChainBlocks.no_blocks_produced')}}<strong>{{ latestTime }}</strong> </span>
|
||||
</div>
|
||||
</b-alert>
|
||||
<b-row>
|
||||
<span
|
||||
v-if="uptime.length===0"
|
||||
class="text-danger"
|
||||
> Your node is out of active validator set</span>
|
||||
> {{$t(uptimeMyChainBlocks.not_active)}}</span>
|
||||
<b-col
|
||||
v-for="(x,index) in uptime"
|
||||
:key="index"
|
||||
|
@ -21,12 +21,12 @@
|
||||
show
|
||||
>
|
||||
<div class="alert-heading">
|
||||
Tips
|
||||
{{ $t('uptimeMyValidators.tips') }}
|
||||
</div>
|
||||
<div class="alert-body">
|
||||
There are two ways to monitor your validators:
|
||||
<li> Pin a validator on Uptime pages.</li>
|
||||
<li> Specify parameters like following: <pre>https://ping.pub/cosmos/uptime/my?validators={"sifchain":["FBADE9A30473BB9ED6DFA16BFB3838E028F33650"],"chain_name":["hexAddress"]}</pre></li>
|
||||
{{ $t('uptimeMyValidators.two_ways') }}
|
||||
<li> {{ $t('uptimeMyValidators.pin') }}</li>
|
||||
<li> {{ $t('uptimeMyValidators.link') }} <pre>https://ping.pub/cosmos/uptime/my?validators={"sifchain":["FBADE9A30473BB9ED6DFA16BFB3838E028F33650"],"chain_name":["hexAddress"]}</pre></li>
|
||||
</div>
|
||||
</b-alert>
|
||||
</div>
|
||||
|
@ -23,7 +23,7 @@
|
||||
style="color: #fff"
|
||||
class="mb-0"
|
||||
>
|
||||
Address: <feather-icon
|
||||
{{ $t('walletAccountDetail.address') }} <feather-icon
|
||||
icon="CopyIcon"
|
||||
size="18"
|
||||
@click="copy()"
|
||||
@ -38,7 +38,7 @@
|
||||
class="d-flex flex-row"
|
||||
>
|
||||
<b-card-header class="pt-0 pl-0 pr-0">
|
||||
<b-card-title>Assets</b-card-title>
|
||||
<b-card-title>{{ $t('walletAccountDetail.assets') }}</b-card-title>
|
||||
<div>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
@ -50,7 +50,7 @@
|
||||
<feather-icon
|
||||
icon="SendIcon"
|
||||
class="d-md-none"
|
||||
/><small class="d-none d-md-block">Transfer</small>
|
||||
/><small class="d-none d-md-block">{{ $t('walletAccountDetail.transfer') }}</small>
|
||||
</b-button>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
@ -61,7 +61,7 @@
|
||||
icon="SendIcon"
|
||||
class="d-md-none"
|
||||
/>
|
||||
<span class="d-none d-md-block">IBC Transfer</span>
|
||||
<span class="d-none d-md-block">{{ $t('walletAccountDetail.ibc_transfer') }}</span>
|
||||
</b-button>
|
||||
</div>
|
||||
</b-card-header>
|
||||
@ -117,7 +117,7 @@
|
||||
</div>
|
||||
<!--/ tokens -->
|
||||
<div class="text-right border-top pt-1">
|
||||
<h2>Total: {{ currency }}{{ formatNumber(assetTable.currency) }}</h2>
|
||||
<h2>{{ $t('walletAccountDetail.total') }}{{ currency }}{{ formatNumber(assetTable.currency) }}</h2>
|
||||
</div>
|
||||
</b-col>
|
||||
</b-row>
|
||||
@ -127,7 +127,7 @@
|
||||
v-if="unbonding && unbonding.length > 0"
|
||||
>
|
||||
<b-card-header class="pt-0 pl-0 pr-0">
|
||||
<b-card-title>Unbonding Tokens</b-card-title>
|
||||
<b-card-title>{{ $t('walletAccountDetail.unbonding') }}</b-card-title>
|
||||
</b-card-header>
|
||||
<b-card-body class="pl-0 pr-0">
|
||||
<b-row
|
||||
@ -135,7 +135,7 @@
|
||||
:key="item.validator_address"
|
||||
>
|
||||
<b-col cols="12">
|
||||
<span class="font-weight-bolder">From: <router-link :to="`../staking/${item.validator_address}`">{{ item.validator_address }}</router-link></span>
|
||||
<span class="font-weight-bolder">{{ $t('walletAccountDetail.from') }}<router-link :to="`../staking/${item.validator_address}`">{{ item.validator_address }}</router-link></span>
|
||||
</b-col>
|
||||
<b-col cols="12">
|
||||
<b-table
|
||||
@ -164,7 +164,7 @@
|
||||
v-if="delegations"
|
||||
>
|
||||
<b-card-header class="pt-0 pl-0 pr-0">
|
||||
<b-card-title>Delegation</b-card-title>
|
||||
<b-card-title>{{ $t('walletAccountDetail.delegation') }}</b-card-title>
|
||||
<div>
|
||||
<b-button
|
||||
v-b-modal.operation-modal
|
||||
@ -176,7 +176,7 @@
|
||||
<feather-icon
|
||||
icon="LogInIcon"
|
||||
class="d-md-none"
|
||||
/><small class="d-none d-md-block">Delegate</small>
|
||||
/><small class="d-none d-md-block">{{ $t('walletAccountDetail.delegate') }}</small>
|
||||
</b-button>
|
||||
<b-button
|
||||
v-if="delegations"
|
||||
@ -188,7 +188,7 @@
|
||||
<feather-icon
|
||||
icon="ShareIcon"
|
||||
class="d-md-none"
|
||||
/><small class="d-none d-md-block"> Withdraw Rewards</small>
|
||||
/><small class="d-none d-md-block">{{ $t('walletAccountDetail.withdraw') }}</small>
|
||||
</b-button>
|
||||
</div>
|
||||
</b-card-header>
|
||||
@ -197,6 +197,15 @@
|
||||
:items="deleTable"
|
||||
stacked="sm"
|
||||
>
|
||||
<template #cell(validator)="data">
|
||||
<span>
|
||||
<router-link
|
||||
:to="`../staking/${data.value.address}`"
|
||||
>
|
||||
{{ data.value.moniker }}
|
||||
</router-link>
|
||||
</span>
|
||||
</template>
|
||||
<template #cell(action)="data">
|
||||
<!-- size -->
|
||||
<b-button-group
|
||||
@ -275,25 +284,25 @@
|
||||
<b-tbody v-if="account.type === 'cosmos-sdk/BaseAccount'">
|
||||
<b-tr>
|
||||
<b-td>
|
||||
Account Type
|
||||
{{ $t('walletAccountDetail.acct_type') }}
|
||||
</b-td><b-td> {{ account.type }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td class="max-width:100px;">
|
||||
Account Number
|
||||
{{ $t('walletAccountDetail.acct_num') }}
|
||||
</b-td><b-td> {{ account.value.account_number }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Sequence </b-td><b-td> {{ account.value.sequence }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.seq') }} </b-td><b-td> {{ account.value.sequence }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Public Key </b-td><b-td> <object-field-component :tablefield="account.value.public_key" /> </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.pub_key') }} </b-td><b-td> <object-field-component :tablefield="account.value.public_key" /> </b-td>
|
||||
</b-tr>
|
||||
</b-tbody>
|
||||
<b-tbody v-else-if="account.type === 'cosmos-sdk/PeriodicVestingAccount' && account.value.base_vesting_account">
|
||||
<b-tr>
|
||||
<b-td>
|
||||
Account Type
|
||||
{{ $t('walletAccountDetail.acct_type') }}
|
||||
</b-td>
|
||||
<b-td>
|
||||
{{ account.type }}
|
||||
@ -301,32 +310,32 @@
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td>
|
||||
Account Number
|
||||
{{ $t('walletAccountDetail.acct_num') }}
|
||||
</b-td><b-td> {{ account.value.base_vesting_account.base_account.account_number }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Sequence </b-td><b-td> {{ account.value.base_vesting_account.base_account.sequence }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.seq') }} </b-td><b-td> {{ account.value.base_vesting_account.base_account.sequence }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Public Key </b-td><b-td> <object-field-component :tablefield="account.value.base_vesting_account.base_account.public_key" /> </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.pub_key') }} </b-td><b-td> <object-field-component :tablefield="account.value.base_vesting_account.base_account.public_key" /> </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Original Vesting </b-td><b-td> {{ formatToken(account.value.base_vesting_account.original_vesting) }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.orig_vest') }} </b-td><b-td> {{ formatToken(account.value.base_vesting_account.original_vesting) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Delegated Free </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_free) }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.delegated_free') }} </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_free) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Delegated Vesting </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_vesting) }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.delegated_vest') }} </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_vesting) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Vesting Time </b-td><b-td> {{ formatTime(account.value.start_time) }} - {{ formatTime(account.value.base_vesting_account.end_time) }}</b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.vest_time') }} </b-td><b-td> {{ formatTime(account.value.start_time) }} - {{ formatTime(account.value.base_vesting_account.end_time) }}</b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Vesting Periods </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.vest_period') }} </b-td>
|
||||
<b-td>
|
||||
<b-table-simple>
|
||||
<th>Length</th><th>Amount</th>
|
||||
<th>{{ $t('walletAccountDetail.length') }}</th><th>{{ $t('walletAccountDetail.amount') }}</th>
|
||||
<b-tr
|
||||
v-for="p, index in account.value.vesting_periods"
|
||||
:key="index"
|
||||
@ -340,31 +349,31 @@
|
||||
<b-tbody v-else-if="account.type === 'cosmos-sdk/DelayedVestingAccount' && account.value.base_vesting_account">
|
||||
<b-tr>
|
||||
<b-td>
|
||||
Account Type
|
||||
{{ $t('walletAccountDetail.acct_type') }}
|
||||
</b-td><b-td> {{ account.type }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td style="max-width:100px;">
|
||||
Account Number
|
||||
{{ $t('walletAccountDetail.acct_num') }}
|
||||
</b-td><b-td> {{ account.value.base_vesting_account.base_account.account_number }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Sequence </b-td><b-td> {{ account.value.base_vesting_account.base_account.sequence }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.seq') }} </b-td><b-td> {{ account.value.base_vesting_account.base_account.sequence }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Public Key </b-td><b-td> <object-field-component :tablefield="account.value.base_vesting_account.base_account.public_key" /> </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.pub_key') }} </b-td><b-td> <object-field-component :tablefield="account.value.base_vesting_account.base_account.public_key" /> </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Original Vesting </b-td><b-td> {{ formatToken(account.value.base_vesting_account.original_vesting) }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.orig_vest') }} </b-td><b-td> {{ formatToken(account.value.base_vesting_account.original_vesting) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Delegated Free </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_free) }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.delegated_free') }} </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_free) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> Delegated Vesting </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_vesting) }} </b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.delegated_vest') }} </b-td><b-td> {{ formatToken(account.value.base_vesting_account.delegated_vesting) }} </b-td>
|
||||
</b-tr>
|
||||
<b-tr>
|
||||
<b-td> End Time </b-td><b-td> {{ formatTime(account.value.base_vesting_account.end_time) }}</b-td>
|
||||
<b-td> {{ $t('walletAccountDetail.end_time') }} </b-td><b-td> {{ formatTime(account.value.base_vesting_account.end_time) }}</b-td>
|
||||
</b-tr>
|
||||
</b-tbody>
|
||||
<object-field-component
|
||||
@ -394,10 +403,10 @@
|
||||
<div class="misc-inner p-2 p-sm-3">
|
||||
<div class="w-100 text-center">
|
||||
<h2 class="mb-1">
|
||||
Account not found 🕵🏻♀️
|
||||
{{ $t('walletAccountDetail.acct_not_found') }} 🕵🏻♀️
|
||||
</h2>
|
||||
<p class="mb-2">
|
||||
Oops! 😖 {{ error }}.
|
||||
{{ $t('walletAccountDetail.opps') }} 😖 {{ error }}.
|
||||
</p>
|
||||
|
||||
<b-button
|
||||
@ -405,7 +414,7 @@
|
||||
class="mb-2 btn-sm-block"
|
||||
:to="{path:'../'}"
|
||||
>
|
||||
Back to home
|
||||
{{ $t('walletAccountDetail.back_home') }}
|
||||
</b-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -621,12 +630,17 @@ export default {
|
||||
},
|
||||
deleTable() {
|
||||
const re = []
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
const decimal = conf.assets[0].exponent || '6'
|
||||
if (this.reward.rewards && this.delegations && this.delegations.length > 0) {
|
||||
this.delegations.forEach(e => {
|
||||
const reward = this.reward.rewards.find(r => r.validator_address === e.delegation.validator_address)
|
||||
re.push({
|
||||
validator: getStakingValidatorOperator(this.$http.config.chain_name, e.delegation.validator_address, 8),
|
||||
token: formatToken(e.balance, {}, 2),
|
||||
validator: {
|
||||
moniker: getStakingValidatorOperator(this.$http.config.chain_name, e.delegation.validator_address, 8),
|
||||
address: e.delegation.validator_address,
|
||||
},
|
||||
token: formatToken(e.balance, {}, decimal),
|
||||
reward: tokenFormatter(reward.reward, this.denoms),
|
||||
action: e.delegation.validator_address,
|
||||
})
|
||||
|
@ -464,15 +464,20 @@ export default {
|
||||
}
|
||||
},
|
||||
initParamsForKeplr(chainid, chain) {
|
||||
const gasPriceStep = chain.keplr_price_step || {
|
||||
low: 0.01,
|
||||
average: 0.025,
|
||||
high: 0.03,
|
||||
}
|
||||
return JSON.stringify({
|
||||
chainId: chainid,
|
||||
chainName: chain.chain_name,
|
||||
rpc: Array.isArray(chain.rpc) ? chain.rpc[0] : chain.rpc,
|
||||
rest: Array.isArray(chain.api) ? chain.api[0] : chain.api,
|
||||
bip44: {
|
||||
coinType: chain.coin_type,
|
||||
coinType: Number(chain.coin_type),
|
||||
},
|
||||
coinType: chain.coin_type,
|
||||
coinType: Number(chain.coin_type),
|
||||
bech32Config: {
|
||||
bech32PrefixAccAddr: chain.addr_prefix,
|
||||
bech32PrefixAccPub: `${chain.addr_prefix}pub`,
|
||||
@ -485,7 +490,7 @@ export default {
|
||||
{
|
||||
coinDenom: chain.assets[0].symbol,
|
||||
coinMinimalDenom: chain.assets[0].base,
|
||||
coinDecimals: chain.assets[0].exponent,
|
||||
coinDecimals: Number(chain.assets[0].exponent),
|
||||
coinGeckoId: chain.assets[0].coingecko_id || 'unknown',
|
||||
},
|
||||
],
|
||||
@ -493,21 +498,18 @@ export default {
|
||||
{
|
||||
coinDenom: chain.assets[0].symbol,
|
||||
coinMinimalDenom: chain.assets[0].base,
|
||||
coinDecimals: chain.assets[0].exponent,
|
||||
coinDecimals: Number(chain.assets[0].exponent),
|
||||
coinGeckoId: chain.assets[0].coingecko_id || 'unknown',
|
||||
gasPriceStep,
|
||||
},
|
||||
],
|
||||
gasPriceStep,
|
||||
stakeCurrency: {
|
||||
coinDenom: chain.assets[0].symbol,
|
||||
coinMinimalDenom: chain.assets[0].base,
|
||||
coinDecimals: chain.assets[0].exponent,
|
||||
coinDecimals: Number(chain.assets[0].exponent),
|
||||
coinGeckoId: chain.assets[0].coingecko_id || 'unknown',
|
||||
},
|
||||
gasPriceStep: {
|
||||
low: 0.01,
|
||||
average: 0.025,
|
||||
high: 0.03,
|
||||
},
|
||||
features: chain.keplr_features || [],
|
||||
}, null, '\t')
|
||||
},
|
||||
|
@ -119,6 +119,8 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
formatedDelegations() {
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
const decimal = conf.assets[0].exponent || '6'
|
||||
return this.delegations.map(x => ({
|
||||
validator: {
|
||||
logo: x.chain.logo,
|
||||
@ -128,13 +130,15 @@ export default {
|
||||
},
|
||||
delegator: x.keyname,
|
||||
delegator_address: x.delegation.delegator_address,
|
||||
delegation: formatToken(x.balance),
|
||||
delegation: formatToken(x.balance, {}, decimal),
|
||||
reward: this.findReward(x.delegation.delegator_address, x.delegation.validator_address),
|
||||
// action: '',
|
||||
}))
|
||||
},
|
||||
groupedDelegations() {
|
||||
const group = {}
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
const decimal = conf.assets[0].exponent || '6'
|
||||
this.delegations.forEach(x => {
|
||||
const d = {
|
||||
validator: {
|
||||
@ -145,7 +149,7 @@ export default {
|
||||
},
|
||||
delegator: x.keyname,
|
||||
delegator_address: x.delegation.delegator_address,
|
||||
delegation: formatToken(x.balance),
|
||||
delegation: formatToken(x.balance, {}, decimal),
|
||||
reward: this.findReward(x.delegation.delegator_address, x.delegation.validator_address),
|
||||
// action: '',
|
||||
}
|
||||
|
@ -69,7 +69,6 @@
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<b-progress
|
||||
:max="100"
|
||||
height="2rem"
|
||||
@ -85,21 +84,21 @@
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+p.id"
|
||||
variant="warning"
|
||||
variant="danger"
|
||||
:value="percent(p.tally.no)"
|
||||
:label="`${percent(p.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+p.id"
|
||||
variant="danger"
|
||||
class="bg-danger bg-darken-4"
|
||||
:value="percent(p.tally.veto)"
|
||||
:label="`${percent(p.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-abstain'+p.id"
|
||||
variant="info"
|
||||
variant="secondary"
|
||||
:value="percent(p.tally.abstain)"
|
||||
:label="`${percent(p.tally.abstain).toFixed()}%`"
|
||||
show-progress
|
||||
@ -129,7 +128,7 @@
|
||||
<span
|
||||
v-for="(v,k) in p.votes"
|
||||
:key="k"
|
||||
> <b-badge :variant="color(v.vote.option)">{{ v.keyname }} : {{ v.vote.option }}</b-badge></span>
|
||||
> <b-badge :variant="color(v.vote.option)">{{ v.keyname }} : {{ formatOption(v.vote.option) }}</b-badge></span>
|
||||
</b-card-footer>
|
||||
</b-card>
|
||||
</b-col>
|
||||
@ -237,6 +236,13 @@ export default {
|
||||
percent: v => percent(v),
|
||||
formatDate: v => dayjs(v).format('YYYY-MM-DD'),
|
||||
formatToken: v => tokenFormatter(v, {}),
|
||||
formatOption: v => {
|
||||
const start = String(v).lastIndexOf('_')
|
||||
if (start > 0) {
|
||||
return String(v).substring(start + 1)
|
||||
}
|
||||
return v
|
||||
},
|
||||
init() {
|
||||
this.accounts = getLocalAccounts()
|
||||
if (this.accounts) {
|
||||
|
@ -63,7 +63,7 @@
|
||||
/>
|
||||
</b-progress>
|
||||
<div class="status-text">
|
||||
<span v-if="hash">SUBMITED</span>
|
||||
<span v-if="hash">SUBMITTED</span>
|
||||
<span v-if="succeed">COMPLETED</span>
|
||||
<span v-if="error">FAILED</span>
|
||||
</div>
|
||||
|
@ -235,7 +235,9 @@ export default {
|
||||
return formatTokenDenom(this.token)
|
||||
},
|
||||
format(v) {
|
||||
return formatToken(v, this.IBCDenom, 6)
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
const decimal = conf.assets[0].exponent || '6'
|
||||
return formatToken(v, this.IBCDenom, decimal)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -179,8 +179,10 @@ export default {
|
||||
return options
|
||||
},
|
||||
tokenOptions() {
|
||||
const conf = this.$http.getSelectedConfig()
|
||||
const decimal = conf.assets[0].exponent || '6'
|
||||
if (!this.delegations) return []
|
||||
return this.delegations.filter(x => x.delegation.validator_address === this.validatorAddress).map(x => ({ value: x.balance.denom, label: formatToken(x.balance) }))
|
||||
return this.delegations.filter(x => x.delegation.validator_address === this.validatorAddress).map(x => ({ value: x.balance.denom, label: formatToken(x.balance, {}, decimal) }))
|
||||
},
|
||||
msg() {
|
||||
return [{
|
||||
|
@ -5,29 +5,53 @@
|
||||
<h4 class="mb-25 font-weight-bolder">
|
||||
{{ statistic || '-' }}
|
||||
</h4>
|
||||
<span>{{ statisticTitle }}</span>
|
||||
<span v-if="!statistic || statistic === '-'">{{ statisticTitle }}</span>
|
||||
<span v-else-if="changes === 0">
|
||||
{{ showPrice(statistic, statisticTitle) }}
|
||||
</span>
|
||||
<span
|
||||
v-else-if="changes < 0"
|
||||
v-b-tooltip.hover.v-danger
|
||||
:title="`${changes.toFixed(1)}%`"
|
||||
class="text-danger"
|
||||
>
|
||||
{{ showPrice(statistic, statisticTitle) }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
v-b-tooltip.hover.v-success
|
||||
:title="`+${changes.toFixed(1)}%`"
|
||||
class="text-success"
|
||||
>
|
||||
{{ showPrice(statistic, statisticTitle) }}
|
||||
</span>
|
||||
</div>
|
||||
<b-avatar
|
||||
v-b-tooltip.hover
|
||||
:variant="`light-${color}`"
|
||||
size="45"
|
||||
>
|
||||
<feather-icon
|
||||
size="21"
|
||||
:icon="icon"
|
||||
/>
|
||||
</b-avatar>
|
||||
:text="statisticTitle.substring(0,1)"
|
||||
:title="statisticTitle"
|
||||
/>
|
||||
</b-card-body>
|
||||
</b-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { BCard, BCardBody, BAvatar } from 'bootstrap-vue'
|
||||
import {
|
||||
BCard, BCardBody, BAvatar, VBTooltip,
|
||||
} from 'bootstrap-vue'
|
||||
import { getUserCurrency, getUserCurrencySign } from '@/libs/utils'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BCard,
|
||||
BCardBody,
|
||||
BAvatar,
|
||||
VBTooltip,
|
||||
},
|
||||
directives: {
|
||||
'b-tooltip': VBTooltip,
|
||||
},
|
||||
props: {
|
||||
icon: {
|
||||
@ -47,5 +71,24 @@ export default {
|
||||
default: 'primary',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
changes: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showPrice(v, statisticTitle) {
|
||||
const token = String(v).split(' ')
|
||||
if (token.length >= 2) {
|
||||
const quote = this.$store.state.chains.quotes[token[1]]
|
||||
if (quote) {
|
||||
const price = quote[getUserCurrency()]
|
||||
this.changes = quote[`${getUserCurrency()}_24h_change`]
|
||||
return `${getUserCurrencySign()}${(Number(token[0].replaceAll(',', '')) * price).toFixed(2)}`
|
||||
}
|
||||
}
|
||||
return statisticTitle
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -20,27 +20,27 @@
|
||||
<div class="gov-wrapper flex-wrap my-1">
|
||||
<div class="gov">
|
||||
<p class="card-text mb-25">
|
||||
Status
|
||||
{{$t('governanceProposal.proposal_status')}}
|
||||
</p>
|
||||
<h6 class="mb-0">
|
||||
<span v-if="p.status == 1">
|
||||
Deposit
|
||||
{{$t('governanceProposal.proposal_status_deposit')}}
|
||||
</span>
|
||||
<span v-else-if="p.status == 2">
|
||||
Voting
|
||||
{{$t('governanceProposal.proposal_status_voting')}}
|
||||
</span>
|
||||
<span v-else-if="p.status == 3">
|
||||
Passed
|
||||
{{$t('governanceProposal.proposal_status_passed')}}
|
||||
</span>
|
||||
<span v-else-if="p.status == 4">
|
||||
Rejected
|
||||
{{$t('governanceProposal.proposal_status_rejected')}}
|
||||
</span>
|
||||
<span v-else>{{ p.status }}</span>
|
||||
</h6>
|
||||
</div>
|
||||
<div class="gov">
|
||||
<p class="card-text mb-25">
|
||||
Start Date
|
||||
{{$t('governanceProposal.proposal_status_start_date')}}
|
||||
</p>
|
||||
<h6 class="mb-0">
|
||||
{{ formatDate(p.voting_start_time) }}
|
||||
@ -48,7 +48,7 @@
|
||||
</div>
|
||||
<div class="gov">
|
||||
<p class="card-text mb-25">
|
||||
End Date
|
||||
{{$t('governanceProposal.proposal_status_end_date')}}
|
||||
</p>
|
||||
<h6 class="mb-0">
|
||||
{{ formatDate(p.voting_end_time) }}
|
||||
@ -56,108 +56,126 @@
|
||||
</div>
|
||||
<div class="gov">
|
||||
<p class="card-text mb-25">
|
||||
Deposit
|
||||
{{$t('governanceProposal.proposal_status_deposit')}}
|
||||
</p>
|
||||
<h6 class="mb-0">
|
||||
{{ formatToken(p.total_deposit) || '-' }}
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<b-progress
|
||||
:max="100"
|
||||
height="2rem"
|
||||
class="mb-2"
|
||||
show-progress
|
||||
>
|
||||
<b-progress-bar
|
||||
:id="'vote-yes'+p.id"
|
||||
variant="success"
|
||||
:value="percent(p.tally.yes)"
|
||||
show-progress
|
||||
:label="`${percent(p.tally.yes).toFixed()}%`"
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+p.id"
|
||||
variant="warning"
|
||||
:value="percent(p.tally.no)"
|
||||
:label="`${percent(p.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+p.id"
|
||||
variant="danger"
|
||||
:value="percent(p.tally.veto)"
|
||||
:label="`${percent(p.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-abstain'+p.id"
|
||||
variant="secondary"
|
||||
:value="percent(p.tally.abstain)"
|
||||
:label="`${percent(p.tally.abstain).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
</b-progress>
|
||||
<b-tooltip
|
||||
:target="'vote-yes'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.yes) }}% voted Yes
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.no) }}% voted No
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.veto) }}% voted No With Veto
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.abstain) }}% voted Abstain
|
||||
</b-tooltip>
|
||||
<b-card-footer class="pb-0">
|
||||
<router-link
|
||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||
:to="`./gov/${p.id}`"
|
||||
variant="outline-primary"
|
||||
>
|
||||
<b-button
|
||||
<div>
|
||||
<div class="scale">
|
||||
<div class="box">
|
||||
<b-progress
|
||||
:max="totalPower && p.status === 2? 100 * (totalPower/p.tally.total) :100"
|
||||
height="2rem"
|
||||
class="mb-2"
|
||||
show-progress
|
||||
>
|
||||
<b-progress-bar
|
||||
:id="'vote-yes'+p.id"
|
||||
variant="success"
|
||||
:value="percent(p.tally.yes)"
|
||||
show-progress
|
||||
:label="`${percent(p.tally.yes).toFixed()}%`"
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+p.id"
|
||||
variant="danger"
|
||||
:value="percent(p.tally.no)"
|
||||
:label="`${percent(p.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+p.id"
|
||||
class="bg-danger bg-darken-4"
|
||||
:value="percent(p.tally.veto)"
|
||||
:label="`${percent(p.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-abstain'+p.id"
|
||||
variant="secondary"
|
||||
:value="percent(p.tally.abstain)"
|
||||
:label="`${percent(p.tally.abstain).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
</b-progress>
|
||||
<div
|
||||
v-if="tallyParam"
|
||||
v-b-tooltip.hover
|
||||
title="Threshold"
|
||||
class="box overlay"
|
||||
:style="`left:${scaleWidth(p)}%;`"
|
||||
/>
|
||||
<div
|
||||
v-if="tallyParam && p.status === 2"
|
||||
v-b-tooltip.hover
|
||||
title="Quorum"
|
||||
class="box overlay"
|
||||
:style="`left:${Number(tallyParam.quorum) * 100}%; border-color:black`"
|
||||
/>
|
||||
</div>
|
||||
<b-tooltip
|
||||
:target="'vote-yes'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.yes) }}% {{ $t('governanceProposal.proposal_votes_yes') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.no) }}% {{ $t('governanceProposal.proposal_votes_no') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.veto) }}% {{ $t('governanceProposal.proposal_votes_nwv') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.abstain) }}% {{ $t('governanceProposal.proposal_votes_abstain') }}
|
||||
</b-tooltip>
|
||||
</div>
|
||||
<b-card-footer class="pb-0">
|
||||
<router-link
|
||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||
:href="`./gov/${p.id}`"
|
||||
:to="`./gov/${p.id}`"
|
||||
variant="outline-primary"
|
||||
>
|
||||
{{ $t('btn_detail') }}
|
||||
<b-button
|
||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||
:href="`./gov/${p.id}`"
|
||||
variant="outline-primary"
|
||||
>
|
||||
{{ $t('governanceProposal.btn_detail') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
<b-button
|
||||
v-if="p.status===1"
|
||||
v-b-modal.operation-modal
|
||||
variant="primary"
|
||||
class="btn float-right mg-2"
|
||||
@click="selectProposal('GovDeposit',p.id, p.title)"
|
||||
>
|
||||
{{ $t('governanceProposal.btn_deposit') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
<b-button
|
||||
v-if="p.status===1"
|
||||
v-b-modal.operation-modal
|
||||
variant="primary"
|
||||
class="btn float-right mg-2"
|
||||
@click="selectProposal('GovDeposit',p.id, p.title)"
|
||||
>
|
||||
{{ $t('btn_deposit') }}
|
||||
</b-button>
|
||||
<b-button
|
||||
v-if="p.status===2"
|
||||
v-b-modal.operation-modal
|
||||
variant="primary"
|
||||
class="btn float-right mg-2"
|
||||
@click="selectProposal('Vote',p.id, p.title)"
|
||||
>
|
||||
{{ $t('btn_vote') }}
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</b-card>
|
||||
<b-button
|
||||
v-if="p.status===2"
|
||||
v-b-modal.operation-modal
|
||||
variant="primary"
|
||||
class="btn float-right mg-2"
|
||||
@click="selectProposal('Vote',p.id, p.title)"
|
||||
>
|
||||
{{ $t('governanceProposal.btn_vote') }}
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</div></b-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
BCard, BCardTitle, BCardFooter, BButton, BProgressBar, BProgress, BBadge, BTooltip, BRow, BCol, VBModal,
|
||||
BCard, BCardTitle, BCardFooter, BButton, BProgressBar, BProgress, BBadge, BTooltip, BRow, BCol, VBModal, VBTooltip,
|
||||
} from 'bootstrap-vue'
|
||||
import Ripple from 'vue-ripple-directive'
|
||||
import { percent, tokenFormatter } from '@/libs/utils'
|
||||
@ -180,6 +198,7 @@ export default {
|
||||
},
|
||||
directives: {
|
||||
'b-modal': VBModal,
|
||||
'b-tooltip': VBTooltip,
|
||||
Ripple,
|
||||
},
|
||||
props: {
|
||||
@ -187,8 +206,25 @@ export default {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
totalPower: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
tallyParam: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
scaleWidth(p) {
|
||||
if (this.tallyParam) {
|
||||
if (p.status === 2) {
|
||||
return Number(this.tallyParam.quorum) * Number(this.tallyParam.threshold) * (1 - p.tally.abstain) * 100
|
||||
}
|
||||
return Number(this.tallyParam.threshold) * (1 - p.tally.abstain) * 100
|
||||
}
|
||||
return 50
|
||||
},
|
||||
selectProposal(modal, pid, title) {
|
||||
this.$parent.operationModalType = modal
|
||||
this.$parent.selectedProposalId = Number(pid)
|
||||
@ -206,7 +242,7 @@ export default {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped>
|
||||
section {
|
||||
display: flex;
|
||||
/* flex-wrap: nowrap; */
|
||||
|
@ -98,6 +98,29 @@
|
||||
<small @click="copy(hexAddress)">{{ hexAddress }}</small>
|
||||
</b-media-body>
|
||||
</b-media>
|
||||
<b-media
|
||||
class="mb-1"
|
||||
no-body
|
||||
>
|
||||
<b-media-aside class="mr-1">
|
||||
<b-avatar
|
||||
rounded
|
||||
variant="light-primary"
|
||||
size="34"
|
||||
>
|
||||
<feather-icon
|
||||
icon="HashIcon"
|
||||
size="18"
|
||||
/>
|
||||
</b-avatar>
|
||||
</b-media-aside>
|
||||
<b-media-body class="text-truncate">
|
||||
<h6 class="mb-0">
|
||||
Signer Address
|
||||
</h6>
|
||||
<small @click="copy(valconsAddress)">{{ valconsAddress }}</small>
|
||||
</b-media-body>
|
||||
</b-media>
|
||||
</b-card>
|
||||
</template>
|
||||
|
||||
@ -138,6 +161,10 @@ export default {
|
||||
type: String,
|
||||
default: '-',
|
||||
},
|
||||
valconsAddress: {
|
||||
type: String,
|
||||
default: '-',
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
copy(v) {
|
||||
|