-
Notifications
You must be signed in to change notification settings - Fork 100
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
Hooking up bonding/unbonding to wallet #257
Changes from 21 commits
e7277a7
4289045
06d84eb
b1b1a2a
c8bded2
67d101f
eb41ea5
f311d86
8b74c7b
6932cbd
77a596d
bfe4c81
375aaf0
abb84de
8937174
aee6ff0
98fa544
b27228c
cff1e3f
467b007
c9d32bb
bfba1d3
3ca302e
d27b7c8
1101f65
c128d74
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,28 +5,30 @@ page.page-bond(title="Bond Atoms") | |
i.material-icons arrow_back | ||
.label Back | ||
|
||
.reserved-atoms(v-if="unbondedAtoms == this.user.atoms") | ||
| You have #[.reserved-atoms__number {{ unbondedAtoms }}] unbonded atoms. Start by bonding some of your atoms to these delegates. | ||
.reserved-atoms(v-else-if="unbondedAtoms === 0") | ||
| You are bonding #[.reserved-atoms__number ALL {{ bondedAtoms }}] atoms to these delegates. We suggest reserving some atoms for personal use—are you sure you wish to proceed? #[a(@click="resetAlloc") (start over?)] | ||
.reserved-atoms(v-else-if="unbondedAtoms < 0") | ||
| #[.reserved-atoms__number.reserved-atoms__number--error You are bonding {{ unbondedAtoms * -1 }} more atoms than exist in your balance.] Please reduce the number of atoms you are bonding to these delegates. #[a(@click="resetAlloc") (start over?)] | ||
.reserved-atoms(v-else) | ||
| You are reserving #[.reserved-atoms__number {{ unbondedAtoms }}] ({{ unbondedAtomsPct }}) atoms. You are bonding #[.reserved-atoms__number {{ bondedAtoms }}] ({{ bondedAtomsPct }}) atoms to these delegates. #[a(@click="resetAlloc") (start over?)] | ||
.reserved-atoms | ||
span(v-if="unbondedAtoms == totalAtoms") | ||
span.reserved-atoms--warning(v-else-if="unbondedAtoms === 0") | ||
| You're trying to bond #[.reserved-atoms__number ALL {{ bondedAtoms }}] atoms to these delegates. We suggest reserving some atoms for personal use — are you sure you wish to proceed? | ||
span.reserved-atoms--error(v-else-if="unbondedAtoms < 0") | ||
| You're trying to bond #[.reserved-atoms__number {{ unbondedAtoms * -1 }}] more atoms than you have. | ||
span(v-else) | ||
| You are bonding #[.reserved-atoms__number {{ bondedAtoms }}] ({{ bondedAtomsPct }}) atoms to these delegates. You will keep #[.reserved-atoms__number {{ unbondedAtoms }}] ({{ unbondedAtomsPct }}) atoms in your wallet. | ||
span(v-if="willUnbondAtoms > 0") | ||
| You will begin unbonding #[.reserved-atoms__number {{ willUnbondAtoms }}] atoms, which will be available in 30 days. | ||
span | ||
| #[a.reserved-atoms__restart(@click="resetAlloc") (start over?)] | ||
|
||
form-struct(:submit="onSubmit") | ||
form-group(v-for='(delegate, index) in fields.delegates' key='delegate.id' | ||
:error="$v.fields.delegates.$each[index].$error") | ||
Label {{ shortenLabel(delegate.delegate.id, 20) }} ({{ percentAtoms(delegate.atoms) }}) | ||
Label {{ shortenLabel(delegate.delegate.description.moniker, 10) }} - {{ shortenLabel(delegate.delegate.id, 20) }} ({{ percentAtoms(delegate.atoms) }}) | ||
field-group | ||
field( | ||
type="number" | ||
step="any" | ||
placeholder="Atoms" | ||
v-model.number="delegate.atoms") | ||
field-addon Atoms | ||
// btn(type="button" value="Max" | ||
@click.native="fillAtoms(delegate.id)") | ||
field-addon Atoms | ||
btn(type="button" icon="clear" @click.native="rm(delegate.id)") | ||
form-msg(name="Atoms" type="required" | ||
v-if="!$v.fields.delegates.$each[index].atoms.required") | ||
|
@@ -66,65 +68,51 @@ export default { | |
ToolBar | ||
}, | ||
computed: { | ||
...mapGetters(['shoppingCart', 'user']), | ||
reservedAtoms () { | ||
return this.shoppingCart.reduce((sum, d) => sum + (d.reservedAtoms || 0), 0) | ||
...mapGetters(['shoppingCart', 'user', 'committedDelegations']), | ||
previouslyBondedAtoms () { | ||
return Object.values(this.committedDelegations).reduce((sum, d) => sum + d, 0) | ||
}, | ||
unreservedAtoms () { | ||
return this.user.atoms - this.reservedAtoms | ||
willUnbondAtoms () { | ||
let sum = 0 | ||
for (let id of Object.keys(this.committedDelegations)) { | ||
let committed = this.committedDelegations[id] | ||
let delegate = this.fields.delegates.find(c => c.id === id) | ||
let willBond = delegate ? delegate.atoms : 0 | ||
let unbondAmount = Math.max(committed - willBond, 0) | ||
sum += unbondAmount | ||
} | ||
return sum | ||
}, | ||
unbondedAtoms () { | ||
let value = this.unreservedAtoms | ||
|
||
// reduce unreserved atoms by bonded atoms | ||
this.fields.delegates.forEach(f => (value -= f.atoms)) | ||
|
||
return value | ||
let willBondSum = this.bondedAtoms | ||
let bondedSum = this.previouslyBondedAtoms | ||
return this.user.atoms - willBondSum + bondedSum - this.willUnbondAtoms | ||
}, | ||
unbondedAtomsPct () { | ||
return Math.round(this.unbondedAtoms / this.user.atoms * 100 * 100) / 100 + '%' | ||
return Math.round(this.unbondedAtoms / this.totalAtoms * 100 * 10) / 10 + '%' | ||
}, | ||
bondedAtoms () { | ||
let value = 0 | ||
this.fields.delegates.forEach(f => (value += f.atoms)) | ||
return value | ||
return this.fields.delegates.reduce((sum, d) => sum + (d.atoms || 0), 0) | ||
}, | ||
bondedAtomsPct () { | ||
return Math.round(this.bondedAtoms / this.user.atoms * 100 * 100) / 100 + '%' | ||
return Math.round(this.bondedAtoms / this.totalAtoms * 100 * 10) / 10 + '%' | ||
}, | ||
totalAtoms () { | ||
return this.bondedAtoms + this.unbondedAtoms | ||
} | ||
}, | ||
data: () => ({ | ||
equalize: false, | ||
atomsMin: 1, | ||
reservedAtomsMin: 0, | ||
atomsMin: 0, | ||
fields: { | ||
reservedAtoms: 0, | ||
delegates: [] | ||
} | ||
}), | ||
methods: { | ||
fillAtoms (delegateId) { | ||
if (delegateId === 'unreserved') { | ||
this.fields.reservedAtoms += this.unbondedAtoms | ||
} else { | ||
let delegate = this.fields.delegates.find(c => c.id === delegateId) | ||
delegate.atoms += this.unbondedAtoms | ||
} | ||
}, | ||
clearAtoms (delegateId) { | ||
if (delegateId === 'unreserved') { | ||
console.log('clearing reserved atoms') | ||
this.fields.reservedAtoms = 0 | ||
} else { | ||
console.log('clearing atoms for', delegateId) | ||
let delegate = this.fields.delegates.find(c => c.delegateId === delegateId) | ||
delegate.atoms = 0 | ||
} | ||
}, | ||
equalAlloc () { | ||
this.equalize = true | ||
this.resetAlloc() | ||
let atoms = this.unreservedAtoms | ||
let atoms = this.unbondedAtoms | ||
let delegates = this.fields.delegates.length | ||
let remainderAtoms = atoms % delegates | ||
|
||
|
@@ -144,11 +132,7 @@ export default { | |
return Math.round(bondedAtoms / this.user.atoms * 100 * 100) / 100 + '%' | ||
}, | ||
async onSubmit () { | ||
if (this.unbondedAtoms === this.user.atoms) { | ||
this.$store.commit('notifyError', { title: 'Unbonded Delegates', | ||
body: 'You either haven\'t bonded any atoms yet, or some delegates have 0 atoms bonded.' }) | ||
return | ||
} else if (this.unbondedAtoms < 0) { | ||
if (this.unbondedAtoms < 0) { | ||
this.$store.commit('notifyError', { title: 'Too Many Allocated Atoms', | ||
body: `You've bonded ${this.unbondedAtoms * -1} more atoms than you have.`}) | ||
return | ||
|
@@ -159,7 +143,7 @@ export default { | |
try { | ||
await this.$store.dispatch('submitDelegation', this.fields) | ||
this.$store.commit('notify', { title: 'Atoms Bonded', | ||
body: 'You have successfully bonded your atoms. You can rebond after the 30 day unbonding period.' }) | ||
body: 'You have successfully updated your delegations.' }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "delegated your atoms"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I figured it might be weird if you only unbond and then see "you have bonded your atoms". What do you think? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh i see! ok. makes sense. forget what i recommended. |
||
} catch (err) { | ||
this.$store.commit('notifyError', { title: 'Error While Bonding Atoms', | ||
body: err.message }) | ||
|
@@ -205,13 +189,6 @@ export default { | |
}, | ||
validations: () => ({ | ||
fields: { | ||
reservedAtoms: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i like that we're getting rid of the concept of "reserved" 👍 |
||
required, | ||
numeric, | ||
between (atoms) { | ||
return between(this.reservedAtomsMin, this.user.atoms)(atoms) | ||
} | ||
}, | ||
delegates: { | ||
$each: { | ||
atoms: { | ||
|
@@ -237,11 +214,17 @@ export default { | |
margin 0 0 1rem | ||
color dim | ||
|
||
.reserved-atoms__number | ||
display inline | ||
color bright | ||
font-weight 500 | ||
&__number | ||
display inline | ||
color bright | ||
font-weight 500 | ||
|
||
&__restart | ||
cursor pointer | ||
|
||
&--error | ||
color danger | ||
|
||
.reserved-atoms__number--error | ||
color danger | ||
&--warning | ||
color warning | ||
</style> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ page(:title='pageTitle') | |
a(@click='setSearch(true)') | ||
i.material-icons search | ||
.label Search | ||
a(@click='updateDelegates()') | ||
a(@click='updateDelegates(address)') | ||
i.material-icons refresh | ||
.label Refresh | ||
router-link(v-if="config.devMode" to='/staking/bond') | ||
|
@@ -69,15 +69,14 @@ export default { | |
data: () => ({ | ||
query: '', | ||
sort: { | ||
property: 'id', | ||
order: 'asc', | ||
property: 'shares', | ||
order: 'desc', | ||
properties: [ | ||
// { id: 1, title: 'Keybase ID', value: 'keybaseID', initial: true }, | ||
{ id: 1, title: 'Public Key', value: 'id', initial: true }, | ||
{ id: 2, title: 'Country', value: 'country' }, | ||
{ id: 3, title: 'Voting Power', value: 'voting_power' }, | ||
{ id: 4, title: 'Bonded Power', value: 'shares' }, | ||
{ id: 5, title: 'Commission', value: 'commission' } | ||
{ id: 1, title: 'Name', value: 'description.moniker' }, | ||
{ id: 2, title: 'Public Key', value: 'id' }, | ||
{ id: 3, title: 'Voting Power', value: 'shares', initial: true }, | ||
{ id: 4, title: 'Bonded Atoms', value: 'voting_power' }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not...?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes more sense to call the percentage of power "Voting Power", since that's how it's been referred to outside of the code. And what's called 'voting_power' in the code isn't necessarily voting power, it's more accurate to refer to it as the number of bonded tokens. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
is percentage of power === voting power OR bonded atoms?
😕 why not? i'm probably just misunderstanding something... |
||
{ id: 5, title: 'Bonded by You', value: 'bonded' } | ||
] | ||
} | ||
}), | ||
|
@@ -96,6 +95,7 @@ export default { | |
mounted () { | ||
Mousetrap.bind(['command+f', 'ctrl+f'], () => this.setSearch(true)) | ||
Mousetrap.bind('esc', () => this.setSearch(false)) | ||
this.updateDelegates(this.user.address) | ||
} | ||
} | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,8 @@ export const connected = state => state.node.connected | |
export const lastHeader = state => state.node.lastHeader | ||
|
||
export const delegates = state => state.delegates | ||
export const shoppingCart = state => state.shoppingCart.delegates | ||
export const shoppingCart = state => state.delegation.delegates | ||
export const committedDelegations = state => state.delegation.committedDelegates | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how does
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's actually the right name, called it |
||
export const user = state => state.user | ||
export const config = state => state.config | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,8 @@ export default ({ commit, basecoin }) => { | |
activeMenu: '', | ||
desktop: false, | ||
devMode: process.env.PREVIEW !== undefined ? JSON.parse(process.env.PREVIEW) : process.env.NODE_ENV === 'development', | ||
// TODO: change to atom | ||
bondingDenom: 'fermion', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we check which network we're using to determine this instead of using a TODO? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be ideal, but I'm not sure of a good heuristic for checking if a network is a testnet (and I'm not sure what the mainnet will be called in the code). We can do this once we have our first mainnet and need the bonding denom to be 'atom' |
||
modals: { | ||
help: { | ||
active: false | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"You've tried to bond {x} more atoms than you have"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