From fe0c866be0c62d6dad59f170ecaa981c7d843d86 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Tue, 6 Apr 2021 14:17:59 +0200 Subject: [PATCH 01/17] fix transaction broadcast --- src/utils/api/transaction/lsk.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utils/api/transaction/lsk.js b/src/utils/api/transaction/lsk.js index 3891863c0f..f5a12525b0 100644 --- a/src/utils/api/transaction/lsk.js +++ b/src/utils/api/transaction/lsk.js @@ -308,9 +308,11 @@ export const create = ({ * @returns {Promise} promise that resolves to a transaction or rejects with an error */ export const broadcast = ({ transaction, serviceUrl }) => { - const schema = moduleAssetSchemas[transaction.moduleAssetId]; + const moduleAssetId = [transaction.moduleID, transaction.assetID].join(':'); + const schema = moduleAssetSchemas[moduleAssetId]; const binary = transactions.getBytes(schema, transaction); const payload = binary.toString('hex'); + const body = JSON.stringify({ transaction: payload }); return new Promise( async (resolve, reject) => { @@ -319,7 +321,7 @@ export const broadcast = ({ transaction, serviceUrl }) => { method: 'POST', baseUrl: serviceUrl, path: '/api/v2/transactions', - body: { transaction: payload }, + body, }); resolve(response); From 393746627c0716c128b0cd4ae8dbeee118ddd3fc Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 12:58:59 +0200 Subject: [PATCH 02/17] add `toJSON` to prototype of Bigint --- src/main.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.js b/src/main.js index 93b018229d..d47ff00546 100644 --- a/src/main.js +++ b/src/main.js @@ -10,6 +10,9 @@ import ipcLocale from '@utils/ipcLocale'; import i18n from './i18n'; import App from './app'; +// eslint-disable-next-line no-extend-native +BigInt.prototype.toJSON = function () { return `${this.toString()}n`; }; + if (PRODUCTION) { externalLinks.init(); } From 9592388851ab09620ddfb40369f8930ffb2833f0 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 12:59:53 +0200 Subject: [PATCH 03/17] fix broadcast --- src/store/actions/transactions.js | 13 ++-- src/utils/api/transaction/lsk.js | 121 +++++++++++++++++++++--------- 2 files changed, 92 insertions(+), 42 deletions(-) diff --git a/src/store/actions/transactions.js b/src/store/actions/transactions.js index 3d5320d8d1..9d3c661b97 100644 --- a/src/store/actions/transactions.js +++ b/src/store/actions/transactions.js @@ -8,6 +8,7 @@ import { getTransactions, create, broadcast } from '@utils/api/transaction'; import { signSendTransaction } from '@utils/hwManager'; import { passphraseUsed } from './account'; import { loadingStarted, loadingFinished } from './loading'; +import { transformTransaction } from '../../utils/api/transaction/lsk'; /** * Action trigger when user logout from the application @@ -99,6 +100,7 @@ export const resetTransactionResult = () => ({ * @param {Number} data.dynamicFeePerByte - In raw format, used for creating BTC transaction. * @param {Number} data.reference - Data field for LSK transactions */ +// eslint-disable-next-line max-statements export const transactionCreated = data => async (dispatch, getState) => { const { account, settings, network, @@ -144,7 +146,7 @@ export const transactionCreated = data => async (dispatch, getState) => { * @param {Number} transaction.dynamicFeePerByte - In raw format, used for creating BTC transaction. * @param {Number} transaction.reference - Data field for LSK transactions */ -export const transactionBroadcasted = (transaction, callback = () => {}) => +export const transactionBroadcasted = transaction => // eslint-disable-next-line max-statements async (dispatch, getState) => { const { network, settings } = getState(); @@ -156,7 +158,6 @@ export const transactionBroadcasted = (transaction, callback = () => {}) => activeToken, )); - callback({ success: !error, error, transaction }); if (error) { dispatch({ type: actionTypes.broadcastedTransactionError, @@ -173,12 +174,8 @@ export const transactionBroadcasted = (transaction, callback = () => {}) => }); if (activeToken !== tokenMap.BTC.key) { - dispatch(addNewPendingTransaction({ - ...transaction, - title: MODULE_ASSETS_NAME_ID_MAP[transaction.moduleAssetId], - amount: transaction.asset.amount, - recipientId: transaction.asset.recipientId, - })); + const transformedTransaction = transformTransaction(transaction); + dispatch(addNewPendingTransaction({ ...transformedTransaction, isPending: true })); } dispatch(passphraseUsed(new Date())); diff --git a/src/utils/api/transaction/lsk.js b/src/utils/api/transaction/lsk.js index f5a12525b0..945824da47 100644 --- a/src/utils/api/transaction/lsk.js +++ b/src/utils/api/transaction/lsk.js @@ -219,51 +219,104 @@ const splitModuleAndAssetIds = (moduleAssetId) => { return [Number(moduleID), Number(assetID)]; }; -// eslint-disable-next-line max-statements -const createTransactionObject = (tx, moduleAssetId) => { - const [moduleID, assetID] = splitModuleAndAssetIds(moduleAssetId); - const { - senderPublicKey, nonce, amount, recipientAddress, data, fee = 0, - } = tx; - - const transaction = { - moduleID, - assetID, - senderPublicKey: Buffer.from(senderPublicKey, 'hex'), - nonce: BigInt(nonce), - fee: BigInt(fee), - signatures: [], +export const transformTransaction = (transaction) => { + const moduleAssetId = [transaction.moduleID, transaction.assetID].join(':'); + const senderAddress = extractAddress(transaction.senderPublicKey); + const senderPublicKey = transaction.senderPublicKey.toString('hex'); + + const transformedTransaction = { + fee: String(transaction.fee), + nonce: String(transaction.nonce), + moduleAssetId, + sender: { publicKey: senderPublicKey, address: senderAddress }, + signatures: transaction.signatures, }; if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.transfer) { - transaction.asset = { - recipientAddress: extractAddress(recipientAddress), - amount: BigInt(amount), - data, + transformedTransaction.asset = { + recipient: { address: extractAddress(transaction.asset.recipientAddress) }, + amount: String(transaction.asset.amount), + data: transaction.asset.data, }; } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.voteDelegate) { - transaction.asset = { - votes: tx.votes, - }; + // @todo fix me + // transformedTransaction.asset = { + // votes: tx.votes, + // }; + } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.unlockToken) { - transaction.asset = { - unlockObjects: tx.unlockObjects, - }; + // @todo fix me + // transformedTransaction.asset = { + // unlockObjects: tx.unlockObjects, + // }; } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.registerDelegate) { - transaction.asset = { - username: tx.username, - }; + // @todo fix me + // transformedTransaction.asset = { + // username: tx.username, + // }; } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.registerMultisignatureGroup) { - transaction.asset = { - numberOfSignatures: tx.numberOfSignatures, - mandatoryKeys: tx.mandatoryKeys, - optionalKeys: tx.optionalKeys, - }; + // @todo fix me + // transformedTransaction.asset = { + // numberOfSignatures: tx.numberOfSignatures, + // mandatoryKeys: tx.mandatoryKeys, + // optionalKeys: tx.optionalKeys, + // }; } else { throw Error('Unknown transaction'); } - return transaction; + return transformedTransaction; +}; +// eslint-disable-next-line max-statements +const createTransactionObject = (tx, moduleAssetId) => { + try { + const [moduleID, assetID] = splitModuleAndAssetIds(moduleAssetId); + const { + senderPublicKey, nonce, amount, recipientAddress, data, fee = 0, + } = tx; + + const transaction = { + moduleID, + assetID, + senderPublicKey: Buffer.from(senderPublicKey, 'hex'), + nonce: BigInt(nonce), + fee: BigInt(fee), + signatures: [], + }; + + if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.transfer) { + transaction.asset = { + recipientAddress: extractAddress(recipientAddress), + amount: BigInt(amount), + data, + }; + } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.voteDelegate) { + transaction.asset = { + votes: tx.votes, + }; + } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.unlockToken) { + transaction.asset = { + unlockObjects: tx.unlockObjects, + }; + } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.registerDelegate) { + transaction.asset = { + username: tx.username, + }; + } else if (moduleAssetId === MODULE_ASSETS_NAME_ID_MAP.registerMultisignatureGroup) { + transaction.asset = { + numberOfSignatures: tx.numberOfSignatures, + mandatoryKeys: tx.mandatoryKeys, + optionalKeys: tx.optionalKeys, + }; + } else { + throw Error('Unknown transaction'); + } + + return transaction; + } catch (e) { + // eslint-disable-next-line no-console + console.error(e); + } }; /** @@ -278,7 +331,6 @@ export const create = ({ network, moduleAssetId, ...transactionObject -// eslint-disable-next-line max-statements }) => new Promise((resolve, reject) => { const { networkIdentifier } = network.networks.LSK; const { @@ -292,6 +344,7 @@ export const create = ({ const signedTransaction = transactions.signTransaction( schema, transaction, Buffer.from(networkIdentifier, 'hex'), passphrase, ); + resolve(signedTransaction); } catch (error) { reject(error); From 3f14f51d153752218340eac40f4cbd099a563727 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 13:00:16 +0200 Subject: [PATCH 04/17] remove eslint ignore rule --- src/components/screens/wallet/transactions/transactionRow.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/screens/wallet/transactions/transactionRow.js b/src/components/screens/wallet/transactions/transactionRow.js index b2e60ac97c..d36811cc6b 100644 --- a/src/components/screens/wallet/transactions/transactionRow.js +++ b/src/components/screens/wallet/transactions/transactionRow.js @@ -13,7 +13,6 @@ import TransactionAsset from './txAsset'; import DialogLink from '../../../toolbox/dialog/link'; import styles from './transactions.css'; -// eslint-disable-next-line complexity const TransactionRow = ({ data, className, t, host, delegates, }) => { From 28ef77addbba4e8b606fd5edaabf314d307908a9 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 13:24:25 +0200 Subject: [PATCH 05/17] separate out cryptographic functions better --- src/utils/account.js | 26 ++++++++++++++++++++------ src/utils/api/account/lsk.js | 10 +++++++--- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/utils/account.js b/src/utils/account.js index 0f78a2c46d..95e3591cb1 100644 --- a/src/utils/account.js +++ b/src/utils/account.js @@ -16,6 +16,23 @@ export const extractPublicKey = (passphrase) => { return undefined; }; +export const extractAddressFromPublicKey = (data) => { + if (regex.publicKey.test(data)) { + return cryptography.getBase32AddressFromPublicKey(data).toString('hex'); + } + if (Buffer.isBuffer(data)) { + return cryptography.getBase32AddressFromPublicKey(data); + } + return undefined; +}; + +export const extractAddressFromPassphrase = (data) => { + if (LiskPassphrase.Mnemonic.validateMnemonic(data)) { + return cryptography.getBase32AddressFromPassphrase(data).toString('hex'); + } + return undefined; +}; + /** * Extracts Lisk address from given passphrase or publicKey * @@ -23,15 +40,12 @@ export const extractPublicKey = (passphrase) => { * @returns {String?} - Extracted address for a given valid passphrase or publicKey */ export const extractAddress = (data) => { - if (LiskPassphrase.Mnemonic.validateMnemonic(data)) { - return cryptography.getBase32AddressFromPassphrase(data).toString('hex'); - } - if (regex.publicKey.test(data)) { - return cryptography.getBase32AddressFromPublicKey(data).toString('hex'); - } if (regex.address.test(data)) { return cryptography.getAddressFromBase32Address(data); } + if (Buffer.isBuffer(data)) { + return cryptography.getBase32AddressFromAddress(data); + } return undefined; }; diff --git a/src/utils/api/account/lsk.js b/src/utils/api/account/lsk.js index 3e9a06979f..e63b0def13 100644 --- a/src/utils/api/account/lsk.js +++ b/src/utils/api/account/lsk.js @@ -2,7 +2,7 @@ import { tokenMap } from '@constants'; import http from '../http'; import ws from '../ws'; import { isEmpty } from '../../helpers'; -import { extractAddress, extractPublicKey } from '../../account'; +import { extractAddressFromPassphrase, extractAddressFromPublicKey, extractPublicKey } from '../../account'; import regex from '../../regex'; const httpPrefix = '/api/v2'; @@ -42,8 +42,11 @@ const getAccountParams = (params) => { // If you have the address, you don't need anything else if (address) return { address }; // convert other params to address - if (publicKey || passphrase) { - return { address: extractAddress(publicKey || passphrase) }; + if (publicKey) { + return { address: extractAddressFromPublicKey(publicKey) }; + } + if (passphrase) { + return { address: extractAddressFromPassphrase(passphrase) }; } // if none of the above, ignore the params return {}; @@ -69,6 +72,7 @@ export const getAccount = async ({ }) => { const normParams = getAccountParams(params); + console.log({ params, normParams }); try { const response = await http({ baseUrl, From 4495b1129587627eaee6147ce6582f4791162f89 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 13:26:10 +0200 Subject: [PATCH 06/17] update other occurances --- src/components/screens/login/login.js | 4 ++-- src/components/screens/register/backupPassphrase.test.js | 4 ++-- src/components/screens/register/register.js | 4 ++-- src/components/toolbox/accountVisual/demo.js | 4 ++-- src/utils/api/delegate/index.js | 4 ++-- src/utils/api/transaction/lsk.js | 3 ++- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/components/screens/login/login.js b/src/components/screens/login/login.js index 62c88513db..57d6c543a8 100644 --- a/src/components/screens/login/login.js +++ b/src/components/screens/login/login.js @@ -6,7 +6,7 @@ import grid from 'flexboxgrid/dist/flexboxgrid.css'; import { Link } from 'react-router-dom'; import { routes, networks, networkKeys } from '@constants'; import { parseSearchParams, stringifySearchParams } from '@utils/searchParams'; -import { extractAddress } from '@utils/account'; +import { extractAddressFromPassphrase } from '@utils/account'; import { getAutoLogInData, findMatchingLoginNetwork } from '@utils/login'; import { getNetworksList } from '@utils/getNetwork'; import Piwik from '@utils/piwik'; @@ -97,7 +97,7 @@ class Login extends React.Component { Piwik.trackingEvent('Login', 'button', 'Login submission'); const { network, login } = this.props; this.secondIteration = true; - if (this.alreadyLoggedWithThisAddress(extractAddress(passphrase), network)) { + if (this.alreadyLoggedWithThisAddress(extractAddressFromPassphrase(passphrase), network)) { this.redirectToReferrer(); } else { login({ passphrase }); diff --git a/src/components/screens/register/backupPassphrase.test.js b/src/components/screens/register/backupPassphrase.test.js index 78744eedc0..2dedb5c49f 100644 --- a/src/components/screens/register/backupPassphrase.test.js +++ b/src/components/screens/register/backupPassphrase.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { expect } from 'chai'; import { mount } from 'enzyme'; import { spy } from 'sinon'; -import { extractAddress } from '../../../utils/account'; +import { extractAddressFromPassphrase } from '../../../utils/account'; import { generatePassphrase } from '../../../utils/passphrase'; import BackupPassphrase from './backupPassphrase'; @@ -12,7 +12,7 @@ describe('Register Process - Backup Passphrase', () => { const passphrase = generatePassphrase(); const account = { - address: extractAddress(passphrase), + address: extractAddressFromPassphrase(passphrase), passphrase, }; diff --git a/src/components/screens/register/register.js b/src/components/screens/register/register.js index 8504aa26fe..f9d30e6957 100644 --- a/src/components/screens/register/register.js +++ b/src/components/screens/register/register.js @@ -1,7 +1,7 @@ import React from 'react'; import grid from 'flexboxgrid/dist/flexboxgrid.css'; import { generatePassphrase } from '@utils/passphrase'; -import { extractAddress } from '@utils/account'; +import { extractAddressFromPassphrase } from '@utils/account'; import { routes } from '@constants'; import ChooseAvatar from './chooseAvatar'; import BackupPassphrase from './backupPassphrase'; @@ -25,7 +25,7 @@ class Register extends React.Component { componentDidMount() { const passphrases = [...Array(5)].map(generatePassphrase); const accounts = passphrases.map(pass => ({ - address: extractAddress(pass), + address: extractAddressFromPassphrase(pass), passphrase: pass, })); this.setState({ diff --git a/src/components/toolbox/accountVisual/demo.js b/src/components/toolbox/accountVisual/demo.js index 59e1f960f3..26a1908610 100644 --- a/src/components/toolbox/accountVisual/demo.js +++ b/src/components/toolbox/accountVisual/demo.js @@ -1,6 +1,6 @@ import React from 'react'; import Waypoint from 'react-waypoint'; -import { extractAddress } from '@utils/account'; +import { extractAddressFromPassphrase } from '@utils/account'; import { generatePassphraseFromSeed } from '@utils/passphrase'; import AccountVisual from '.'; import DemoRenderer from '../demoRenderer'; @@ -29,7 +29,7 @@ class AccountVisualDemo extends React.Component { } const accounts = bytes.map(seed => generatePassphraseFromSeed({ seed })) - .map(extractAddress); + .map(extractAddressFromPassphrase); function onlyUnique(value, index, self) { return self.indexOf(value) === index; diff --git a/src/utils/api/delegate/index.js b/src/utils/api/delegate/index.js index bfb239e79d..fc74632b04 100644 --- a/src/utils/api/delegate/index.js +++ b/src/utils/api/delegate/index.js @@ -1,6 +1,6 @@ import http from '../http'; import ws, { subscribe, unsubscribe } from '../ws'; -import { extractAddress } from '../../account'; +import { extractAddress, extractAddressFromPublicKey } from '../../account'; import regex from '../../regex'; const httpPrefix = '/api/v2'; @@ -21,7 +21,7 @@ export const wsMethods = { const getDelegateProps = ({ address, publicKey, username }) => { if (username) return { username }; if (address) return { address }; - if (publicKey) return { address: extractAddress(publicKey) }; + if (publicKey) return { address: extractAddressFromPublicKey(publicKey) }; return {}; }; diff --git a/src/utils/api/transaction/lsk.js b/src/utils/api/transaction/lsk.js index 945824da47..8ea2d1c4b1 100644 --- a/src/utils/api/transaction/lsk.js +++ b/src/utils/api/transaction/lsk.js @@ -17,6 +17,7 @@ import ws from '../ws'; import { getDelegates } from '../delegate'; import regex from '../../regex'; import { validateAddress } from '../../validators'; +import { extractAddressFromPublicKey } from '../../account'; const httpPrefix = '/api/v2'; @@ -221,7 +222,7 @@ const splitModuleAndAssetIds = (moduleAssetId) => { export const transformTransaction = (transaction) => { const moduleAssetId = [transaction.moduleID, transaction.assetID].join(':'); - const senderAddress = extractAddress(transaction.senderPublicKey); + const senderAddress = extractAddressFromPublicKey(transaction.senderPublicKey); const senderPublicKey = transaction.senderPublicKey.toString('hex'); const transformedTransaction = { From 34147117fcf9efb9c5d3a8a5032c2a079fc79b4d Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 13:26:33 +0200 Subject: [PATCH 07/17] fix addNewPendingTransaction action --- src/store/actions/transactions.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/store/actions/transactions.js b/src/store/actions/transactions.js index 9d3c661b97..41c939b4a0 100644 --- a/src/store/actions/transactions.js +++ b/src/store/actions/transactions.js @@ -3,7 +3,7 @@ import to from 'await-to-js'; import { actionTypes, tokenMap, MODULE_ASSETS_NAME_ID_MAP, loginTypes, } from '@constants'; -import { extractAddress } from '@utils/account'; +import { extractAddressFromPublicKey } from '@utils/account'; import { getTransactions, create, broadcast } from '@utils/api/transaction'; import { signSendTransaction } from '@utils/hwManager'; import { passphraseUsed } from './account'; @@ -25,10 +25,7 @@ export const emptyTransactionsData = () => ({ type: actionTypes.emptyTransaction */ export const addNewPendingTransaction = data => ({ type: actionTypes.addNewPendingTransaction, - data: { - ...data, - senderId: extractAddress(data.senderPublicKey), - }, + data, }); /** From a0094e65a51ecd4bf5a4f97b85d3dd0bb38254c1 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 13:40:53 +0200 Subject: [PATCH 08/17] fix issues with confirming pending transactions --- src/store/actions/transactions.js | 6 ++---- src/store/middlewares/account.js | 4 ++-- src/utils/api/transaction/lsk.js | 4 +++- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/store/actions/transactions.js b/src/store/actions/transactions.js index 41c939b4a0..b1d3ae7754 100644 --- a/src/store/actions/transactions.js +++ b/src/store/actions/transactions.js @@ -64,18 +64,16 @@ export const transactionsRetrieved = ({ data: { offset, address, + filters, confirmed: response.data, count: response.meta.total, - filters, }, }); }) .catch((error) => { dispatch({ type: actionTypes.transactionLoadFailed, - data: { - error, - }, + data: { error }, }); }) .finally(() => { diff --git a/src/store/middlewares/account.js b/src/store/middlewares/account.js index b26e16992a..4143d34254 100644 --- a/src/store/middlewares/account.js +++ b/src/store/middlewares/account.js @@ -81,8 +81,8 @@ const checkTransactionsAndUpdateAccount = async (store, action) => { const blockContainsRelevantTransaction = txs.filter((transaction) => { if (!transaction) return false; return ( - account.summary?.address === transaction.senderId - || account.summary?.address === transaction.recipientId + account.summary?.address === transaction.sender.address + || account.summary?.address === transaction.asset?.recipient.address ); }).length > 0; diff --git a/src/utils/api/transaction/lsk.js b/src/utils/api/transaction/lsk.js index 8ea2d1c4b1..ee3da22ef3 100644 --- a/src/utils/api/transaction/lsk.js +++ b/src/utils/api/transaction/lsk.js @@ -225,10 +225,12 @@ export const transformTransaction = (transaction) => { const senderAddress = extractAddressFromPublicKey(transaction.senderPublicKey); const senderPublicKey = transaction.senderPublicKey.toString('hex'); + console.log(transaction); const transformedTransaction = { + id: transaction.id.toString('hex'), + moduleAssetId, fee: String(transaction.fee), nonce: String(transaction.nonce), - moduleAssetId, sender: { publicKey: senderPublicKey, address: senderAddress }, signatures: transaction.signatures, }; From e60b692ad8c62bec2c915f02222c88dbb583d7d0 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 14:51:35 +0200 Subject: [PATCH 09/17] make getAccounts call properly --- src/store/actions/account.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/store/actions/account.js b/src/store/actions/account.js index bda665f416..0dbe4be7bb 100644 --- a/src/store/actions/account.js +++ b/src/store/actions/account.js @@ -1,6 +1,6 @@ import { to } from 'await-to-js'; import { toast } from 'react-toastify'; -import { loginTypes, actionTypes } from '@constants'; +import { loginTypes, actionTypes, tokenMap } from '@constants'; import { getAccount } from '@utils/api/account'; import { getConnectionErrorMessage } from '@utils/getNetwork'; import { networkStatusUpdated } from './network'; @@ -68,7 +68,11 @@ export const accountDataUpdated = tokensTypes => : [settings.token.active]; const params = activeTokens.reduce((acc, token) => { - acc[token] = { address: account.info[token].address }; + if (token === tokenMap.LSK.key) { + acc[token] = { address: account.info[tokenMap.LSK.key].summary.address }; + } else { + acc[token] = { address: account.info[token].address }; + } return acc; }, {}); From 6277f8e45d5670fcc81f68a4ed5446ce9c09b307 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 15:12:09 +0200 Subject: [PATCH 10/17] fix votes api call --- src/store/actions/voting.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/actions/voting.js b/src/store/actions/voting.js index 3d440f481a..fce919813c 100644 --- a/src/store/actions/voting.js +++ b/src/store/actions/voting.js @@ -78,7 +78,7 @@ export const votesSubmitted = data => export const votesRetrieved = () => async (dispatch, getState) => { const { account, network } = getState(); - const address = account.info[tokenMap.LSK.key].address; + const address = account.info[tokenMap.LSK.key].summary.address; const votes = await getVotes({ network, params: { address } }); dispatch({ From e1c62ff9a4ce0b05b7ff81d036d6dfbaadecd754 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Wed, 7 Apr 2021 16:06:44 +0200 Subject: [PATCH 11/17] fix wallet/votes and wallet/delegateProfile crashes --- .../wallet/delegateProfile/delegateVotesView.js | 2 +- .../screens/wallet/delegateProfile/index.js | 5 ++++- src/components/screens/wallet/votes/index.js | 12 ++---------- src/components/screens/wallet/votes/votes.js | 8 ++++---- src/components/toolbox/table/index.js | 2 +- 5 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/components/screens/wallet/delegateProfile/delegateVotesView.js b/src/components/screens/wallet/delegateProfile/delegateVotesView.js index 8a22d53e68..55eedb5750 100644 --- a/src/components/screens/wallet/delegateProfile/delegateVotesView.js +++ b/src/components/screens/wallet/delegateProfile/delegateVotesView.js @@ -47,7 +47,7 @@ const DelegateVotesView = ({ className={`${grid.col} ${grid['col-xs-12']} ${voters.data.length ? styles.votesContainer : ''} votes-container`} > getVoters({ network, params }), - defaultData: [], + defaultData: { + account: {}, + votes: [], + }, getApiParams: (_, ownProps) => ({ address: ownProps.account.summary.address }), transformResponse: response => (response.data.votes ?? []), }, diff --git a/src/components/screens/wallet/votes/index.js b/src/components/screens/wallet/votes/index.js index 1d2081a956..761d53a6aa 100644 --- a/src/components/screens/wallet/votes/index.js +++ b/src/components/screens/wallet/votes/index.js @@ -7,20 +7,12 @@ import { getAccounts } from '@utils/api/account'; import withData from '@utils/withData'; import Votes from './votes'; -const emptyVotes = { - account: {}, - votes: [], -}; - const apis = { votes: { apiUtil: (network, params) => getVotes({ network, params }), - defaultData: { - account: {}, - votes: [], - }, + defaultData: [], autoload: false, - transformResponse: response => response.data?.votes ?? emptyVotes, + transformResponse: response => response.data?.votes ?? [], }, accounts: { apiUtil: (network, params) => getAccounts({ network, params }), diff --git a/src/components/screens/wallet/votes/votes.js b/src/components/screens/wallet/votes/votes.js index 33cc802062..d33a8ac118 100644 --- a/src/components/screens/wallet/votes/votes.js +++ b/src/components/screens/wallet/votes/votes.js @@ -39,14 +39,14 @@ const Votes = ({ // Fetch delegate profiles to define rank, productivity and delegate weight useEffect(() => { - if (isEmpty(accounts.data) && votes.data.votes.length) { - const addressList = votes.data.votes.map(vote => vote.address); + if (isEmpty(accounts.data) && votes.data.length) { + const addressList = votes.data.map(vote => vote.address); accounts.loadData({ addressList }); } }, [votes.data]); const areLoading = accounts.isLoading || votes.isLoading; - const filteredVotes = votes.data.votes.filter((vote) => { + const filteredVotes = votes.data.filter((vote) => { if (!vote.username) return false; return vote.username.indexOf(filterValue) > -1; }); @@ -68,7 +68,7 @@ const Votes = ({ )} Date: Wed, 7 Apr 2021 16:07:32 +0200 Subject: [PATCH 12/17] fix issue when votes retrieved are empty --- src/store/reducers/voting.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/store/reducers/voting.js b/src/store/reducers/voting.js index f556a91978..7d0b8e490e 100644 --- a/src/store/reducers/voting.js +++ b/src/store/reducers/voting.js @@ -8,17 +8,20 @@ import { actionTypes } from '@constants'; */ const voting = (state = {}, action) => { switch (action.type) { - case actionTypes.votesRetrieved: - return action.data - .reduce((votesDict, delegate) => { - votesDict[delegate.address] = { - confirmed: Number(delegate.amount), - unconfirmed: Number(delegate.amount), - username: delegate.username, - }; - return votesDict; - }, {}); - + case actionTypes.votesRetrieved: { + if (action.data.account.votesUsed) { + return action.data + .reduce((votesDict, delegate) => { + votesDict[delegate.address] = { + confirmed: Number(delegate.amount), + unconfirmed: Number(delegate.amount), + username: delegate.username, + }; + return votesDict; + }, {}); + } + return {}; + } case actionTypes.voteEdited: return { ...state, From 5c351c27a3681aab18012faf8ef389cf7e6a9440 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Fri, 9 Apr 2021 09:56:05 +0200 Subject: [PATCH 13/17] throw errors instead of returning undefined if cryptographic conversions fail --- src/utils/account.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils/account.js b/src/utils/account.js index 95e3591cb1..4eb5760b96 100644 --- a/src/utils/account.js +++ b/src/utils/account.js @@ -13,7 +13,7 @@ export const extractPublicKey = (passphrase) => { if (LiskPassphrase.Mnemonic.validateMnemonic(passphrase)) { return cryptography.getKeys(passphrase).publicKey.toString('hex'); } - return undefined; + throw Error('Invalid passphrase'); }; export const extractAddressFromPublicKey = (data) => { @@ -23,14 +23,14 @@ export const extractAddressFromPublicKey = (data) => { if (Buffer.isBuffer(data)) { return cryptography.getBase32AddressFromPublicKey(data); } - return undefined; + throw Error(`Unable to convert publicKey ${data} to address`); }; export const extractAddressFromPassphrase = (data) => { if (LiskPassphrase.Mnemonic.validateMnemonic(data)) { return cryptography.getBase32AddressFromPassphrase(data).toString('hex'); } - return undefined; + throw Error('Invalid passphrase'); }; /** @@ -46,7 +46,7 @@ export const extractAddress = (data) => { if (Buffer.isBuffer(data)) { return cryptography.getBase32AddressFromAddress(data); } - return undefined; + throw Error('Invalid publicKey or passphrase'); }; export const getActiveTokenAccount = state => ({ From d9ac2d8f99e41dc2f7966405e469f111cfa0516c Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Fri, 9 Apr 2021 09:56:50 +0200 Subject: [PATCH 14/17] null check data before checking its length --- src/components/toolbox/table/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/toolbox/table/index.js b/src/components/toolbox/table/index.js index 4f64714275..dd54daa009 100644 --- a/src/components/toolbox/table/index.js +++ b/src/components/toolbox/table/index.js @@ -63,7 +63,7 @@ import styles from './table.css'; * you can use this property. */ const Table = ({ - data = [], + data, loadData, header, row, @@ -97,7 +97,7 @@ const Table = ({ data={emptyState} error={error} isLoading={isLoading} - isListEmpty={data.length === 0} + isListEmpty={data?.length === 0} className={styles.emptyState} /> From f88ec8cb2e5fa12b88cf14dfcfc463525e8df575 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Fri, 9 Apr 2021 09:58:31 +0200 Subject: [PATCH 15/17] replace regex for address with validation from lisk elements --- src/utils/account.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/account.js b/src/utils/account.js index 4eb5760b96..3085fb41da 100644 --- a/src/utils/account.js +++ b/src/utils/account.js @@ -40,7 +40,7 @@ export const extractAddressFromPassphrase = (data) => { * @returns {String?} - Extracted address for a given valid passphrase or publicKey */ export const extractAddress = (data) => { - if (regex.address.test(data)) { + if (cryptography.validateBase32Address()(data)) { return cryptography.getAddressFromBase32Address(data); } if (Buffer.isBuffer(data)) { From 33002ac5f0b9e4953f812fc912ee1f2d8339945e Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Fri, 9 Apr 2021 09:59:09 +0200 Subject: [PATCH 16/17] remove console.log --- src/utils/api/account/lsk.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/api/account/lsk.js b/src/utils/api/account/lsk.js index e63b0def13..7d368c64d8 100644 --- a/src/utils/api/account/lsk.js +++ b/src/utils/api/account/lsk.js @@ -72,7 +72,6 @@ export const getAccount = async ({ }) => { const normParams = getAccountParams(params); - console.log({ params, normParams }); try { const response = await http({ baseUrl, From fa23341aa6ca639a1b42c14ab58f5f7db52a4fc7 Mon Sep 17 00:00:00 2001 From: UsamaHameed Date: Fri, 9 Apr 2021 10:00:16 +0200 Subject: [PATCH 17/17] remove console.log --- src/utils/api/transaction/lsk.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/api/transaction/lsk.js b/src/utils/api/transaction/lsk.js index ee3da22ef3..2132450b5a 100644 --- a/src/utils/api/transaction/lsk.js +++ b/src/utils/api/transaction/lsk.js @@ -225,7 +225,6 @@ export const transformTransaction = (transaction) => { const senderAddress = extractAddressFromPublicKey(transaction.senderPublicKey); const senderPublicKey = transaction.senderPublicKey.toString('hex'); - console.log(transaction); const transformedTransaction = { id: transaction.id.toString('hex'), moduleAssetId,