diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 353af18b..4df5fd08 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,5 +14,7 @@ build.publish: - 'curl -H "Authorization: Bearer ${ACCESS_TOKEN}" -H "x-goog-api-version: 2" -H "Content-Length: 0" -X POST -v "https://www.googleapis.com/chromewebstore/v1.1/items/${CHROME_APP_ID}/publish?publishTarget=default"' only: - tags + except: + - /^.*rc.*$/ tags: - docker diff --git a/.travis.yml b/.travis.yml index ccb5143b..84e503f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,14 +21,27 @@ jobs: if: branch IN (develop, master) AND type = pull_request script: npm run test +# - stage: build +# name: "Build Artifacts" +# if: (branch = master OR branch = develop) AND type = push +# addons: +# artifacts: +# working_dir: build/zip/ +# paths: +# - echo_bridge.zip +# script: +# - npm run build-ext +# - "echo \"Download URL: https://${ARTIFACTS_BUCKET}.s3.amazonaws.com/echoprotocol/bridge-extension/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/echo_bridge.zip\"" + - stage: build - name: "Build Artifacts" - if: (branch = master OR tag IS present) AND type = push - addons: - artifacts: - working_dir: build/zip/ - paths: - - echo_bridge.zip + name: "Build Tag Artifacts" + if: tag IS present script: - npm run build-ext - - "echo \"Download URL: https://${ARTIFACTS_BUCKET}.s3.amazonaws.com/echoprotocol/bridge-extension/${TRAVIS_BUILD_NUMBER}/${TRAVIS_JOB_NUMBER}/echo_bridge.zip\"" + deploy: + provider: releases + api_key: $GITHUB_OAUTH_TOKEN + file: build/zip/echo_bridge.zip + skip_cleanup: true + on: + tags: true diff --git a/LICENSE b/LICENSE index 618eaab4..c7ef468b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) ECHO DEVELOPMENT LTD +Copyright (c) Echo Technological Solutions LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md index 8d43369a..689b8fe3 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ ED25519.verifyMessage(signature, message, publicKey); The MIT License (MIT) -Copyright (c) ECHO DEVELOPMENT LTD +Copyright (c) Echo Technological Solutions LLC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/config/manifest.json b/config/manifest.json index ae538d7c..f960dd35 100644 --- a/config/manifest.json +++ b/config/manifest.json @@ -18,7 +18,7 @@ "96": "images/96.png", "128": "images/128.png" }, - "version": "1.10.0", + "version": "1.10.2", "background": { "scripts": [ "background.js" diff --git a/examples/examples.md b/examples/examples.md index 7bf7e520..a544bc75 100644 --- a/examples/examples.md +++ b/examples/examples.md @@ -7,7 +7,7 @@ const tr = window.echojslib.echo.createTransaction(); const bytecode = '606060405260126006556000600755341561001957600080fd5b604051602080610dd283398101604052808051600160a060020a03331660008181526001602052604080822082905590805560048054600160a060020a0319168317905591935091507fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed94905160405180910390a2600555610d338061009f6000396000f3006060604052600436106101485763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461014d57806307da68f514610172578063095ea7b31461018757806313af4035146101bd57806318160ddd146101dc57806323b872dd146101ef578063313ce5671461021757806340c10f191461022a57806342966c681461024c5780635ac801fe1461026257806370a082311461027857806375f12b21146102975780637a9e5e4b146102aa5780638da5cb5b146102c957806395d89b41146102f85780639dc29fac1461030b578063a0712d681461032d578063a9059cbb14610343578063b753a98c14610365578063bb35783b14610387578063be9a6555146103af578063bf7e214f146103c2578063daea85c5146103d5578063dd62ed3e146103f4578063f2d5d56b14610419575b600080fd5b341561015857600080fd5b61016061043b565b60405190815260200160405180910390f35b341561017d57600080fd5b610185610441565b005b341561019257600080fd5b6101a9600160a060020a03600435166024356104e0565b604051901515815260200160405180910390f35b34156101c857600080fd5b610185600160a060020a036004351661050d565b34156101e757600080fd5b61016061058c565b34156101fa57600080fd5b6101a9600160a060020a0360043581169060243516604435610592565b341561022257600080fd5b610160610707565b341561023557600080fd5b610185600160a060020a036004351660243561070d565b341561025757600080fd5b6101856004356107d3565b341561026d57600080fd5b6101856004356107e0565b341561028357600080fd5b610160600160a060020a0360043516610806565b34156102a257600080fd5b6101a9610821565b34156102b557600080fd5b610185600160a060020a0360043516610831565b34156102d457600080fd5b6102dc6108b0565b604051600160a060020a03909116815260200160405180910390f35b341561030357600080fd5b6101606108bf565b341561031657600080fd5b610185600160a060020a03600435166024356108c5565b341561033857600080fd5b610185600435610a33565b341561034e57600080fd5b6101a9600160a060020a0360043516602435610a3d565b341561037057600080fd5b610185600160a060020a0360043516602435610a4a565b341561039257600080fd5b610185600160a060020a0360043581169060243516604435610a5a565b34156103ba57600080fd5b610185610a6b565b34156103cd57600080fd5b6102dc610b04565b34156103e057600080fd5b6101a9600160a060020a0360043516610b13565b34156103ff57600080fd5b610160600160a060020a0360043581169060243516610b39565b341561042457600080fd5b610185600160a060020a0360043516602435610b64565b60075481565b61045733600035600160e060020a031916610b6f565b151561046257600080fd5b600435602435808233600160a060020a031660008035600160e060020a0319169034903660405183815260406020820181815290820183905260608201848480828437820191505094505050505060405180910390a450506004805474ff0000000000000000000000000000000000000000191660a060020a179055565b60045460009060a060020a900460ff16156104fa57600080fd5b6105048383610c7b565b90505b92915050565b61052333600035600160e060020a031916610b6f565b151561052e57600080fd5b6004805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038381169190911791829055167fce241d7ca1f669fee44b6fc00b8eba2df3bb514eed0f6f668f8f89096e81ed9460405160405180910390a250565b60005490565b60045460009060a060020a900460ff16156105ac57600080fd5b33600160a060020a031684600160a060020a0316141580156105f65750600160a060020a038085166000908152600260209081526040808320339094168352929052205460001914155b1561065457600160a060020a038085166000908152600260209081526040808320339094168352929052205461062c9083610ce7565b600160a060020a03808616600090815260026020908152604080832033909416835292905220555b600160a060020a0384166000908152600160205260409020546106779083610ce7565b600160a060020a0380861660009081526001602052604080822093909355908516815220546106a69083610cf7565b600160a060020a03808516600081815260016020526040908190209390935591908616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b60065481565b61072333600035600160e060020a031916610b6f565b151561072e57600080fd5b60045460a060020a900460ff161561074557600080fd5b600160a060020a0382166000908152600160205260409020546107689082610cf7565b600160a060020a0383166000908152600160205260408120919091555461078f9082610cf7565b600055600160a060020a0382167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405190815260200160405180910390a25050565b6107dd33826108c5565b50565b6107f633600035600160e060020a031916610b6f565b151561080157600080fd5b600755565b600160a060020a031660009081526001602052604090205490565b60045460a060020a900460ff1681565b61084733600035600160e060020a031916610b6f565b151561085257600080fd5b6003805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038381169190911791829055167f1abebea81bfa2637f28358c371278fb15ede7ea8dd28d2e03b112ff6d936ada460405160405180910390a250565b600454600160a060020a031681565b60055481565b6108db33600035600160e060020a031916610b6f565b15156108e657600080fd5b60045460a060020a900460ff16156108fd57600080fd5b33600160a060020a031682600160a060020a0316141580156109475750600160a060020a038083166000908152600260209081526040808320339094168352929052205460001914155b156109a557600160a060020a038083166000908152600260209081526040808320339094168352929052205461097d9082610ce7565b600160a060020a03808416600090815260026020908152604080832033909416835292905220555b600160a060020a0382166000908152600160205260409020546109c89082610ce7565b600160a060020a038316600090815260016020526040812091909155546109ef9082610ce7565b600055600160a060020a0382167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405190815260200160405180910390a25050565b6107dd338261070d565b6000610504338484610592565b610a55338383610592565b505050565b610a65838383610592565b50505050565b610a8133600035600160e060020a031916610b6f565b1515610a8c57600080fd5b600435602435808233600160a060020a031660008035600160e060020a0319169034903660405183815260406020820181815290820183905260608201848480828437820191505094505050505060405180910390a450506004805474ff000000000000000000000000000000000000000019169055565b600354600160a060020a031681565b60045460009060a060020a900460ff1615610b2d57600080fd5b61050782600019610c7b565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b610a55823383610592565b600030600160a060020a031683600160a060020a03161415610b9357506001610507565b600454600160a060020a0384811691161415610bb157506001610507565b600354600160a060020a03161515610bcb57506000610507565b600354600160a060020a031663b70096138430856000604051602001526040517c010000000000000000000000000000000000000000000000000000000063ffffffff8616028152600160a060020a039384166004820152919092166024820152600160e060020a03199091166044820152606401602060405180830381600087803b1515610c5957600080fd5b6102c65a03f11515610c6a57600080fd5b505050604051805190509050610507565b600160a060020a03338116600081815260026020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b8082038281111561050757600080fd5b8082018281101561050757600080fd00a165627a7a72305820c3b70a68c1ccfc4b88f478523cfc01b3108a40e2c6d0132d5b736b0c3034972800294d4b520000000000000000000000000000000000000000000000000000000000'; -tr.addOperation(echojslib.constants.OPERATIONS_IDS.CREATE_CONTRACT, { +tr.addOperation(echojslib.constants.OPERATIONS_IDS.CONTRACT_CREATE, { code: bytecode, eth_accuracy: false, registrar: '1.2.1', @@ -24,10 +24,10 @@ await tr.broadcast(); ```javascript const tr = window.echojslib.echo.createTransaction(); -tr.addOperation(echojslib.constants.OPERATIONS_IDS.CALL_CONTRACT, { +tr.addOperation(echojslib.constants.OPERATIONS_IDS.CONTRACT_CALL, { registrar: '1.2.1', code: '86be3f80' + '0000000000000000000000000000000000000000000000000000000000000001', // setVariable(uint256) - callee: '1.14.1', // contract id + callee: '1.9.1', // contract id value: { asset_id: '1.3.0', amount: 0 }, }); diff --git a/examples/index.html b/examples/index.html index 14dc0754..7fd719e8 100644 --- a/examples/index.html +++ b/examples/index.html @@ -104,7 +104,7 @@

