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": [{
|
||||
"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",
|
||||
"sdk_version": "0.45.11",
|
||||
"addr_prefix": "jkl",
|
||||
"logo": "/logos/jackal.png",
|
||||
"assets": [{
|
||||
"assets": [
|
||||
{
|
||||
"base": "ujkl",
|
||||
"symbol": "JKL",
|
||||
"exponent": "6",
|
||||
"coingecko_id": "jackal",
|
||||
"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,6 +2,8 @@
|
||||
"message": {
|
||||
|
||||
},
|
||||
|
||||
"chains": {
|
||||
"cosmos": "Cosmos Hub",
|
||||
"kava": "Kava",
|
||||
"akash-network": "Akash Decloud",
|
||||
@ -33,6 +35,12 @@
|
||||
"odin": "ODIN",
|
||||
"chihuahua": "CHIHUAHUA",
|
||||
|
||||
"gravity": "Gravity(WIP)",
|
||||
"pools": "Pools(WIP)"
|
||||
},
|
||||
|
||||
"dashboard": {
|
||||
"dashboard": "Dashboard",
|
||||
"staking": "Staking",
|
||||
"governance": "Governance",
|
||||
"summary": "Summary",
|
||||
@ -41,25 +49,103 @@
|
||||
"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"
|
||||
},
|
||||
|
||||
"gravity": "Gravity(WIP)",
|
||||
"pools": "Pools(WIP)",
|
||||
|
||||
"governanceProposal": {
|
||||
"proposal_id": "Proposal ID",
|
||||
"proposal_type": "Proposal Type",
|
||||
"proposal_proposer": "Proposer",
|
||||
"proposal_submit_time": "Submited Time",
|
||||
"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"
|
||||
"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"
|
||||
>
|
||||
<b-col
|
||||
md="6"
|
||||
sm="12"
|
||||
>
|
||||
<b-media
|
||||
no-body
|
||||
class="mb-1"
|
||||
>
|
||||
<b-media-aside
|
||||
v-b-modal.operation-modal
|
||||
@click="selectProposal('Vote',prop.id, prop.title)"
|
||||
@click="showDetail(prop.id)"
|
||||
>
|
||||
<b-avatar
|
||||
rounded
|
||||
size="42"
|
||||
:variant="myVotes[prop.id] ? 'light-primary': 'primary'"
|
||||
variant="light-primary"
|
||||
>
|
||||
{{ myVotes[prop.id] || 'Vote' }}
|
||||
{{ 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">
|
||||
{{ prop.id }}. {{ prop.title }}
|
||||
<b-badge
|
||||
pill
|
||||
variant="light-primary"
|
||||
>
|
||||
{{ formatType(prop.contents['@type']) }}
|
||||
</b-badge>{{ prop.title }}
|
||||
</h6>
|
||||
<small>{{ formatType(prop.contents['@type']) }} {{ formatEnding(prop.voting_end_time) }}</small>
|
||||
<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-table>
|
||||
<b-card-footer class="text-right">
|
||||
<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()"
|
||||
>
|
||||
<feather-icon icon="AwardIcon" />
|
||||
Widthdraw Rewards
|
||||
{{ $t('dashboard.withdraw_reward') }}
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</template>
|
||||
</b-table>
|
||||
</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,19 +114,22 @@
|
||||
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>
|
||||
<div>
|
||||
<div class="scale">
|
||||
<div class="box">
|
||||
<b-progress
|
||||
:max="100"
|
||||
:max="totalPower && proposal.status ===2? 100 * (totalPower/proposal.tally.total) :100"
|
||||
height="2rem"
|
||||
class="mb-2"
|
||||
show-progress
|
||||
@ -127,14 +143,14 @@
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-no'+proposal.id"
|
||||
variant="warning"
|
||||
variant="danger"
|
||||
:value="percent(proposal.tally.no)"
|
||||
:label="`${percent(proposal.tally.no).toFixed()}%`"
|
||||
show-progress
|
||||
/>
|
||||
<b-progress-bar
|
||||
:id="'vote-veto'+proposal.id"
|
||||
variant="danger"
|
||||
class="bg-danger bg-darken-4"
|
||||
:value="percent(proposal.tally.veto)"
|
||||
:label="`${percent(proposal.tally.veto).toFixed()}%`"
|
||||
show-progress
|
||||
@ -150,23 +166,32 @@
|
||||
<b-tooltip
|
||||
:target="'vote-yes'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.yes) }}% voted Yes
|
||||
{{ percent(proposal.tally.yes) }}% {{ $t('governanceProposal.proposal_votes_yes') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.no) }}% voted No
|
||||
{{ percent(proposal.tally.no) }}% {{ $t('governanceProposal.proposal_votes_no') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.veto) }}% voted No With Veto
|
||||
{{ percent(proposal.tally.veto) }}% voted {{ $t('governanceProposal.proposal_votes_nwv') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+proposal.id"
|
||||
>
|
||||
{{ percent(proposal.tally.abstain) }}% voted Abstain
|
||||
{{ 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"
|
||||
@ -186,9 +211,9 @@
|
||||
@click="loadVotes()"
|
||||
>
|
||||
<feather-icon icon="PlusIcon" />
|
||||
Load More Votes
|
||||
{{ $t('governanceProposal.proposal_votes_load') }}
|
||||
</div>
|
||||
</b-card-body>
|
||||
</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,15 +277,29 @@ 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.initBlocks()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.blocks = [] // clear running tasks if it is not finish
|
||||
this.syncing = false
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
fetchMissingInfo() {
|
||||
this.$http.getSlashingSigningInfo().then(res => {
|
||||
if (res.info) {
|
||||
res.info.forEach(x => {
|
||||
@ -296,14 +310,7 @@ export default {
|
||||
})
|
||||
}
|
||||
})
|
||||
this.initBlocks()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.blocks = [] // clear running tasks if it is not finish
|
||||
this.syncing = false
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
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 => {
|
||||
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"
|
||||
:text="statisticTitle.substring(0,1)"
|
||||
:title="statisticTitle"
|
||||
/>
|
||||
</b-avatar>
|
||||
</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,16 +56,18 @@
|
||||
</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>
|
||||
|
||||
<div>
|
||||
<div class="scale">
|
||||
<div class="box">
|
||||
<b-progress
|
||||
:max="100"
|
||||
:max="totalPower && p.status === 2? 100 * (totalPower/p.tally.total) :100"
|
||||
height="2rem"
|
||||
class="mb-2"
|
||||
show-progress
|
||||
@ -79,14 +81,14 @@
|
||||
/>
|
||||
<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
|
||||
@ -99,26 +101,42 @@
|
||||
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) }}% voted Yes
|
||||
{{ percent(p.tally.yes) }}% {{ $t('governanceProposal.proposal_votes_yes') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-no'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.no) }}% voted No
|
||||
{{ percent(p.tally.no) }}% {{ $t('governanceProposal.proposal_votes_no') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-veto'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.veto) }}% voted No With Veto
|
||||
{{ percent(p.tally.veto) }}% {{ $t('governanceProposal.proposal_votes_nwv') }}
|
||||
</b-tooltip>
|
||||
<b-tooltip
|
||||
:target="'vote-abstain'+p.id"
|
||||
>
|
||||
{{ percent(p.tally.abstain) }}% voted Abstain
|
||||
{{ 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)'"
|
||||
@ -130,7 +148,7 @@
|
||||
:href="`./gov/${p.id}`"
|
||||
variant="outline-primary"
|
||||
>
|
||||
{{ $t('btn_detail') }}
|
||||
{{ $t('governanceProposal.btn_detail') }}
|
||||
</b-button>
|
||||
</router-link>
|
||||
<b-button
|
||||
@ -140,7 +158,7 @@
|
||||
class="btn float-right mg-2"
|
||||
@click="selectProposal('GovDeposit',p.id, p.title)"
|
||||
>
|
||||
{{ $t('btn_deposit') }}
|
||||
{{ $t('governanceProposal.btn_deposit') }}
|
||||
</b-button>
|
||||
<b-button
|
||||
v-if="p.status===2"
|
||||
@ -149,15 +167,15 @@
|
||||
class="btn float-right mg-2"
|
||||
@click="selectProposal('Vote',p.id, p.title)"
|
||||
>
|
||||
{{ $t('btn_vote') }}
|
||||
{{ $t('governanceProposal.btn_vote') }}
|
||||
</b-button>
|
||||
</b-card-footer>
|
||||
</b-card>
|
||||
</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) {
|
||||
|