forked from LaconicNetwork/cosmos-explorer
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17fba7d61e | ||
|
|
566ae0a95b | ||
|
|
23baabc026 | ||
|
|
eaa77918ac | ||
|
|
2fc3031f84 | ||
|
|
405cb90667 | ||
|
|
02b5baf304 | ||
|
|
6c59bb6f60 |
@@ -21,6 +21,9 @@
|
|||||||
</b-input-group>
|
</b-input-group>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
<operation-transfer-component
|
||||||
|
:recipient-address.sync="selectedAddress"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -33,6 +36,7 @@ import Ripple from 'vue-ripple-directive'
|
|||||||
import {
|
import {
|
||||||
addressEnCode, addressDecode,
|
addressEnCode, addressDecode,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
|
import OperationTransferComponent from '@/views/OperationTransferComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppFooter',
|
name: 'AppFooter',
|
||||||
@@ -43,6 +47,7 @@ export default {
|
|||||||
BFormInput,
|
BFormInput,
|
||||||
BInputGroupPrepend,
|
BInputGroupPrepend,
|
||||||
BInputGroup,
|
BInputGroup,
|
||||||
|
OperationTransferComponent,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
Ripple,
|
Ripple,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
{
|
{
|
||||||
"chain_name": "cosmos",
|
"chain_name": "cosmos",
|
||||||
"api": ["https://cosmos.api.ping.pub"],
|
"api": ["https://cosmos.api.ping.pub"],
|
||||||
|
"rpc": ["https://cosmos.rpc.ping.pub:443","http://your-host:26657"]
|
||||||
"sdk_version": "0.42.6",
|
"sdk_version": "0.42.6",
|
||||||
"coin_type": "118",
|
"coin_type": "118",
|
||||||
"min_tx_fee": "800",
|
"min_tx_fee": "800",
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
```
|
```
|
||||||
- **chain_name** the name to identify the chain on ping.pub
|
- **chain_name** the name to identify the chain on ping.pub
|
||||||
- **api** the rest api endpoint.(make sure that CORS is enabled: `Allow-Control-Allow-Origin: *`)
|
- **api** the rest api endpoint.(make sure that CORS is enabled: `Allow-Control-Allow-Origin: *`)
|
||||||
|
- **rpc** the rpc endpoint, make sure that the port is added.
|
||||||
- **assets** Native Assets on blockchain.
|
- **assets** Native Assets on blockchain.
|
||||||
# Test
|
# Test
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"chain_name": "akash-network",
|
"chain_name": "akash-network",
|
||||||
"api": ["https://akash.api.ping.pub"],
|
"api": ["https://akash.api.ping.pub"],
|
||||||
|
"rpc": ["http://rpc.akash.forbole.com:80", "http://akashsentry01.skynetvalidators.com:26657"],
|
||||||
"sdk_version": "0.41.3",
|
"sdk_version": "0.41.3",
|
||||||
"coin_type": "118",
|
"coin_type": "118",
|
||||||
"min_tx_fee": "8000",
|
"min_tx_fee": "8000",
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"chain_name": "cosmos",
|
"chain_name": "cosmos",
|
||||||
"coingecko": "cosmos",
|
"coingecko": "cosmos",
|
||||||
"api": ["https://lcd-cosmoshub.blockapsis.com", "https://cosmos.api.ping.pub", "https://cosmoshub.stakesystems.io"],
|
"api": ["https://cosmos.api.ping.pub", "https://lcd-cosmoshub.blockapsis.com"],
|
||||||
|
"rpc": ["http://cosmos.rpc.ping.pub:26657", "https://cosmoshub.validator.network:443"],
|
||||||
"sdk_version": "0.44.3",
|
"sdk_version": "0.44.3",
|
||||||
"coin_type": "118",
|
"coin_type": "118",
|
||||||
"min_tx_fee": "800",
|
"min_tx_fee": "800",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"chain_name": "iris-network",
|
"chain_name": "iris-network",
|
||||||
"api": "https://iris.api.ping.pub",
|
"api": "https://iris.api.ping.pub",
|
||||||
|
"rpc": ["http://34.82.96.8:26657","http://34.77.68.145:26657"],
|
||||||
"sdk_version": "0.42.4",
|
"sdk_version": "0.42.4",
|
||||||
"coin_type": "118",
|
"coin_type": "118",
|
||||||
"min_tx_fee": "40000",
|
"min_tx_fee": "40000",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
"blocks": "Blocks",
|
"blocks": "Blocks",
|
||||||
"blockchains": "Blockchains",
|
"blockchains": "Blockchains",
|
||||||
"uptime": "Uptime",
|
"uptime": "Uptime",
|
||||||
|
"statesync": "State Sync",
|
||||||
"trade": "Trade",
|
"trade": "Trade",
|
||||||
|
|
||||||
"gravity": "Gravity(WIP)",
|
"gravity": "Gravity(WIP)",
|
||||||
|
|||||||
@@ -106,26 +106,16 @@
|
|||||||
</b-button>
|
</b-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<b-dropdown-item
|
<!-- <b-dropdown-item
|
||||||
v-for="(item,k) in accounts"
|
:to="{ name: 'portfolio' }"
|
||||||
:key="k"
|
class="d-none"
|
||||||
:disabled="!item.address"
|
|
||||||
@click="updateDefaultWallet(item.wallet)"
|
|
||||||
>
|
>
|
||||||
<div class="d-flex flex-column">
|
<feather-icon
|
||||||
<span class="font-weight-bolder">{{ item.wallet }}
|
icon="PieChartIcon"
|
||||||
<b-avatar
|
size="16"
|
||||||
v-if="item.wallet===walletName"
|
/>
|
||||||
variant="success"
|
<span class="align-middle ml-50">Portofolio</span>
|
||||||
size="sm"
|
</b-dropdown-item> -->
|
||||||
>
|
|
||||||
<feather-icon icon="CheckIcon" />
|
|
||||||
</b-avatar>
|
|
||||||
</span>
|
|
||||||
<small>{{ item.address ? formatAddr(item.address.addr) : `Not available for ${selected_chain.chain_name}` }}</small>
|
|
||||||
</div>
|
|
||||||
</b-dropdown-item>
|
|
||||||
<b-dropdown-divider />
|
|
||||||
|
|
||||||
<b-dropdown-item :to="{ name: 'accounts' }">
|
<b-dropdown-item :to="{ name: 'accounts' }">
|
||||||
<feather-icon
|
<feather-icon
|
||||||
@@ -165,7 +155,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
BLink, BNavbarNav, BMedia, BMediaAside, BAvatar, BMediaBody, VBTooltip, BButton,
|
BLink, BNavbarNav, BMedia, BMediaAside, BAvatar, BMediaBody, VBTooltip, BButton,
|
||||||
BDropdown, BDropdownItem, BDropdownDivider,
|
BDropdown, BDropdownItem,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
import Ripple from 'vue-ripple-directive'
|
import Ripple from 'vue-ripple-directive'
|
||||||
import DarkToggler from '@core/layouts/components/app-navbar/components/DarkToggler.vue'
|
import DarkToggler from '@core/layouts/components/app-navbar/components/DarkToggler.vue'
|
||||||
@@ -186,7 +176,6 @@ export default {
|
|||||||
BButton,
|
BButton,
|
||||||
BDropdown,
|
BDropdown,
|
||||||
BDropdownItem,
|
BDropdownItem,
|
||||||
BDropdownDivider,
|
|
||||||
|
|
||||||
// Navbar Components
|
// Navbar Components
|
||||||
DarkToggler,
|
DarkToggler,
|
||||||
@@ -235,26 +224,14 @@ export default {
|
|||||||
}
|
}
|
||||||
return [conf.api]
|
return [conf.api]
|
||||||
},
|
},
|
||||||
accounts() {
|
|
||||||
let accounts = getLocalAccounts() || {}
|
|
||||||
accounts = Object.entries(accounts).map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.selected_chain.chain_name) }))
|
|
||||||
|
|
||||||
if (!this.$store.state.chains.defaultWallet && this.accounts.length > 0) {
|
|
||||||
this.updateDefaultWallet(this.accounts[0].wallet)
|
|
||||||
}
|
|
||||||
return accounts
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
const accounts = Object.keys(getLocalAccounts() || {})
|
||||||
|
if (!this.$store.state.chains.defaultWallet && accounts.length > 0) {
|
||||||
|
this.$store.commit('setDefaultWallet', accounts[0])
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatAddr(v) {
|
|
||||||
return v.substring(0, 10).concat('...', v.substring(v.length - 10))
|
|
||||||
},
|
|
||||||
updateDefaultWallet(v) {
|
|
||||||
this.$store.commit('setDefaultWallet', v)
|
|
||||||
},
|
|
||||||
change(v) {
|
change(v) {
|
||||||
this.index = v
|
this.index = v
|
||||||
const conf = this.$store.state.chains.selected
|
const conf = this.$store.state.chains.selected
|
||||||
|
|||||||
+1
-14
@@ -60,7 +60,7 @@ export default class ChainFetch {
|
|||||||
if (conf.chain_name === 'injective') {
|
if (conf.chain_name === 'injective') {
|
||||||
return ChainFetch.fetch('https://tm.injective.network', '/block').then(data => Block.create(commonProcess(data)))
|
return ChainFetch.fetch('https://tm.injective.network', '/block').then(data => Block.create(commonProcess(data)))
|
||||||
}
|
}
|
||||||
return this.get(`/blocks/latest?${new Date().getTime()}`, config).then(data => Block.create(data))
|
return this.get('/blocks/latest', config).then(data => Block.create(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBlockByHeight(height, config = null) {
|
async getBlockByHeight(height, config = null) {
|
||||||
@@ -386,19 +386,6 @@ export default class ChainFetch {
|
|||||||
return ChainFetch.fetchCoinMarketCap(`/quote/${symbol}`)
|
return ChainFetch.fetchCoinMarketCap(`/quote/${symbol}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate Execution of tx
|
|
||||||
async simulate(tx, config = null) {
|
|
||||||
return this.post('/cosmos/tx/v1beta1/simulate', tx, config).then(res => {
|
|
||||||
if (res.code && res.code !== 0) {
|
|
||||||
throw new Error(res.message)
|
|
||||||
}
|
|
||||||
if (res.tx_response && res.tx_response.code !== 0) {
|
|
||||||
throw new Error(res.tx_response.raw_log)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tx Submit
|
// Tx Submit
|
||||||
async broadcastTx(bodyBytes, config = null) {
|
async broadcastTx(bodyBytes, config = null) {
|
||||||
const txString = toBase64(TxRaw.encode(bodyBytes).finish())
|
const txString = toBase64(TxRaw.encode(bodyBytes).finish())
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ const modules = [
|
|||||||
title: 'uptime',
|
title: 'uptime',
|
||||||
route: 'uptime',
|
route: 'uptime',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
scope: 'normal',
|
||||||
|
title: 'statesync',
|
||||||
|
route: 'statesync',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
scope: 'cos-mos',
|
scope: 'cos-mos',
|
||||||
title: 'gravity',
|
title: 'gravity',
|
||||||
|
|||||||
+14
-8
@@ -117,6 +117,20 @@ const router = new VueRouter({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/:chain/statesync',
|
||||||
|
name: 'statesync',
|
||||||
|
component: () => import('@/views/StateSync.vue'),
|
||||||
|
meta: {
|
||||||
|
pageTitle: 'State Sync',
|
||||||
|
breadcrumb: [
|
||||||
|
{
|
||||||
|
text: 'State Synchronization',
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/:chain/uptime',
|
path: '/:chain/uptime',
|
||||||
name: 'uptime',
|
name: 'uptime',
|
||||||
@@ -317,14 +331,6 @@ const router = new VueRouter({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
// common modules
|
// common modules
|
||||||
{
|
|
||||||
path: '/user/login',
|
|
||||||
name: 'login',
|
|
||||||
component: () => import('@/views/Login.vue'),
|
|
||||||
meta: {
|
|
||||||
layout: 'full',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/error/error-404',
|
path: '/error/error-404',
|
||||||
name: 'error-404',
|
name: 'error-404',
|
||||||
|
|||||||
+15
-12
@@ -157,19 +157,19 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
<b-button
|
<b-button
|
||||||
v-if="p.status===1"
|
v-if="p.status===1"
|
||||||
v-b-modal.operation-modal
|
v-b-modal.deposit-window
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="btn float-right mg-2"
|
class="btn float-right mg-2"
|
||||||
@click="selectProposal('GovDeposit',p.id, p.title)"
|
@click="selectProposal(p.id, p.title)"
|
||||||
>
|
>
|
||||||
{{ $t('btn_deposit') }}
|
{{ $t('btn_deposit') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-if="p.status===2"
|
v-if="p.status===2"
|
||||||
v-b-modal.operation-modal
|
v-b-modal.vote-window
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="btn float-right mg-2"
|
class="btn float-right mg-2"
|
||||||
@click="selectProposal('Vote',p.id, p.title)"
|
@click="selectProposal(p.id, p.title)"
|
||||||
>
|
>
|
||||||
{{ $t('btn_vote') }}
|
{{ $t('btn_vote') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
@@ -177,10 +177,13 @@
|
|||||||
</b-card>
|
</b-card>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
<operation-modal
|
<operation-vote-component
|
||||||
:type="operationModalType"
|
|
||||||
:proposal-id="selectedProposalId"
|
:proposal-id="selectedProposalId"
|
||||||
:proposal-title="selectedTitle"
|
:title="selectedTitle"
|
||||||
|
/>
|
||||||
|
<operation-gov-deposit-component
|
||||||
|
:proposal-id="selectedProposalId"
|
||||||
|
:title="selectedTitle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -193,7 +196,8 @@ import Ripple from 'vue-ripple-directive'
|
|||||||
import { Proposal } from '@/libs/data'
|
import { Proposal } from '@/libs/data'
|
||||||
import { percent, tokenFormatter } from '@/libs/utils'
|
import { percent, tokenFormatter } from '@/libs/utils'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationVoteComponent from './OperationVoteComponent.vue'
|
||||||
|
import OperationGovDepositComponent from './OperationGovDepositComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -208,7 +212,8 @@ export default {
|
|||||||
BCardBody,
|
BCardBody,
|
||||||
BRow,
|
BRow,
|
||||||
BCol,
|
BCol,
|
||||||
OperationModal,
|
OperationVoteComponent,
|
||||||
|
OperationGovDepositComponent,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-modal': VBModal,
|
'b-modal': VBModal,
|
||||||
@@ -220,7 +225,6 @@ export default {
|
|||||||
selectedTitle: '',
|
selectedTitle: '',
|
||||||
proposals: [new Proposal()],
|
proposals: [new Proposal()],
|
||||||
max: 1,
|
max: 1,
|
||||||
operationModalType: '',
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -230,8 +234,7 @@ export default {
|
|||||||
percent: v => percent(v),
|
percent: v => percent(v),
|
||||||
formatDate: v => dayjs(v).format('YYYY-MM-DD'),
|
formatDate: v => dayjs(v).format('YYYY-MM-DD'),
|
||||||
formatToken: v => tokenFormatter(v, {}),
|
formatToken: v => tokenFormatter(v, {}),
|
||||||
selectProposal(modal, pid, title) {
|
selectProposal(pid, title) {
|
||||||
this.operationModalType = modal
|
|
||||||
this.selectedProposalId = Number(pid)
|
this.selectedProposalId = Number(pid)
|
||||||
this.selectedTitle = title
|
this.selectedTitle = title
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -109,11 +109,10 @@
|
|||||||
</b-button>
|
</b-button>
|
||||||
</router-link>
|
</router-link>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.vote-window
|
||||||
:disabled="proposal.status!=2"
|
:disabled="proposal.status!=2"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="btn float-right mg-2"
|
class="btn float-right mg-2"
|
||||||
@click="openModal('Vote')"
|
|
||||||
>
|
>
|
||||||
{{ $t('btn_vote') }}
|
{{ $t('btn_vote') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
@@ -233,29 +232,30 @@
|
|||||||
</b-button>
|
</b-button>
|
||||||
</router-link>
|
</router-link>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.deposit-window
|
||||||
:disabled="proposal.status!=1"
|
:disabled="proposal.status!=1"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="btn float-right mg-2"
|
class="btn float-right mg-2"
|
||||||
@click="openModal('GovDeposit')"
|
|
||||||
>
|
>
|
||||||
{{ $t('btn_deposit') }}
|
{{ $t('btn_deposit') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.vote-window
|
||||||
:disabled="proposal.status!=2"
|
:disabled="proposal.status!=2"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="btn float-right mg-2 mr-1"
|
class="btn float-right mg-2 mr-1"
|
||||||
@click="openModal('Vote')"
|
|
||||||
>
|
>
|
||||||
{{ $t('btn_vote') }}
|
{{ $t('btn_vote') }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</b-card-footer>
|
</b-card-footer>
|
||||||
</b-card>
|
</b-card>
|
||||||
<operation-modal
|
<operation-vote-component
|
||||||
:type="operationModalType"
|
|
||||||
:proposal-id="Number(proposal.id)"
|
:proposal-id="Number(proposal.id)"
|
||||||
:proposal-title="proposal.title"
|
:title="proposal.title"
|
||||||
|
/>
|
||||||
|
<operation-gov-deposit-component
|
||||||
|
:proposal-id="Number(proposal.id)"
|
||||||
|
:title="proposal.title"
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
@@ -273,9 +273,9 @@ import {
|
|||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import { Proposal, Proposer } from '@/libs/data'
|
import { Proposal, Proposer } from '@/libs/data'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
||||||
|
import OperationVoteComponent from './OperationVoteComponent.vue'
|
||||||
|
import OperationGovDepositComponent from './OperationGovDepositComponent.vue'
|
||||||
// import { formatToken } from '@/libs/data/data'
|
// import { formatToken } from '@/libs/data/data'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -295,8 +295,9 @@ export default {
|
|||||||
BTooltip,
|
BTooltip,
|
||||||
BBadge,
|
BBadge,
|
||||||
ObjectFieldComponent,
|
ObjectFieldComponent,
|
||||||
|
OperationVoteComponent,
|
||||||
|
OperationGovDepositComponent,
|
||||||
FlipCountdown,
|
FlipCountdown,
|
||||||
OperationModal,
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@@ -306,7 +307,6 @@ export default {
|
|||||||
proposer: new Proposer(),
|
proposer: new Proposer(),
|
||||||
deposits: [],
|
deposits: [],
|
||||||
votes: [],
|
votes: [],
|
||||||
operationModalType: '',
|
|
||||||
votes_fields: [
|
votes_fields: [
|
||||||
{
|
{
|
||||||
key: 'voter',
|
key: 'voter',
|
||||||
@@ -411,9 +411,6 @@ export default {
|
|||||||
formatAddress(v) {
|
formatAddress(v) {
|
||||||
return getStakingValidatorByAccount(this.$http.config.chain_name, v)
|
return getStakingValidatorByAccount(this.$http.config.chain_name, v)
|
||||||
},
|
},
|
||||||
openModal(type) {
|
|
||||||
this.operationModalType = type
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+26
-10
@@ -78,7 +78,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #cell(operation)="data">
|
<template #cell(operation)="data">
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.delegate-window
|
||||||
:name="data.item.operator_address"
|
:name="data.item.operator_address"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -186,7 +186,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #cell(operation)="data">
|
<template #cell(operation)="data">
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.delegate-window
|
||||||
:name="data.item.operator_address"
|
:name="data.item.operator_address"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -210,10 +210,7 @@
|
|||||||
</small>
|
</small>
|
||||||
</template>
|
</template>
|
||||||
</b-card>
|
</b-card>
|
||||||
<operation-modal
|
<operation-delegate-component :validator-address="validator_address" />
|
||||||
type="Delegate"
|
|
||||||
:validator-address="validator_address"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -225,9 +222,9 @@ import {
|
|||||||
percent, StakingParameters, formatToken,
|
percent, StakingParameters, formatToken,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import { keybase } from '@/libs/fetch'
|
import { keybase } from '@/libs/fetch'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
|
||||||
// import { toHex } from '@cosmjs/encoding'
|
// import { toHex } from '@cosmjs/encoding'
|
||||||
// import fetch from 'node-fetch'
|
// import fetch from 'node-fetch'
|
||||||
|
import OperationDelegateComponent from './OperationDelegateComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -240,15 +237,32 @@ export default {
|
|||||||
BCardTitle,
|
BCardTitle,
|
||||||
BCardBody,
|
BCardBody,
|
||||||
BButton,
|
BButton,
|
||||||
|
OperationDelegateComponent,
|
||||||
BFormRadioGroup,
|
BFormRadioGroup,
|
||||||
BFormGroup,
|
BFormGroup,
|
||||||
OperationModal,
|
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-tooltip': VBTooltip,
|
'b-tooltip': VBTooltip,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
keys: [
|
||||||
|
'bitsongvaloper1jxv0u20scum4trha72c7ltfgfqef6nscl86wxa',
|
||||||
|
'akashvaloper1vgstlgtsx4w80gphwgre0fcvc04lcnaelukvll',
|
||||||
|
'certikvaloper1jxv0u20scum4trha72c7ltfgfqef6nsczkvcu7',
|
||||||
|
'cosmosvaloper1jxv0u20scum4trha72c7ltfgfqef6nsch7q6cu',
|
||||||
|
'iva16plp8cmfkjssp222taq6pv6mkm8c5pa9lcktta',
|
||||||
|
'junovaloper1jxv0u20scum4trha72c7ltfgfqef6nscm9pmg2',
|
||||||
|
'kavavaloper1xftqdxvq0xkv2mu8c5y0jrsc578tak4m9u0s44',
|
||||||
|
'kivaloper1jxv0u20scum4trha72c7ltfgfqef6nschqtan9',
|
||||||
|
'osmovaloper1jxv0u20scum4trha72c7ltfgfqef6nscqx0u46',
|
||||||
|
'persistencevaloper1jxv0u20scum4trha72c7ltfgfqef6nsc4zjpnj',
|
||||||
|
'starsvaloper1jxv0u20scum4trha72c7ltfgfqef6nscdghxyx',
|
||||||
|
'digvaloper1jxv0u20scum4trha72c7ltfgfqef6nsc4s577p',
|
||||||
|
'bcnavaloper1jxv0u20scum4trha72c7ltfgfqef6nsc384wxf',
|
||||||
|
'pbvaloper1jxv0u20scum4trha72c7ltfgfqef6nsc5nn6cf',
|
||||||
|
'rizonvaloper1jxv0u20scum4trha72c7ltfgfqef6nsczn2l68',
|
||||||
|
],
|
||||||
islive: true,
|
islive: true,
|
||||||
validator_address: null,
|
validator_address: null,
|
||||||
mintInflation: 0,
|
mintInflation: 0,
|
||||||
@@ -299,7 +313,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
pingVals() {
|
pingVals() {
|
||||||
return this.list.filter(x => x.description.identity === '6783E9F948541962')
|
return this.list.filter(x => this.keys.includes(x.operator_address))
|
||||||
},
|
},
|
||||||
list() {
|
list() {
|
||||||
return this.validators.map(x => {
|
return this.validators.map(x => {
|
||||||
@@ -313,6 +327,9 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.$http.getStakingPool().then(pool => {
|
||||||
|
this.stakingPool = pool.bondedToken
|
||||||
|
})
|
||||||
this.getValidatorListByHeight()
|
this.getValidatorListByHeight()
|
||||||
this.$http.getStakingParameters().then(res => {
|
this.$http.getStakingParameters().then(res => {
|
||||||
this.stakingParameters = res
|
this.stakingParameters = res
|
||||||
@@ -364,7 +381,6 @@ export default {
|
|||||||
identities.push(identity)
|
identities.push(identity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.stakingPool = total
|
|
||||||
if (total > 100) {
|
if (total > 100) {
|
||||||
this.getValidatorListByHeight(100)
|
this.getValidatorListByHeight(100)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<b-card-header>
|
<b-card-header>
|
||||||
<b-card-title>Outstanding Rewards</b-card-title>
|
<b-card-title>Outstanding Rewards</b-card-title>
|
||||||
<feather-icon
|
<feather-icon
|
||||||
v-b-modal.WithdrawCommission
|
v-b-modal.withdraw-commission-window
|
||||||
icon="MoreVerticalIcon"
|
icon="MoreVerticalIcon"
|
||||||
size="18"
|
size="18"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
</b-card-body>
|
</b-card-body>
|
||||||
<b-card-body class="pt-0">
|
<b-card-body class="pt-0">
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.WithdrawCommission
|
v-b-modal.withdraw-commission-window
|
||||||
block
|
block
|
||||||
size="sm"
|
size="sm"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
@@ -84,11 +84,9 @@
|
|||||||
Withdraw Commission
|
Withdraw Commission
|
||||||
</b-button>
|
</b-button>
|
||||||
</b-card-body>
|
</b-card-body>
|
||||||
<operation-modal
|
<operation-withdraw-commission-component
|
||||||
type="WithdrawCommission"
|
|
||||||
modal-id="WithdrawCommission"
|
|
||||||
:address="address"
|
|
||||||
:validator-address="validator"
|
:validator-address="validator"
|
||||||
|
:address="address"
|
||||||
/>
|
/>
|
||||||
</b-card>
|
</b-card>
|
||||||
</template>
|
</template>
|
||||||
@@ -100,7 +98,7 @@ import {
|
|||||||
import { sha256 } from '@cosmjs/crypto'
|
import { sha256 } from '@cosmjs/crypto'
|
||||||
import { toHex } from '@cosmjs/encoding'
|
import { toHex } from '@cosmjs/encoding'
|
||||||
import { formatToken, numberWithCommas } from '@/libs/utils'
|
import { formatToken, numberWithCommas } from '@/libs/utils'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationWithdrawCommissionComponent from './OperationWithdrawCommissionComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -113,7 +111,7 @@ export default {
|
|||||||
BMedia,
|
BMedia,
|
||||||
BMediaAside,
|
BMediaAside,
|
||||||
BAvatar,
|
BAvatar,
|
||||||
OperationModal,
|
OperationWithdrawCommissionComponent,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-wrap">
|
<div class="d-flex flex-wrap">
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.delegate-window
|
||||||
variant="primary"
|
variant="primary"
|
||||||
class="mr-25 mb-25"
|
class="mr-25 mb-25"
|
||||||
>
|
>
|
||||||
@@ -268,10 +268,7 @@
|
|||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
</template>
|
</template>
|
||||||
<operation-modal
|
<operation-delegate-component :validator-address="validator.operator_address" />
|
||||||
type="Delegate"
|
|
||||||
:validator-address="validator.operator_address"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -284,10 +281,10 @@ import {
|
|||||||
percent, formatToken, StakingParameters, Validator, operatorAddressToAccount, consensusPubkeyToHexAddress, toDay, abbrMessage, abbrAddress,
|
percent, formatToken, StakingParameters, Validator, operatorAddressToAccount, consensusPubkeyToHexAddress, toDay, abbrMessage, abbrAddress,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import { keybase } from '@/libs/fetch'
|
import { keybase } from '@/libs/fetch'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
|
||||||
import StakingAddressComponent from './StakingAddressComponent.vue'
|
import StakingAddressComponent from './StakingAddressComponent.vue'
|
||||||
import StakingCommissionComponent from './StakingCommissionComponent.vue'
|
import StakingCommissionComponent from './StakingCommissionComponent.vue'
|
||||||
import StakingRewardComponent from './StakingRewardComponent.vue'
|
import StakingRewardComponent from './StakingRewardComponent.vue'
|
||||||
|
import OperationDelegateComponent from './OperationDelegateComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -303,7 +300,7 @@ export default {
|
|||||||
StakingAddressComponent,
|
StakingAddressComponent,
|
||||||
StakingCommissionComponent,
|
StakingCommissionComponent,
|
||||||
StakingRewardComponent,
|
StakingRewardComponent,
|
||||||
OperationModal,
|
OperationDelegateComponent,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-modal': VBModal,
|
'b-modal': VBModal,
|
||||||
|
|||||||
@@ -0,0 +1,169 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container-md">
|
||||||
|
<b-card>
|
||||||
|
<b-card-title>
|
||||||
|
Starting New Node From State Sync <b-badge variant="danger">
|
||||||
|
WIP
|
||||||
|
</b-badge>
|
||||||
|
</b-card-title>
|
||||||
|
<b class="mt-1">1. What's State Sync? </b><br>
|
||||||
|
The Tendermint Core 0.34 release includes support for state sync, which allows a new node to join a network by fetching a snapshot of the application state at a recent height instead of fetching and replaying all historical blocks. This can reduce the time needed to sync with the network from days to minutes.
|
||||||
|
Click <a href="https://blog.cosmos.network/cosmos-sdk-state-sync-guide-99e4cf43be2f">here</a> for more infomation.
|
||||||
|
<br><br>
|
||||||
|
<b class="mt-1">2. How to use it? </b><br>
|
||||||
|
We can configure Tendermint to use state sync in <code>$DAEMON_HOME/config/config.toml</code>, then start your daemon.
|
||||||
|
<ul class="mt-1">
|
||||||
|
<li
|
||||||
|
v-for="e in error"
|
||||||
|
:key="e"
|
||||||
|
class="text-danger"
|
||||||
|
>
|
||||||
|
{{ e }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<b-form-textarea
|
||||||
|
id="textarea-state"
|
||||||
|
v-model="state"
|
||||||
|
:state="valid"
|
||||||
|
readonly
|
||||||
|
placeholder="Loading..."
|
||||||
|
rows="7"
|
||||||
|
class="mt-1"
|
||||||
|
@change="check()"
|
||||||
|
/>
|
||||||
|
</b-card>
|
||||||
|
|
||||||
|
<b-card>
|
||||||
|
<b-card-title>
|
||||||
|
Enable Snapshot For State Sync
|
||||||
|
</b-card-title>
|
||||||
|
To make state sync works, We need at least 2 available RPC servers which enabled snapshot. You can configure in <code>$DAEMON_HOME/config/app.toml</code>,
|
||||||
|
and don't forget to share your snapshot server <a href="https://github.com/ping-pub/explorer/discussions">Here</a>
|
||||||
|
<b-form-textarea
|
||||||
|
id="snapshot"
|
||||||
|
v-model="snapshot"
|
||||||
|
readonly
|
||||||
|
rows="8"
|
||||||
|
class="mt-1"
|
||||||
|
/>
|
||||||
|
</b-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
BCard, BCardTitle, BFormTextarea, BBadge,
|
||||||
|
} from 'bootstrap-vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
BBadge,
|
||||||
|
BCard,
|
||||||
|
BCardTitle,
|
||||||
|
BFormTextarea,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
const { rpc } = this.$store.state.chains.selected
|
||||||
|
let servers = ''
|
||||||
|
if (rpc && Array.isArray(rpc)) {
|
||||||
|
servers = rpc.join(',')
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
servers,
|
||||||
|
height: 0,
|
||||||
|
hash: '',
|
||||||
|
error: [],
|
||||||
|
state: '',
|
||||||
|
valid: false,
|
||||||
|
snapshot: `[state-sync]
|
||||||
|
|
||||||
|
# snapshot-interval specifies the block interval at which local state sync snapshots are
|
||||||
|
# taken (0 to disable). Must be a multiple of pruning-keep-every.
|
||||||
|
snapshot-interval = 1000
|
||||||
|
|
||||||
|
# snapshot-keep-recent specifies the number of recent snapshots to keep and serve (0 to keep all). each snapshot is around 500MiB
|
||||||
|
snapshot-keep-recent = 2`,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// computed: {
|
||||||
|
// state: {
|
||||||
|
// get() {
|
||||||
|
// let servers = ''
|
||||||
|
// const { rpc } = this.$store.state.chains.selected
|
||||||
|
// if (rpc && Array.isArray(rpc)) {
|
||||||
|
// servers = rpc.join(',')
|
||||||
|
// }
|
||||||
|
// return `[statesync]
|
||||||
|
// enable = true
|
||||||
|
// rpc_servers = "${servers}"
|
||||||
|
// trust_height = ${this.height}
|
||||||
|
// trust_hash = "${this.hash}"
|
||||||
|
// trust_period = "168h" # 2/3 of unbonding time`
|
||||||
|
// },
|
||||||
|
// set(text) {
|
||||||
|
// console.log(text)
|
||||||
|
// // this.state = text
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
created() {
|
||||||
|
const interval = 1000
|
||||||
|
this.$http.getLatestBlock().then(l => {
|
||||||
|
const { height } = l.block.header
|
||||||
|
if (height > interval) {
|
||||||
|
this.$http.getBlockByHeight(Math.trunc(height / interval) * interval).then(x => {
|
||||||
|
this.hash = x.block_id.hash
|
||||||
|
this.height = x.block.header.height
|
||||||
|
this.state = `[statesync]
|
||||||
|
enable = true
|
||||||
|
rpc_servers = "${this.servers}"
|
||||||
|
trust_height = ${this.height}
|
||||||
|
trust_hash = "${this.hash}"
|
||||||
|
trust_period = "168h" # 2/3 of unbonding time`
|
||||||
|
this.check()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
check() {
|
||||||
|
this.valid = true
|
||||||
|
this.error = []
|
||||||
|
this.state.split('\n').forEach(element => {
|
||||||
|
const v = this.kv(element)
|
||||||
|
if (v[0] === 'trust_height' && Number(v[1]) < 1) {
|
||||||
|
this.valid = false
|
||||||
|
this.error.push('Trust Height should be set.')
|
||||||
|
}
|
||||||
|
if (v[0] === 'trust_hash' && v[1].length < 10) {
|
||||||
|
this.valid = false
|
||||||
|
this.error.push('Trust Hash is invalid.')
|
||||||
|
}
|
||||||
|
if (v[0] === 'rpc_servers') {
|
||||||
|
if (v[1].indexOf(',') > 1) {
|
||||||
|
v[1].replace(/"/g, '').split(',').forEach(host => {
|
||||||
|
const re = /^(.)+:\d+$/g
|
||||||
|
if (!re.test(host)) {
|
||||||
|
this.valid = false
|
||||||
|
this.error.push(`"${host}" is not a valid host. Make sure that the port is added.`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// valid = true
|
||||||
|
} else {
|
||||||
|
this.valid = false
|
||||||
|
this.error.push('No RPC serser is configured.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return this.valid
|
||||||
|
},
|
||||||
|
kv(line) {
|
||||||
|
if (line && line.indexOf('=') > 0) {
|
||||||
|
const s = line.split('=')
|
||||||
|
return [s[0].trim(), s[1].trim()]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -39,28 +39,26 @@
|
|||||||
<b-card-title>Assets</b-card-title>
|
<b-card-title>Assets</b-card-title>
|
||||||
<div>
|
<div>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.transfer-window
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
class="mr-25"
|
class="mr-25"
|
||||||
@click="setOperationModalType('Transfer')"
|
|
||||||
>
|
|
||||||
<feather-icon
|
|
||||||
icon="SendIcon"
|
|
||||||
class="d-md-none"
|
|
||||||
/><small class="d-none d-md-block">Transfer</small>
|
|
||||||
</b-button>
|
|
||||||
<b-button
|
|
||||||
v-b-modal.operation-modal
|
|
||||||
variant="danger"
|
|
||||||
size="sm"
|
|
||||||
@click="setOperationModalType('IBCTransfer')"
|
|
||||||
><feather-icon
|
><feather-icon
|
||||||
icon="SendIcon"
|
icon="SendIcon"
|
||||||
class="d-md-none"
|
class="d-md-none"
|
||||||
/>
|
/>
|
||||||
<span class="d-none d-md-block">IBC Transfer</span>
|
<span class="d-none d-md-block">Transfer</span>
|
||||||
</b-button>
|
</b-button>
|
||||||
|
<b-button
|
||||||
|
v-b-modal.ibc-transfer-window
|
||||||
|
variant="danger"
|
||||||
|
size="sm"
|
||||||
|
><feather-icon
|
||||||
|
icon="SendIcon"
|
||||||
|
class="d-md-none"
|
||||||
|
/>
|
||||||
|
<span class="d-none d-md-block">IBC Transfer
|
||||||
|
</span></b-button>
|
||||||
</div>
|
</div>
|
||||||
</b-card-header>
|
</b-card-header>
|
||||||
<b-card-body class="pl-0 pr-0">
|
<b-card-body class="pl-0 pr-0">
|
||||||
@@ -126,11 +124,10 @@
|
|||||||
<b-card-title>Delegation</b-card-title>
|
<b-card-title>Delegation</b-card-title>
|
||||||
<div>
|
<div>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.delegate-window
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
class="mr-25"
|
class="mr-25"
|
||||||
@click="setOperationModalType('Delegate')"
|
|
||||||
>
|
>
|
||||||
<feather-icon
|
<feather-icon
|
||||||
icon="LogInIcon"
|
icon="LogInIcon"
|
||||||
@@ -139,10 +136,9 @@
|
|||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-if="delegations"
|
v-if="delegations"
|
||||||
v-b-modal.operation-modal
|
v-b-modal.withdraw-window
|
||||||
variant="primary"
|
variant="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
@click="setOperationModalType('Withdraw')"
|
|
||||||
>
|
>
|
||||||
<feather-icon
|
<feather-icon
|
||||||
icon="ShareIcon"
|
icon="ShareIcon"
|
||||||
@@ -162,29 +158,29 @@
|
|||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.delegate-window
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
v-b-tooltip.hover.top="'Delegate'"
|
v-b-tooltip.hover.top="'Delegate'"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
@click="selectValue(data.value,'Delegate')"
|
@click="selectValue(data.value)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="LogInIcon" />
|
<feather-icon icon="LogInIcon" />
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.redelegate-window
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
v-b-tooltip.hover.top="'Redelegate'"
|
v-b-tooltip.hover.top="'Redelegate'"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
@click="selectValue(data.value,'Redelegate')"
|
@click="selectValue(data.value)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="ShuffleIcon" />
|
<feather-icon icon="ShuffleIcon" />
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.unbond-window
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
v-b-tooltip.hover.top="'Unbond'"
|
v-b-tooltip.hover.top="'Unbond'"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
@click="selectValue(data.value,'Unbond')"
|
@click="selectValue(data.value)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="LogOutIcon" />
|
<feather-icon icon="LogOutIcon" />
|
||||||
</b-button>
|
</b-button>
|
||||||
@@ -342,10 +338,20 @@
|
|||||||
<vue-qr :text="address" />
|
<vue-qr :text="address" />
|
||||||
</b-popover>
|
</b-popover>
|
||||||
|
|
||||||
<operation-modal
|
<operation-transfer-component :address="address" />
|
||||||
:type="operationModalType"
|
<operation-transfer-2-component :address="address" />
|
||||||
|
<operation-withdraw-component :address="address" />
|
||||||
|
<operation-unbond-component
|
||||||
:address="address"
|
:address="address"
|
||||||
:validator-address="selectedValidator"
|
:validator-address.sync="selectedValidator"
|
||||||
|
/>
|
||||||
|
<operation-delegate-component
|
||||||
|
:address="address"
|
||||||
|
:validator-address.sync="selectedValidator"
|
||||||
|
/>
|
||||||
|
<operation-redelegate-component
|
||||||
|
:address="address"
|
||||||
|
:validator-address.sync="selectedValidator"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -367,8 +373,13 @@ import {
|
|||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import { sha256 } from '@cosmjs/crypto'
|
import { sha256 } from '@cosmjs/crypto'
|
||||||
import { toHex } from '@cosmjs/encoding'
|
import { toHex } from '@cosmjs/encoding'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
|
||||||
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
import ObjectFieldComponent from './ObjectFieldComponent.vue'
|
||||||
|
import OperationTransferComponent from './OperationTransferComponent.vue'
|
||||||
|
import OperationWithdrawComponent from './OperationWithdrawComponent.vue'
|
||||||
|
import OperationUnbondComponent from './OperationUnbondComponent.vue'
|
||||||
|
import OperationDelegateComponent from './OperationDelegateComponent.vue'
|
||||||
|
import OperationRedelegateComponent from './OperationRedelegateComponent.vue'
|
||||||
|
import OperationTransfer2Component from './OperationTransfer2Component.vue'
|
||||||
import ChartComponentDoughnut from './ChartComponentDoughnut.vue'
|
import ChartComponentDoughnut from './ChartComponentDoughnut.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -394,8 +405,13 @@ export default {
|
|||||||
// eslint-disable-next-line vue/no-unused-components
|
// eslint-disable-next-line vue/no-unused-components
|
||||||
ToastificationContent,
|
ToastificationContent,
|
||||||
ObjectFieldComponent,
|
ObjectFieldComponent,
|
||||||
|
OperationTransferComponent,
|
||||||
|
OperationWithdrawComponent,
|
||||||
|
OperationDelegateComponent,
|
||||||
|
OperationRedelegateComponent,
|
||||||
|
OperationUnbondComponent,
|
||||||
|
OperationTransfer2Component,
|
||||||
ChartComponentDoughnut,
|
ChartComponentDoughnut,
|
||||||
OperationModal,
|
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-modal': VBModal,
|
'b-modal': VBModal,
|
||||||
@@ -418,7 +434,6 @@ export default {
|
|||||||
unbonding: [],
|
unbonding: [],
|
||||||
quotes: {},
|
quotes: {},
|
||||||
transactions: [],
|
transactions: [],
|
||||||
operationModalType: '',
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -605,12 +620,8 @@ export default {
|
|||||||
this.transactions = res
|
this.transactions = res
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
selectValue(v, type) {
|
selectValue(v) {
|
||||||
this.selectedValidator = v
|
this.selectedValidator = v
|
||||||
this.setOperationModalType(type)
|
|
||||||
},
|
|
||||||
setOperationModalType(type) {
|
|
||||||
this.operationModalType = type
|
|
||||||
},
|
},
|
||||||
formatHash: abbrAddress,
|
formatHash: abbrAddress,
|
||||||
formatDenom(v) {
|
formatDenom(v) {
|
||||||
|
|||||||
@@ -153,15 +153,15 @@
|
|||||||
/>
|
/>
|
||||||
<b-dropdown-item
|
<b-dropdown-item
|
||||||
v-if="balances[acc.addr]"
|
v-if="balances[acc.addr]"
|
||||||
v-b-modal.operation-modal
|
v-b-modal.transfer-window
|
||||||
@click="transfer('Transfer',acc.addr)"
|
@click="transfer(acc.addr)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="SendIcon" /> Transfer
|
<feather-icon icon="SendIcon" /> Transfer
|
||||||
</b-dropdown-item>
|
</b-dropdown-item>
|
||||||
<b-dropdown-item
|
<b-dropdown-item
|
||||||
v-if="balances[acc.addr]"
|
v-if="balances[acc.addr]"
|
||||||
v-b-modal.operation-modal
|
v-b-modal.ibc-transfer-window
|
||||||
@click="transfer('IBCTransfer',acc.addr)"
|
@click="transfer(acc.addr)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="SendIcon" /> IBC Transfer
|
<feather-icon icon="SendIcon" /> IBC Transfer
|
||||||
</b-dropdown-item>
|
</b-dropdown-item>
|
||||||
@@ -265,10 +265,10 @@
|
|||||||
Connect Wallet
|
Connect Wallet
|
||||||
</b-card>
|
</b-card>
|
||||||
</router-link>
|
</router-link>
|
||||||
<operation-modal
|
<operation-transfer-component
|
||||||
:type="operationModalType"
|
:address.sync="selectedAddress"
|
||||||
:address="selectedAddress"
|
|
||||||
/>
|
/>
|
||||||
|
<operation-transfer-2-component :address="selectedAddress" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -287,7 +287,8 @@ import {
|
|||||||
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
|
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
|
||||||
import AppCollapse from '@core/components/app-collapse/AppCollapse.vue'
|
import AppCollapse from '@core/components/app-collapse/AppCollapse.vue'
|
||||||
import AppCollapseItem from '@core/components/app-collapse/AppCollapseItem.vue'
|
import AppCollapseItem from '@core/components/app-collapse/AppCollapseItem.vue'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
import OperationTransferComponent from './OperationTransferComponent.vue'
|
||||||
|
import OperationTransfer2Component from './OperationTransfer2Component.vue'
|
||||||
import ChartComponentDoughnut from './ChartComponentDoughnut.vue'
|
import ChartComponentDoughnut from './ChartComponentDoughnut.vue'
|
||||||
import EchartScatter from './components/charts/EchartScatter.vue'
|
import EchartScatter from './components/charts/EchartScatter.vue'
|
||||||
|
|
||||||
@@ -308,13 +309,14 @@ export default {
|
|||||||
// eslint-disable-next-line vue/no-unused-components
|
// eslint-disable-next-line vue/no-unused-components
|
||||||
VBTooltip,
|
VBTooltip,
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
|
OperationTransferComponent,
|
||||||
// eslint-disable-next-line vue/no-unused-components
|
// eslint-disable-next-line vue/no-unused-components
|
||||||
ToastificationContent,
|
ToastificationContent,
|
||||||
|
OperationTransfer2Component,
|
||||||
ChartComponentDoughnut,
|
ChartComponentDoughnut,
|
||||||
AppCollapse,
|
AppCollapse,
|
||||||
AppCollapseItem,
|
AppCollapseItem,
|
||||||
EchartScatter,
|
EchartScatter,
|
||||||
OperationModal,
|
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-tooltip': VBTooltip,
|
'b-tooltip': VBTooltip,
|
||||||
@@ -333,7 +335,6 @@ export default {
|
|||||||
delegations: {},
|
delegations: {},
|
||||||
ibcDenom: {},
|
ibcDenom: {},
|
||||||
quotes: {},
|
quotes: {},
|
||||||
operationModalType: '',
|
|
||||||
options: {
|
options: {
|
||||||
maintainAspectRatio: false,
|
maintainAspectRatio: false,
|
||||||
legend: {
|
legend: {
|
||||||
@@ -532,8 +533,7 @@ export default {
|
|||||||
this.currency2 = c
|
this.currency2 = c
|
||||||
this.currency = getUserCurrencySign()
|
this.currency = getUserCurrencySign()
|
||||||
},
|
},
|
||||||
transfer(type, addr) {
|
transfer(addr) {
|
||||||
this.operationModalType = type
|
|
||||||
this.selectedAddress = addr
|
this.selectedAddress = addr
|
||||||
},
|
},
|
||||||
completeAdd() {
|
completeAdd() {
|
||||||
|
|||||||
@@ -42,29 +42,29 @@
|
|||||||
size="sm"
|
size="sm"
|
||||||
>
|
>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.delegate-window
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
v-b-tooltip.hover.top="'Delegate'"
|
v-b-tooltip.hover.top="'Delegate'"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
@click="selectValue('Delegate',data.item)"
|
@click="selectValue(data.item)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="LogInIcon" />
|
<feather-icon icon="LogInIcon" />
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.redelegate-window
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
v-b-tooltip.hover.top="'Redelegate'"
|
v-b-tooltip.hover.top="'Redelegate'"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
@click="selectValue('Redelegate',data.item)"
|
@click="selectValue(data.item)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="ShuffleIcon" />
|
<feather-icon icon="ShuffleIcon" />
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button
|
<b-button
|
||||||
v-b-modal.operation-modal
|
v-b-modal.unbond-window
|
||||||
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
|
||||||
v-b-tooltip.hover.top="'Unbond'"
|
v-b-tooltip.hover.top="'Unbond'"
|
||||||
variant="outline-primary"
|
variant="outline-primary"
|
||||||
@click="selectValue('Unbond',data.item)"
|
@click="selectValue(data.item)"
|
||||||
>
|
>
|
||||||
<feather-icon icon="LogOutIcon" />
|
<feather-icon icon="LogOutIcon" />
|
||||||
</b-button>
|
</b-button>
|
||||||
@@ -74,10 +74,18 @@
|
|||||||
</b-card>
|
</b-card>
|
||||||
|
|
||||||
<!--- not completed--->
|
<!--- not completed--->
|
||||||
<operation-modal
|
<operation-withdraw-component :address="address" />
|
||||||
:type="operationModalType"
|
<operation-unbond-component
|
||||||
:address="address"
|
:address="address"
|
||||||
:validator-address="selectedValidator"
|
:validator-address.sync="selectedValidator"
|
||||||
|
/>
|
||||||
|
<operation-delegate-component
|
||||||
|
:address="address"
|
||||||
|
:validator-address.sync="selectedValidator"
|
||||||
|
/>
|
||||||
|
<operation-redelegate-component
|
||||||
|
:address="address"
|
||||||
|
:validator-address.sync="selectedValidator"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -91,7 +99,11 @@ import {
|
|||||||
formatToken, getCachedValidators, getLocalAccounts, getLocalChains, tokenFormatter,
|
formatToken, getCachedValidators, getLocalAccounts, getLocalChains, tokenFormatter,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
import FeatherIcon from '@/@core/components/feather-icon/FeatherIcon.vue'
|
import FeatherIcon from '@/@core/components/feather-icon/FeatherIcon.vue'
|
||||||
import OperationModal from '@/views/components/OperationModal/index.vue'
|
|
||||||
|
import OperationWithdrawComponent from './OperationWithdrawComponent.vue'
|
||||||
|
import OperationUnbondComponent from './OperationUnbondComponent.vue'
|
||||||
|
import OperationDelegateComponent from './OperationDelegateComponent.vue'
|
||||||
|
import OperationRedelegateComponent from './OperationRedelegateComponent.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -101,7 +113,11 @@ export default {
|
|||||||
BTable,
|
BTable,
|
||||||
BCard,
|
BCard,
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
OperationModal,
|
|
||||||
|
OperationWithdrawComponent,
|
||||||
|
OperationDelegateComponent,
|
||||||
|
OperationRedelegateComponent,
|
||||||
|
OperationUnbondComponent,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-tooltip': VBTooltip,
|
'b-tooltip': VBTooltip,
|
||||||
@@ -137,7 +153,6 @@ export default {
|
|||||||
accounts: [],
|
accounts: [],
|
||||||
delegations: [],
|
delegations: [],
|
||||||
rewards: {},
|
rewards: {},
|
||||||
operationModalType: '',
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -185,8 +200,7 @@ export default {
|
|||||||
this.init()
|
this.init()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
selectValue(type, v) {
|
selectValue(v) {
|
||||||
this.operationModalType = type
|
|
||||||
this.address = v.delegator_address
|
this.address = v.delegator_address
|
||||||
this.selectedValidator = v.validator.validator
|
this.selectedValidator = v.validator.validator
|
||||||
return v
|
return v
|
||||||
|
|||||||
@@ -1,214 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
v-if="false"
|
|
||||||
class="board "
|
|
||||||
>
|
|
||||||
<div class="data">
|
|
||||||
<div class="board-row">
|
|
||||||
<div class="key">
|
|
||||||
AMOUNT
|
|
||||||
</div>
|
|
||||||
<div class="value">
|
|
||||||
1,233,000 USDT
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="board-row">
|
|
||||||
<div class="key">
|
|
||||||
BRIDGE FEE
|
|
||||||
</div>
|
|
||||||
<div class="value">
|
|
||||||
3,000 USDT
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sum">
|
|
||||||
<div class="key">
|
|
||||||
TRANSFER AMOUNT
|
|
||||||
</div>
|
|
||||||
<div class="value">
|
|
||||||
1,213,000 USDT
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p
|
|
||||||
v-if="succeed"
|
|
||||||
class="result-text mt-1 text-success"
|
|
||||||
>
|
|
||||||
Congratulations! Transfer completed successfully.
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
v-else-if="error"
|
|
||||||
class="result-text mt-1 text-danger"
|
|
||||||
>
|
|
||||||
{{ error }}
|
|
||||||
</p>
|
|
||||||
<p
|
|
||||||
v-else
|
|
||||||
class="result-text mt-1 text-primary"
|
|
||||||
>
|
|
||||||
Processing...
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="status">
|
|
||||||
<!-- <b-progress
|
|
||||||
:value="100"
|
|
||||||
:variant="progressColor"
|
|
||||||
:animated="isLoading"
|
|
||||||
/> -->
|
|
||||||
<b-progress :animated="isLoading">
|
|
||||||
<b-progress-bar
|
|
||||||
variant="success"
|
|
||||||
:value="progresBar[0]"
|
|
||||||
/>
|
|
||||||
<b-progress-bar
|
|
||||||
variant="danger"
|
|
||||||
:value="progresBar[1]"
|
|
||||||
/>
|
|
||||||
<b-progress-bar
|
|
||||||
variant="info"
|
|
||||||
:value="progresBar[2]"
|
|
||||||
/>
|
|
||||||
</b-progress>
|
|
||||||
<div class="status-text">
|
|
||||||
<span v-if="hash">SUBMITED</span>
|
|
||||||
<span v-if="succeed">COMPLETED</span>
|
|
||||||
<span v-if="error">FAILED</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="link">
|
|
||||||
<router-link
|
|
||||||
to="/"
|
|
||||||
>
|
|
||||||
View details
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { BProgress, BProgressBar } from 'bootstrap-vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
BProgress,
|
|
||||||
BProgressBar,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
hash: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isLoading: true,
|
|
||||||
succeed: false,
|
|
||||||
error: '',
|
|
||||||
checkTimes: 0,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
progresBar() {
|
|
||||||
// success: [100, 0, 0]
|
|
||||||
// fail: [50, 50, 0]
|
|
||||||
// pending: [0, 0, 100]
|
|
||||||
if (!this.hash) {
|
|
||||||
return [0, 0, 100]
|
|
||||||
}
|
|
||||||
if (this.succeed) {
|
|
||||||
return [100, 0, 0]
|
|
||||||
}
|
|
||||||
return [50, 0, 50]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.timer = setInterval(this.trace, 6000)
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
trace() {
|
|
||||||
if (this.hash) {
|
|
||||||
this.error = null
|
|
||||||
this.$http.getTxs(this.hash).then(res => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.succeed = true
|
|
||||||
clearInterval(this.timer)
|
|
||||||
window.location.reload()
|
|
||||||
} else if (res.code !== 3) { // code 3 is tx unconfirmed(not founded).
|
|
||||||
this.error = res.raw_log
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
|
||||||
}, () => {
|
|
||||||
// error statement
|
|
||||||
this.checkTimes += 1
|
|
||||||
if (this.checkTimes > 5) {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
this.error = 'Timeout'
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
this.error = e
|
|
||||||
clearInterval(this.timer)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.board {
|
|
||||||
background: #f8f8f8;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 0 12px;
|
|
||||||
margin: 35px 0;
|
|
||||||
.data {
|
|
||||||
padding: 10px 0;
|
|
||||||
border-bottom: 1px solid #607d8b;
|
|
||||||
}
|
|
||||||
.board-row {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 34px;
|
|
||||||
.key {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
.value {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sum {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 15px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.result-text {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.status {
|
|
||||||
margin-top: 30px;
|
|
||||||
.status-text {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-top: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.link {
|
|
||||||
margin-top: 20px;
|
|
||||||
text-align: center;
|
|
||||||
a {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: var(--purple)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,240 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Delegator"
|
|
||||||
label-for="Delegator"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Delegator"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
v-model="selectedAddress"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Validator"
|
|
||||||
>
|
|
||||||
<b-form-group
|
|
||||||
label="Validator"
|
|
||||||
label-for="validator"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
v-model="selectedValidator"
|
|
||||||
:options="valOptions"
|
|
||||||
:reduce="val => val.value"
|
|
||||||
placeholder="Select a validator"
|
|
||||||
:readonly="validatorAddress"
|
|
||||||
:selectable="(v) => v.value"
|
|
||||||
/>
|
|
||||||
</b-form-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Available Token"
|
|
||||||
label-for="Token"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Token"
|
|
||||||
>
|
|
||||||
<b-form-select
|
|
||||||
v-model="token"
|
|
||||||
text-field="label"
|
|
||||||
>
|
|
||||||
<b-form-select-option
|
|
||||||
v-for="x in balanceOptions"
|
|
||||||
:key="x.denom"
|
|
||||||
:value="x.denom"
|
|
||||||
>
|
|
||||||
{{ format(x) }}
|
|
||||||
</b-form-select-option>
|
|
||||||
</b-form-select>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Amount"
|
|
||||||
label-for="Amount"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|regex:^([0-9\.]+)$"
|
|
||||||
name="amount"
|
|
||||||
>
|
|
||||||
<b-input-group>
|
|
||||||
<b-form-input
|
|
||||||
id="Amount"
|
|
||||||
v-model="amount"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a number"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<b-input-group-append is-text>
|
|
||||||
{{ printDenom() }}
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BFormInput, BFormGroup, BFormSelect, BFormSelectOption,
|
|
||||||
BInputGroupAppend,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken, formatTokenDenom, getUnitAmount,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
import vSelect from 'vue-select'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
BFormSelect,
|
|
||||||
BFormSelectOption,
|
|
||||||
vSelect,
|
|
||||||
BInputGroupAppend,
|
|
||||||
|
|
||||||
ValidationProvider,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
validatorAddress: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
balance: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedAddress: this.address,
|
|
||||||
availableAddress: [],
|
|
||||||
validators: [],
|
|
||||||
unbundValidators: [],
|
|
||||||
selectedValidator: this.validatorAddress,
|
|
||||||
token: '',
|
|
||||||
amount: null,
|
|
||||||
selectedChain: '',
|
|
||||||
IBCDenom: {},
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
valOptions() {
|
|
||||||
let options = []
|
|
||||||
const vals = this.validators.map(x => ({ value: x.operator_address, label: `${x.description.moniker} (${Number(x.commission.rate) * 100}%)` }))
|
|
||||||
if (vals.length > 0) {
|
|
||||||
options.push({ value: null, label: '=== ACTIVE VALIDATORS ===' })
|
|
||||||
options = options.concat(vals)
|
|
||||||
}
|
|
||||||
const unbunded = this.unbundValidators.map(x => ({ value: x.operator_address, label: `* ${x.description.moniker} (${Number(x.commission.rate) * 100}%)` }))
|
|
||||||
if (unbunded.length > 0) {
|
|
||||||
options.push({ value: null, label: '=== INACTIVE VALIDATORS ===', disabled: true })
|
|
||||||
options = options.concat(unbunded)
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
},
|
|
||||||
balanceOptions() {
|
|
||||||
return this.setupBalance()
|
|
||||||
},
|
|
||||||
msg() {
|
|
||||||
return [{
|
|
||||||
typeUrl: '/cosmos.staking.v1beta1.MsgDelegate',
|
|
||||||
value: {
|
|
||||||
delegatorAddress: this.selectedAddress,
|
|
||||||
validatorAddress: this.selectedValidator,
|
|
||||||
amount: {
|
|
||||||
amount: getUnitAmount(this.amount, this.token),
|
|
||||||
denom: this.token,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Delegate Token',
|
|
||||||
historyName: 'delegate',
|
|
||||||
})
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadData() {
|
|
||||||
this.$http.getValidatorList().then(v => {
|
|
||||||
this.validators = v
|
|
||||||
})
|
|
||||||
this.$http.getValidatorUnbondedList().then(v => {
|
|
||||||
this.unbundValidators = v
|
|
||||||
})
|
|
||||||
},
|
|
||||||
setupBalance() {
|
|
||||||
if (this.balance && this.balance.length > 0) {
|
|
||||||
this.token = this.balance[0].denom
|
|
||||||
return this.balance
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
},
|
|
||||||
printDenom() {
|
|
||||||
return formatTokenDenom(this.token)
|
|
||||||
},
|
|
||||||
format(v) {
|
|
||||||
return formatToken(v, this.IBCDenom, 6)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<h4>{{ proposalId }}. {{ proposalTitle }}</h4>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Depositor"
|
|
||||||
label-for="Voter"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Voter"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
v-model="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Available Token"
|
|
||||||
label-for="Token"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Token"
|
|
||||||
>
|
|
||||||
<b-form-select
|
|
||||||
v-model="token"
|
|
||||||
>
|
|
||||||
<b-form-select-option
|
|
||||||
v-for="item in balanceOptions"
|
|
||||||
:key="item.denom"
|
|
||||||
:value="item.denom"
|
|
||||||
>
|
|
||||||
{{ format(item) }}
|
|
||||||
</b-form-select-option>
|
|
||||||
</b-form-select>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Amount"
|
|
||||||
label-for="Amount"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|regex:^([0-9\.]+)$"
|
|
||||||
name="amount"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
id="Amount"
|
|
||||||
v-model="amount"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a number"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<b-input-group-append is-text>
|
|
||||||
{{ printDenom() }}
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BFormInput, BFormGroup, BFormSelect,
|
|
||||||
BInputGroupAppend, BFormSelectOption,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken, formatTokenDenom, getUnitAmount,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'DepositDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
BFormSelect,
|
|
||||||
BInputGroupAppend,
|
|
||||||
BFormSelectOption,
|
|
||||||
ValidationProvider,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
proposalId: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
proposalTitle: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
balance: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
token: null,
|
|
||||||
amount: '',
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
msg() {
|
|
||||||
return [{
|
|
||||||
typeUrl: '/cosmos.gov.v1beta1.MsgDeposit',
|
|
||||||
value: {
|
|
||||||
depositor: this.address,
|
|
||||||
proposalId: String(this.proposalId),
|
|
||||||
amount: [
|
|
||||||
{
|
|
||||||
amount: getUnitAmount(this.amount, this.token),
|
|
||||||
denom: this.token,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
balanceOptions() {
|
|
||||||
return this.setupBalance()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Deposit',
|
|
||||||
historyName: 'deposit',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
printDenom() {
|
|
||||||
return formatTokenDenom(this.token)
|
|
||||||
},
|
|
||||||
format(v) {
|
|
||||||
return formatToken(v)
|
|
||||||
},
|
|
||||||
setupBalance() {
|
|
||||||
if (this.balance && this.balance.length > 0) {
|
|
||||||
this.token = this.balance[0].denom
|
|
||||||
return this.balance
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@core/scss/vue/libs/vue-select.scss';
|
|
||||||
</style>
|
|
||||||
@@ -1,307 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Sender"
|
|
||||||
label-for="Account"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
:value="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</b-input-group>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Available Token"
|
|
||||||
label-for="Token"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Token"
|
|
||||||
>
|
|
||||||
<b-form-select
|
|
||||||
v-model="token"
|
|
||||||
@change="tokenChange"
|
|
||||||
>
|
|
||||||
<template #first>
|
|
||||||
<b-form-select-option
|
|
||||||
value=""
|
|
||||||
>
|
|
||||||
-- Please select a token --
|
|
||||||
</b-form-select-option>
|
|
||||||
</template>
|
|
||||||
<b-form-select-option
|
|
||||||
v-for="item in balance"
|
|
||||||
:key="item.denom"
|
|
||||||
:value="item.denom"
|
|
||||||
>
|
|
||||||
{{ format(item) }}
|
|
||||||
</b-form-select-option>
|
|
||||||
</b-form-select>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Amount"
|
|
||||||
label-for="Amount"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|regex:^([0-9\.]+)$"
|
|
||||||
name="amount"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
id="Amount"
|
|
||||||
v-model="amount"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a number"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<b-input-group-append is-text>
|
|
||||||
{{ printDenom() }}
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
:label="`Destination: ${targetChainId}`"
|
|
||||||
label-for="destination"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="destination"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
v-model="destination"
|
|
||||||
name="destination"
|
|
||||||
:options="destinationOptions"
|
|
||||||
placeholder="Select a channel"
|
|
||||||
@input="onChannelChange()"
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Recipient"
|
|
||||||
label-for="Recipient"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="recipient"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
id="Recipient"
|
|
||||||
v-model="recipient"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a destination address"
|
|
||||||
/>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BInputGroupAppend, BFormInput, BFormGroup, BFormSelect, BFormSelectOption,
|
|
||||||
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken, formatTokenDenom, getUnitAmount,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
import vSelect from 'vue-select'
|
|
||||||
import { coin } from '@cosmjs/amino'
|
|
||||||
import dayjs from 'dayjs'
|
|
||||||
import { toHex } from '@cosmjs/encoding'
|
|
||||||
import { sha256 } from '@cosmjs/crypto'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'TransforDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BInputGroupAppend,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
BFormSelect,
|
|
||||||
BFormSelectOption,
|
|
||||||
vSelect,
|
|
||||||
|
|
||||||
ValidationProvider,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
balance: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
targetChainId: '',
|
|
||||||
token: '',
|
|
||||||
amount: null,
|
|
||||||
recipient: null,
|
|
||||||
IBCDenom: {},
|
|
||||||
paths: {},
|
|
||||||
destination: {},
|
|
||||||
channels: [],
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
destinationOptions() {
|
|
||||||
if (!this.token && this.token === '') return []
|
|
||||||
const options = this.channels.map(x => ({ port_id: x.port_id, channel_id: x.channel_id, label: `${x.chain_id ? x.chain_id : ''} ${x.port_id}/${x.channel_id}` }))
|
|
||||||
if (this.token.startsWith('ibc/')) {
|
|
||||||
const query = this.paths[this.token]
|
|
||||||
return query ? options.filter(x => x.channel_id === query.channel_id) : options
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
},
|
|
||||||
|
|
||||||
msg() {
|
|
||||||
const timeout = dayjs().add(4, 'hour')
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
typeUrl: '/ibc.applications.transfer.v1.MsgTransfer',
|
|
||||||
value: {
|
|
||||||
sourcePort: this.destination.port_id,
|
|
||||||
sourceChannel: this.destination.channel_id,
|
|
||||||
token: coin(Number(getUnitAmount(this.amount, this.token)), this.token),
|
|
||||||
sender: this.address,
|
|
||||||
receiver: this.recipient,
|
|
||||||
timeoutTimestamp: String(timeout.utc().valueOf() * 1000000),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
balanceOptions() {
|
|
||||||
return this.setupBalance()
|
|
||||||
},
|
|
||||||
selectedChain() {
|
|
||||||
return this.$store.state.chains.selected
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'IBC Transfer Tokens',
|
|
||||||
historyName: 'transfer',
|
|
||||||
})
|
|
||||||
this.setActionName()
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadData() {
|
|
||||||
this.destination = null
|
|
||||||
this.channels = []
|
|
||||||
this.token = ''
|
|
||||||
this.targetChainId = ''
|
|
||||||
if (this.address) {
|
|
||||||
this.$http.getAllIBCDenoms(this.selectedChain).then(x => {
|
|
||||||
x.denom_traces.forEach(trace => {
|
|
||||||
const hash = toHex(sha256(new TextEncoder().encode(`${trace.path}/${trace.base_denom}`)))
|
|
||||||
const ibcDenom = `ibc/${hash.toUpperCase()}`
|
|
||||||
// add base_denom to cache
|
|
||||||
this.$set(this.IBCDenom, ibcDenom, trace.base_denom)
|
|
||||||
// store channel/part for ibc denoms
|
|
||||||
const path = trace.path.split('/')
|
|
||||||
if (path.length >= 2) {
|
|
||||||
this.paths[ibcDenom] = {
|
|
||||||
channel_id: path[path.length - 1],
|
|
||||||
port_id: path[path.length - 2],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
this.$http.getIBCChannels(this.selectedChain, null).then(ret => {
|
|
||||||
const chans = ret.channels.filter(x => x.state === 'STATE_OPEN').map(x => ({ channel_id: x.channel_id, port_id: x.port_id }))
|
|
||||||
this.$set(this, 'channels', chans)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setupBalance() {
|
|
||||||
if (this.balance && this.balance.length > 0) {
|
|
||||||
this.token = this.balance[0].denom
|
|
||||||
return this.balance
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
},
|
|
||||||
tokenChange() {
|
|
||||||
// eslint-disable-next-line prefer-destructuring
|
|
||||||
this.destination = this.destinationOptions[0]
|
|
||||||
this.recipient = null
|
|
||||||
this.setActionName()
|
|
||||||
this.onChannelChange()
|
|
||||||
},
|
|
||||||
|
|
||||||
setActionName() {
|
|
||||||
this.$emit('update', {
|
|
||||||
actionName: this.token.startsWith('ibc') ? 'Withdraw' : 'Deposit',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
format(v) {
|
|
||||||
return formatToken(v, this.IBCDenom)
|
|
||||||
},
|
|
||||||
printDenom() {
|
|
||||||
return formatTokenDenom(this.IBCDenom[this.token] || this.token)
|
|
||||||
},
|
|
||||||
onChannelChange() {
|
|
||||||
this.$http.getIBCChannelClientState(this.destination.channel_id, this.destination.port_id, this.selectedChain).then(cs => {
|
|
||||||
this.targetChainId = cs.identified_client_state.client_state.chain_id
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@core/scss/vue/libs/vue-select.scss';
|
|
||||||
</style>
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Delegator"
|
|
||||||
label-for="Account"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Delegator"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
v-model="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="From Validator"
|
|
||||||
label-for="validator"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
:value="validatorAddress"
|
|
||||||
:options="valOptions"
|
|
||||||
:reduce="val => val.value"
|
|
||||||
placeholder="Select a validator"
|
|
||||||
:disabled="true"
|
|
||||||
/>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Current Delegation"
|
|
||||||
label-for="Token"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Token"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
v-model="token"
|
|
||||||
:options="tokenOptions"
|
|
||||||
:reduce="token => token.value"
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="To Validator"
|
|
||||||
label-for="validator"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
v-model="toValidator"
|
|
||||||
:options="valOptions"
|
|
||||||
:reduce="val => val.value"
|
|
||||||
placeholder="Select a validator"
|
|
||||||
:selectable="(v) => v.value"
|
|
||||||
/>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Amount"
|
|
||||||
label-for="Amount"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|regex:^([0-9\.]+)$"
|
|
||||||
name="amount"
|
|
||||||
>
|
|
||||||
<b-input-group>
|
|
||||||
<b-form-input
|
|
||||||
id="Amount"
|
|
||||||
v-model="amount"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a number"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<b-input-group-append is-text>
|
|
||||||
{{ printDenom() }}
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BFormInput, BFormGroup,
|
|
||||||
BInputGroupAppend,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken, formatTokenDenom, getUnitAmount,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
import vSelect from 'vue-select'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Redelegate',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
vSelect,
|
|
||||||
BInputGroupAppend,
|
|
||||||
ValidationProvider,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
validatorAddress: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
selectedAddress: this.address,
|
|
||||||
unbundValidators: [],
|
|
||||||
validators: [],
|
|
||||||
toValidator: null,
|
|
||||||
token: '',
|
|
||||||
amount: null,
|
|
||||||
delegations: [],
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
valOptions() {
|
|
||||||
let options = []
|
|
||||||
const vals = this.validators.map(x => ({ value: x.operator_address, label: `${x.description.moniker} (${Number(x.commission.rate) * 100}%)` }))
|
|
||||||
if (vals.length > 0) {
|
|
||||||
options.push({ value: null, label: '=== ACTIVE VALIDATORS ===' })
|
|
||||||
options = options.concat(vals)
|
|
||||||
}
|
|
||||||
const unbunded = this.unbundValidators.map(x => ({ value: x.operator_address, label: `* ${x.description.moniker} (${Number(x.commission.rate) * 100}%)` }))
|
|
||||||
if (unbunded.length > 0) {
|
|
||||||
options.push({ value: null, label: '=== INACTIVE VALIDATORS ===', disabled: true })
|
|
||||||
options = options.concat(unbunded)
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
},
|
|
||||||
tokenOptions() {
|
|
||||||
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) }))
|
|
||||||
},
|
|
||||||
msg() {
|
|
||||||
return [{
|
|
||||||
typeUrl: '/cosmos.staking.v1beta1.MsgBeginRedelegate',
|
|
||||||
value: {
|
|
||||||
delegatorAddress: this.address,
|
|
||||||
validatorSrcAddress: this.validatorAddress,
|
|
||||||
validatorDstAddress: this.toValidator,
|
|
||||||
amount: {
|
|
||||||
amount: getUnitAmount(this.amount, this.token),
|
|
||||||
denom: this.token,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Redelegate Token',
|
|
||||||
historyName: 'redelegate',
|
|
||||||
})
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
loadData() {
|
|
||||||
this.$http.getValidatorList().then(v => {
|
|
||||||
this.validators = v
|
|
||||||
})
|
|
||||||
this.$http.getValidatorUnbondedList().then(v => {
|
|
||||||
this.unbundValidators = v
|
|
||||||
})
|
|
||||||
this.$http.getStakingDelegations(this.address).then(res => {
|
|
||||||
this.delegations = res.delegation_responses
|
|
||||||
this.delegations.forEach(x => {
|
|
||||||
if (x.delegation.validator_address === this.validatorAddress) {
|
|
||||||
this.token = x.balance.denom
|
|
||||||
this.$emit('update', {
|
|
||||||
feeDenom: x.balance.denom,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
format(v) {
|
|
||||||
return formatToken(v)
|
|
||||||
},
|
|
||||||
printDenom() {
|
|
||||||
return formatTokenDenom(this.token)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@core/scss/vue/libs/vue-select.scss';
|
|
||||||
</style>
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Sender"
|
|
||||||
label-for="sender"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
|
|
||||||
<b-form-input
|
|
||||||
name="sender"
|
|
||||||
:value="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</b-input-group>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Recipient"
|
|
||||||
label-for="Recipient"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="recipient"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
id="Recipient"
|
|
||||||
v-model="recipient"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
/>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Available Token"
|
|
||||||
label-for="Token"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Token"
|
|
||||||
>
|
|
||||||
<b-form-select
|
|
||||||
v-model="token"
|
|
||||||
>
|
|
||||||
<b-form-select-option
|
|
||||||
v-for="item in balanceOptions"
|
|
||||||
:key="item.denom"
|
|
||||||
:value="item.denom"
|
|
||||||
>
|
|
||||||
{{ format(item) }}
|
|
||||||
</b-form-select-option>
|
|
||||||
</b-form-select>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Amount"
|
|
||||||
label-for="Amount"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|regex:^([0-9\.]+)$"
|
|
||||||
name="amount"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
id="Amount"
|
|
||||||
v-model="amount"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a number"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<b-input-group-append is-text>
|
|
||||||
{{ printDenom() }}
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BInputGroupAppend, BFormInput, BFormGroup, BFormSelect, BFormSelectOption,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken, formatTokenDenom, getUnitAmount,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'TransforDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BInputGroupAppend,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
BFormSelect,
|
|
||||||
BFormSelectOption,
|
|
||||||
ValidationProvider,
|
|
||||||
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
balance: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
token: '',
|
|
||||||
amount: null,
|
|
||||||
recipient: '',
|
|
||||||
IBCDenom: {},
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
msg() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
typeUrl: '/cosmos.bank.v1beta1.MsgSend',
|
|
||||||
value: {
|
|
||||||
fromAddress: this.address,
|
|
||||||
toAddress: this.recipient,
|
|
||||||
amount: [
|
|
||||||
{
|
|
||||||
amount: getUnitAmount(this.amount, this.token),
|
|
||||||
denom: this.token,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
balanceOptions() {
|
|
||||||
return this.setupBalance()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Transfer Tokens',
|
|
||||||
historyName: 'send',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
setupBalance() {
|
|
||||||
if (this.balance && this.balance.length > 0) {
|
|
||||||
this.token = this.balance[0].denom
|
|
||||||
return this.balance
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
},
|
|
||||||
format(v) {
|
|
||||||
return formatToken(v, this.IBCDenom)
|
|
||||||
},
|
|
||||||
printDenom() {
|
|
||||||
return formatTokenDenom(this.IBCDenom[this.token] || this.token)
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Delegator"
|
|
||||||
label-for="Account"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
v-model="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Validator"
|
|
||||||
label-for="validator"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
:value="validatorAddress"
|
|
||||||
:options="valOptions"
|
|
||||||
:reduce="val => val.value"
|
|
||||||
placeholder="Select a validator"
|
|
||||||
:disabled="true"
|
|
||||||
/>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Current Delegation"
|
|
||||||
label-for="Token"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Token"
|
|
||||||
>
|
|
||||||
<v-select
|
|
||||||
v-model="token"
|
|
||||||
:options="tokenOptions"
|
|
||||||
:reduce="token => token.value"
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Amount"
|
|
||||||
label-for="Amount"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|regex:^([0-9\.]+)$"
|
|
||||||
name="amount"
|
|
||||||
>
|
|
||||||
<b-input-group>
|
|
||||||
<b-form-input
|
|
||||||
id="Amount"
|
|
||||||
v-model="amount"
|
|
||||||
:state="errors.length > 0 ? false:null"
|
|
||||||
placeholder="Input a number"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<b-input-group-append is-text>
|
|
||||||
{{ printDenom() }}
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BFormInput, BFormGroup, BInputGroupAppend,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken, formatTokenDenom, getUnitAmount,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
import vSelect from 'vue-select'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'UnbondDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
vSelect,
|
|
||||||
BInputGroupAppend,
|
|
||||||
ValidationProvider,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
validatorAddress: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
validators: [],
|
|
||||||
token: '',
|
|
||||||
amount: null,
|
|
||||||
delegations: [],
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
valOptions() {
|
|
||||||
return this.validators.map(x => ({ value: x.operator_address, label: `${x.description.moniker} (${Number(x.commission.rate) * 100}%)` }))
|
|
||||||
},
|
|
||||||
tokenOptions() {
|
|
||||||
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) }))
|
|
||||||
},
|
|
||||||
msg() {
|
|
||||||
return [{
|
|
||||||
typeUrl: '/cosmos.staking.v1beta1.MsgUndelegate',
|
|
||||||
value: {
|
|
||||||
delegatorAddress: this.address,
|
|
||||||
validatorAddress: this.validatorAddress,
|
|
||||||
amount: {
|
|
||||||
amount: getUnitAmount(this.amount, this.token),
|
|
||||||
denom: this.token,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Unbond Token',
|
|
||||||
historyName: 'unbond',
|
|
||||||
})
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
loadData() {
|
|
||||||
if (this.address) {
|
|
||||||
this.$http.getValidatorList().then(v => {
|
|
||||||
this.validators = v
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.$http.getStakingDelegations(this.address).then(res => {
|
|
||||||
this.delegations = res.delegation_responses
|
|
||||||
this.delegations.forEach(x => {
|
|
||||||
if (x.delegation.validator_address === this.validatorAddress) {
|
|
||||||
this.token = x.balance.denom
|
|
||||||
this.$emit('update', {
|
|
||||||
feeDenom: x.balance.denom,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
printDenom() {
|
|
||||||
return formatTokenDenom(this.token)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@core/scss/vue/libs/vue-select.scss';
|
|
||||||
</style>
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<h4>{{ proposalId }}. {{ proposalTitle }}</h4>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Voter"
|
|
||||||
label-for="Account"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="Voter"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
v-model="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Option"
|
|
||||||
label-for="option"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
#default="{ errors }"
|
|
||||||
rules="required"
|
|
||||||
name="option"
|
|
||||||
>
|
|
||||||
<div class="demo-inline-spacing">
|
|
||||||
|
|
||||||
<b-form-radio
|
|
||||||
v-model="option"
|
|
||||||
name="option"
|
|
||||||
value="1"
|
|
||||||
class="custom-control-success"
|
|
||||||
>
|
|
||||||
Yes
|
|
||||||
</b-form-radio>
|
|
||||||
<b-form-radio
|
|
||||||
v-model="option"
|
|
||||||
name="option"
|
|
||||||
value="3"
|
|
||||||
class="custom-control-warning"
|
|
||||||
>
|
|
||||||
No
|
|
||||||
</b-form-radio>
|
|
||||||
<b-form-radio
|
|
||||||
v-model="option"
|
|
||||||
name="option"
|
|
||||||
value="4"
|
|
||||||
class="custom-control-danger"
|
|
||||||
>
|
|
||||||
No With Veto
|
|
||||||
</b-form-radio>
|
|
||||||
<b-form-radio
|
|
||||||
v-model="option"
|
|
||||||
name="option"
|
|
||||||
value="2"
|
|
||||||
class="custom-control-secondary"
|
|
||||||
>
|
|
||||||
Abstain
|
|
||||||
</b-form-radio>
|
|
||||||
</div>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BRow, BCol, BFormGroup, BFormInput,
|
|
||||||
BFormRadio,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
formatToken,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'VoteDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BFormGroup,
|
|
||||||
BFormRadio,
|
|
||||||
ValidationProvider,
|
|
||||||
BFormInput,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
proposalId: {
|
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
proposalTitle: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
option: null,
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
msg() {
|
|
||||||
return [{
|
|
||||||
typeUrl: '/cosmos.gov.v1beta1.MsgVote',
|
|
||||||
value: {
|
|
||||||
voter: this.address,
|
|
||||||
proposalId: this.proposalId,
|
|
||||||
option: Number(this.option),
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Vote',
|
|
||||||
historyName: 'vote',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
format(v) {
|
|
||||||
return formatToken(v)
|
|
||||||
},
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@core/scss/vue/libs/vue-select.scss';
|
|
||||||
</style>
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Sender"
|
|
||||||
label-for="Account"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
:value="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</b-input-group>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
BRow, BCol, BInputGroup, BFormInput, BFormGroup,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'WithdrawDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
account: [],
|
|
||||||
balance: [],
|
|
||||||
delegations: [],
|
|
||||||
feeDenom: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
msg() {
|
|
||||||
const txMsgs = []
|
|
||||||
this.delegations.forEach(i => {
|
|
||||||
txMsgs.push({
|
|
||||||
typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward',
|
|
||||||
value: {
|
|
||||||
delegatorAddress: this.address,
|
|
||||||
validatorAddress: i.delegation.validator_address,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return txMsgs
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Withdraw Rewards',
|
|
||||||
historyName: 'withdraw',
|
|
||||||
})
|
|
||||||
this.loadData()
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
loadData() {
|
|
||||||
this.$http.getStakingDelegations(this.address).then(res => {
|
|
||||||
this.delegations = res.delegation_responses
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<b-row>
|
|
||||||
<b-col>
|
|
||||||
<b-form-group
|
|
||||||
label="Sender"
|
|
||||||
label-for="Account"
|
|
||||||
>
|
|
||||||
<b-input-group class="mb-25">
|
|
||||||
<b-form-input
|
|
||||||
:value="address"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
</b-input-group>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'WithdrawCommissionDialogue',
|
|
||||||
components: {
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
validatorAddress: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
msg() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward',
|
|
||||||
value: {
|
|
||||||
delegatorAddress: this.address,
|
|
||||||
validatorAddress: this.validatorAddress,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeUrl: '/cosmos.distribution.v1beta1.MsgWithdrawValidatorCommission',
|
|
||||||
value: {
|
|
||||||
validatorAddress: this.validatorAddress,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$emit('update', {
|
|
||||||
modalTitle: 'Withdraw Validator Commission',
|
|
||||||
historyName: 'withdraw',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
<template>
|
|
||||||
<b-modal
|
|
||||||
:id="modalId"
|
|
||||||
centered
|
|
||||||
size="md"
|
|
||||||
:title="modalTitle"
|
|
||||||
:ok-title="actionName"
|
|
||||||
scrollable
|
|
||||||
:hide-header-close="!showResult"
|
|
||||||
:hide-footer="showResult"
|
|
||||||
modal-class="custom-transaction-modal"
|
|
||||||
:ok-disabled="isOwner"
|
|
||||||
@hidden="resetModal"
|
|
||||||
@ok="handleOk"
|
|
||||||
@show="initialize"
|
|
||||||
>
|
|
||||||
<b-overlay
|
|
||||||
:show="isOwner"
|
|
||||||
rounded="sm"
|
|
||||||
>
|
|
||||||
<template #overlay>
|
|
||||||
<div class="text-center">
|
|
||||||
<b-avatar
|
|
||||||
icon="stopwatch"
|
|
||||||
font-scale="3"
|
|
||||||
animation="cylon"
|
|
||||||
/>
|
|
||||||
<p id="cancel-label">
|
|
||||||
{{ blockingMsg }}
|
|
||||||
</p>
|
|
||||||
<b-button
|
|
||||||
v-ripple.400="'rgba(255, 255, 255, 0.15)'"
|
|
||||||
variant="outline-primary"
|
|
||||||
to="/wallet/import"
|
|
||||||
>
|
|
||||||
Connect Wallet
|
|
||||||
</b-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<validation-observer
|
|
||||||
v-if="!showResult"
|
|
||||||
ref="simpleRules"
|
|
||||||
>
|
|
||||||
<b-form>
|
|
||||||
<component
|
|
||||||
:is="type"
|
|
||||||
ref="component"
|
|
||||||
:address="selectedAddress"
|
|
||||||
:validator-address="validatorAddress"
|
|
||||||
:balance="balance"
|
|
||||||
:proposal-id="proposalId"
|
|
||||||
:proposal-title="proposalTitle"
|
|
||||||
@update="componentUpdate"
|
|
||||||
/>
|
|
||||||
<b-row>
|
|
||||||
<b-col cols="12">
|
|
||||||
<b-form-group>
|
|
||||||
<b-form-checkbox
|
|
||||||
v-model="advance"
|
|
||||||
name="advance"
|
|
||||||
value="true"
|
|
||||||
>
|
|
||||||
<small>Advanced</small>
|
|
||||||
</b-form-checkbox>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row v-if="advance">
|
|
||||||
<b-col cols="12">
|
|
||||||
<b-form-group
|
|
||||||
label="Fee"
|
|
||||||
label-for="Fee"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
rules="required|integer"
|
|
||||||
name="fee"
|
|
||||||
>
|
|
||||||
<b-input-group>
|
|
||||||
<b-form-input v-model="fee" />
|
|
||||||
<b-input-group-append>
|
|
||||||
<b-form-select
|
|
||||||
v-model="feeDenom"
|
|
||||||
:options="feeDenoms"
|
|
||||||
value-field="denom"
|
|
||||||
text-field="denom"
|
|
||||||
/>
|
|
||||||
</b-input-group-append>
|
|
||||||
</b-input-group>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12">
|
|
||||||
<b-form-group
|
|
||||||
label="Gas"
|
|
||||||
label-for="gas"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
name="gas"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
id="gas"
|
|
||||||
v-model="gas"
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
<b-col cols="12">
|
|
||||||
<b-form-group
|
|
||||||
label="Memo"
|
|
||||||
label-for="Memo"
|
|
||||||
>
|
|
||||||
<validation-provider
|
|
||||||
v-slot="{ errors }"
|
|
||||||
name="memo"
|
|
||||||
>
|
|
||||||
<b-form-input
|
|
||||||
id="Memo"
|
|
||||||
v-model="memo"
|
|
||||||
max="2"
|
|
||||||
/>
|
|
||||||
<small class="text-danger">{{ errors[0] }}</small>
|
|
||||||
</validation-provider>
|
|
||||||
</b-form-group>
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
<b-row v-if="advance">
|
|
||||||
<b-col>
|
|
||||||
<wallet-input-vue v-model="wallet" />
|
|
||||||
</b-col>
|
|
||||||
</b-row>
|
|
||||||
</b-form>
|
|
||||||
{{ error }}
|
|
||||||
</validation-observer>
|
|
||||||
|
|
||||||
<TransactionResult
|
|
||||||
v-else
|
|
||||||
:hash="txHash"
|
|
||||||
/>
|
|
||||||
</b-overlay>
|
|
||||||
</b-modal>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { ValidationProvider, ValidationObserver } from 'vee-validate'
|
|
||||||
import {
|
|
||||||
BAvatar, BModal, BRow, BCol, BInputGroup, BFormInput, BFormGroup, BFormSelect, BFormSelectOption,
|
|
||||||
BForm, BButton, BInputGroupAppend, BFormCheckbox, BOverlay,
|
|
||||||
} from 'bootstrap-vue'
|
|
||||||
import Ripple from 'vue-ripple-directive'
|
|
||||||
import {
|
|
||||||
required, email, url, between, alpha, integer, password, min, digits, alphaDash, length,
|
|
||||||
} from '@validations'
|
|
||||||
import {
|
|
||||||
extractAccountNumberAndSequence, getLocalAccounts, setLocalTxHistory, sign, timeIn,
|
|
||||||
} from '@/libs/utils'
|
|
||||||
import vSelect from 'vue-select'
|
|
||||||
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
|
|
||||||
|
|
||||||
import WalletInputVue from '../WalletInput.vue'
|
|
||||||
import Delegate from './components/Delegate.vue'
|
|
||||||
import Redelegate from './components/Redelegate.vue'
|
|
||||||
import Withdraw from './components/Withdraw.vue'
|
|
||||||
import Unbond from './components/Unbond.vue'
|
|
||||||
import Transfer from './components/Transfer.vue'
|
|
||||||
import IBCTransfer from './components/IBCTransfer.vue'
|
|
||||||
import Vote from './components/Vote.vue'
|
|
||||||
import WithdrawCommission from './components/WithdrawCommission.vue'
|
|
||||||
import GovDeposit from './components/GovDeposit.vue'
|
|
||||||
import TransactionResult from './TransactionResult.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'DelegateDialogue',
|
|
||||||
components: {
|
|
||||||
BAvatar,
|
|
||||||
BModal,
|
|
||||||
BRow,
|
|
||||||
BCol,
|
|
||||||
BForm,
|
|
||||||
BInputGroup,
|
|
||||||
BFormInput,
|
|
||||||
BFormGroup,
|
|
||||||
BFormSelect,
|
|
||||||
BFormSelectOption,
|
|
||||||
BFormCheckbox,
|
|
||||||
vSelect,
|
|
||||||
BButton,
|
|
||||||
BInputGroupAppend,
|
|
||||||
BOverlay,
|
|
||||||
WalletInputVue,
|
|
||||||
|
|
||||||
ValidationProvider,
|
|
||||||
ValidationObserver,
|
|
||||||
// eslint-disable-next-line vue/no-unused-components
|
|
||||||
ToastificationContent,
|
|
||||||
Delegate,
|
|
||||||
Redelegate,
|
|
||||||
Withdraw,
|
|
||||||
Unbond,
|
|
||||||
Transfer,
|
|
||||||
IBCTransfer,
|
|
||||||
Vote,
|
|
||||||
WithdrawCommission,
|
|
||||||
GovDeposit,
|
|
||||||
TransactionResult,
|
|
||||||
},
|
|
||||||
directives: {
|
|
||||||
Ripple,
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
modalId: {
|
|
||||||
type: String,
|
|
||||||
default: 'operation-modal',
|
|
||||||
},
|
|
||||||
validatorAddress: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
address: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
proposalId: {
|
|
||||||
type: Number,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
proposalTitle: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
modalTitle: '',
|
|
||||||
historyName: '',
|
|
||||||
selectedValidator: null,
|
|
||||||
selectedChain: null,
|
|
||||||
token: '',
|
|
||||||
chainId: '',
|
|
||||||
balance: [],
|
|
||||||
IBCDenom: {},
|
|
||||||
error: null,
|
|
||||||
sequence: 1,
|
|
||||||
accountNumber: 0,
|
|
||||||
advance: false,
|
|
||||||
fee: '900',
|
|
||||||
feeDenom: '',
|
|
||||||
wallet: 'ledgerUSB',
|
|
||||||
gas: '250000',
|
|
||||||
memo: '',
|
|
||||||
blockingMsg: this.address ? 'You are not the owner' : 'No available account found.',
|
|
||||||
actionName: 'Send',
|
|
||||||
showResult: false,
|
|
||||||
txHash: '',
|
|
||||||
|
|
||||||
required,
|
|
||||||
password,
|
|
||||||
email,
|
|
||||||
min,
|
|
||||||
integer,
|
|
||||||
url,
|
|
||||||
alpha,
|
|
||||||
between,
|
|
||||||
digits,
|
|
||||||
length,
|
|
||||||
alphaDash,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
feeDenoms() {
|
|
||||||
if (!this.balance) return []
|
|
||||||
return this.balance.filter(item => !item.denom.startsWith('ibc'))
|
|
||||||
},
|
|
||||||
accounts() {
|
|
||||||
const accounts = getLocalAccounts()
|
|
||||||
const selectedWallet = this.$store.state.chains.defaultWallet
|
|
||||||
return accounts[selectedWallet]
|
|
||||||
},
|
|
||||||
isOwner() {
|
|
||||||
if (this.accounts) {
|
|
||||||
this.updateWallet(this.accounts.device)
|
|
||||||
if (this.accounts.address.findIndex(x => x.addr === this.selectedAddress) > -1) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
},
|
|
||||||
selectedAddress() {
|
|
||||||
if (this.address) {
|
|
||||||
return this.address
|
|
||||||
}
|
|
||||||
const chain = this.$store.state.chains.selected.chain_name
|
|
||||||
const selectedAddress = this.accounts.address.find(x => x.chain === chain)
|
|
||||||
return selectedAddress?.addr
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initialize() {
|
|
||||||
this.$http.getLatestBlock().then(ret => {
|
|
||||||
this.chainId = ret.block.header.chain_id
|
|
||||||
const notSynced = timeIn(ret.block.header.time, 10, 'm')
|
|
||||||
if (notSynced) {
|
|
||||||
this.error = 'Client is not synced or blockchain is halted'
|
|
||||||
} else {
|
|
||||||
this.error = null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.$http.getAuthAccount(this.selectedAddress).then(ret => {
|
|
||||||
const account = extractAccountNumberAndSequence(ret)
|
|
||||||
this.accountNumber = account.accountNumber
|
|
||||||
this.sequence = account.sequence
|
|
||||||
})
|
|
||||||
this.$http.getBankBalances(this.selectedAddress).then(res => {
|
|
||||||
if (res && res.length > 0) {
|
|
||||||
this.balance = res.reverse()
|
|
||||||
const token = this.balance.find(i => !i.denom.startsWith('ibc'))
|
|
||||||
this.token = token.denom
|
|
||||||
if (token) this.feeDenom = token.denom
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.fee = this.$store.state.chains.selected?.min_tx_fee || '1000'
|
|
||||||
this.feeDenom = this.$store.state.chains.selected?.assets[0]?.base || ''
|
|
||||||
},
|
|
||||||
componentUpdate(obj) {
|
|
||||||
Object.keys(obj).forEach(key => {
|
|
||||||
this[key] = obj[key]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleOk(bvModalEvt) {
|
|
||||||
bvModalEvt.preventDefault()
|
|
||||||
this.$refs.simpleRules.validate().then(ok => {
|
|
||||||
if (ok) {
|
|
||||||
this.sendTx().then(ret => {
|
|
||||||
console.log(ret)
|
|
||||||
this.error = ret
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
resetModal() {
|
|
||||||
this.feeDenom = ''
|
|
||||||
this.error = null
|
|
||||||
this.showResult = false
|
|
||||||
},
|
|
||||||
async sendTx() {
|
|
||||||
const txMsgs = this.$refs.component.msg
|
|
||||||
if (txMsgs.length === 0) {
|
|
||||||
this.error = 'No delegation found'
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
if (!this.accountNumber) {
|
|
||||||
this.error = 'Account number should not be empty!'
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const txFee = {
|
|
||||||
amount: [
|
|
||||||
{
|
|
||||||
amount: this.fee,
|
|
||||||
denom: this.feeDenom,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
gas: this.gas,
|
|
||||||
}
|
|
||||||
|
|
||||||
const signerData = {
|
|
||||||
accountNumber: this.accountNumber,
|
|
||||||
sequence: this.sequence,
|
|
||||||
chainId: this.chainId,
|
|
||||||
}
|
|
||||||
|
|
||||||
sign(
|
|
||||||
this.wallet,
|
|
||||||
this.chainId,
|
|
||||||
this.selectedAddress,
|
|
||||||
txMsgs,
|
|
||||||
txFee,
|
|
||||||
this.memo,
|
|
||||||
signerData,
|
|
||||||
).then(bodyBytes => {
|
|
||||||
this.showResult = true
|
|
||||||
this.$http.broadcastTx(bodyBytes, this.selectedChain).then(res => {
|
|
||||||
this.txHash = res.tx_response.txhash
|
|
||||||
setLocalTxHistory({
|
|
||||||
chain: this.$store.state.chains.selected,
|
|
||||||
op: this.historyName,
|
|
||||||
hash: res.tx_response.txhash,
|
|
||||||
time: new Date(),
|
|
||||||
})
|
|
||||||
}).catch(e => {
|
|
||||||
console.log(e)
|
|
||||||
this.error = e
|
|
||||||
})
|
|
||||||
}).catch(e => {
|
|
||||||
console.log(e)
|
|
||||||
|
|
||||||
this.error = e
|
|
||||||
})
|
|
||||||
return ''
|
|
||||||
},
|
|
||||||
updateWallet(v) {
|
|
||||||
console.log('device', v)
|
|
||||||
if (v && v !== 'address') {
|
|
||||||
this.wallet = v
|
|
||||||
}
|
|
||||||
this.wallet = 'keplr'
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss">
|
|
||||||
@import '@core/scss/vue/libs/vue-select.scss';
|
|
||||||
.custom-transaction-modal {
|
|
||||||
.modal-header {
|
|
||||||
.modal-title {
|
|
||||||
font-size: 24px;
|
|
||||||
}
|
|
||||||
.close {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
Reference in New Issue
Block a user