From e4f691ab78b6a17581cd27b4d88adeed2492b166 Mon Sep 17 00:00:00 2001 From: kandrusyak Date: Wed, 24 Aug 2022 13:24:10 +0300 Subject: [PATCH] add processed fields --- src/pages/digitalId/ProfileId.jsx | 1 - src/partials/profile/ProfileTableItem.jsx | 133 +++++---- src/shared/fetchWrapper.js | 3 +- src/shared/statusMap.js | 3 +- src/store/store.js | 339 +++++++++++++--------- 5 files changed, 291 insertions(+), 188 deletions(-) diff --git a/src/pages/digitalId/ProfileId.jsx b/src/pages/digitalId/ProfileId.jsx index d85da0c..8a14d6d 100644 --- a/src/pages/digitalId/ProfileId.jsx +++ b/src/pages/digitalId/ProfileId.jsx @@ -161,7 +161,6 @@ const Profile = observer (() => { }; const addDataParameters = () => { - console.log(addedValues) const label = addedValues.label.toLowerCase().split(' ').join(''); if(labelMap[label]) addedValues.key = addedValues.label.toLowerCase().split(' ').join(''); diff --git a/src/partials/profile/ProfileTableItem.jsx b/src/partials/profile/ProfileTableItem.jsx index 713c9b0..cdc7ef8 100644 --- a/src/partials/profile/ProfileTableItem.jsx +++ b/src/partials/profile/ProfileTableItem.jsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import { statusMap } from '../../shared/statusMap'; function ProfileTableItem(props) { const [descriptionOpen, setDescriptionOpen] = useState(false); @@ -10,7 +11,13 @@ function ProfileTableItem(props) {
@@ -20,44 +27,50 @@ function ProfileTableItem(props) { {props.property}
-
{props.status==='Blockchained'?`${props.value.slice(0,4)}****${props.value.slice(props.value.length-4)}`:props.value}
+
+ {props.status === 'Blockchained' || props.status === statusMap.processed + ? `${props.value.slice(0, 4)}****${props.value.slice(props.value.length - 4)}` + : props.value} +
{props.property}
- {(props.status === 'Blockchained') ? ( -
- {props.status} -
) : - (props.status === 'Stored') ? ( -
- {props.status} -
) : - (props.status === 'Completed') ? ( -
- {props.status} -
) : ( -
- {props.status} -
) - } + {props.status === 'Blockchained' ? ( +
{props.status}
+ ) : props.status === statusMap.processed ? ( +
{props.status}
+ ) : props.status === 'Stored' ? ( +
{props.status}
+ ) : props.status === 'Completed' ? ( +
{props.status}
+ ) : ( +
{props.status}
+ )}
- {(props.avatars) ? ( - props.avatars.map((avatar, index) => ( - Avatar + {props.avatars + ? props.avatars.map((avatar, index) => ( + Avatar )) - ): null} + : null}
@@ -74,31 +87,40 @@ function ProfileTableItem(props) { -
- -
- +
+ +
+ - +
- - + +
Transaction - 0x12831823791203192418234841238468 + + 0x12831823791203192418234841238468 +
{/* Progress validation bar */} @@ -113,8 +135,11 @@ function ProfileTableItem(props) { {props.transactions.map((data, index) => (
  • - {(props.transactions[index+1]) ? ( - + {props.transactions[index + 1] ? ( + ) : null}

    Validate by - {data} + + {data} +

    - {data} + + {data} + Transactions ID
    - {data.slice(2, data.length)} + + {data.slice(2, data.length)} + Validated data
    @@ -146,8 +177,8 @@ function ProfileTableItem(props) {
    - - + + ); } diff --git a/src/shared/fetchWrapper.js b/src/shared/fetchWrapper.js index c8d63de..39ae489 100644 --- a/src/shared/fetchWrapper.js +++ b/src/shared/fetchWrapper.js @@ -8,8 +8,9 @@ function prepareUrl(url) { function handleRequest(method, url, headers, attempts, token, body) { return new Promise((resolve, reject) => { - store.loading = true; (function internalRequest() { + if(store) + store.loading = true; return request(method, url, headers, token, body) .then(resolve) .catch(err => --attempts > 0 ? internalRequest() : reject(err)) diff --git a/src/shared/statusMap.js b/src/shared/statusMap.js index 69d8d1c..964ab00 100644 --- a/src/shared/statusMap.js +++ b/src/shared/statusMap.js @@ -2,5 +2,6 @@ export const statusMap={ completed:'Completed', incorrect:'Incorrect', stored: 'Stored', - blockchained: 'Blockchained' + blockchained: 'Blockchained', + processed: 'Processed' } diff --git a/src/store/store.js b/src/store/store.js index aa48fd4..1b03108 100644 --- a/src/store/store.js +++ b/src/store/store.js @@ -1,169 +1,202 @@ -import {reaction, makeAutoObservable, onBecomeObserved, onBecomeUnobserved} from "mobx"; -import {cryptography} from "@liskhq/lisk-client"; -import { passphrase, transactions } from "@liskhq/lisk-client"; -import {getNodeInfo} from '../api/node'; -import {fetchWrapper} from '../shared/fetchWrapper'; -import {labelMap} from "../shared/labelMap"; -import {statusMap} from "../shared/statusMap"; -import {generateSvgAvatar} from "../images/GenerateOnboardingSvg/GenerateSvg"; -import { - encryptAccountData, - generateSetTransaction, generateTransaction, - hashAccountData, -} from '../utils/Utils'; -import { - removeFeatureAssetSchema, - setFeatureAssetSchema, -} from '../utils/Schemas'; +import { reaction, makeAutoObservable, onBecomeObserved, onBecomeUnobserved } from 'mobx'; +import { cryptography } from '@liskhq/lisk-client'; +import { passphrase } from '@liskhq/lisk-client'; +import { getNodeInfo } from '../api/node'; +import { fetchWrapper } from '../shared/fetchWrapper'; +import { labelMap } from '../shared/labelMap'; +import { statusMap } from '../shared/statusMap'; +import { generateSvgAvatar } from '../images/GenerateOnboardingSvg/GenerateSvg'; +import { encryptAccountData, generateTransaction, hashAccountData } from '../utils/Utils'; class Store { - _accountData = [] + _accountData = []; - _passPhrase = '' + _passPhrase = ''; - _nodeInfo = {} + _nodeInfo = {}; - _keysArray = [] + _keysArray = []; - _sharedData = [] + _sharedData = []; - _transactionsInfo = [] + _transactionsInfo = []; _accountInfo = {}; _loading = false; + _tempTransactions = []; + constructor() { makeAutoObservable(this, {}); - reaction(() => this.keysArray, () => this.fetchSharedData()) - reaction(() => this.address, () => this.fetchAccountInfo()) - onBecomeObserved(this, "decryptedAccountData", () => this.fetchNewAccountData()) - onBecomeObserved(this, "sharedData", () => this.fetchKeysArray()) - onBecomeUnobserved(this, "sharedData", () => this.unobservedSharedData()) - onBecomeObserved(this, "transactionsInfo", () => this.fetchTransactionsInfo()) - onBecomeUnobserved(this, "transactionsInfo", () => this.unobservedTransactionsInfo()) + reaction( + () => this.keysArray, + () => this.fetchSharedData() + ); + reaction( + () => this.address, + () => this.fetchAccountInfo() + ); + onBecomeObserved(this, 'decryptedAccountData', () => this.fetchNewAccountData()); + onBecomeObserved(this, 'sharedData', () => this.fetchKeysArray()); + onBecomeUnobserved(this, 'sharedData', () => this.unobservedSharedData()); + onBecomeObserved(this, 'transactionsInfo', () => this.fetchTransactionsInfo()); + onBecomeUnobserved(this, 'transactionsInfo', () => this.unobservedTransactionsInfo()); - this.fetchNodeInfo() - }; + this.fetchNodeInfo(); + } fetchNewAccountData() { getNodeInfo() - .then((info)=>{ - this.fetchNodeInfoSuccess(info) - fetchWrapper.getAuth('data/private', { - networkIdentifier: this.nodeInfo.networkIdentifier, - lastBlockID: this.nodeInfo.lastBlockID - }).then((res) => this.accountDataFetchChange(res)) + .then((info) => { + this.fetchNodeInfoSuccess(info); + fetchWrapper + .getAuth('data/private', { + networkIdentifier: this.nodeInfo.networkIdentifier, + lastBlockID: this.nodeInfo.lastBlockID, }) - .catch((err) => this.fetchNodeInfoFailed(err)) + .then((res) => this.accountDataFetchChange(res)) + .catch((err) => this.fetchError(err)); + }) + .catch((err) => this.fetchError(err)); } fetchAccountInfo() { - fetchWrapper.get(`accounts/${this.address}`).then((res) => this.fetchAccountInfoSuccess(res)) + fetchWrapper + .get(`accounts/${this.address}`) + .then((res) => this.fetchAccountInfoSuccess(res)) + .catch((err) => this.fetchError(err)); } fetchKeysArray() { getNodeInfo() - .then((info)=>{ - this.fetchNodeInfoSuccess(info) - fetchWrapper.getAuth('data/shared/', { + .then((info) => { + this.fetchNodeInfoSuccess(info); + fetchWrapper + .getAuth('data/shared/', { networkIdentifier: this.nodeInfo.networkIdentifier, - lastBlockID: this.nodeInfo.lastBlockID - }).then((res) => this.keysArrayFetchChange(res)) + lastBlockID: this.nodeInfo.lastBlockID, + }) + .then((res) => this.keysArrayFetchChange(res)); }) - .catch((err) => this.fetchNodeInfoFailed(err)) + .catch((err) => this.fetchError(err)); } fetchTransactionsInfo() { - fetchWrapper.get(`account/transactions/${this.address}`, { + fetchWrapper + .get(`account/transactions/${this.address}`, { networkIdentifier: this.nodeInfo.networkIdentifier, - lastBlockID: this.nodeInfo.lastBlockID - }).then((res) => this.saveInfoTransactions(res)) - }; + lastBlockID: this.nodeInfo.lastBlockID, + }) + .then((res) => this.saveInfoTransactions(res)) + .catch((err) => this.fetchError(err)); + } + + fetchTempTransactions() { + fetchWrapper + .get('node/transactions') + .then((res) => this.fetchTempTransactionsSuccess(res)) + .catch((err) => this.fetchError(err)); + } fetchPassPhrase() { - this._passPhrase = sessionStorage.getItem('passPhrase') || '' + this._passPhrase = sessionStorage.getItem('passPhrase') || ''; } fetchSharedData() { - this._keysArray.forEach((elem) => fetchWrapper.get(`data/shared/${elem}`).then((res) => this.changeSharedData(res))) - }; + this._keysArray.forEach((elem) => + fetchWrapper + .get(`data/shared/${elem}`) + .then((res) => this.changeSharedData(res)) + .catch((err) => this.fetchError(err)) + ); + } fetchNodeInfo() { getNodeInfo() - .then((info)=>this.fetchNodeInfoSuccess(info)) - .catch((err) => this.fetchNodeInfoFailed(err)) + .then((info) => this.fetchNodeInfoSuccess(info)) + .catch((err) => this.fetchError(err)); } pushAccountData(data = this.accountData) { - fetchWrapper.postAuth('data/private', { - networkIdentifier: this.nodeInfo.networkIdentifier, - lastBlockID: this.nodeInfo.lastBlockID - }, [...encryptAccountData(data, this.passPhrase, this.pubKey)]) - .then(() => this.fetchNewAccountData()) + fetchWrapper + .postAuth( + 'data/private', + { + networkIdentifier: this.nodeInfo.networkIdentifier, + lastBlockID: this.nodeInfo.lastBlockID, + }, + [...encryptAccountData(data, this.passPhrase, this.pubKey)] + ) + .then(() => this.fetchNewAccountData()) + .catch((err) => this.fetchError(err)); } pushAccountDataToBlockchain(data = this.decryptedAccountData) { - const [removed, changed] = hashAccountData(data, this.decryptedAccountData, this.accountFeaturesMap) - const builder = generateTransaction(BigInt(this.accountInfo?.sequence?.nonce || 0), this.addressAndPubKey.publicKey, this.nodeInfo.networkIdentifier, this.passPhrase); + const [removed, changed] = hashAccountData(data, this.decryptedAccountData, this.accountFeaturesMap); + const builder = generateTransaction( + BigInt(this.accountInfo?.sequence?.nonce || 0), + this.addressAndPubKey.publicKey, + this.nodeInfo.networkIdentifier, + this.passPhrase + ); let signedTx = null; - if(removed.length !== 0) - signedTx = builder.remove(removed); + if (removed.length !== 0) signedTx = builder.remove(removed); - if(changed.length !== 0) - signedTx = builder.update(changed) - if(signedTx) { - fetchWrapper.post('transactions', {}, signedTx); + if (changed.length !== 0) signedTx = builder.update(changed); + if (signedTx) { + fetchWrapper.post('transactions', {}, signedTx) + .then(() => this.fetchTempTransactions()) + .catch((err) => this.fetchError(err)); this.accountInfo.sequence.nonce++; } } - - generatePassPhrase() { this._passPhrase = passphrase.Mnemonic.generateMnemonic(); sessionStorage.setItem('passPhrase', this._passPhrase); - }; + } savePastPassPhrase(phrase) { - this._passPhrase=phrase + this._passPhrase = phrase; sessionStorage.setItem('passPhrase', this._passPhrase); - }; + } unobservedTransactionsInfo() { - this._transactionsInfo = [] - }; + this._transactionsInfo = []; + } unobservedSharedData() { - this._sharedData = [] - }; + this._sharedData = []; + } changeSharedData(incomingData) { this._sharedData.push({ data: incomingData.data, - }) + }); } saveDataRegistration(data) { this._accountData = data; - }; + } clearDataRegistration() { this._accountData = []; - }; + } saveInfoTransactions(transaction) { - this._transactionsInfo = transaction.data + this._transactionsInfo = transaction.data; } accountDataFetchChange(res) { if (res.data) { this._accountData = res.data; } - }; + this.fetchTempTransactions(); + } keysArrayFetchChange(res) { this._keysArray = res.data; @@ -171,101 +204,121 @@ class Store { fetchNodeInfoSuccess(info) { this._nodeInfo = info.data; - this.fetchPassPhrase() - } - - fetchNodeInfoFailed(err) { - console.log(err); + this.fetchPassPhrase(); } fetchAccountInfoSuccess(res) { this._accountInfo = res.data; - if(this.accountInfo?.sequence?.nonce) - this.accountInfo.sequence.nonce = parseInt(this.accountInfo.sequence.nonce) || 0 + if (this.accountInfo?.sequence?.nonce) + this.accountInfo.sequence.nonce = parseInt(this.accountInfo.sequence.nonce) || 0; + } + + fetchTempTransactionsSuccess(res) { + this._tempTransactions = res.data; + } + + fetchError(err) { + console.log(err); } get sharedData() { - return this._sharedData.map(elem => ({ - data: elem.data.map(item => ({ + return this._sharedData.map((elem) => ({ + data: elem.data.map((item) => ({ label: labelMap[item.label], value: item.value, - })) + })), })); - }; + } get transactionsInfo() { - return this._transactionsInfo.map(item => { + return this._transactionsInfo.map((item) => { return { id: item.id, sender_avatar: item.asset.recipientAddress && generateSvgAvatar(item.senderPublicKey), avatar_size: 24, - transaction: item.asset.features.map(asset => { + transaction: item.asset.features.map((asset) => { return { transaction_id: item.id, - address: item.asset.recipientAddress && cryptography.bufferToHex(cryptography.getAddressFromPublicKey(cryptography.hexToBuffer(item.senderPublicKey))), + address: + item.asset.recipientAddress && + cryptography.bufferToHex( + cryptography.getAddressFromPublicKey(cryptography.hexToBuffer(item.senderPublicKey)) + ), value: asset.value, - label: labelMap[asset.label] || asset.label - } - }) - } - }) + label: labelMap[asset.label] || asset.label, + }; + }), + }; + }); } get decryptedAccountData() { - const allAccountData=this._accountData.concat(this.accountFeatures.filter(item=>!this._accountData.find(elem=>elem.label===item.label))) + const allAccountData = this._accountData.concat( + this.accountFeatures.filter((item) => !this._accountData.find((elem) => elem.label === item.label)) + ); return allAccountData.map((elem) => { - const initialData={ + const initialData = { ...elem, key: elem.label, label: labelMap[elem.label] || elem.label, status: '', value: '', - seed: '' - } - if(!this._accountData.find(item=>item.label===elem.label)) { + seed: '', + }; + if(this.processedFeatures[elem.label]) + return { + ...initialData, + status: statusMap.processed, + value: elem.value, + } + if (!this._accountData.find((item) => item.label === elem.label)) { return { ...initialData, status: statusMap.blockchained, - value: elem.value - } + value: elem.value, + }; } - const [seed, value] = cryptography.decryptMessageWithPassphrase(elem.value, elem.value_nonce, this.passPhrase, this.pubKey).split(':'); - const hashValue=cryptography.hash(Buffer.concat([Buffer.from(seed, 'utf8'), cryptography.hash(value, 'utf8')])).toString('hex') - if(!this.accountFeatures.find(item=>item.label===elem.label)) { + const [seed, value] = cryptography + .decryptMessageWithPassphrase(elem.value, elem.value_nonce, this.passPhrase, this.pubKey) + .split(':'); + const hashValue = cryptography + .hash(Buffer.concat([Buffer.from(seed, 'utf8'), cryptography.hash(value, 'utf8')])) + .toString('hex'); + if (!this.accountFeatures.find((item) => item.label === elem.label)) { return { ...initialData, status: statusMap.stored, value, - seed - } + seed, + }; } - if(this.accountFeatures.find(item=>item.label===elem.label).value!==hashValue) { + if (this.accountFeatures.find((item) => item.label === elem.label).value !== hashValue) { return { ...initialData, status: statusMap.incorrect, value, - seed - } + seed, + }; } return { ...initialData, status: statusMap.completed, value, - seed - } - }) + seed, + }; + }); } get firstName() { - return this.decryptedAccountData.find(item => item.key === 'firstname')?.value + return this.decryptedAccountData.find((item) => item.key === 'firstname')?.value; } get lastName() { - return this.decryptedAccountData.find(item => item.key === 'secondname')?.value + return this.decryptedAccountData.find((item) => item.key === 'secondname')?.value; } get accountName() { - return this.firstName || this.lastName || this.pubKey + return this.firstName || this.lastName || this.pubKey; } get keysArray() { @@ -273,12 +326,12 @@ class Store { } get passPhrase() { - return this._passPhrase + return this._passPhrase; } get accountData() { - return this._accountData - }; + return this._accountData; + } get accountInfo() { return this._accountInfo; @@ -297,15 +350,14 @@ class Store { } get address() { - return this.addressAndPubKey.address.toString('hex') + return this.addressAndPubKey.address.toString('hex'); } get tokenKey() { const stringToSign = this.nodeInfo.networkIdentifier + this.nodeInfo.lastBlockID; - if(!stringToSign) - return ''; - const sign = cryptography.signDataWithPassphrase(Buffer.from(stringToSign, 'hex'), this.passPhrase).toString('hex') - return this.pubKey + ':' +sign + if (!stringToSign) return ''; + const sign = cryptography.signDataWithPassphrase(Buffer.from(stringToSign, 'hex'), this.passPhrase).toString('hex'); + return this.pubKey + ':' + sign; } get accountIdentity() { @@ -317,10 +369,13 @@ class Store { } get accountFeaturesMap() { - return this.accountFeatures.reduce((acc, item) => ({ - ...acc, - [item.label]: item.value - }), {}) + return this.accountFeatures.reduce( + (acc, item) => ({ + ...acc, + [item.label]: item.value, + }), + {} + ); } get loading() { @@ -330,6 +385,22 @@ class Store { set loading(value) { this._loading = value; } + + get tempTransactions() { + return this._tempTransactions; + } + + get processedFeatures() { + return this.tempTransactions + .filter(item => item.senderPublicKey === this.pubKey) + .reduce((acc, item) => { + const { features } = item.asset; + return { + ...acc, + ...features.reduce((obj, feature) => ({...obj, [feature.label]: true}), {}) + } + }, {}) + } } export const store = new Store();