diff --git a/package-lock.json b/package-lock.json index 5eedcf4439..4d8c339fe1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "waves-client", - "version": "1.3.14", + "version": "1.3.16", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -845,9 +845,9 @@ "integrity": "sha512-1qxL22a8LRA38xxzmmJktdVdGTfz2d9SXr9SI2gPpCJSKYrKb7SNGbOE3TgIyCRY0fquOHMtkwXuKGRw+LsJoA==" }, "@waves/signature-adapter": { - "version": "5.1.11", - "resolved": "https://registry.npmjs.org/@waves/signature-adapter/-/signature-adapter-5.1.11.tgz", - "integrity": "sha512-NzMZRcUQ2j1spq5ZilekcqGV3zLQph0KRDxlJmjHpaB+3Wpzp8lBMG0KcRj108ZggDRjlv3vkvhrUUsUpjx4TA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@waves/signature-adapter/-/signature-adapter-5.2.0.tgz", + "integrity": "sha512-Euk9djG9yOkase45mehIDGAgkBe3iiHxSGUhzk8Yl6IPhfZl4022Nf8+Ylu4ieQUDTXhYcjnOiyeGYNdZAfFyA==", "requires": { "@types/ramda": "^0.25.46", "@waves/bignumber": "^0.0.1", @@ -855,7 +855,7 @@ "@waves/ledger": "^3.4.0", "@waves/money-like-to-node": "0.0.10", "@waves/ts-types": "^0.2.0", - "@waves/waves-transactions": "^3.14.6", + "@waves/waves-transactions": "^3.16.3", "ramda": "^0.25.0" }, "dependencies": { @@ -864,35 +864,17 @@ "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.25.51.tgz", "integrity": "sha512-xcmtfHIgF9SYjhGdsZR1nQslxG4hu0cIpFfLQ4CWdw3KzHvl7ki1AzFLQUkbDTG42ZN3ZsQfdRzXRlkAvbIy5Q==" }, - "@waves/ts-lib-crypto": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@waves/ts-lib-crypto/-/ts-lib-crypto-1.0.2.tgz", - "integrity": "sha512-sauJe9pS5rGeXHxOV6HMU7osHIGwer3gLfERiEz/JGpl594/Yc4v5h0UaUYs6iEd5ASr08STHvcSX/vi/FPPww==", - "requires": { - "node-forge": "^0.8.5" - } - }, "@waves/ts-types": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@waves/ts-types/-/ts-types-0.2.0.tgz", "integrity": "sha512-mJOovPtwTyFV6fgI+KKFJ8IeqWSTXdKPOwgcCX9vT7wwMNwiJS2dMboAW2acR8YLiPy7LzZ5t41JCxvGLU+ZSA==" - }, - "@waves/waves-transactions": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/@waves/waves-transactions/-/waves-transactions-3.16.1.tgz", - "integrity": "sha512-aVvOJR4UnQI8jgzXvEMTQZ28/WqxGu3znCXh3kgNkdnYBg8P/8Q45Cn7v5p2PVyLy57EOJk6zdzFw1Tb2Er15g==", - "requires": { - "@waves/marshall": "^0.8.0", - "@waves/ts-lib-crypto": "^1.0.2", - "axios": "^0.19.0" - } } } }, "@waves/ts-lib-crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@waves/ts-lib-crypto/-/ts-lib-crypto-1.0.1.tgz", - "integrity": "sha512-aeB3I5DYE1j5gMbM4tzoHdaOVTJj73MldrJ0LNa5zmOAAWz8cFpELjVTChVj+6qzm0EuQD8I0kTcEfdwmHR/jw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@waves/ts-lib-crypto/-/ts-lib-crypto-1.1.1.tgz", + "integrity": "sha512-rU4NOa2agwpQmDAomnU2NSbnla3XvEL8PJB4hn8pKWqVxnfcyL4OwxgSUPhLZsV4SQgWasDqBpaLB3mVYf/QRA==", "requires": { "node-forge": "^0.8.5" } @@ -919,12 +901,12 @@ } }, "@waves/waves-transactions": { - "version": "3.14.3", - "resolved": "https://registry.npmjs.org/@waves/waves-transactions/-/waves-transactions-3.14.3.tgz", - "integrity": "sha512-wmyZZa+bIYbYxsqg6NipcO+d7yrfnhIJXrcl7QH0B4wzaVgUiMTedrPLDlGaxgq7yPMFyH3DALIjd+NBXtJYhw==", + "version": "3.16.3", + "resolved": "https://registry.npmjs.org/@waves/waves-transactions/-/waves-transactions-3.16.3.tgz", + "integrity": "sha512-PDk9/AC1ZNzRqb0K8AGDX2iGsZo2/LibW82rBZ6J6jvpKwkg0VFE/ly7kLh1bFJC5oHmlE34bFB0YqnWYGfutw==", "requires": { "@waves/marshall": "^0.8.0", - "@waves/ts-lib-crypto": "^1.0.1", + "@waves/ts-lib-crypto": "^1.1.1", "axios": "^0.19.0" } }, diff --git a/package.json b/package.json index 8242f33504..f24bec058f 100644 --- a/package.json +++ b/package.json @@ -110,10 +110,10 @@ "@waves/ledger": "^3.4.0", "@waves/marshall": "^0.8.0", "@waves/oracle-data": "^0.0.6", - "@waves/signature-adapter": "^5.1.11", + "@waves/signature-adapter": "^5.2.0", "@waves/ts-types": "0.0.2", "@waves/waves-browser-bus": "^0.1.5", - "@waves/waves-transactions": "^3.14.3", + "@waves/waves-transactions": "^3.16.3", "angular": "1.6.6", "angular-animate": "1.6.6", "angular-aria": "1.6.6", diff --git a/src/modules/app/services/User.js b/src/modules/app/services/User.js index 0ec6b3f0d4..09dd20657e 100644 --- a/src/modules/app/services/User.js +++ b/src/modules/app/services/User.js @@ -89,6 +89,10 @@ * @type {string} */ encryptedSeed; + /** + * @type {string} + */ + encryptedPrivateKey; /** * @type {string} */ @@ -362,6 +366,7 @@ * @param {string} data.name * @param {string} data.id * @param {string} data.encryptedSeed + * @param {string} data.encryptedPrivateKey * @param {string} data.publicKey * @param {string} data.password * @param {string} data.userType @@ -384,6 +389,7 @@ name: data.name, userType: data.userType, encryptedSeed: data.encryptedSeed, + encryptedPrivateKey: data.encryptedPrivateKey, publicKey: data.publicKey, settings: { termsAccepted: false, @@ -597,6 +603,7 @@ this.name = null; this.publicKey = null; this.encryptedSeed = null; + this.encryptedPrivateKey = null; this.userType = null; this.settings = Object.create(null); this.lastLogin = Date.now(); diff --git a/src/modules/import/templates/import.html b/src/modules/import/templates/import.html index f3e5684986..00ec810b9f 100644 --- a/src/modules/import/templates/import.html +++ b/src/modules/import/templates/import.html @@ -14,8 +14,9 @@ w-analytics event="'Import Backup Click'" event-target="'ui'">
-
-
+
+
-
+
@@ -31,7 +32,7 @@
-
+
diff --git a/src/modules/restore/controllers/RestoreCtrl.js b/src/modules/restore/controllers/RestoreCtrl.js index eaae7c2cd6..a68aead60b 100644 --- a/src/modules/restore/controllers/RestoreCtrl.js +++ b/src/modules/restore/controllers/RestoreCtrl.js @@ -2,6 +2,13 @@ 'use strict'; const analytics = require('@waves/event-sender'); + const { validators, libs } = require('@waves/waves-transactions'); + const { isPublicKey } = validators; + const { address, publicKey } = libs.crypto; + const TABS = { + seed: 'seed', + key: 'key' + }; /** * @param Base @@ -17,12 +24,10 @@ constructor() { super($scope); + $scope.TABS = TABS; this.seedForm = null; - /** - * @type {string} - */ - this.address = ''; + this.keyForm = null; /** * @type {string} */ @@ -30,19 +35,19 @@ /** * @type {string} */ - this.name = ''; + this.key = ''; /** * @type {string} */ - this.encryptedSeed = ''; + this.address = ''; /** * @type {string} */ - this.password = ''; + this.name = ''; /** * @type {string} */ - this.restoreType = ''; + this.password = ''; /** * @type {boolean} */ @@ -51,11 +56,32 @@ * @type {number} */ this.activeStep = 0; + /** + * @type {string[]} + */ + this.tabs = Object.values(TABS); + /** + * @type {string} + */ + this.activeTab = TABS.seed; this.observe('seed', this._onChangeSeed); this.observeOnce('seedForm', () => { - this.receive(utils.observe(this.seedForm, '$valid'), this._onChangeSeed, this); + this.receive(utils.observe(this.seedForm, '$valid'), () => { + if (this.activeTab === TABS.seed) { + this._onChangeSeed(); + } + }); }); + this.observe('key', this._onChangeKey); + this.observeOnce('keyForm', () => { + this.receive(utils.observe(this.keyForm, '$valid'), () => { + if (this.activeTab === TABS.key) { + this._onChangeKey(); + } + }); + }); + this.observe('activeTab', this._onChangeActiveTab); } showTutorialModals() { @@ -63,18 +89,17 @@ } restore() { - if (!this.saveUserData) { this.password = Date.now().toString(); } else { analytics.send({ name: 'Import Backup Protect Your Account Continue Click', target: 'ui' }); } - const encryptedSeed = new ds.Seed(this.seed, window.WavesApp.network.code).encrypt(this.password); + const { encrypted, type } = this._getEncryptedAndType(); const userSettings = user.getDefaultUserSettings({ termsAccepted: false }); const newUser = { - userType: this.restoreType, + userType: type, address: this.address, name: this.name, password: this.password, @@ -82,7 +107,7 @@ path: this.userPath, settings: userSettings, saveToStorage: this.saveUserData, - encryptedSeed + ...encrypted }; const api = ds.signature.getDefaultSignatureApi(newUser); @@ -116,6 +141,13 @@ return modalManager.showImportAccountsModal(); } + /** + * @param {string} tab + */ + setActiveTab(tab) { + this.activeTab = tab; + } + /** * @private */ @@ -127,6 +159,52 @@ } } + /** + * @private + */ + _onChangeKey() { + if (this.keyForm.$valid && isPublicKey(this.key)) { + const pubKey = publicKey({ privateKey: this.key }); + this.address = address({ publicKey: pubKey }, window.WavesApp.network.code); + } else { + this.address = ''; + } + } + + /** + * @private + */ + _onChangeActiveTab() { + const tab = this.activeTab[0].toUpperCase() + this.activeTab.substring(1); + this[`_onChange${tab}`](); + } + + /** + * @return {{encrypted: {encryptedSeed: string}, type: string}| + * {encrypted: {encryptedPrivateKey: string}, type: string}} + * @private + */ + _getEncryptedAndType() { + switch (this.activeTab) { + case TABS.key: + return ({ + encrypted: { + encryptedPrivateKey: new ds.Seed(this.key, window.WavesApp.network.code) + .encrypt(this.password) + }, + type: 'privateKey' + }); + default: + return ({ + encrypted: { + encryptedSeed: new ds.Seed(this.seed, window.WavesApp.network.code) + .encrypt(this.password) + }, + type: 'seed' + }); + } + } + } return new RestoreCtrl(); diff --git a/src/modules/restore/less/restore.less b/src/modules/restore/less/restore.less index e5e5c7b40f..9abcf11b0c 100644 --- a/src/modules/restore/less/restore.less +++ b/src/modules/restore/less/restore.less @@ -46,7 +46,7 @@ body.restore { .avatar-img { width: 100%; height: 100%; - } + } } } @@ -71,6 +71,44 @@ body.restore { } } } + + .tab { + display: flex; + margin: 0 auto 20px; + max-width: 320px; + + &__item { + height: 42px; + .body-2; + color: @color-basic-700; + cursor: pointer; + padding: 0 10px; + align-items: center; + justify-content: center; + display: inline-flex; + flex: 1 0; + white-space: nowrap; + border: 1px solid @color-basic-200; + margin-right: -1px; + transition: background 0.5s; + + &:first-child { + border-top-left-radius: @border-radius; + border-bottom-left-radius: @border-radius; + } + + &:last-child { + border-top-right-radius: @border-radius; + border-bottom-right-radius: @border-radius; + margin-right: 0; + } + + &.active { + background-color: @color-white; + color: @color-submit-400; + } + } + } } @media screen and (max-width: 768px) { @@ -105,4 +143,4 @@ body.restore { } } } -} \ No newline at end of file +} diff --git a/src/modules/restore/templates/restore.html b/src/modules/restore/templates/restore.html index 889b998100..499658969d 100644 --- a/src/modules/restore/templates/restore.html +++ b/src/modules/restore/templates/restore.html @@ -7,15 +7,26 @@ -
-
- +
+
+
-
+
+
+
+ +
+
-
-
+
+ -
- -
-
-
-
- {{$ctrl.address}} -
+ +
+ +
+
+ +
+
+
+
+ {{$ctrl.address}}
+
+ -
- - -
-
-
-
-
- - - - +
+ + +
+
+
+
+
+ + + diff --git a/src/modules/saveSeed/controllers/SaveSeedCtrl.js b/src/modules/saveSeed/controllers/SaveSeedCtrl.js index fb26475c00..7b66589001 100644 --- a/src/modules/saveSeed/controllers/SaveSeedCtrl.js +++ b/src/modules/saveSeed/controllers/SaveSeedCtrl.js @@ -86,7 +86,7 @@ let canLoginPromise; - if (this._isSeedAdapter(api)) { + if (this._isSeedAdapter(api) || this._isPrivateKey(api)) { canLoginPromise = adapterAvailablePromise.then(() => api.getAddress()) .then(address => address === activeUser.address ? true : Promise.reject('Wrong address!')); } else { @@ -142,6 +142,15 @@ return api.type && api.type === 'seed'; } + /** + * @param {Adapter} api + * @return boolean + * @private + */ + _isPrivateKey(api) { + return api.type && api.type === 'privateKey'; + } + /** * @private */ @@ -172,7 +181,8 @@ _updateActiveUserAddress() { if (this.userList.length) { this.activeUserAddress = this.userList[0].address; - this.needPassword = !this.userList[0].userType || this.userList[0].userType === 'seed'; + this.needPassword = !this.userList[0].userType || this.userList[0].userType === 'seed' || + this.userList[0].userType === 'privateKey'; } else { this.activeUserAddress = null; this.needPassword = true; @@ -211,7 +221,8 @@ }); this._activeUserIndex = index; - this.needPassword = !this.userList[index].userType || this.userList[index].userType === 'seed'; + this.needPassword = !this.userList[index].userType || this.userList[index].userType === 'seed' || + this.userList[index].userType === 'privateKey'; } } diff --git a/src/modules/signIn/controllers/SignInCtrl.js b/src/modules/signIn/controllers/SignInCtrl.js index c9fcdaef11..07a339733f 100644 --- a/src/modules/signIn/controllers/SignInCtrl.js +++ b/src/modules/signIn/controllers/SignInCtrl.js @@ -91,7 +91,7 @@ let canLoginPromise; - if (this._isSeedAdapter(api)) { + if (this._isSeedAdapter(api) || this._isPrivateKeyAdapter(api)) { canLoginPromise = adapterAvailablePromise.then(() => api.getAddress()) .then(address => address === activeUser.address ? true : Promise.reject('Wrong address!')); } else { @@ -106,7 +106,7 @@ address: activeUser.address }); }, () => { - if (!this._isSeedAdapter(api)) { + if (!this._isSeedAdapter(api) && !this._isPrivateKeyAdapter(api)) { const errorData = { error: 'load-user-error', userType: api.type, @@ -147,6 +147,15 @@ return api.type && api.type === 'seed'; } + /** + * @param {Adapter} api + * return boolean + * @private + */ + _isPrivateKeyAdapter(api) { + return api.type && api.type === 'privateKey'; + } + /** * @private */ @@ -187,7 +196,9 @@ _updateActiveUserAddress() { if (this.userList.length) { this.activeUserAddress = this.userList[0].address; - this.needPassword = !this.userList[0].userType || this.userList[0].userType === 'seed'; + this.needPassword = !this.userList[0].userType || + this.userList[0].userType === 'seed' || + this.userList[0].userType === 'privateKey'; } else { this.activeUserAddress = null; this.needPassword = true; @@ -226,7 +237,9 @@ }); this._activeUserIndex = index; - this.needPassword = !this.userList[index].userType || this.userList[index].userType === 'seed'; + this.needPassword = !this.userList[index].userType || + this.userList[index].userType === 'seed' || + this.userList[index].userType === 'privateKey'; } } diff --git a/src/modules/utils/modals/confirmDeleteUser/confirmDeleteUser.modal.html b/src/modules/utils/modals/confirmDeleteUser/confirmDeleteUser.modal.html index 9c0e347c57..5b75f9789b 100644 --- a/src/modules/utils/modals/confirmDeleteUser/confirmDeleteUser.modal.html +++ b/src/modules/utils/modals/confirmDeleteUser/confirmDeleteUser.modal.html @@ -7,6 +7,7 @@

+

@@ -14,8 +15,9 @@

-
-
+
+
+
+
+
+

+
+
+ +
+
+ + + +
+

diff --git a/src/modules/utils/services/utils.js b/src/modules/utils/services/utils.js index 9f44c4b4ae..08455d3fb8 100644 --- a/src/modules/utils/services/utils.js +++ b/src/modules/utils/services/utils.js @@ -1888,7 +1888,7 @@ */ const modalManager = $injector.get('modalManager'); - if (user.userType === 'seed') { + if (user.userType === 'seed' || user.userType === 'privateKey') { return signable.addMyProof() .then(() => signable); }