diff --git a/app/src/main/mockServer.js b/app/src/main/mockServer.js
index a0f4a2c166..95f9d4dd97 100644
--- a/app/src/main/mockServer.js
+++ b/app/src/main/mockServer.js
@@ -3,11 +3,6 @@ let proxy = require('express-http-proxy')
let randomBytes = require('crypto').pseudoRandomBytes
let casual = require('casual')
-let randomPubkey = () => ({
- type: 'ed25519',
- data: randomBytes(32).toString('hex')
-})
-
let randomAddress = () => randomBytes(20).toString('hex')
let randomTime = () => Date.now() - casual.integer(0, 32e7)
@@ -23,24 +18,6 @@ let randomBondTx = (address, delegator) => ({
height: 1000
})
-let randomCandidate = () => ({
- address: randomAddress(),
- owner: randomAddress(), // address
- shares: casual.integer(1000, 1e7),
- votingPower: casual.integer(10, 1e5),
- since: casual.date('YYYY-MM-DD'),
- description: {
- name: casual.username,
- website: casual.url,
- details: casual.sentences(3)
- },
- commissionRate: casual.double(0.005, 0.05),
- commissionMax: casual.double(0.05, 0.25),
- status: [ 'active', 'bonding', 'unbonding' ][Math.floor(Math.random() * 3)],
- slashRatio: Math.random() < 0.9 ? casual.double(0.01, 0.5) : 0,
- reDelegatingShares: casual.integer(1000, 1e7)
-})
-
module.exports = function (port = 8999) {
let app = express()
@@ -52,38 +29,6 @@ module.exports = function (port = 8999) {
// })
// delegation mock API
- let candidates = new Array(50).fill(0).map(randomPubkey)
- app.get('/query/stake/candidates', (req, res) => {
- res.json({
- height: 10000,
- data: candidates
- })
- })
- app.get('/query/stake/candidates/:pubkey', (req, res) => {
- res.json({
- height: 10000,
- data: {
- pubkey: randomPubkey(),
- owner: {
- chain: 'gaia-1',
- app: 'sig',
- address: randomBytes(20).toString('hex')
- },
- shares: Math.floor(Math.random() * 1e7),
- voting_power: Math.floor(Math.random() * 1e5),
- description: JSON.stringify({
- description: casual.sentences(3),
- commission: casual.double(0.005, 0.05),
- commissionMax: casual.double(0.05, 0.25),
- commissionMaxRate: casual.double(0.005, 0.05),
- url: casual.url,
- keybaseID: casual.username,
- country: casual.country,
- startDate: casual.date('YYYY-MM-DD')
- })
- }
- })
- })
app.post('/tx/stake/delegate/:pubkey/:amount', (req, res) => {
res.json({
'type': 'sigs/one',
@@ -150,9 +95,8 @@ module.exports = function (port = 8999) {
}
})
})
- app.get('/candidates', (req, res) => {
- res.json(new Array(200).fill(0).map(randomCandidate))
- })
+
+ // tx history
app.get('/tx/bondings/delegator/:address', (req, res) => {
let { address } = req.params
let txs = new Array(100).fill(0)
diff --git a/app/src/renderer/components/common/AppMenu.vue b/app/src/renderer/components/common/AppMenu.vue
index c6898820a4..bea41a16ae 100644
--- a/app/src/renderer/components/common/AppMenu.vue
+++ b/app/src/renderer/components/common/AppMenu.vue
@@ -7,7 +7,7 @@ menu.app-menu
list-item(to="/wallet/transactions" exact @click.native="close" title="Transactions")
part(title='Governance' v-if="config.devMode")
list-item(to="/proposals" exact @click.native="close" title="Proposals")
- part(title='Stake' v-if="config.devMode")
+ part(title='Stake')
list-item(to="/staking" exact @click.native="close" title="Delegates")
part(title='Monitor' v-if="config.devMode")
list-item(to="/blockchain" exact @click.native="close" title="Blockchain")
diff --git a/app/src/renderer/components/staking/LiDelegate.vue b/app/src/renderer/components/staking/LiDelegate.vue
index f0aa2f7d48..ca9b115d20 100644
--- a/app/src/renderer/components/staking/LiDelegate.vue
+++ b/app/src/renderer/components/staking/LiDelegate.vue
@@ -7,16 +7,18 @@ transition(name='ts-li-delegate'): div(:class='styles')
template
i.fa.fa-check-square-o(v-if='inCart' @click='rm(delegate)')
i.fa.fa-square-o(v-else @click='add(delegate)')
- router-link(:to="{ name: 'delegate', params: { delegate: delegate.id }}")
- | {{ delegate.keybaseID}}
- .value {{ delegate.country }}
+ router-link(v-if="config.devMode" :to="{ name: 'delegate', params: { delegate: delegate.id }}")
+ //- | {{ delegate.keybaseID ? delegate.keybaseID : 'n/a'}}
+ | {{ delegate.id }}
+ a(v-else) {{ delegate.id }}
+ .value {{ delegate.country ? delegate.country : 'n/a' }}
.value.voting_power.num.bar
span {{ num.prettyInt(delegate.voting_power) }}
.bar(:style='vpStyles')
.value.delegated.num.bar.delegated
span {{ num.prettyInt(delegate.shares) }}
.bar(:style='sharesStyles')
- .value {{ (delegate.commission * 100).toFixed(2) }}%
+ .value {{ delegate.commission ? (delegate.commission * 100).toFixed(2) + '%' : 'n/a' }}
menu
btn(theme='cosmos' v-if='inCart'
icon='delete' value='Remove' size='sm' @click.native='rm(delegate)')
@@ -36,7 +38,7 @@ export default {
Btn
},
computed: {
- ...mapGetters(['shoppingCart', 'delegates']),
+ ...mapGetters(['shoppingCart', 'delegates', 'config']),
styles () {
let value = 'li-delegate'
if (this.inCart) value += ' li-delegate-active '
diff --git a/app/src/renderer/components/staking/PageDelegates.vue b/app/src/renderer/components/staking/PageDelegates.vue
index 9106de6555..8e2fd07f28 100644
--- a/app/src/renderer/components/staking/PageDelegates.vue
+++ b/app/src/renderer/components/staking/PageDelegates.vue
@@ -4,11 +4,14 @@ page(:title='pageTitle')
a(@click='setSearch(true)')
i.material-icons search
.label Search
- router-link(to='/staking/bond')
+ a(@click='updateDelegates()')
+ i.material-icons refresh
+ .label Refresh
+ router-link(v-if="config.devMode" to='/staking/bond')
i.material-icons check_circle
.label Bond Atoms
modal-search(v-if="filters.delegates.search.visible" type="delegates")
- template(v-if="filteredDelegates.length > 0")
+ template(v-if="delegates.length > 0")
panel-sort(:sort='sort')
li-delegate(
v-for='i in filteredDelegates'
@@ -42,7 +45,7 @@ export default {
ToolBar
},
computed: {
- ...mapGetters(['delegates', 'filters', 'shoppingCart']),
+ ...mapGetters(['delegates', 'filters', 'shoppingCart', 'config']),
pageTitle () {
if (this.shoppingCart.length > 0) {
return `Delegates (${this.shoppingCart.length} Selected)`
@@ -54,7 +57,7 @@ export default {
let query = this.filters.delegates.search.query
let list = orderBy(this.delegates, [this.sort.property], [this.sort.order])
if (this.filters.delegates.search.visible) {
- return list.filter(i => includes(i.keybaseID.toLowerCase(), query.toLowerCase()))
+ return list.filter(i => includes(JSON.stringify(i).toLowerCase(), query.toLowerCase()))
} else {
return list
}
@@ -63,10 +66,11 @@ export default {
data: () => ({
query: '',
sort: {
- property: 'keybaseID',
+ property: 'id',
order: 'asc',
properties: [
- { id: 1, title: 'Keybase ID', value: 'keybaseID', initial: true },
+ // { 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: 'Delegated Power', value: 'shares' },
@@ -75,6 +79,7 @@ export default {
}
}),
methods: {
+ updateDelegates () { this.$store.dispatch('getDelegates') },
setSearch (bool) { this.$store.commit('setSearchVisible', ['delegates', bool]) }
},
mounted () {
diff --git a/app/src/renderer/vuex/modules/delegates.js b/app/src/renderer/vuex/modules/delegates.js
index d3c7963a95..5bc6a5bf53 100644
--- a/app/src/renderer/vuex/modules/delegates.js
+++ b/app/src/renderer/vuex/modules/delegates.js
@@ -1,17 +1,12 @@
-function pubkeyToString (pubkey) {
- // go-wire key encoding,
- // ed25519 keys prefixed w/ 01, secp256k1 w/ 02
- let type = pubkey.type === 'ed25519' ? '01' : '02'
- return type + pubkey.data
-}
+import axios from 'axios'
export default ({ dispatch, node }) => {
const state = []
const mutations = {
addDelegate (state, delegate) {
- delegate.id = pubkeyToString(delegate.pubkey)
- Object.assign(delegate, JSON.parse(delegate.description))
+ delegate.id = delegate.pub_key.data
+ Object.assign(delegate, delegate.description)
// return if we already have this delegate
for (let existingDelegate of state) {
@@ -30,7 +25,9 @@ export default ({ dispatch, node }) => {
}
},
async getDelegate ({ commit }, pubkey) {
- let delegate = (await node.candidate(pubkeyToString(pubkey))).data
+ let delegate = (await axios.get('http://localhost:8998/query/stake/candidate/' + pubkey.data)).data.data
+ // TODO move into cosmos-sdk
+ // let delegate = (await node.candidate(pubkeyToString(pubkey))).data
commit('addDelegate', delegate)
}
}
diff --git a/test/unit/specs/LiDelegate.spec.js b/test/unit/specs/LiDelegate.spec.js
index 79ccdc4f1c..15f8a6d863 100644
--- a/test/unit/specs/LiDelegate.spec.js
+++ b/test/unit/specs/LiDelegate.spec.js
@@ -15,7 +15,10 @@ describe('LiDelegate', () => {
store = new Vuex.Store({
getters: {
shoppingCart: () => shoppingCart.state.delegates,
- delegates: () => delegates.state
+ delegates: () => delegates.state,
+ config: () => ({
+ devMode: true
+ })
},
modules: {
shoppingCart,
@@ -24,26 +27,30 @@ describe('LiDelegate', () => {
})
store.commit('addDelegate', {
- pubkey: 'pubkeyX',
- description: JSON.stringify({
- id: 'idX',
+ pub_key: {
+ type: 'ed25519',
+ data: 'pubkeyX'
+ },
+ voting_power: 10000,
+ shares: 5000,
+ description: {
description: 'descriptionX',
- voting_power: 10000,
- shares: 5000,
keybaseID: 'keybaseX',
country: 'USA'
- })
+ }
})
store.commit('addDelegate', {
- pubkey: 'pubkeyY',
- description: JSON.stringify({
- id: 'idY',
+ pub_key: {
+ type: 'ed25519',
+ data: 'pubkeyY'
+ },
+ voting_power: 30000,
+ shares: 10000,
+ description: {
description: 'descriptionY',
- voting_power: 30000,
- shares: 10000,
keybaseID: 'keybaseY',
country: 'Canada'
- })
+ }
})
delegate = store.state.delegates[0]
diff --git a/test/unit/specs/PageDelegates.spec.js b/test/unit/specs/PageDelegates.spec.js
index 6215380e3b..ca97b7267c 100644
--- a/test/unit/specs/PageDelegates.spec.js
+++ b/test/unit/specs/PageDelegates.spec.js
@@ -17,7 +17,10 @@ describe('PageDelegates', () => {
getters: {
shoppingCart: () => shoppingCart.state.delegates,
delegates: () => delegates.state,
- filters: () => filters.state
+ filters: () => filters.state,
+ config: () => ({
+ devMode: true
+ })
},
modules: {
shoppingCart,
@@ -27,26 +30,30 @@ describe('PageDelegates', () => {
})
store.commit('addDelegate', {
- pubkey: 'pubkeyY',
- description: JSON.stringify({
- id: 'idY',
- description: 'descriptionY',
- voting_power: 30000,
- shares: 10000,
- keybaseID: 'keybaseY',
- country: 'Canada'
- })
- })
- store.commit('addDelegate', {
- pubkey: 'pubkeyX',
- description: JSON.stringify({
- id: 'idX',
+ pub_key: {
+ type: 'ed25519',
+ data: 'pubkeyX'
+ },
+ voting_power: 10000,
+ shares: 5000,
+ description: {
description: 'descriptionX',
- voting_power: 2000,
- shares: 5000,
keybaseID: 'keybaseX',
country: 'USA'
- })
+ }
+ })
+ store.commit('addDelegate', {
+ pub_key: {
+ type: 'ed25519',
+ data: 'pubkeyY'
+ },
+ voting_power: 30000,
+ shares: 10000,
+ description: {
+ description: 'descriptionY',
+ keybaseID: 'keybaseY',
+ country: 'Canada'
+ }
})
wrapper = mount(PageDelegates, {
@@ -58,6 +65,7 @@ describe('PageDelegates', () => {
})
jest.spyOn(store, 'commit')
+ jest.spyOn(store, 'dispatch')
})
it('has the expected html structure', () => {
@@ -69,19 +77,26 @@ describe('PageDelegates', () => {
expect(wrapper.contains('.ni-modal-search')).toBe(true)
})
+ it('should refresh candidates on click', () => {
+ wrapper.findAll('.ni-tool-bar i').at(1).trigger('click')
+ expect(store.dispatch).toHaveBeenCalledWith('getDelegates')
+ })
+
it('should sort the delegates by selected property', () => {
- expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['idX', 'idY'])
- wrapper.vm.sort = 'voting_power'
- expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['idY', 'idX'])
+ expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['pubkeyX', 'pubkeyY'])
+
+ wrapper.vm.sort.property = 'voting_power'
+ wrapper.vm.sort.order = 'desc'
+ expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['pubkeyY', 'pubkeyX'])
})
it('should filter the delegates', () => {
store.commit('setSearchVisible', ['delegates', true])
store.commit('setSearchQuery', ['delegates', 'baseX'])
- expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['idX'])
- expect(wrapper.html()).toMatchSnapshot()
+ expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['pubkeyX'])
+ expect(wrapper.vm.$el).toMatchSnapshot()
store.commit('setSearchQuery', ['delegates', 'baseY'])
- expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['idY'])
+ expect(wrapper.vm.filteredDelegates.map(x => x.id)).toEqual(['pubkeyY'])
})
it('should show the amount of selected delegates', () => {
@@ -96,7 +111,10 @@ describe('PageDelegates', () => {
getters: {
shoppingCart: () => shoppingCart.state,
delegates: () => [],
- filters: () => filters.state
+ filters: () => filters.state,
+ config: () => ({
+ devMode: true
+ })
},
modules: {
shoppingCart,
diff --git a/test/unit/specs/__snapshots__/LiDelegate.spec.js.snap b/test/unit/specs/__snapshots__/LiDelegate.spec.js.snap
index b7b49d639b..429c267078 100644
--- a/test/unit/specs/__snapshots__/LiDelegate.spec.js.snap
+++ b/test/unit/specs/__snapshots__/LiDelegate.spec.js.snap
@@ -21,7 +21,7 @@ exports[`LiDelegate has the expected html structure 1`] = `