Contract

id="contract-receiver" name="contract-receiver" placeholder="callee" - value="1.14.442" + value="1.9.442" /> Update account - -
-

Upgrade account

-
- - -
-
-
-

Sign message

@@ -439,7 +423,7 @@

Sign message

$("#contract-click").click(function(e) { if (!isAccess) return; const transaction = { - type: window.echojslib.constants.OPERATIONS_IDS.CALL_CONTRACT, + type: window.echojslib.constants.OPERATIONS_IDS.CONTRACT_CALL, registrar: jQuery("#contract-registrar")[0].value, code: jQuery("#contract-code")[0].value, value: { @@ -461,7 +445,7 @@

Sign message

const tr = window.echojslib.echo.createTransaction(); - tr.addOperation(window.echojslib.constants.OPERATIONS_IDS.CALL_CONTRACT, { + tr.addOperation(window.echojslib.constants.OPERATIONS_IDS.CONTRACT_CALL, { registrar: transaction.registrar, value: { asset_id: transaction.value.asset_id, @@ -494,7 +478,7 @@

Sign message

$("#contactCreate-click").click(function (e) { if (!isAccess) return; const transaction = { - type: window.echojslib.constants.OPERATIONS_IDS.CREATE_CONTRACT, + type: window.echojslib.constants.OPERATIONS_IDS.CONTRACT_CREATE, registrar: jQuery("#contactCreate-fromAddress")[0].value, code: jQuery("#contactCreate-code")[0].value, value: { @@ -512,7 +496,7 @@

Sign message

const tr = window.echojslib.echo.createTransaction(); - tr.addOperation(window.echojslib.constants.OPERATIONS_IDS.CREATE_CONTRACT, { + tr.addOperation(window.echojslib.constants.OPERATIONS_IDS.CONTRACT_CREATE, { registrar: transaction.registrar, value: { amount: transaction.value.amount, @@ -546,8 +530,6 @@

Sign message

if (!isAccess) return; const transaction = { registrar: jQuery("#createAccount-registrar")[0].value, - referrer: jQuery("#createAccount-registrar")[0].value, - referrer_percent: 0, echorand_key: jQuery("#createAccount-echorandKey")[0].value, name: jQuery("#createAccount-name")[0].value, active: { @@ -629,37 +611,6 @@

Sign message

}); }); - $("#upgradeAccount-click").click(function (e) { - if (!isAccess) return; - const transaction = { - account_to_upgrade: jQuery("#upgradeAccount-registrar")[0].value, - upgrade_to_lifetime_member: true - }; - - const tr = window.echojslib.echo.createTransaction(); - - tr.addOperation(window.echojslib.constants.OPERATIONS_IDS.ACCOUNT_UPGRADE, transaction); - - tr.signWithBridge() - .then(result => { - result.broadcast() - .then((res) => { - jQuery("#upgradeAccount-info").html( - `

RESULT: ${JSON.stringify(res)}

` - ); - }).catch(err => { - jQuery("#upgradeAccount-info").html( - `

ERROR: ${JSON.stringify(err)}

` - ); - }); - }) - .catch(err => { - jQuery("#upgradeAccount-info").html( - `

ERROR: ${JSON.stringify(err)}

` - ); - }); - }); - $("#signMessage-click").click(function (e) { if (!isAccess) return; echojslib.extension.proofOfAuthority('This is example message!', jQuery("#signMessage-account")[0].value) diff --git a/extension/background.js b/extension/background.js index 97891ca0..e91efdba 100644 --- a/extension/background.js +++ b/extension/background.js @@ -65,6 +65,8 @@ let signMessageRequests = []; const providerNotification = new NotificationManager(); const signNotification = new NotificationManager(); +const tabUrls = {}; + const connectSubscribe = (status) => { try { switch (status) { @@ -102,7 +104,7 @@ const getNetwork = async () => { const createSocket = async (url) => { if (!url) { - const network = await getNetwork(); + const network = await storage.get('current_network') || NETWORKS[0]; ({ url } = network); @@ -199,10 +201,12 @@ const createNotification = (title = '', message = '') => { */ const createAccount = async (name, path) => { try { + storageSetDraft(FORM_SIGN_UP, 'loading', true); const network = await getNetwork(); const { error, example } = await validateAccountExist(name); if (error) { + storageSetDraft(FORM_SIGN_UP, 'loading', false); storageSetDraft(FORM_SIGN_UP, 'error', { error, example }); emitter.emit('offerName', error, example); return null; @@ -217,8 +221,9 @@ const createAccount = async (name, path) => { storage.remove(DRAFT_STORAGE_KEY); } catch (err) { await emitter.emit('addAccountError', FormatHelper.formatError(err)); - storageSetDraft(FORM_SIGN_UP, 'error', { error: FormatHelper.formatError(err), example: '' }); + } finally { + storageSetDraft(FORM_SIGN_UP, 'loading', false); } return null; @@ -261,11 +266,24 @@ const resolveAccounts = async () => { */ const onMessage = (request, sender, sendResponse) => { const { hostname } = urlParse(sender.tab.url); + const { id: tabId } = sender.tab; request = JSON.parse(JSON.stringify(request)); if (!request.method || !request.appId || request.appId !== APP_ID) return false; + if (request.method === 'closeTab') { + const indexFindRequest = providerRequests.findIndex((rq) => rq.origin === hostname); + if (indexFindRequest === -1) return true; + const indexTabId = providerRequests[indexFindRequest].tabs + .findIndex((id) => id === tabId); + if (indexTabId === -1) return true; + providerRequests[indexFindRequest].cbs.splice(indexTabId, 1); + providerRequests[indexFindRequest].ids.splice(indexTabId, 1); + providerRequests[indexFindRequest].tabs.splice(indexTabId, 1); + return true; + } + if (typeof processedOrigins[hostname] !== 'boolean') { if (request.method !== 'getAccess') { @@ -273,12 +291,20 @@ const onMessage = (request, sender, sendResponse) => { return true; } - if (providerRequests.find((p) => p.origin === hostname)) { - sendResponse({ id: request.id, error: 'Access has already requested' }); + const indexRequest = providerRequests.findIndex((p) => p.origin === hostname); + if (indexRequest !== -1) { + providerRequests[indexRequest].ids.push(request.id); + providerRequests[indexRequest].cbs.push(sendResponse); + providerRequests[indexRequest].tabs.push(tabId); return true; } - providerRequests.push({ origin: hostname, id: request.id, cb: sendResponse }); + providerRequests.push({ + origin: hostname, + tabs: [tabId], + ids: [request.id], + cbs: [sendResponse], + }); setBadge(); @@ -619,15 +645,16 @@ const onSwitchActiveAccount = (res) => { * @param {Boolean} status */ export const onProviderApproval = (err, id, status) => { - const request = providerRequests.find((r) => String(r.id) === id); + const request = providerRequests.find(({ ids }) => String(ids[0]) === id); if (!request) { return; } - request.cb({ error: err, id: request.id, status }); - providerRequests = providerRequests.filter((p) => p.id !== request.id); + request.ids.forEach((rId, index) => request.cbs[index]({ error: err, id: rId, status })); + + providerRequests = providerRequests.filter(({ ids }) => ids[0] !== request.ids[0]); processedOrigins[request.origin] = status; if (!providerRequests.length) { @@ -713,8 +740,8 @@ window.getList = () => requestQueue.map(({ id, data }) => ({ id, options: data } window.getPrivateKey = () => PrivateKey; window.getAes = () => aes; window.Transaction = () => Transaction; -window.getProviderMap = () => providerRequests.reduce((map, { id, origin }) => { - map[id] = origin; +window.getProviderMap = () => providerRequests.reduce((map, { ids: [reqId], origin }) => { + map[reqId] = origin; return map; }, {}); @@ -737,3 +764,6 @@ crypto.on('unlocked', onPinUnlock); extensionizer.runtime.onInstalled.addListener(onFirstInstall); extensionizer.browserAction.setBadgeText({ text: 'BETA' }); + + + diff --git a/extension/contentscript.js b/extension/contentscript.js index 6ad45e0b..6e8378ff 100644 --- a/extension/contentscript.js +++ b/extension/contentscript.js @@ -2,6 +2,7 @@ const extensionizer = require('./extensionizer'); const { APP_ID } = require('../src/constants/GlobalConstants'); +const getAccessRequest = {}; /** * inpage script injection to web page @@ -49,14 +50,28 @@ const onResponse = (res, origin = '*') => { * On Inpage message * @param event */ -const onMessage = (event) => { - - const { data } = event; +const onMessage = async (event) => { + const { data, origin } = event; if (data.target !== 'content' || !data.appId || data.appId !== APP_ID) return; try { - extensionizer.runtime.sendMessage(data, (res) => onResponse(res, event.origin)); + if (data.method !== 'getAccess') { + extensionizer.runtime.sendMessage(data, (res) => onResponse(res, event.origin)); + return; + } + if (!getAccessRequest[origin]) { + getAccessRequest[origin] = new Promise((resolve) => { + extensionizer.runtime.sendMessage(data, (res) => { + onResponse(res, event.origin); + resolve(res); + }); + }); + } else { + const result = await getAccessRequest[origin]; + result.id = event.data.id; + onResponse(result, event.origin); + } } catch (err) { if (err.message.match(/Invocation of form runtime\.connect/) && err.message.match(/doesn't match definition runtime\.connect/)) { console.error('Connection to background error, please reload the page', err); @@ -66,5 +81,12 @@ const onMessage = (event) => { } }; +window.addEventListener('beforeunload', () => { + extensionizer.runtime.sendMessage({ + method: 'closeTab', + appId: APP_ID, + }); +}); + window.addEventListener('message', onMessage, false); diff --git a/package.json b/package.json index 81b1e7b4..88b5f094 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "echo-bridge", "description": "The bridge between your web site and the Echo", - "version": "1.10.0", + "version": "1.10.2", "scripts": { "start": "cross-env NODE_ENV=local webpack-dev-server --mode development --progress --colors --history-api-fallback --hot --inline --port 8081", "build": "cross-env NODE_ENV=production webpack --progress --display-error-details --colors --mode production", @@ -24,7 +24,7 @@ "classnames": "^2.2.6", "config": "^1.30.0", "crypto-random-string": "^1.0.0", - "echojs-lib": "^1.4.0", + "echojs-lib": "^1.6.0", "events": "^3.0.0", "file-loader": "^1.1.11", "focus-trap-react": "^4.0.1", diff --git a/src/actions/BalanceActions.js b/src/actions/BalanceActions.js index 1bac908e..b043a97e 100644 --- a/src/actions/BalanceActions.js +++ b/src/actions/BalanceActions.js @@ -264,7 +264,7 @@ export const setFeeFormValue = () => async (dispatch, getState) => { }, callee: receiver, registrar: fromAccount, - type: OPERATIONS_IDS.CALL_CONTRACT, + type: OPERATIONS_IDS.CONTRACT_CALL, value: { amount: 0, asset_id: assets.get(balances.getIn([selectedFeeBalance, 'asset_type'])), @@ -376,7 +376,7 @@ export const send = () => async (dispatch, getState) => { }, callee: receiver, registrar: fromAccount, - type: OPERATIONS_IDS.CALL_CONTRACT, + type: OPERATIONS_IDS.CONTRACT_CALL, value: { asset_id: coreAsset, amount: 0, @@ -621,6 +621,15 @@ export const watchToken = (contractId) => async (dispatch, getState) => { } const accountId = getState().global.getIn(['account', 'id']); + const [, { code }] = contract; + + const isErc20Token = ValidateTransactionHelper.isErc20Contract(code); + + if (!isErc20Token) { + dispatch(setFormError(FORM_WATCH_TOKEN, 'contractId', 'Invalid token contract')); + dispatch(GlobalReducer.actions.set({ field: 'loading', value: false })); + return null; + } const { symbol, precision, balance } = await getTokenDetails(contractId, accountId); diff --git a/src/actions/ChainStoreAction.js b/src/actions/ChainStoreAction.js index 3c79b8cb..fd431bcc 100644 --- a/src/actions/ChainStoreAction.js +++ b/src/actions/ChainStoreAction.js @@ -6,6 +6,8 @@ import BalanceReducer from '../reducers/BalanceReducer'; import BlockchainReducer from '../reducers/BlockchainReducer'; import { initAssetsBalances, updateTokens } from './BalanceActions'; +import { setValue } from './FormActions'; +import { storageGetDraft } from './GlobalActions'; import echoService from '../services/echo'; @@ -15,13 +17,16 @@ import { } from '../constants/GlobalConstants'; import ChainStoreCacheNames from '../constants/ChainStoreConstants'; import { CONNECTION_ERROR_PATH } from '../constants/RouterConstants'; +import { FORM_SIGN_UP } from '../constants/FormConstants'; import storage from '../services/storage'; import history from '../history'; -import FormatHelper from '../helpers/FormatHelper'; import { updateHistory } from './HistoryActions'; +import FormatHelper from '../helpers/FormatHelper'; + + /** * copy object from ChainStore lib to redux every time when triggered, check connection * @returns {Function} @@ -38,6 +43,17 @@ export const subscribe = () => (dispatch) => { dispatch(updateHistory()); }; +/** + * check loading create account + * @returns {Function} + */ +export const checkActiveLoading = () => async (dispatch) => { + const draftStorage = await storageGetDraft(); + const signUp = draftStorage[FORM_SIGN_UP]; + const loading = signUp && signUp.loading; + dispatch(setValue(FORM_SIGN_UP, 'loading', loading)); + dispatch(GlobalReducer.actions.set({ field: 'loading', value: loading })); +}; /** * connect socket current network * @returns {Function} diff --git a/src/actions/GlobalActions.js b/src/actions/GlobalActions.js index d8305136..97e06556 100644 --- a/src/actions/GlobalActions.js +++ b/src/actions/GlobalActions.js @@ -6,7 +6,7 @@ import { initCrypto, setCryptoInfo, getCryptoInfo, removeCryptoInfo } from './Cr import history from '../history'; import { setFormError, setValue, toggleLoading } from './FormActions'; -import { disconnect, connect } from './ChainStoreAction'; +import { disconnect, connect, checkActiveLoading } from './ChainStoreAction'; import { getTokenDetails, initAssetsBalances, removeBalances } from './BalanceActions'; import { globals, loadRequests } from './SignActions'; @@ -377,7 +377,7 @@ export const onLogout = (name) => async (dispatch, getState) => { await dispatch(initAccount(accounts.getIn([networkName, 0]))); emitter.emit('activeAccountResponse', accounts.getIn([networkName, 0])); - history.push(CREATE_ACCOUNT_PATH); + history.push(INDEX_PATH); } catch (err) { dispatch(set('error', FormatHelper.formatError(err))); } @@ -446,7 +446,7 @@ export const loadInfo = () => async (dispatch, getState) => { Object.entries(tokens).forEach(([accountId, tokensArray]) => { tokensArray.forEach((id) => { - stateTokens = stateTokens.setIn([accountId, `1.14.${id}`], new Map({})); + stateTokens = stateTokens.setIn([accountId, `1.9.${id}`], new Map({})); }); }); @@ -680,8 +680,8 @@ export const switchAccountNetwork = (accountName, network) => async (dispatch) = */ export const globalInit = () => async (dispatch) => { await dispatch(connect()); - await dispatch(initCrypto()); + dispatch(checkActiveLoading()); }; /** diff --git a/src/actions/SignActions.js b/src/actions/SignActions.js index ae6541f8..997511d5 100644 --- a/src/actions/SignActions.js +++ b/src/actions/SignActions.js @@ -48,7 +48,7 @@ const getOperationFee = async (type, transaction) => { let tr = echoService.getChainLib().createTransaction(); - if (type === OPERATIONS_IDS.CALL_CONTRACT) { + if (type === OPERATIONS_IDS.CONTRACT_CALL) { options.fee = undefined; } @@ -206,6 +206,7 @@ export const removeTransaction = (id, isClose) => async (dispatch, getState) => dispatch(GlobalReducer.actions.setIn({ field: 'sign', params: { + transactions: new List(), current: null, }, })); @@ -296,13 +297,7 @@ export const requestHandler = (id, options) => async (dispatch, getState) => { return null; } - // const error = await dispatch(validateTransaction(options)); - // if (error) { - // emitter.emit('response', `${error}`, id, ERROR_STATUS); - // return null; - // } - - const transactions = getState().global.getIn(['sign', 'transactions']); + let transactions = getState().global.getIn(['sign', 'transactions']); if (!transactions.size) { dispatch(GlobalReducer.actions.setIn({ @@ -314,12 +309,17 @@ export const requestHandler = (id, options) => async (dispatch, getState) => { }), }, })); - // await dispatch(setTransaction({ id, options })); } + transactions = transactions.push({ id, options }); + + const dataToShow = await getFetchedData(transactions.get(0).options); dispatch(GlobalReducer.actions.setIn({ field: 'sign', - params: { transactions: transactions.push({ id, options }) }, + params: { + transactions, + dataToShow: new Map(dataToShow), + }, })); return null; diff --git a/src/constants/GlobalConstants.js b/src/constants/GlobalConstants.js index b7c2f5c9..e28247e4 100644 --- a/src/constants/GlobalConstants.js +++ b/src/constants/GlobalConstants.js @@ -154,3 +154,16 @@ export const STORE = 'keyval'; export const PATTERN_ID_MESSAGE = '*'; export const LENGTH_ID_MESSAGE = 10; + +export const ERC20_HASHES = { + 'totalSupply()': '18160ddd', + 'balanceOf(address)': '70a08231', + 'allowance(address,address)': 'dd62ed3e', + 'transfer(address,uint256)': 'a9059cbb', + 'approve(address,uint256)': '095ea7b3', + 'transferFrom(address,address,uint256)': '23b872dd', + 'Transfer(address,address,uint256)': 'ddf252ad', + 'decimals()': '313ce567', + 'symbol()': '95d89b41', +}; + diff --git a/src/constants/OperationConstants.js b/src/constants/OperationConstants.js index bdcb4867..1540b07d 100644 --- a/src/constants/OperationConstants.js +++ b/src/constants/OperationConstants.js @@ -76,18 +76,6 @@ export const operationFields = { field: 'key_auths', }, }, - upgradeAccount: { - account_to_upgrade: { - type: 'account_id', - }, - fee: { - type: 'asset_object', - hasProperties: 'asset_id', - }, - upgrade_to_lifetime_member: { - field: 'string', - }, - }, }; export const operationFieldsSend = { @@ -111,7 +99,7 @@ export const operationFieldsSend = { hasProperties: ['amount', 'asset_id'], }, }, - [OPERATIONS_IDS.CALL_CONTRACT]: { + [OPERATIONS_IDS.CONTRACT_CALL]: { fee: { type: 'asset_object', required: false, @@ -143,8 +131,7 @@ export const operationKeys = { createContract: 'registrar', createAccount: 'registrar', updateAccount: 'account', - upgradeAccount: 'account_to_upgrade', - [OPERATIONS_IDS.CALL_CONTRACT]: 'registrar', + [OPERATIONS_IDS.CONTRACT_CALL]: 'registrar', }; export const operationTypes = { @@ -154,11 +141,11 @@ export const operationTypes = { }, contract: { name: 'Contract call', - code: OPERATIONS_IDS.CALL_CONTRACT, + code: OPERATIONS_IDS.CONTRACT_CALL, }, createContract: { name: 'Contract create', - code: OPERATIONS_IDS.CREATE_CONTRACT, + code: OPERATIONS_IDS.CONTRACT_CREATE, }, createAccount: { name: 'Account create', @@ -168,10 +155,6 @@ export const operationTypes = { name: 'Update account', code: OPERATIONS_IDS.ACCOUNT_UPDATE, }, - upgradeAccount: { - name: 'Upgrade account', - code: OPERATIONS_IDS.ACCOUNT_UPGRADE, - }, }; export const historyOperations = [ diff --git a/src/constants/TransactionConstants.js b/src/constants/TransactionConstants.js index c114c863..cd2e1d28 100644 --- a/src/constants/TransactionConstants.js +++ b/src/constants/TransactionConstants.js @@ -11,46 +11,6 @@ export default { asset: 'amount.asset_id', }, }, - limit_order_create: { - value: OPERATIONS_IDS.LIMIT_ORDER_CREATE, - name: 'Place order', - options: { - from: 'seller', - subject: null, - value: 'amount_to_sell.amount', - asset: 'amount_to_sell.asset_id', - }, - }, - limit_order_cancel: { - value: OPERATIONS_IDS.LIMIT_ORDER_CANCEL, - name: 'Cancel order', - options: { - from: 'fee_paying_account', - subject: ['order', 'name'], - value: null, - asset: null, - }, - }, - call_order_update: { - value: OPERATIONS_IDS.CALL_ORDER_UPDATE, - name: 'Update margin', - options: { - from: 'funding_account', - subject: null, - value: null, - asset: null, - }, - }, - fill_order: { - value: OPERATIONS_IDS.FILL_ORDER, - name: 'Fill order', - options: { - from: 'account_id', - subject: ['order_id', null], - value: 'pays.amount', - asset: 'pays.asset_id', - }, - }, account_create: { value: OPERATIONS_IDS.ACCOUNT_CREATE, name: 'Account created', @@ -81,16 +41,6 @@ export default { asset: null, }, }, - account_upgrade: { - value: OPERATIONS_IDS.ACCOUNT_UPGRADE, - name: 'Upgrade Account', - options: { - from: 'account_to_upgrade', - subject: null, - value: null, - asset: null, - }, - }, account_transfer: { value: OPERATIONS_IDS.ACCOUNT_TRANSFER, name: 'Transfer Account', @@ -171,26 +121,6 @@ export default { asset: 'asset_id', }, }, - asset_settle: { - value: OPERATIONS_IDS.ASSET_SETTLE, - name: 'Asset settlement', - options: { - from: 'account', - subject: null, - value: 'amount.amount', - asset: 'amount.asset_id', - }, - }, - asset_global_settle: { - value: OPERATIONS_IDS.ASSET_GLOBAL_SETTLE, - name: 'Global asset settlement', - options: { - from: 'issuer', - subject: null, - value: 'settle_price', - asset: 'asset_to_settle', - }, - }, asset_publish_feed: { value: OPERATIONS_IDS.ASSET_PUBLISH_FEED, name: 'Publish feed', @@ -231,46 +161,6 @@ export default { asset: null, }, }, - withdraw_permission_create: { - value: OPERATIONS_IDS.WITHDRAW_PERMISSION_CREATE, - name: 'Create withdrawal permission', - options: { - from: 'withdraw_from_account', - subject: null, - value: null, - asset: null, - }, - }, - withdraw_permission_update: { - value: OPERATIONS_IDS.WITHDRAW_PERMISSION_UPDATE, - name: 'Update withdrawal permission', - options: { - from: 'withdraw_from_account', - subject: null, - value: null, - asset: null, - }, - }, - withdraw_permission_claim: { - value: OPERATIONS_IDS.WITHDRAW_PERMISSION_CLAIM, - name: 'Claim withdrawal permission', - options: { - from: 'withdraw_from_account', - subject: ['withdraw_to_account', 'name'], - value: 'amount_to_withdraw.amount', - asset: 'amount_to_withdraw.asset_id', - }, - }, - withdraw_permission_delete: { - value: OPERATIONS_IDS.WITHDRAW_PERMISSION_DELETE, - name: 'Delete withdrawal permission', - options: { - from: 'withdraw_from_account', - subject: null, - value: null, - asset: null, - }, - }, committee_member_create: { value: OPERATIONS_IDS.COMMITTEE_MEMBER_CREATE, name: 'Create committee member', @@ -321,26 +211,6 @@ export default { asset: 'amount.asset_id', }, }, - custom: { - value: OPERATIONS_IDS.CUSTOM, - name: 'Custom', - options: { - from: 'payer', - subject: null, - value: null, - asset: null, - }, - }, - assert: { - value: OPERATIONS_IDS.ASSERT, - name: 'Assert operation', - options: { - from: 'fee_paying_account', - subject: null, - value: null, - asset: null, - }, - }, balance_claim: { value: OPERATIONS_IDS.BALANCE_CLAIM, name: 'Claim balance', @@ -361,16 +231,6 @@ export default { asset: 'amount.asset_id', }, }, - asset_settle_cancel: { - value: OPERATIONS_IDS.ASSET_SETTLE_CANCEL, - name: 'Cancel asset settlement', - options: { - from: 'account', - subject: null, - value: 'amount.amount', - asset: 'amount.asset_id', - }, - }, asset_claim_fees: { value: OPERATIONS_IDS.ASSET_CLAIM_FEES, name: 'Claim asset fees', @@ -382,7 +242,7 @@ export default { }, }, contract: { - value: OPERATIONS_IDS.CREATE_CONTRACT, + value: OPERATIONS_IDS.CONTRACT_CREATE, name: 'Contract created', options: { from: 'registrar', @@ -391,9 +251,9 @@ export default { asset: 'value.asset_id', }, }, - call_contract: { - value: OPERATIONS_IDS.CALL_CONTRACT, - name: 'Call contract', + contract_call: { + value: OPERATIONS_IDS.CONTRACT_CALL, + name: 'Contract call', options: { from: 'registrar', subject: null, @@ -412,7 +272,7 @@ export default { }, }, change_sidechain_config: { - value: OPERATIONS_IDS.CHANGE_SIDECHAIN_CONFIG, + value: OPERATIONS_IDS.SIDECHAIN_CHANGE_CONFIG, name: 'Change sidechain config', options: { from: null, @@ -441,9 +301,9 @@ export default { asset: 'amount.asset_id', }, }, - generate_eth_address: { - value: OPERATIONS_IDS.GENERATE_ETH_ADDRESS, - name: 'Generate eth address', + sidechain_eth_create_address: { + value: OPERATIONS_IDS.SIDECHAIN_ETH_CREATE_ADDRESS, + name: 'Sidechain eth create address', options: { from: 'account', subject: null, @@ -451,9 +311,9 @@ export default { asset: null, }, }, - create_eth_address: { - value: OPERATIONS_IDS.CREATE_ETH_ADDRESS, - name: 'Create eth address', + sidechain_eth_approve_address: { + value: OPERATIONS_IDS.SIDECHAIN_ETH_APPROVE_ADDRESS, + name: 'Sidechain eth approve address', options: { from: 'account', subject: null, @@ -461,9 +321,9 @@ export default { asset: null, }, }, - deposit_eth: { - value: OPERATIONS_IDS.DEPOSIT_ETH, - name: 'Deposit eth', + sidechain_eth_deposit: { + value: OPERATIONS_IDS.SIDECHAIN_ETH_DEPOSIT, + name: 'Sidechain eth deposit', options: { from: 'committee_member_id', subject: ['account', 'name'], @@ -471,9 +331,9 @@ export default { asset: null, }, }, - withdraw_eth: { - value: OPERATIONS_IDS.WITHDRAW_ETH, - name: 'Withdraw eth', + sidechain_eth_withdraw: { + value: OPERATIONS_IDS.SIDECHAIN_ETH_WITHDRAW, + name: 'Sidechain eth withdraw', options: { from: 'account', subject: ['eth_addr'], @@ -481,9 +341,9 @@ export default { asset: null, }, }, - approve_withdraw_eth: { - value: OPERATIONS_IDS.APPROVE_WITHDRAW_ETH, - name: 'Approve withdraw eth', + sidechain_eth_approve_withdraw: { + value: OPERATIONS_IDS.SIDECHAIN_ETH_APPROVE_WITHDRAW, + name: 'Sidechain eth approve withdraw', options: { from: 'committee_member_id', subject: ['withdraw_id'], @@ -512,7 +372,7 @@ export default { }, }, sidechain_issue: { - value: OPERATIONS_IDS.SIDECHAIN_ISSUE, + value: OPERATIONS_IDS.SIDECHAIN_ETH_ISSUE, name: 'Sidechain issue', options: { from: 'account', @@ -522,7 +382,7 @@ export default { }, }, sidechain_burn: { - value: OPERATIONS_IDS.SIDECHAIN_BURN, + value: OPERATIONS_IDS.SIDECHAIN_ETH_BURN, name: 'Sidechain burn', options: { from: 'account', @@ -532,7 +392,7 @@ export default { }, }, register_erc20_token: { - value: OPERATIONS_IDS.REGISTER_ERC20_TOKEN, + value: OPERATIONS_IDS.SIDECHAIN_ERC20_REGISTER_TOKEN, name: 'Register ERC20 token', options: { from: 'account', @@ -542,7 +402,7 @@ export default { }, }, deposit_erc20_token: { - value: OPERATIONS_IDS.DEPOSIT_ERC20_TOKEN, + value: OPERATIONS_IDS.SIDECHAIN_ERC20_DEPOSIT_TOKEN, name: 'Deposit ERC20 token', options: { from: 'account', @@ -552,7 +412,7 @@ export default { }, }, withdraw_erc20_token: { - value: OPERATIONS_IDS.WITHDRAW_ERC20_TOKEN, + value: OPERATIONS_IDS.SIDECHAIN_ERC20_WITHDRAW_TOKEN, name: 'Withdraw ERC20 token', options: { from: 'account', @@ -562,7 +422,7 @@ export default { }, }, approve_erc20_token_withdraw: { - value: OPERATIONS_IDS.APPROVE_ERC20_TOKEN_WITHDRAW, + value: OPERATIONS_IDS.SIDECHAIN_ERC20_APPROVE_TOKEN_WITHDRAW, name: 'Approve ERC20 token withdraw', options: { from: 'account', diff --git a/src/containers/App.jsx b/src/containers/App.jsx index ef8fc334..64da2903 100644 --- a/src/containers/App.jsx +++ b/src/containers/App.jsx @@ -15,7 +15,6 @@ import { PIN_PATHS, SIGN_TRANSACTION_PATH, CONNECTION_ERROR_PATH } from '../cons import bridgeLogo from '../assets/images/bridge-logo-hor-bw.svg'; - class App extends React.Component { @@ -40,7 +39,9 @@ class App extends React.Component { } renderApp() { - const { children, loading, pathname } = this.props; + const { + children, loading, pathname, + } = this.props; return (
diff --git a/src/containers/CreateAccount/index.jsx b/src/containers/CreateAccount/index.jsx index bbe7192a..173d814a 100644 --- a/src/containers/CreateAccount/index.jsx +++ b/src/containers/CreateAccount/index.jsx @@ -67,7 +67,11 @@ class CreateAccount extends React.Component { } componentWillUnmount() { - storageRemoveDraft(); + const { accounts, networkName } = this.props; + if (accounts.get(networkName).size) { + storageRemoveDraft(); + } + this.props.clearForm(); } diff --git a/src/containers/SignTransaction/index.jsx b/src/containers/SignTransaction/index.jsx index 19dbfd53..892bb513 100644 --- a/src/containers/SignTransaction/index.jsx +++ b/src/containers/SignTransaction/index.jsx @@ -44,6 +44,8 @@ class SignTransaction extends React.Component { return null; } + this.loadInfo(); + return null; } diff --git a/src/helpers/ValidateTransactionHelper.js b/src/helpers/ValidateTransactionHelper.js index 1baa3863..9d551da9 100644 --- a/src/helpers/ValidateTransactionHelper.js +++ b/src/helpers/ValidateTransactionHelper.js @@ -1,4 +1,5 @@ import BN from 'bignumber.js'; +import { ERC20_HASHES } from '../constants/GlobalConstants'; class ValidateTransactionHelper { @@ -6,7 +7,7 @@ class ValidateTransactionHelper { id = id.split('.'); - if (id.length !== 3 || parseInt(id[2], 10).toString() !== id[2] || id.splice(0, 2).join('.') !== '1.14') { + if (id.length !== 3 || parseInt(id[2], 10).toString() !== id[2] || id.splice(0, 2).join('.') !== '1.9') { return 'Invalid contract ID'; } @@ -73,6 +74,20 @@ class ValidateTransactionHelper { return null; } + /** + * + * @param {String} scriptHex + * @returns {boolean} + */ + static isErc20Contract(scriptHex) { + if (scriptHex) { + const hashes = Object.values(ERC20_HASHES); + return hashes.every((hash) => scriptHex.includes(hash)); + } + + return false; + } + } export default ValidateTransactionHelper; diff --git a/src/reducers/FormReducer.js b/src/reducers/FormReducer.js index 27ba932f..7584754d 100644 --- a/src/reducers/FormReducer.js +++ b/src/reducers/FormReducer.js @@ -19,6 +19,7 @@ const DEFAULT_FIELDS = Map({ const DEFAULT_FORM_FIELDS = { [FORM_SIGN_UP]: Map({ + loading: false, accountName: { error: null, example: '',