Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a new flow allowing to delegate to many nodes in a row #115

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/components/misc/ValidatorList/ValidatorRow.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<tr class="validator_row">
<tr :class="[!isSelected ? 'validator_row unselected' : 'validator_row selected']">
<td class="id">{{ validator.nodeID }}</td>
<td class="amount">{{ amtText }}</td>
<td class="amount">{{ remainingAmtText }}</td>
Expand All @@ -8,7 +8,9 @@
<td>{{ uptimeText }}</td>
<td>{{ feeText }}%</td>
<td>
<button class="button_secondary" @click="select">Select</button>
<button class="button_secondary" @click="select">
{{ !isSelected ? ' Select ' : 'Unselected' }}
</button>
</td>
</tr>
</template>
Expand All @@ -26,6 +28,7 @@ import { ValidatorListItem } from '@/store/modules/platform/types'
@Component
export default class ValidatorsList extends Vue {
@Prop() validator!: ValidatorListItem
isSelected: boolean = false

get remainingMs(): number {
let end = this.validator.endTime
Expand Down Expand Up @@ -113,6 +116,7 @@ export default class ValidatorsList extends Vue {

select() {
this.$emit('select', this.validator)
this.isSelected = !this.isSelected
}
}
</script>
Expand All @@ -133,13 +137,21 @@ button {
.id {
word-break: break-all;
}

td {
padding: 4px 14px;
background-color: var(--bg-light);
border: 1px solid var(--bg);
font-size: 13px;
}

.selected {
background-color: var(--success);
}

.unselected {
background-color: var(--bg-light);
}

@include main.medium-device {
td {
font-size: 10px !important;
Expand Down
173 changes: 143 additions & 30 deletions src/components/wallet/earn/Delegate/AddDelegator.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
<template>
<div class="add_delegator">
<NodeSelection v-if="!selected" @select="onselect" class="node_selection"></NodeSelection>
<NodeSelection v-if="!hasSelectedNode" @finish="onfinish"></NodeSelection>
<div class="cols" v-else>
<div class="node_col">
<button @click="selected = null" class="close_but button_secondary">
<fa icon="sync"></fa>
Change Node
</button>
<NodeCard :node="selected"></NodeCard>
<div class="card_headers">
<button @click="selected = []" class="close_but button_secondary">
<fa icon="sync"></fa>
Change Node
</button>
<div class="card_navigator">
<button @click="selectPreviousNode" style="margin-right: 3px">
<fa icon="arrow-left"></fa>
</button>
{{ index + 1 }}/{{ selected.length }}
<button @click="selectNextNode" style="margin-left: 3px">
<fa icon="arrow-right"></fa>
</button>
</div>
</div>
<NodeCard :node="selectedNode"></NodeCard>
</div>
<transition-group name="fade" mode="out-in">
<div class="ins_col" key="form" v-show="!isConfirm">
Expand Down Expand Up @@ -186,9 +197,26 @@
<label>{{ $t('earn.delegate.success.reason') }}</label>
<p>{{ txReason }}</p>
</div>
<v-btn @click="cancel" block class="button_secondary" depressed v-if="txStatus">
Back to Earn
</v-btn>
<div v-if="txStatus">
<v-btn
v-if="!hasNextSelectedNode"
@click="cancel"
block
class="button_secondary"
depressed
>
Back to Earn
</v-btn>
<v-btn
v-if="hasNextSelectedNode"
@click="resetAndSelectNextNode"
block
class="button_secondary"
depressed
>
Delegate Next
</v-btn>
</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -224,6 +252,7 @@ import { WalletType } from '@/js/wallets/types'
import UtxoSelectForm from '@/components/wallet/earn/UtxoSelectForm.vue'
import Expandable from '@/components/misc/Expandable.vue'
import NodeCard from '@/components/wallet/earn/Delegate/NodeCard.vue'
import { HdWalletCore } from '@/js/wallets/HdWalletCore'

const MIN_MS = 60000
const HOUR_MS = MIN_MS * 60
Expand All @@ -247,12 +276,12 @@ const DAY_MS = HOUR_MS * 24
})
export default class AddDelegator extends Vue {
search: string = ''
selected: ValidatorListItem | null = null
selected: ValidatorListItem[] = []
stakeAmt: BN = new BN(0)
startDate: string = new Date(Date.now() + MIN_MS * 15).toISOString()
endDate: string = new Date().toISOString()
rewardIn: string = ''
rewardDestination = 'local' // local || custom
rewardDestination: 'local' | 'custom' = 'local' // local || custom
err: string = ''
isLoading = false
isConfirm = false
Expand All @@ -268,6 +297,7 @@ export default class AddDelegator extends Vue {
formRewardAddr = ''

currency_type = 'AVAX'
index = 0

mounted() {
this.rewardSelect('local')
Expand All @@ -276,9 +306,12 @@ export default class AddDelegator extends Vue {
this.endDate = val
}

onselect(val: ValidatorListItem) {
onfinish(vals: ValidatorListItem[]) {
if (!vals) return
if (vals.length <= 0) return
this.search = ''
this.selected = val
this.index = 0
this.selected = vals
}

async submit() {
Expand All @@ -304,6 +337,12 @@ export default class AddDelegator extends Vue {
this.formRewardAddr,
this.formUtxos
)
// increases security and privacy by guaranteeing that
// P-CHAIN address will be regenerated according to BIP32
if (wallet instanceof HdWalletCore) {
await wallet.platformHelper.findHdIndex()
wallet.updateAvmUTXOSet()
}
this.isSuccess = true
this.txId = txId
this.updateTxStatus(txId)
Expand All @@ -321,7 +360,7 @@ export default class AddDelegator extends Vue {
})

// Update History
setTimeout(() => {
setTimeout(async () => {
this.$store.dispatch('Assets/updateUTXOs')
this.$store.dispatch('History/updateTransactionHistory')
}, 3000)
Expand Down Expand Up @@ -372,6 +411,54 @@ export default class AddDelegator extends Vue {
})
}

get selectedNode(): ValidatorListItem {
return this.selected[this.index]
}

get hasSelectedNode(): boolean {
return this.selected.length > 0
}

get hasNextSelectedNode(): boolean {
return this.selected.length > this.index + 1
}

get hasPreviousSelectedNode(): boolean {
return this.index >= 0 && this.hasSelectedNode
}

reset() {
this.isLoading = false
this.isConfirm = false
this.isSuccess = false
this.txId = ''
this.txStatus = ''
this.txReason = null

this.formNodeID = ''
this.formUtxos = []
this.formAmt = new BN(0)
this.formEnd = new Date()
this.rewardSelect(this.rewardDestination)
}

selectNextNode() {
if (!this.hasNextSelectedNode) return
this.index++
}

resetAndSelectNextNode() {
if (!this.hasSelectedNode) return
if (!this.hasNextSelectedNode) return
this.reset()
this.selectNextNode()
}

selectPreviousNode() {
if (!this.hasPreviousSelectedNode) return
this.index--
}

get estimatedReward(): Big {
let start = new Date(this.startDate)
let end = new Date(this.endDate)
Expand Down Expand Up @@ -409,7 +496,7 @@ export default class AddDelegator extends Vue {
formCheck(): boolean {
this.err = ''

if (!this.selected) {
if (!this.hasSelectedNode) {
this.err = this.$t('earn.delegate.errs.no_node') as string
// this.err = "You must specify a validator."
return false
Expand All @@ -436,7 +523,7 @@ export default class AddDelegator extends Vue {
return false
}

let validatorEndtime = this.selected.endTime.getTime()
let validatorEndtime = this.selectedNode.endTime.getTime()

if (endTime > validatorEndtime) {
this.err = this.$t('earn.delegate.errs.val_end') as string
Expand Down Expand Up @@ -469,7 +556,7 @@ export default class AddDelegator extends Vue {
}

updateFormData() {
this.formNodeID = this.selected!.nodeID
this.formNodeID = this.selectedNode.nodeID
this.formAmt = this.stakeAmt
this.formEnd = new Date(this.endDate)
this.formRewardAddr = this.rewardIn
Expand All @@ -494,9 +581,9 @@ export default class AddDelegator extends Vue {

// Maximum end date is end of validator's staking duration
get endMaxDate(): string | undefined {
if (!this.selected) return undefined
if (!this.hasSelectedNode) return undefined

return this.selected.endTime.toISOString()
return this.selectedNode.endTime.toISOString()
}

get stakingDuration(): number {
Expand All @@ -519,8 +606,8 @@ export default class AddDelegator extends Vue {
}

get delegationFee(): number {
if (!this.selected) return 0
return this.selected.fee
if (!this.hasSelectedNode) return 0
return this.selectedNode.fee
}

get totalFee(): BN {
Expand Down Expand Up @@ -559,12 +646,12 @@ export default class AddDelegator extends Vue {
}

get remainingAmt(): BN {
if (!this.selected) return new BN(0)
if (!this.hasSelectedNode) return new BN(0)
// let totDel: BN = this.$store.getters["Platform/validatorTotalDelegated"](this.selected.nodeID);
let nodeMaxStake: BN = this.$store.getters['Platform/validatorMaxStake'](this.selected)
let nodeMaxStake: BN = this.$store.getters['Platform/validatorMaxStake'](this.selectedNode)

let totDel = this.selected.delegatedStake
let valAmt = this.selected.validatorStake
let totDel = this.selectedNode.delegatedStake
let valAmt = this.selectedNode.validatorStake
return nodeMaxStake.sub(totDel).sub(valAmt)
}

Expand Down Expand Up @@ -627,10 +714,6 @@ export default class AddDelegator extends Vue {
height: 100%;
}

.node_selection {
height: 100%;
}

.cols {
display: grid;
grid-template-columns: max-content 1fr 340px;
Expand Down Expand Up @@ -724,6 +807,20 @@ label {
/* width: 100%;*/
/*}*/

.card_headers {
display: flex;
justify-content: space-between;
}

.card_navigator {
background-color: var(--secondary-color);
color: var(--bg);
padding: 2px 14px;
font-size: 13px;
border-radius: 6px;
margin-bottom: 14px;
}

.reward_in {
width: 100%;
transition-duration: 0.2s;
Expand Down Expand Up @@ -864,12 +961,28 @@ label {
}

.close_but {
width: 100%;
width: 40%;
padding: 12px;
}

.node_col {
margin-bottom: 24px;
}

.card_navigator {
background-color: var(--secondary-color);
color: var(--bg);
padding: 12px;
font-size: 100%;
border-radius: 6px;
margin-bottom: 14px;
justify-content: space-between;
text-align: center;
width: 40%;
button {
padding-left: 12px;
padding-right: 12px;
}
}
}
</style>
Loading