diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2602e2dcf..4648ac5cb0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,11 +14,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* removed light theme option from preferences page @jolesbi
* enabled staked balance on PageWallet in production @faboweb
* removed unused xmlhttprequest dependency @faboweb
+* LCD staking endpoints @fedekunze @faboweb
### Added
* storing balance, tx history and delegations locally to serve an old state faster @faboweb
* added error message for missing network config @faboweb
+* showing staking txs in history @faboweb
### Fixed
diff --git a/README.md b/README.md
index 5309ac70d6..177f200e7d 100644
--- a/README.md
+++ b/README.md
@@ -182,7 +182,7 @@ $ sed -i.bak 's/seeds = ""/seeds = "localhost"/g' ./builds/testnets/local-testne
Activate TX indexing in your local node:
```bash
-$ sed -i.bak 's/index_all_tags = true/index_all_tags = false/g' ./builds/testnets/local-testnet/config.toml
+$ sed -i.bak 's/index_all_tags = false/index_all_tags = true/g' ~/.gaiad-testnet/config/config.toml
```
Store the gaia version used in your local testnet:
diff --git a/app/src/renderer/components/common/AppHeader.vue b/app/src/renderer/components/common/AppHeader.vue
index 0e189ce8dc..7c0a630be4 100644
--- a/app/src/renderer/components/common/AppHeader.vue
+++ b/app/src/renderer/components/common/AppHeader.vue
@@ -44,6 +44,7 @@ export default {
document.documentElement.clientWidth,
window.innerWidth || 0
)
+
if (w >= 1024) {
this.close()
this.$store.commit("setConfigDesktop", true)
@@ -65,6 +66,7 @@ export default {
#app-header
z-index z(appHeader)
+
.container
-webkit-app-region drag
@@ -85,7 +87,6 @@ export default {
top 0
left 0
width 100%
-
background var(--app-bg)
> .container
@@ -103,7 +104,6 @@ export default {
align-items center
justify-content center
padding 0 1rem
-
color var(--link)
cursor pointer
@@ -131,6 +131,7 @@ export default {
border-bottom px solid var(--bc)
padding 2.5rem 1rem 1rem 1rem
line-height normal
+
img
height 1.75rem
diff --git a/app/src/renderer/components/staking/PageBond.vue b/app/src/renderer/components/staking/PageBond.vue
index 92c99c1970..60fda33780 100644
--- a/app/src/renderer/components/staking/PageBond.vue
+++ b/app/src/renderer/components/staking/PageBond.vue
@@ -152,15 +152,17 @@ export default {
ToolBar
},
computed: {
- ...mapGetters(["shoppingCart", "user", "committedDelegations", "config"]),
+ ...mapGetters(["shoppingCart", "user", "delegation", "config"]),
denom() {
return this.config.bondingDenom.toUpperCase()
},
totalAtoms() {
- return parseInt(this.user.atoms) + this.oldBondedAtoms
+ return (
+ parseInt(this.user.atoms) + this.oldBondedAtoms + this.oldUnbondingAtoms
+ )
},
oldBondedAtoms() {
- return Object.values(this.committedDelegations).reduce(
+ return Object.values(this.delegation.committedDelegates).reduce(
(sum, d) => sum + parseInt(d),
0
)
@@ -177,6 +179,14 @@ export default {
return atoms
}, this.oldUnbondedAtoms)
},
+ oldUnbondingAtoms() {
+ return Object.values(this.delegation.unbondingDelegations).reduce(
+ (atoms, value) => {
+ return atoms + value
+ },
+ 0
+ )
+ },
newUnbondingAtoms() {
return this.fields.delegates.reduce((atoms, d) => {
let delta = d.oldAtoms - d.atoms
@@ -184,7 +194,7 @@ export default {
return atoms + delta
}
return atoms
- }, 0)
+ }, this.oldUnbondingAtoms)
},
newUnbondingAtomsDelta() {
return this.delta(this.newUnbondingAtoms, 0)
@@ -247,7 +257,7 @@ export default {
}
},
resetFields() {
- let committedDelegations = this.committedDelegations
+ let committedDelegations = this.delegation.committedDelegates
let totalAtoms = this.totalAtoms
this.fields.bondConfirm = false
this.fields.delegates = this.shoppingCart.map(c =>
diff --git a/app/src/renderer/components/wallet/PageTransactions.vue b/app/src/renderer/components/wallet/PageTransactions.vue
index 8bd0958c92..546fbc1d1a 100644
--- a/app/src/renderer/components/wallet/PageTransactions.vue
+++ b/app/src/renderer/components/wallet/PageTransactions.vue
@@ -9,14 +9,19 @@ tm-page(title='Transactions')
modal-search(type="transactions" v-if="somethingToSearch")
tm-data-loading(v-if="wallet.historyLoading")
- data-empty-tx(v-else-if='transactions.length === 0')
+ data-empty-tx(v-else-if='allTransactions.length === 0')
data-empty-search(v-else-if="filteredTransactions.length === 0")
- tm-li-transaction(
- v-else
- v-for="i in filteredTransactions"
- :key="shortid.generate()"
- :transaction="i"
- :address="wallet.address")
+ template(v-else v-for="i in filteredTransactions")
+ tm-li-transaction(
+ v-if="i.type === 'wallet'"
+ :key="shortid.generate()"
+ :transaction="i"
+ :address="wallet.address")
+ tm-li-staking-transaction(
+ v-if="i.type === 'staking'"
+ :key="shortid.generate()"
+ :transaction="i"
+ :address="wallet.address")
diff --git a/app/src/renderer/components/wallet/TmLiStakingTransaction.vue b/app/src/renderer/components/wallet/TmLiStakingTransaction.vue
new file mode 100644
index 0000000000..e557cb4ddc
--- /dev/null
+++ b/app/src/renderer/components/wallet/TmLiStakingTransaction.vue
@@ -0,0 +1,160 @@
+
+.tm-li-tx(v-if="type === 'cosmos-sdk/MsgDelegate'" @click="() => devMode && viewTransaction()")
+ .tx-icon: i.material-icons remove_circle
+ .tx-container
+ .tx-element.tx-coins
+ .tx-coin
+ .key {{ tx.delegation.denom.toUpperCase() }}
+ .value {{ pretty(tx.delegation.amount) }}
+ div
+ .tx-element.tx-date(v-if="devMode") {{ date }}
+ .tx-element.tx-address Staked to {{ tx.validator_addr }}
+
+.tm-li-tx.tm-li-tx-sent(v-else-if="type === 'cosmos-sdk/BeginUnbonding'" @click="() => devMode && viewTransaction()")
+ .tx-icon: i.material-icons add_circle
+ .tx-container
+ .tx-element.tx-coins
+ .tx-coin
+ .key STEAK
+ .value {{ pretty(tx.shares_amount) }}
+ div
+ .tx-element.tx-date(v-if="devMode") {{ date }}
+ .tx-element.tx-address Started unbonding from {{ tx.validator_addr }}
+
+
+
+
+
diff --git a/app/src/renderer/components/wallet/TmLiTransaction.vue b/app/src/renderer/components/wallet/TmLiTransaction.vue
new file mode 100644
index 0000000000..57e8f15a0a
--- /dev/null
+++ b/app/src/renderer/components/wallet/TmLiTransaction.vue
@@ -0,0 +1,219 @@
+
+mixin tx-container-sent
+ .tx-container
+ .tx-element.tx-coins
+ .tx-coin(v-for='coin in coinsSent')
+ .key {{ coin.denom.toUpperCase() }}
+ .value {{ pretty(coin.amount) }}
+ div
+ .tx-element.tx-date(v-if="devMode") {{ date }}
+ .tx-element.tx-address(v-if="!sentSelf") Sent to {{ receiver }}
+ .tx-element.tx-address(v-if="sentSelf") You sent this amount to yourself.
+.tm-li-tx(v-if="sentSelf" @click="() => devMode && viewTransaction()")
+ .tx-icon: i.material-icons swap_horiz
+ +tx-container-sent
+
+.tm-li-tx.tm-li-tx-sent(v-else-if="sent" @click="() => devMode && viewTransaction()")
+ .tx-icon: i.material-icons remove_circle
+ +tx-container-sent
+
+.tm-li-tx.tm-li-tx-received(v-else @click="() => devMode && viewTransaction()")
+ .tx-icon: i.material-icons add_circle
+ .tx-container
+ .tx-element.tx-coins
+ .tx-coin(v-for='coin, key in coinsReceived' :key="key")
+ .key {{ coin.denom.toUpperCase() }}
+ .value {{ pretty(coin.amount) }}
+ div
+ .tx-element.tx-date(v-if="devMode") {{ date }}
+ .tx-element.tx-address Received from {{ sender }}
+
+
+
+
+
diff --git a/app/src/renderer/connectors/lcdClient.js b/app/src/renderer/connectors/lcdClient.js
index 79d470fbd0..75974d5ec1 100644
--- a/app/src/renderer/connectors/lcdClient.js
+++ b/app/src/renderer/connectors/lcdClient.js
@@ -90,12 +90,64 @@ Object.assign(Client.prototype, {
},
tx: argReq("GET", "/txs"),
- // staking
- updateDelegations: req("POST", "/stake/delegations"),
- candidates: req("GET", "/stake/validators"),
- getValidators: req("GET", "/validatorsets/latest"),
- queryDelegation: function(delegator, validator) {
- return req("GET", `/stake/${delegator}/delegation/${validator}`).call(this)
+ /* ============ STAKE ============ */
+
+ // Get all delegations information from a delegator
+ getDelegator: function(addr) {
+ return req("GET", `/stake/delegators/${addr}`).call(this)
+ },
+ // Get all txs from a delegator
+ getDelegatorTxs: function(addr, types) {
+ if (!types) {
+ return req("GET", `/stake/delegators/${addr}/txs`).call(this)
+ } else {
+ return req("GET", `/stake/delegators/${addr}/txs?type=${types}`).call(
+ this
+ )
+ }
+ },
+ // // Query all validators that a delegator is bonded to
+ // getDelegatorValidators: function(delegatorAddr) {
+ // return req("GET", `/stake/delegators/${delegatorAddr}/validators`).call(this)
+ // },
+ // // Query a validator info that a delegator is bonded to
+ // getDelegatorValidator: function(delegatorAddr, validatorAddr) {
+ // return req("GET", `/stake/delegators/${delegatorAddr}/validators/${validatorAddr}`).call(this)
+ // },
+
+ // Get a list containing all the validator candidates
+ getCandidates: req("GET", "/stake/validators"),
+ // Get information from a validator
+ getCandidate: function(addr) {
+ return req("GET", `/stake/validators/${addr}`).call(this)
+ },
+ // // Get all of the validator bonded delegators
+ // getValidatorDelegators: function(addr) {
+ // return req("GET", `/stake/validator/${addr}/delegators`).call(this)
+ // },
+
+ // Get the list of the validators in the latest validator set
+ getValidatorSet: req("GET", "/validatorsets/latest"),
+
+ updateDelegations: function(delegatorAddr, data) {
+ return req("POST", `/stake/delegators/${delegatorAddr}/delegations`).call(
+ this,
+ data
+ )
+ },
+
+ // Query a delegation between a delegator and a validator
+ queryDelegation: function(delegatorAddr, validatorAddr) {
+ return req(
+ "GET",
+ `/stake/delegators/${delegatorAddr}/delegations/${validatorAddr}`
+ ).call(this)
+ },
+ queryUnbonding: function(delegatorAddr, validatorAddr) {
+ return req(
+ "GET",
+ `/stake/delegators/${delegatorAddr}/unbonding_delegations/${validatorAddr}`
+ ).call(this)
}
})
diff --git a/app/src/renderer/connectors/lcdClientMock.js b/app/src/renderer/connectors/lcdClientMock.js
index a995f0ceb8..d5ccf0dcd7 100644
--- a/app/src/renderer/connectors/lcdClientMock.js
+++ b/app/src/renderer/connectors/lcdClientMock.js
@@ -48,6 +48,7 @@ let state = {
value: {
msg: [
{
+ type: "cosmos-sdk/Send",
value: {
inputs: [
{
@@ -84,6 +85,7 @@ let state = {
value: {
msg: [
{
+ type: "cosmos-sdk/Send",
value: {
inputs: [
{
@@ -118,12 +120,15 @@ let state = {
],
stake: {
[addresses[0]]: {
- [validators[0]]: {
- delegator_addr: addresses[0],
- validator_addr: validators[0],
- shares: "130",
- height: 123
- }
+ delegations: [
+ {
+ delegator_addr: addresses[0],
+ validator_addr: validators[0],
+ shares: "14",
+ height: 123
+ }
+ ],
+ unbonding_delegations: []
}
},
candidates: [
@@ -236,8 +241,8 @@ module.exports = {
)
})
},
- async tx() {
- return {}
+ async tx(hash) {
+ return state.txs.find(tx => tx.hash === hash)
},
async send(to, req) {
let fromKey = state.keys.find(a => a.name === req.name)
@@ -254,7 +259,10 @@ module.exports = {
},
// staking
- async updateDelegations({ name, sequence, delegations, begin_unbondings }) {
+ async updateDelegations(
+ delegatorAddr,
+ { name, sequence, delegations, begin_unbondings }
+ ) {
let results = []
let fromKey = state.keys.find(a => a.name === name)
@@ -294,10 +302,15 @@ module.exports = {
// update stake
let delegator = state.stake[fromKey.address]
if (!delegator) {
- state.stake[fromKey.address] = {}
+ state.stake[fromKey.address] = {
+ delegations: [],
+ unbonding_delegations: []
+ }
delegator = state.stake[fromKey.address]
}
- let delegation = delegator[tx.validator_addr]
+ let delegation = delegator.delegations.find(
+ d => d.validator_addr === tx.validator_addr
+ )
if (!delegation) {
delegation = {
delegator_addr: fromKey.address,
@@ -305,8 +318,9 @@ module.exports = {
shares: "0",
height: 0
}
- delegator[tx.validator_addr] = delegation
+ delegator.delegations.push(delegation)
}
+
let shares = parseInt(delegation.shares)
delegation.shares = (shares + amount).toString()
@@ -316,6 +330,7 @@ module.exports = {
parseInt(candidate.delegator_shares) + amount
).toString()
+ storeTx("cosmos-sdk/MsgDelegate", tx)
results.push(txResult(0))
}
@@ -334,7 +349,9 @@ module.exports = {
results.push(txResult(2, "Nonexistent delegator"))
return results
}
- let delegation = delegator[tx.validator_addr]
+ let delegation = delegator.delegations.find(
+ d => d.validator_addr === tx.validator_addr
+ )
if (!delegation) {
results.push(txResult(2, "Nonexistent delegation"))
return results
@@ -345,26 +362,59 @@ module.exports = {
let candidate = state.candidates.find(c => c.owner === tx.validator_addr)
shares = parseInt(candidate.tokens)
candidate.tokens = (+shares - amount).toString()
+ delegator.unbonding_delegations.push(
+ Object.assign({}, tx, {
+ balance: {
+ amount: tx.shares
+ }
+ })
+ )
+ storeTx("cosmos-sdk/BeginUnbonding", tx)
results.push(txResult(0))
}
return results
},
async queryDelegation(delegatorAddress, validatorAddress) {
+ let delegator = state.stake[delegatorAddress]
+ if (!delegator) return {}
+ return delegator.delegations.find(
+ ({ validator_addr }) => validator_addr === validatorAddress
+ )
+ },
+ async queryUnbonding(delegatorAddress, validatorAddress) {
let delegator = state.stake[delegatorAddress]
if (!delegator) return
- return delegator[validatorAddress]
+ return delegator.unbonding_delegations.find(
+ d => d.validator_addr === validatorAddress
+ )
+ },
+ // Get all delegations information from a delegator
+ getDelegator(delegatorAddress) {
+ let delegator = state.stake[delegatorAddress] || {}
+ return delegator
+ },
+ getDelegatorTxs(addr, types = []) {
+ if (types.length === 0) types = ["bonding", "unbonding"]
+ types = types.map(type => {
+ if (type === "bonding") return "cosmos-sdk/MsgDelegate"
+ if (type === "unbonding") return "cosmos-sdk/BeginUnbonding"
+ })
+ return getTxs(types)
},
- async candidates() {
+ async getCandidates() {
return state.candidates
},
- async getValidators() {
+ async getValidatorSet() {
return {
block_height: 1,
validators: state.candidates
}
},
+ async getCandidate(addr) {
+ return state.candidates.find(c => c.owner === addr)
+ },
// exports to be used in tests
state,
addresses,
@@ -435,43 +485,52 @@ function send(to, from, req) {
}
// log tx
+ storeTx("cosmos-sdk/Send", {
+ inputs: [
+ {
+ coins: req.amount,
+ address: from
+ }
+ ],
+ outputs: [
+ {
+ coins: req.amount,
+ address: to
+ }
+ ]
+ })
+
+ // if receiver is bot address, send money back
+ if (to === botAddress) {
+ send(from, botAddress, {
+ amount: req.amount,
+ sequence: state.accounts[botAddress].sequence
+ })
+ }
+
+ return txResult(0)
+}
+
+function storeTx(type, body) {
state.txs.push({
tx: {
value: {
msg: [
{
- value: {
- inputs: [
- {
- coins: req.amount,
- address: from
- }
- ],
- outputs: [
- {
- coins: req.amount,
- address: to
- }
- ]
- }
+ type,
+ value: body
}
]
}
},
hash: makeHash(),
- height: getHeight() + (from === botAddress ? 1 : 0),
+ height: getHeight(),
time: Date.now()
})
+}
- // if receiver is bot address, send money back
- if (to === botAddress) {
- send(from, botAddress, {
- amount: req.amount,
- sequence: state.accounts[botAddress].sequence
- })
- }
-
- return txResult(0)
+function getTxs(types) {
+ return state.txs.filter(tx => types.indexOf(tx.tx.value.msg[0].type) !== -1)
}
// function delegate (sender, { pub_key: { data: pubKey }, amount: delegation }) {
diff --git a/app/src/renderer/vuex/getters.js b/app/src/renderer/vuex/getters.js
index a310805974..78a1832cdf 100644
--- a/app/src/renderer/vuex/getters.js
+++ b/app/src/renderer/vuex/getters.js
@@ -17,6 +17,7 @@ export const transactions = state => state.wallet.history
export const wallet = state => state.wallet
// staking
+export const delegation = state => state.delegation
export const committedDelegations = state => state.delegation.committedDelegates
export const delegates = state => state.delegates
export const shoppingCart = state => state.delegation.delegates
diff --git a/app/src/renderer/vuex/modules/delegates.js b/app/src/renderer/vuex/modules/delegates.js
index ab16ae8a83..2ef8eca4a5 100644
--- a/app/src/renderer/vuex/modules/delegates.js
+++ b/app/src/renderer/vuex/modules/delegates.js
@@ -38,16 +38,16 @@ export default ({ node }) => {
},
async getDelegates({ state, commit }) {
commit("setDelegateLoading", true)
- let delegates = await node.candidates()
- let { validators } = await node.getValidators()
- for (let delegate of delegates) {
+ let candidates = await node.getCandidates()
+ let { validators } = await node.getValidatorSet()
+ for (let delegate of candidates) {
if (validators.find(v => v.pub_key === delegate.pub_key)) {
delegate.isValidator = true
}
commit("addDelegate", delegate)
}
- commit("setDelegates", delegates)
+ commit("setDelegates", candidates)
commit("setDelegateLoading", false)
return state.delegates
diff --git a/app/src/renderer/vuex/modules/delegation.js b/app/src/renderer/vuex/modules/delegation.js
index 6e51c627b6..404d90eb16 100644
--- a/app/src/renderer/vuex/modules/delegation.js
+++ b/app/src/renderer/vuex/modules/delegation.js
@@ -6,7 +6,9 @@ export default ({ node }) => {
delegates: [],
// our delegations which are already on the blockchain
- committedDelegates: {}
+ committedDelegates: {},
+ unbondingDelegations: {},
+ delegationTxs: []
}
const mutations = {
@@ -36,6 +38,18 @@ export default ({ node }) => {
committedDelegates[candidateId] = value
}
state.committedDelegates = committedDelegates
+ },
+ setUnbondingDelegations(state, { candidateId, value }) {
+ let unbondingDelegations = Object.assign({}, state.unbondingDelegations)
+ if (value === 0) {
+ delete unbondingDelegations[candidateId]
+ } else {
+ unbondingDelegations[candidateId] = value
+ }
+ state.unbondingDelegations = unbondingDelegations
+ },
+ setDelegationTxs(state, txs) {
+ state.delegationTxs = txs
}
}
@@ -46,36 +60,44 @@ export default ({ node }) => {
}
},
// load committed delegations from LCD
- async getBondedDelegates({ state, rootState, dispatch }, candidates) {
+ async getBondedDelegates(
+ { state, rootState, commit, dispatch },
+ candidates
+ ) {
state.loading = true
let address = rootState.user.address
candidates = candidates || (await dispatch("getDelegates"))
- await Promise.all(
- candidates.map(candidate =>
- dispatch("getBondedDelegate", {
- delegator: address,
- validator: candidate.owner
+ let delegator = await node.getDelegator(address)
+ if (delegator.delegations) {
+ delegator.delegations.forEach(({ validator_addr, shares }) => {
+ commit("setCommittedDelegation", {
+ candidateId: validator_addr,
+ value: parseFloat(shares)
})
+ if (shares > 0) {
+ const delegate = candidates.find(
+ ({ owner }) => owner === validator_addr // this should change to address instead of owner
+ )
+ commit("addToCart", delegate)
+ }
+ })
+ }
+ if (delegator.unbonding_delegations) {
+ delegator.unbonding_delegations.forEach(
+ ({ validator_addr, balance: { amount } }) => {
+ commit("setUnbondingDelegations", {
+ candidateId: validator_addr,
+ value: parseFloat(amount)
+ })
+ }
)
- )
+ }
state.loading = false
},
- // load committed delegation from LCD
- async getBondedDelegate({ commit, rootState }, { delegator, validator }) {
- let bond = await node.queryDelegation(delegator, validator)
-
- let shares = bond ? bond.shares : 0
- let delegate = rootState.delegates.delegates.find(
- d => d.owner === validator
- )
-
- commit("setCommittedDelegation", {
- candidateId: validator,
- value: shares
- })
- if (shares > 0) {
- commit("addToCart", delegate)
- }
+ async getDelegationTxs({ commit, rootState }) {
+ let address = rootState.user.address
+ let txs = await node.getDelegatorTxs(address)
+ commit("setDelegationTxs", txs)
},
async updateDelegates({ dispatch }) {
let candidates = await dispatch("getDelegates")
@@ -117,6 +139,7 @@ export default ({ node }) => {
await dispatch("sendTx", {
type: "updateDelegations",
+ to: rootState.wallet.address, // TODO strange syntax
delegations: delegate,
begin_unbondings: unbond
})
diff --git a/app/src/renderer/vuex/modules/node.js b/app/src/renderer/vuex/modules/node.js
index 39f0b781b0..ea585e6370 100644
--- a/app/src/renderer/vuex/modules/node.js
+++ b/app/src/renderer/vuex/modules/node.js
@@ -36,7 +36,7 @@ export default function({ node }) {
}
const actions = {
- setLastHeader({ state, rootState, dispatch }, header) {
+ async setLastHeader({ state, rootState, dispatch }, header) {
state.lastHeader = header
// TODO do this somewhere else probably
@@ -44,7 +44,7 @@ export default function({ node }) {
rootState.wallet.zoneIds.unshift(header.chain_id)
}
- dispatch("maybeUpdateValidators", header)
+ await dispatch("maybeUpdateValidators", header)
},
async reconnect({ commit }) {
if (state.stopConnecting) return
diff --git a/app/src/renderer/vuex/modules/user.js b/app/src/renderer/vuex/modules/user.js
index 391643beca..60a37e9b63 100644
--- a/app/src/renderer/vuex/modules/user.js
+++ b/app/src/renderer/vuex/modules/user.js
@@ -109,7 +109,7 @@ export default ({ node }) => {
let { address } = await node.getKey(account)
state.address = address
- commit("loadPersistedState", { account, password })
+ commit("loadPersistedState", { address, password })
commit("setModalSession", false)
dispatch("initializeWallet", address)
dispatch("loadErrorCollection", account)
diff --git a/app/src/renderer/vuex/modules/validators.js b/app/src/renderer/vuex/modules/validators.js
index 198e8de8ce..f74bfa7dfd 100644
--- a/app/src/renderer/vuex/modules/validators.js
+++ b/app/src/renderer/vuex/modules/validators.js
@@ -20,25 +20,24 @@ export default ({ node }) => {
dispatch("getValidators")
}
},
- getValidators({ state, commit }) {
+ async getValidators({ state, commit }) {
state.loading = true
- node.rpc.validators((err, { validators } = {}) => {
- if (err) {
- commit("notifyError", {
- title: "Error fetching validator set",
- body: err.message
- })
- return
- }
+ try {
+ let validators = (await node.getValidatorSet()).validators
commit("setValidators", validators)
- state.loading = false
- })
+ } catch (err) {
+ commit("notifyError", {
+ title: "Error fetching validator set",
+ body: err.message
+ })
+ }
+ state.loading = false
},
- maybeUpdateValidators({ state, commit, dispatch }, header) {
+ async maybeUpdateValidators({ state, commit, dispatch }, header) {
let validatorHash = header.validators_hash
if (validatorHash === state.validatorHash) return
commit("setValidatorHash", validatorHash)
- dispatch("getValidators")
+ await dispatch("getValidators")
}
}
diff --git a/app/src/renderer/vuex/modules/wallet.js b/app/src/renderer/vuex/modules/wallet.js
index b6e513a852..e7ceb8624e 100644
--- a/app/src/renderer/vuex/modules/wallet.js
+++ b/app/src/renderer/vuex/modules/wallet.js
@@ -69,7 +69,7 @@ export default ({ node }) => {
},
queryWalletState({ dispatch }) {
dispatch("queryWalletBalances")
- dispatch("queryWalletHistory")
+ // dispatch("queryWalletHistory") // is done on mounting transactions
},
async queryWalletBalances({ state, rootState, commit }) {
let res = await node.queryAccount(state.address)
diff --git a/app/src/renderer/vuex/store.js b/app/src/renderer/vuex/store.js
index 6c6fa9a9ce..1ca4037985 100644
--- a/app/src/renderer/vuex/store.js
+++ b/app/src/renderer/vuex/store.js
@@ -47,11 +47,11 @@ function persistState(state) {
state.user.password
)
// Store the state object as a JSON string
- localStorage.setItem("store_" + state.user.account, encryptedState)
+ localStorage.setItem("store_" + state.user.address, encryptedState)
}
-function loadPersistedState(state, { account, password }) {
- const cachedState = localStorage.getItem("store_" + account)
+function loadPersistedState(state, { address, password }) {
+ const cachedState = localStorage.getItem("store_" + address)
if (cachedState) {
const bytes = CryptoJS.AES.decrypt(cachedState, password)
const plaintext = bytes.toString(CryptoJS.enc.Utf8)
diff --git a/tasks/build/Gaia/COMMIT.sh b/tasks/build/Gaia/COMMIT.sh
index 61800138c4..f097f53326 100755
--- a/tasks/build/Gaia/COMMIT.sh
+++ b/tasks/build/Gaia/COMMIT.sh
@@ -2,4 +2,4 @@
# This is the commit of the SDK version to use for building Gaia. We use an
# explicit hash instead of a tag so we don't have to trust GitHub.
-export COMMIT=23e3d5ac12145c02fcb4b4767d7dfccad782aee5
+export COMMIT=6d95d1cef47ec6806fba26e17ac63c7d387bb771
diff --git a/test/e2e/launch.js b/test/e2e/launch.js
index 1683776d15..41e9524a91 100644
--- a/test/e2e/launch.js
+++ b/test/e2e/launch.js
@@ -253,6 +253,9 @@ function initLocalNode() {
const localnodeProcess = spawn(command, { shell: true })
localnodeProcess.stderr.pipe(process.stderr)
+ // the init command now asks for a password for some default account we don't need
+ localnodeProcess.stdin.write("\n")
+
localnodeProcess.stdout.once("data", data => {
let msg = data.toString()
diff --git a/test/unit/helpers/vuex-setup.js b/test/unit/helpers/vuex-setup.js
index 7fe8d0ae87..b6c971a5e7 100644
--- a/test/unit/helpers/vuex-setup.js
+++ b/test/unit/helpers/vuex-setup.js
@@ -16,7 +16,7 @@ export default function vuexSetup() {
function init(
componentConstructor,
testType = shallow,
- { stubs, getters = {}, propsData, doBefore = () => {} } // doBefore receives router and store
+ { stubs, getters = {}, propsData, methods, doBefore = () => {} } // doBefore receives router and store
) {
const node = Object.assign({}, require("../helpers/node_mock"))
const modules = Modules({ node })
@@ -58,7 +58,8 @@ export default function vuexSetup() {
store,
router,
stubs,
- propsData
+ propsData,
+ methods
})
}
}
@@ -67,22 +68,24 @@ export default function vuexSetup() {
localVue,
shallow: (
componentConstructor,
- { stubs, getters, propsData, doBefore } = {}
+ { stubs, getters, propsData, methods, doBefore } = {}
) =>
init(componentConstructor, shallow, {
stubs,
getters,
propsData,
+ methods,
doBefore
}),
mount: (
componentConstructor,
- { stubs, getters, propsData, doBefore } = {}
+ { stubs, getters, propsData, methods, doBefore } = {}
) =>
init(componentConstructor, mount, {
stubs,
getters,
propsData,
+ methods,
doBefore
})
}
diff --git a/test/unit/specs/__snapshots__/lcdClient.spec.js.snap b/test/unit/specs/__snapshots__/lcdClient.spec.js.snap
index 72925727b2..767113f074 100644
--- a/test/unit/specs/__snapshots__/lcdClient.spec.js.snap
+++ b/test/unit/specs/__snapshots__/lcdClient.spec.js.snap
@@ -1,9 +1,53 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`LCD Client queries for a candidate 1`] = `
+Array [
+ Array [
+ "http://localhost:8998/stake/validators/abc",
+ undefined,
+ ],
+]
+`;
+
+exports[`LCD Client queries for a delegation summary for a delegator 1`] = `
+Array [
+ Array [
+ "http://localhost:8998/stake/delegators/abc",
+ undefined,
+ ],
+]
+`;
+
+exports[`LCD Client queries for a delegation txs 1`] = `
+Array [
+ Array [
+ "http://localhost:8998/stake/delegators/abc/txs",
+ undefined,
+ ],
+ Array [
+ "http://localhost:8998/stake/delegators/abc/txs?type=bonding",
+ undefined,
+ ],
+ Array [
+ "http://localhost:8998/stake/delegators/abc/txs?type=unbonding",
+ undefined,
+ ],
+]
+`;
+
exports[`LCD Client queries for shares for a validator and delegate 1`] = `
Array [
Array [
- "http://localhost:8998/stake/abc/delegation/efg",
+ "http://localhost:8998/stake/delegators/abc/delegations/efg",
+ undefined,
+ ],
+]
+`;
+
+exports[`LCD Client queries for undelegations between a delegator and a validator 1`] = `
+Array [
+ Array [
+ "http://localhost:8998/stake/delegators/abc/unbonding_delegations/def",
undefined,
],
]
diff --git a/test/unit/specs/__snapshots__/lcdClientMock.spec.js.snap b/test/unit/specs/__snapshots__/lcdClientMock.spec.js.snap
index cd6a39cd30..3028ce00dc 100644
--- a/test/unit/specs/__snapshots__/lcdClientMock.spec.js.snap
+++ b/test/unit/specs/__snapshots__/lcdClientMock.spec.js.snap
@@ -2,10 +2,10 @@
exports[`LCD Client Mock delegates to multiple validators at once 1`] = `"10"`;
-exports[`LCD Client Mock delegates to multiple validators at once 2`] = `"140"`;
+exports[`LCD Client Mock delegates to multiple validators at once 2`] = `"24"`;
exports[`LCD Client Mock deletes keys 1`] = `[Error: Passwords do not match]`;
-exports[`LCD Client Mock queries bondings per delegator 1`] = `"130"`;
+exports[`LCD Client Mock queries bondings per delegator 1`] = `"14"`;
exports[`LCD Client Mock updates keys 1`] = `[Error: Passwords do not match]`;
diff --git a/test/unit/specs/components/common/AppHeader.spec.js b/test/unit/specs/components/common/AppHeader.spec.js
index d03615efe3..0da3326809 100644
--- a/test/unit/specs/components/common/AppHeader.spec.js
+++ b/test/unit/specs/components/common/AppHeader.spec.js
@@ -8,8 +8,7 @@ describe("AppHeader", () => {
beforeEach(() => {
instance = mount(AppHeader, {
- stubs: { "app-menu": "