add payme

This commit is contained in:
liangping 2022-09-11 10:03:34 +08:00
parent c6933d7722
commit c00fd6fe8c
6 changed files with 344 additions and 26 deletions

View File

@ -211,6 +211,24 @@ const router = new VueRouter({
],
},
},
{
path: '/:chain/account/:address/receive',
name: 'chain-receive',
component: () => import('@/views/WalletAccountReceive.vue'),
meta: {
pageTitle: 'Accounts',
breadcrumb: [
{
text: 'Accounts',
active: true,
},
{
text: 'Pay Me',
active: true,
},
],
},
},
{
path: '/:chain/staking',
name: 'staking',

View File

@ -93,33 +93,34 @@
<b-card-title>Active Proposals</b-card-title>
</b-card-header>
<b-card-body>
<b-link
v-for="prop in proposals"
<b-media
v-for="prop in proprosals2"
:key="prop.id"
:to="`./${chain}/gov/${prop.id}`"
no-body
class="mb-1"
>
<b-media
no-body
class="mb-1"
<b-media-aside
v-b-modal.operation-modal
@click="selectProposal('Vote',prop.id, prop.title)"
>
<b-media-aside>
<b-avatar
rounded
size="42"
variant="light-primary"
>
{{ prop.id }}
</b-avatar>
</b-media-aside>
<b-avatar
rounded
size="42"
:variant="myVotes[prop.id] ? 'light-primary': 'primary'"
>
{{ myVotes[prop.id] || 'Vote' }}
</b-avatar>
</b-media-aside>
<b-link :to="`./${chain}/gov/${prop.id}`">
<b-media-body class="d-flex flex-column justify-content-center">
<h6 class="transaction-title">
{{ prop.title }}
{{ prop.id }}. {{ prop.title }}
</h6>
<small>{{ formatType(prop.contents['@type']) }} {{ formatEnding(prop.voting_end_time) }}</small>
</b-media-body>
</b-media>
</b-link>
<div v-if="proposals.length === 0">
</b-link>
</b-media>
<div v-if="proprosals2.length === 0">
No active proposal!
<b-link :to="`./${chain}/gov`">
Browse all
@ -195,6 +196,114 @@
/>
</b-col>
</b-row>
<b-row v-if="stakingList && stakingList.length > 0">
<b-col>
<b-table
:items="stakingList"
:fields="fields"
>
<template #cell(action)="data">
<!-- size -->
<b-button-group
size="sm"
>
<b-button
v-b-modal.operation-modal
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
v-b-tooltip.hover.top="'Delegate'"
variant="outline-primary"
@click="selectDelegation(data,'Delegate')"
>
<feather-icon icon="LogInIcon" />
</b-button>
<b-button
v-b-modal.operation-modal
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
v-b-tooltip.hover.top="'Redelegate'"
variant="outline-primary"
@click="selectDelegation(data,'Redelegate')"
>
<feather-icon icon="ShuffleIcon" />
</b-button>
<b-button
v-b-modal.operation-modal
v-ripple.400="'rgba(113, 102, 240, 0.15)'"
v-b-tooltip.hover.top="'Unbond'"
variant="outline-primary"
@click="selectDelegation(data,'Unbond')"
>
<feather-icon icon="LogOutIcon" />
</b-button>
</b-button-group>
</template>
</b-table>
</b-col>
</b-row>
<b-row v-if="unbonding && unbonding.length > 0">
<b-col>
<b-card>
<b-card-header class="pt-0 pl-0 pr-0">
<b-card-title>Unbonding Tokens</b-card-title>
</b-card-header>
<b-card-body class="pl-0 pr-0">
<b-row
v-for="item in unbonding"
:key="item.validator_address"
>
<b-col cols="12">
<span class="font-weight-bolder">From: <router-link :to="`../staking/${item.validator_address}`">{{ item.validator_address }}</router-link></span>
</b-col>
<b-col cols="12">
<b-table
:items="item.entries"
class="mt-1"
striped
hover
responsive="sm"
stacked="sm"
>
<template #cell(completion_time)="data">
{{ formatDate(data.item.completion_time) }}
</template>
<template #cell(initial_balance)="data">
{{ data.item.initial_balance }}{{ stakingParameters.bond_denom }}
</template>
<template #cell(balance)="data">
{{ data.item.balance }}{{ stakingParameters.bond_denom }}
</template>
</b-table>
</b-col>
</b-row>
</b-card-body>
</b-card>
</b-col>
</b-row>
<b-row class="mt-1">
<b-col cols="6">
<b-button
v-b-modal.operation-modal
block
variant="success"
@click="selectSend()"
>
<feather-icon icon="SendIcon" />
Send
</b-button>
</b-col>
<b-col cols="6">
<b-button
block
variant="info"
:to="`${chain}/account/${address}/receive`"
>
<feather-icon
icon="PlusCircleIcon"
/>
receive
</b-button>
</b-col>
</b-row>
</b-card>
<router-link to="/wallet/import">
<b-card class="addzone text-center">
@ -202,25 +311,39 @@
Connect Wallet
</b-card>
</router-link>
<operation-modal
:address="address"
:validator-address="selectedValidator"
:type="operationModalType"
:proposal-id="selectedProposalId"
:proposal-title="selectedTitle"
/>
</div>
</template>
<script>
import {
BRow, BCol, BAlert, BCard, BTable, BFormCheckbox, BCardHeader, BCardTitle, BMedia, BMediaAside, BMediaBody, BAvatar,
BCardBody, BLink,
BCardBody, BLink, BButtonGroup, BButton, BTooltip, VBModal, VBTooltip,
} from 'bootstrap-vue'
import {
formatNumber, formatTokenAmount, isToken, percent, timeIn, toDay, toDuration, tokenFormatter, getLocalAccounts,
getStakingValidatorOperator,
} from '@/libs/utils'
import OperationModal from '@/views/components/OperationModal/index.vue'
import Ripple from 'vue-ripple-directive'
import ParametersModuleComponent from './components/parameters/ParametersModuleComponent.vue'
import DashboardCardHorizontal from './components/dashboard/DashboardCardHorizontal.vue'
import DashboardCardVertical from './components/dashboard/DashboardCardVertical.vue'
import DashboardPriceChart2 from './components/dashboard/DashboardPriceChart2.vue'
import FeatherIcon from '../@core/components/feather-icon/FeatherIcon.vue'
export default {
components: {
BAvatar,
BButtonGroup,
BTooltip,
BButton,
BRow,
BCol,
BAlert,
@ -235,13 +358,24 @@ export default {
BCardBody,
BLink,
OperationModal,
ParametersModuleComponent,
DashboardCardHorizontal,
DashboardPriceChart2,
DashboardCardVertical,
FeatherIcon,
},
directives: {
'b-modal': VBModal,
'b-tooltip': VBTooltip,
Ripple,
},
data() {
return {
fields: ['validator', 'delegation', 'rewards', 'action'],
delegations: [],
rewards: [],
unbonding: [],
chain: this.$store.state.chains.selected.chain_name,
syncing: false,
latestTime: '',
@ -254,12 +388,24 @@ export default {
ratio: '-',
inflation: '-',
proposals: [],
myVotes: {},
selectedValidator: '',
selectedProposalId: 0,
selectedTitle: '',
operationModalType: '',
voteColors: {
YES: 'success',
NO: 'warning',
ABSTAIN: 'info',
NO_WITH_VETO: 'danger',
},
walletBalances: '-',
walletStaking: '-',
walletRewards: '-',
walletUnbonding: '-',
address: null,
}
},
computed: {
@ -277,8 +423,26 @@ export default {
}
return key || 'Wallet'
},
proprosals2() {
return this.proposals
},
stakingList() {
return this.delegations.map(x => {
const rewards = this.rewards.find(r => r.validator_address === x.delegation.validator_address)
return {
valAddress: x.delegation.validator_address,
validator: getStakingValidatorOperator(this.$store.state.chains.selected.chain_name, x.delegation.validator_address),
delegation: this.formatToken([x.balance]),
rewards: rewards ? this.formatToken(rewards.reward) : '',
action: '',
}
})
},
},
created() {
this.$http.getGovernanceListByStatus(2).then(res => {
this.proposals = res.proposals
})
this.$http.getLatestBlock().then(res => {
this.height = res.block.header.height
if (timeIn(res.block.header.time, 3, 'm')) {
@ -313,12 +477,20 @@ export default {
this.inflation = '-'
})
}
this.$http.getGovernanceListByStatus(2).then(res => {
this.proposals = res.proposals
})
},
methods: {
selectProposal(modal, pid, title) {
this.operationModalType = modal
this.selectedProposalId = Number(pid)
this.selectedTitle = title
},
selectDelegation(v, type) {
this.selectedValidator = v.item.valAddress
this.operationModalType = type
},
selectSend() {
this.operationModalType = 'Transfer'
},
formatToken(tokens) {
if (Array.isArray(tokens)) {
let nativeToken = tokens.filter(x => x.denom.length < 11)
@ -345,10 +517,12 @@ export default {
this.walletBalances = this.formatToken(bal)
})
this.$http.getStakingReward(address).then(res => {
this.rewards = res.rewards
this.walletRewards = this.formatToken(res.rewards.map(x => x.reward).flat())
})
this.$http.getStakingDelegations(address).then(res => {
const delegations = res.delegation_responses || res
this.delegations = delegations
this.walletStaking = this.formatToken(delegations.map(x => x.balance).flat())
})
this.$http.getStakingUnbonding(address).then(res => {
@ -357,6 +531,7 @@ export default {
const newTokens = []
const denom = token.base
const unbonding = res.unbonding_responses || res
this.unbonding = unbonding
unbonding.forEach(x => {
x.entries.forEach(y => {
newTokens.push({
@ -370,6 +545,19 @@ export default {
}
}
})
this.proposals.forEach(x => {
this.$http.getGovernanceProposalVote(x.id, address, null)
.then(v => {
console.log(v)
this.myVotes[x.id] = this.formatVoteOption(v.vote.option)
})
.catch(() => {
this.myVotes[x.id] = null
})
})
},
formatVoteOption(v) {
return v.replaceAll('VOTE_OPTION_', '')
},
formatEnding(v) {
return toDay(v, 'from')

View File

@ -0,0 +1,103 @@
<template>
<div class="d-flex justify-content-center">
<b-card>
<b-card-header class="d-flex justify-content-center">
<h2>Pay Me</h2>
</b-card-header>
<b-card-body class="d-flex justify-content-center flex-column">
<vue-qr :text="address" />
<div>
{{ address }}
<feather-icon
icon="CopyIcon"
size="12"
@click="copy()"
/>
</div>
<b-button
v-b-modal.operation-modal
block
variant="success"
class="mt-2"
>
<feather-icon icon="SendIcon" />
Go To Pay
</b-button>
</b-card-body>
</b-card>
<operation-modal
:address="fromAddress"
:to-address="address"
type="Transfer"
/>
</div>
</template>
<script>
import VueQr from 'vue-qr'
import {
BCard, BCardHeader, BCardBody, BFormInput, BButton,
} from 'bootstrap-vue'
import OperationModal from '@/views/components/OperationModal/index.vue'
import { getLocalAccounts } from '@/libs/utils'
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
export default {
components: {
BButton,
BCard,
BCardHeader,
BCardBody,
BFormInput,
VueQr,
OperationModal,
},
data() {
const { address } = this.$route.params
return {
address,
}
},
computed: {
fromAddress() {
const key = this.$store?.state?.chains?.defaultWallet
if (key) {
const accounts = getLocalAccounts() || {}
const account = Object.entries(accounts)
.map(v => ({ wallet: v[0], address: v[1].address.find(x => x.chain === this.$store.state.chains.selected.chain_name) }))
.filter(v => v.address)
.find(x => x.wallet === key)
if (account) {
return account.address.addr
}
}
return null
},
},
methods: {
copy() {
this.$copyText(this.address).then(() => {
this.$toast({
component: ToastificationContent,
props: {
title: 'Address copied',
icon: 'BellIcon',
},
})
}, e => {
this.$toast({
component: ToastificationContent,
props: {
title: `Failed to copy address! ${e}`,
icon: 'BellIcon',
variant: 'danger',
},
})
})
},
},
}
</script>

View File

@ -134,6 +134,10 @@ export default {
type: String,
default: '',
},
toAddress: {
type: String,
default: '',
},
balance: {
type: Array,
default: () => [],
@ -145,7 +149,7 @@ export default {
currencySign: getUserCurrencySign(),
token: '',
amount: null,
recipient: '',
recipient: this.toAddress,
required,
password,
email,

View File

@ -47,6 +47,7 @@
:balance="balance"
:proposal-id="proposalId"
:proposal-title="proposalTitle"
:to-address="toAddress"
@update="componentUpdate"
/>
<b-row v-if="advance">
@ -263,6 +264,10 @@ export default {
type: String,
default: null,
},
toAddress: {
type: String,
default: null,
},
},
data() {
return {

View File

@ -3,7 +3,7 @@
<b-card-body class="d-flex justify-content-between align-items-center">
<div class="truncate">
<h4 class="mb-25 font-weight-bolder">
{{ statistic }}
{{ statistic || '-' }}
</h4>
<span>{{ statisticTitle }}</span>
</div>