From 0b74fb81803f507ac859464bbadaed86c0769483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Thu, 15 Apr 2021 12:56:05 +0200 Subject: [PATCH 01/38] [DDW-652] Hardware Wallets spending password issue with Trezor (#2520) * [DDW-652] Introduce a fix for the hardware wallets spending password issue * [DDW-652] Use finally clause in try/catch to resume polling * [DDW-652] Remove unnecessary logs --- CHANGELOG.md | 6 +++++ source/renderer/app/api/api.js | 14 +++++++---- .../app/stores/HardwareWalletsStore.js | 24 +++++++++++++++++++ source/renderer/app/stores/WalletsStore.js | 13 ++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b506a7978..866ee98024 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Changelog ========= +## vNext + +### Fixes + +- Fixed hardware wallets spending password issue ([PR 2519](https://github.com/input-output-hk/daedalus/pull/2519)) + ## 4.0.5 ### Features diff --git a/source/renderer/app/api/api.js b/source/renderer/app/api/api.js index 854677da52..3c5a70e043 100644 --- a/source/renderer/app/api/api.js +++ b/source/renderer/app/api/api.js @@ -255,12 +255,21 @@ export default class AdaApi { getWallets = async (): Promise> => { logger.debug('AdaApi::getWallets called'); + const { + getHardwareWalletLocalData, + getHardwareWalletsLocalData, + } = global.daedalus.api.localStorage; try { const wallets: AdaWallets = await getWallets(this.config); const legacyWallets: LegacyAdaWallets = await getLegacyWallets( this.config ); - logger.debug('AdaApi::getWallets success', { wallets, legacyWallets }); + const hwLocalData = await getHardwareWalletsLocalData(); + logger.debug('AdaApi::getWallets success', { + wallets, + legacyWallets, + hwLocalData: filterLogData(hwLocalData), + }); map(legacyWallets, (legacyAdaWallet) => { const extraLegacyWalletProps = { address_pool_gap: 0, // Not needed for legacy wallets @@ -281,9 +290,6 @@ export default class AdaApi { return await Promise.all( wallets.map(async (wallet) => { const { id } = wallet; - const { - getHardwareWalletLocalData, - } = global.daedalus.api.localStorage; const walletData = await getHardwareWalletLocalData(id); return _createWalletFromServerData({ ...wallet, diff --git a/source/renderer/app/stores/HardwareWalletsStore.js b/source/renderer/app/stores/HardwareWalletsStore.js index 33dc5a12ed..bfa3e427d2 100644 --- a/source/renderer/app/stores/HardwareWalletsStore.js +++ b/source/renderer/app/stores/HardwareWalletsStore.js @@ -482,6 +482,9 @@ export default class HardwareWalletsStore extends Store { logger.debug( '[HW-DEBUG] HWStore - Establish connection:: Transaction initiated - Recognized device found' ); + logger.debug('[HW-DEBUG] HWStore - Set transport device 1', { + recognizedPairedHardwareWallet, + }); runInAction('HardwareWalletsStore:: Set transport device', () => { this.transportDevice = recognizedPairedHardwareWallet; }); @@ -532,6 +535,9 @@ export default class HardwareWalletsStore extends Store { isTrezor, } ); + logger.debug('[HW-DEBUG] HWStore - Set transport device 2', { + lastDeviceTransport, + }); runInAction('HardwareWalletsStore:: Set transport device', () => { this.transportDevice = lastDeviceTransport; }); @@ -649,6 +655,9 @@ export default class HardwareWalletsStore extends Store { } // All Checks pass - mark device as connected (set transport device for this session) + logger.debug('[HW-DEBUG] HWStore - Set transport device 3', { + transportDevice, + }); runInAction('HardwareWalletsStore:: set HW device CONNECTED', () => { this.transportDevice = transportDevice; }); @@ -1001,6 +1010,17 @@ export default class HardwareWalletsStore extends Store { } // Software Wallet not recognized, create new one with default name + logger.debug('[HW-DEBUG] HWStore - Initiate HW create / restore', { + transportDevice, + device: { + deviceId, + deviceType, + deviceModel, + deviceName, + path: forcedPath || path, + firmwareVersion: null, + }, + }); await this.actions.wallets.createHardwareWallet.trigger({ walletName: deviceName || DEFAULT_HW_NAME, extendedPublicKey, @@ -1013,6 +1033,7 @@ export default class HardwareWalletsStore extends Store { firmwareVersion: null, }, }); + logger.debug('[HW-DEBUG] HWStore - HW created / restored'); // Get all Pending devices with this path and delete const recognizedPendingDevice = find( @@ -1503,6 +1524,9 @@ export default class HardwareWalletsStore extends Store { logger.debug('[HW-DEBUG] Sign Trezor: ', { id }); const transportDevice = await this.establishHardwareWalletConnection(); if (transportDevice) { + logger.debug('[HW-DEBUG] HWStore - Set transport device 4', { + transportDevice, + }); runInAction( 'HardwareWalletsStore:: Set transport device fomr tx init', () => { diff --git a/source/renderer/app/stores/WalletsStore.js b/source/renderer/app/stores/WalletsStore.js index da95263aa8..26c7891133 100644 --- a/source/renderer/app/stores/WalletsStore.js +++ b/source/renderer/app/stores/WalletsStore.js @@ -586,7 +586,18 @@ export default class WalletsStore extends Store { const { deviceId, deviceType, deviceModel, deviceName, path } = device; const accountPublicKey = extendedPublicKey.publicKeyHex + extendedPublicKey.chainCodeHex; + + logger.debug('[HW-DEBUG] HWStore - Execute HW create / restore', { + deviceId, + deviceType, + deviceModel, + deviceName, + path, + walletName, + }); + try { + await this._pausePolling(); const wallet = await this.createHardwareWalletRequest.execute({ walletName, accountPublicKey, @@ -620,6 +631,8 @@ export default class WalletsStore extends Store { } } catch (error) { throw error; + } finally { + this._resumePolling(); } }; From 95f378b2cab3089b0cf6cf9ef72e866441816662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Fri, 16 Apr 2021 18:55:10 +0200 Subject: [PATCH 02/38] [DDW-577] Introduce a fix for HW crashes when device is busy --- .../app/stores/HardwareWalletsStore.js | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/source/renderer/app/stores/HardwareWalletsStore.js b/source/renderer/app/stores/HardwareWalletsStore.js index bfa3e427d2..4e3e4fca98 100644 --- a/source/renderer/app/stores/HardwareWalletsStore.js +++ b/source/renderer/app/stores/HardwareWalletsStore.js @@ -1,6 +1,6 @@ // @flow import { observable, action, runInAction, computed } from 'mobx'; -import { get, map, find, findLast, filter } from 'lodash'; +import { get, map, find, findLast, filter, includes } from 'lodash'; import semver from 'semver'; import Store from './lib/Store'; import Request from './lib/LocalizedRequest'; @@ -723,7 +723,6 @@ export default class HardwareWalletsStore extends Store { this.hwDeviceStatus = HwDeviceStatuses.LAUNCHING_CARDANO_APP; try { const cardanoAdaApp = await getCardanoAdaAppChannel.request({ path }); - logger.debug( '[HW-DEBUG] HWStore - cardanoAdaApp RESPONSE: ', cardanoAdaApp @@ -757,6 +756,26 @@ export default class HardwareWalletsStore extends Store { logger.debug('[HW-DEBUG] HWStore - Cardano app fetching error', { error, }); + const isDeviceBusy = includes(error.message, 'Ledger Device is busy'); + + if (isDeviceBusy) { + // Keep isTransactionInitiated active & Set new device listener by initiating transaction + // Show message to reconnect proper software wallet device pair + this.stopCardanoAdaAppFetchPoller(); + logger.debug('[HW-DEBUG] Device is busy: ', { + walletId, + error, + }); + runInAction( + 'HardwareWalletsStore:: set HW device CONNECTING FAILED', + () => { + this.hwDeviceStatus = HwDeviceStatuses.CONNECTING_FAILED; + this.activeDevicePath = null; + this.unfinishedWalletTxSigning = walletId; + } + ); + } + if (error.code === 'DEVICE_NOT_CONNECTED') { // Special case. E.g. device unplugged before cardano app is opened // Stop poller and re-initiate connecting state / don't kill devices listener From 501647e8164927ba9b5e630e51a05c67733ac28e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Fri, 16 Apr 2021 19:00:30 +0200 Subject: [PATCH 03/38] [DDW-577] CHANGELOG update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 866ee98024..70b64e21cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog ### Fixes +- Fixed hardware wallets confirmation crashing issue when device is in "Busy" state ([PR 2522](https://github.com/input-output-hk/daedalus/pull/2522)) - Fixed hardware wallets spending password issue ([PR 2519](https://github.com/input-output-hk/daedalus/pull/2519)) ## 4.0.5 From cec3b21cd3f7671f2b0d0dabfef45907aa13a1f9 Mon Sep 17 00:00:00 2001 From: Danilo Prates Date: Tue, 20 Apr 2021 16:10:15 -0300 Subject: [PATCH 04/38] [DDW-657] Fix blank currency selection after updating to 4.0.5 (#2529) * [DDW-657] Fix case with deprecated local currency * [DDW-657] Move deprecated logic to the localstorage and fix old formats * [DDW-657] CHANGELOG --- CHANGELOG.md | 1 + source/renderer/app/api/utils/localStorage.js | 34 +++++++++++++++---- source/renderer/app/config/currencyConfig.js | 3 ++ source/renderer/app/stores/WalletsStore.js | 6 ++-- source/renderer/app/types/currencyTypes.js | 7 ++++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70b64e21cc..006e20602b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog ### Fixes +- Fixed blank currency selection after updating to 4.0.5 ([PR 2529](https://github.com/input-output-hk/daedalus/pull/2529)) - Fixed hardware wallets confirmation crashing issue when device is in "Busy" state ([PR 2522](https://github.com/input-output-hk/daedalus/pull/2522)) - Fixed hardware wallets spending password issue ([PR 2519](https://github.com/input-output-hk/daedalus/pull/2519)) diff --git a/source/renderer/app/api/utils/localStorage.js b/source/renderer/app/api/utils/localStorage.js index 546daa058c..e877d7ae2d 100644 --- a/source/renderer/app/api/utils/localStorage.js +++ b/source/renderer/app/api/utils/localStorage.js @@ -2,7 +2,7 @@ /* eslint-disable consistent-return */ -import { includes, without } from 'lodash'; +import { includes, without, get } from 'lodash'; import { electronStoreConversation } from '../../ipc/electronStoreConversation'; import { WalletMigrationStatuses } from '../../stores/WalletMigrationStore'; import { @@ -18,7 +18,7 @@ import type { DeviceType, } from '../../../../common/types/hardware-wallets.types'; import type { StorageKey } from '../../../../common/types/electron-store.types'; -import type { Currency } from '../../types/currencyTypes'; +import type { Currency, DeprecatedCurrency } from '../../types/currencyTypes'; import { CURRENCY_IS_ACTIVE_BY_DEFAULT, CURRENCY_DEFAULT_SELECTED, @@ -188,11 +188,33 @@ export default class LocalStorageApi { unsetDataLayerMigrationAcceptance = (): Promise => LocalStorageApi.unset(keys.DATA_LAYER_MIGRATION_ACCEPTANCE); - getCurrencySelected = (): Promise => - LocalStorageApi.get(keys.CURRENCY_SELECTED, CURRENCY_DEFAULT_SELECTED); + getCurrencySelected = async (): Promise => { + const localCurrencySelected: Promise< + Currency | DeprecatedCurrency | string + > = await LocalStorageApi.get( + keys.CURRENCY_SELECTED, + CURRENCY_DEFAULT_SELECTED + ); + if (typeof localCurrencySelected === 'string') return localCurrencySelected; + /** + * + * Prior versions were storing the whole Currency object, + * which could lead different formats (e.g. currency.code or currency.symbol) + * It now stores only the currency code string, + * but we need to account for users storing old formats + * + * In this case, we also set the correct local code value + * + */ + const localCurrencyCode: string = + get(localCurrencySelected, 'code') || + get(localCurrencySelected, 'symbol'); + this.setCurrencySelected(localCurrencyCode); + return localCurrencyCode; + }; - setCurrencySelected = (currency: Currency): Promise => - LocalStorageApi.set(keys.CURRENCY_SELECTED, currency); + setCurrencySelected = (currencyCode: string): Promise => + LocalStorageApi.set(keys.CURRENCY_SELECTED, currencyCode); unsetCurrencySelected = (): Promise => LocalStorageApi.unset(keys.CURRENCY_SELECTED); diff --git a/source/renderer/app/config/currencyConfig.js b/source/renderer/app/config/currencyConfig.js index 506804f198..07000d48e9 100644 --- a/source/renderer/app/config/currencyConfig.js +++ b/source/renderer/app/config/currencyConfig.js @@ -70,3 +70,6 @@ export const getLocalizedCurrency = ( ...omit(rawCurrency, ['name']), name: rawCurrency.name[currentLocale] || rawCurrency.name[LOCALES.english], }); + +export const getCurrencyFromCode = (code: string): Currency => + currenciesList[code]; diff --git a/source/renderer/app/stores/WalletsStore.js b/source/renderer/app/stores/WalletsStore.js index 26c7891133..a2ad31c4cb 100644 --- a/source/renderer/app/stores/WalletsStore.js +++ b/source/renderer/app/stores/WalletsStore.js @@ -35,6 +35,7 @@ import { CURRENCY_REQUEST_RATE_INTERVAL, getLocalizedCurrency, getLocalizedCurrenciesList, + getCurrencyFromCode, } from '../config/currencyConfig'; import type { WalletKind, @@ -350,7 +351,8 @@ export default class WalletsStore extends Store { // Check if the user has already selected a currency // Otherwise applies the default currency - const currencySelected = await this.api.localStorage.getCurrencySelected(); + const localCurrencyCode = await this.api.localStorage.getCurrencySelected(); + const currencySelected = getCurrencyFromCode(localCurrencyCode); runInAction(() => { this.currencyIsActive = currencyIsActive; @@ -417,7 +419,7 @@ export default class WalletsStore extends Store { if (currencySelected) { this.currencySelected = currencySelected; this.getCurrencyRate(); - await this.api.localStorage.setCurrencySelected(currencySelected); + await this.api.localStorage.setCurrencySelected(currencySelected.code); } }; diff --git a/source/renderer/app/types/currencyTypes.js b/source/renderer/app/types/currencyTypes.js index ff8ae26fcd..78a5912ae6 100644 --- a/source/renderer/app/types/currencyTypes.js +++ b/source/renderer/app/types/currencyTypes.js @@ -18,6 +18,13 @@ export type LocalizedCurrency = { id?: string, }; +export type DeprecatedCurrency = { + symbol: string, + name: string, + decimalDigits?: number, + id?: string, +}; + export type Request = HttpOptions | Function; export type RequestName = 'list' | 'rate'; From 16acbca78a55a7bf2b7fb2d5022e90dcbfb45316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Thu, 22 Apr 2021 15:13:31 +0200 Subject: [PATCH 05/38] [DDW-655] Update and migrate Ledger JS library to version 3.0.0. (#2530) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [DDW-655] Introduce Ledger JS lib migration to version 3.0.0 * [DDW-655] Fix yarn.lock, remove logs and code cleanuo * [DDW-655] Changelog update * [DDW-655] Fix yarn.lock Co-authored-by: Tomislav Horaček --- CHANGELOG.md | 4 ++ package.json | 2 +- source/common/types/hardware-wallets.types.js | 3 +- source/main/ipc/getHardwareWalletChannel.js | 48 +++++++++-------- .../app/stores/HardwareWalletsStore.js | 6 ++- source/renderer/app/utils/shelleyLedger.js | 52 ++++++++++++------- yarn.lock | 27 ++++------ 7 files changed, 82 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 006e20602b..961298efe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ Changelog - Fixed hardware wallets confirmation crashing issue when device is in "Busy" state ([PR 2522](https://github.com/input-output-hk/daedalus/pull/2522)) - Fixed hardware wallets spending password issue ([PR 2519](https://github.com/input-output-hk/daedalus/pull/2519)) +### Chores + +- Updated `@cardano-foundation/ledgerjs-hw-app-cardano` package to version `3.0.0` ([PR 2530](https://github.com/input-output-hk/daedalus/pull/2530)) + ## 4.0.5 ### Features diff --git a/package.json b/package.json index 42c684fe3b..f4f917d5ad 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,7 @@ "yarn-lockfile": "1.1.1" }, "dependencies": { - "@cardano-foundation/ledgerjs-hw-app-cardano": "2.2.0", + "@cardano-foundation/ledgerjs-hw-app-cardano": "3.0.0", "@iohk-jormungandr/wallet-js": "0.5.0-pre7", "aes-js": "3.1.2", "bech32": "2.0.0", diff --git a/source/common/types/hardware-wallets.types.js b/source/common/types/hardware-wallets.types.js index a6a195be4b..c04a5c3d81 100644 --- a/source/common/types/hardware-wallets.types.js +++ b/source/common/types/hardware-wallets.types.js @@ -236,10 +236,11 @@ export type LedgerSignTransactionRequest = { protocolMagic: number, certificates: Array, withdrawals: Array, - metadataHashHex: ?string, + auxiliaryData: ?string, reset?: boolean, devicePath: ?string, validityIntervalStartStr?: string, + signingMode: string, }; export type TrezorSignTransactionRequest = { diff --git a/source/main/ipc/getHardwareWalletChannel.js b/source/main/ipc/getHardwareWalletChannel.js index bf86b54343..b391fff268 100644 --- a/source/main/ipc/getHardwareWalletChannel.js +++ b/source/main/ipc/getHardwareWalletChannel.js @@ -407,16 +407,16 @@ export const handleHardwareWalletRequests = async ( } logger.info('[HW-DEBUG] GET CARDANO APP'); deviceConnection = devicesMemo[path].AdaConnection; - const appVersion = await deviceConnection.getVersion(); + const { version } = await deviceConnection.getVersion(); logger.info('[HW-DEBUG] getCardanoAdaAppChannel:: appVersion'); - const deviceSerial = await deviceConnection.getSerial(); + const { serial } = await deviceConnection.getSerial(); logger.info('[HW-DEBUG] getCardanoAdaAppChannel:: deviceSerial'); - const { minor, major, patch } = appVersion; + const { minor, major, patch } = version; return Promise.resolve({ minor, major, patch, - deviceId: deviceSerial.serial, + deviceId: serial, }); } catch (error) { const errorCode = error.code || ''; @@ -541,9 +541,10 @@ export const handleHardwareWalletRequests = async ( if (!deviceConnection) { throw new Error('Ledger device not connected'); } - const extendedPublicKey = await deviceConnection.getExtendedPublicKey( - utils.str_to_path(path) - ); + + const extendedPublicKey = await deviceConnection.getExtendedPublicKey({ + path: utils.str_to_path(path), + }); const deviceSerial = await deviceConnection.getSerial(); return Promise.resolve({ publicKeyHex: extendedPublicKey.publicKeyHex, @@ -566,9 +567,10 @@ export const handleHardwareWalletRequests = async ( networkId, certificates, withdrawals, - metadataHashHex, + auxiliaryData, devicePath, // validityIntervalStartStr, + signingMode, } = params; logger.info('[HW-DEBUG] SIGN Ledger transaction'); deviceConnection = devicePath @@ -579,19 +581,23 @@ export const handleHardwareWalletRequests = async ( if (!deviceConnection) { throw new Error('Device not connected!'); } - - const signedTransaction = await deviceConnection.signTransaction( - networkId, - protocolMagic, - inputs, - outputs, - fee, - ttl, - certificates, - withdrawals, - metadataHashHex - // validityIntervalStartStr - ); + const signedTransaction = await deviceConnection.signTransaction({ + signingMode, + tx: { + network: { + networkId, + protocolMagic, + }, + inputs, + outputs, + fee, + ttl, + certificates, + withdrawals, + auxiliaryData, + // validityIntervalStart, + }, + }); return Promise.resolve(signedTransaction); } catch (e) { throw e; diff --git a/source/renderer/app/stores/HardwareWalletsStore.js b/source/renderer/app/stores/HardwareWalletsStore.js index 4e3e4fca98..72466955ee 100644 --- a/source/renderer/app/stores/HardwareWalletsStore.js +++ b/source/renderer/app/stores/HardwareWalletsStore.js @@ -2,6 +2,7 @@ import { observable, action, runInAction, computed } from 'mobx'; import { get, map, find, findLast, filter, includes } from 'lodash'; import semver from 'semver'; +import { TransactionSigningMode } from '@cardano-foundation/ledgerjs-hw-app-cardano'; import Store from './lib/Store'; import Request from './lib/LocalizedRequest'; import { HwDeviceStatuses } from '../domains/Wallet'; @@ -1397,7 +1398,7 @@ export default class HardwareWalletsStore extends Store { const fee = formattedAmountToLovelace(flatFee.toString()); const ttl = this._getTtl(); const absoluteSlotNumber = this._getAbsoluteSlotNumber(); - const metadataHashHex = null; + const auxiliaryData = null; const { isMainnet } = this.environment; try { @@ -1415,7 +1416,8 @@ export default class HardwareWalletsStore extends Store { : HW_SHELLEY_CONFIG.NETWORK.TESTNET.protocolMagic, certificates: certificatesData, withdrawals: withdrawalsData, - metadataHashHex, + signingMode: TransactionSigningMode.ORDINARY_TRANSACTION, + auxiliaryData, devicePath, }); diff --git a/source/renderer/app/utils/shelleyLedger.js b/source/renderer/app/utils/shelleyLedger.js index 79ad2487df..7ca0d097ee 100644 --- a/source/renderer/app/utils/shelleyLedger.js +++ b/source/renderer/app/utils/shelleyLedger.js @@ -1,5 +1,9 @@ // @flow -import { utils } from '@cardano-foundation/ledgerjs-hw-app-cardano'; +import { + utils, + TxOutputDestinationType, + AddressType, +} from '@cardano-foundation/ledgerjs-hw-app-cardano'; import { encode } from 'borc'; import blakejs from 'blakejs'; import { map, groupBy, sortBy } from 'lodash'; @@ -149,7 +153,7 @@ export const prepareTokenBundle = (assets: CoinSelectionAssetsType) => { const tokenBundle = map(tokenObjectEntries, ([policyId, tokens]) => { const tokensList = tokens.map(({ assetName, quantity }) => ({ assetNameHex: assetName, - amountStr: quantity.toString(), + amount: quantity.toString(), })); return { policyIdHex: policyId, @@ -245,10 +249,12 @@ export const ShelleyTxWithdrawal = ( export const prepareLedgerCertificate = (cert: CoinSelectionCertificate) => { return { type: CERTIFICATE_TYPE[cert.certificateType], - path: derivationPathToLedgerPath(cert.rewardAccountPath), - poolKeyHashHex: cert.pool - ? utils.buf_to_hex(utils.bech32_decodeAddress(cert.pool)) - : null, + params: { + path: derivationPathToLedgerPath(cert.rewardAccountPath), + poolKeyHashHex: cert.pool + ? utils.buf_to_hex(utils.bech32_decodeAddress(cert.pool)) + : null, + }, }; }; @@ -257,7 +263,7 @@ export const prepareLedgerWithdrawal = ( ) => { return { path: derivationPathToLedgerPath(withdrawal.derivationPath), - amountStr: withdrawal.amount.quantity.toString(), + amount: withdrawal.amount.quantity.toString(), }; }; @@ -414,21 +420,31 @@ export const prepareLedgerOutput = ( if (isChange) { return { - addressTypeNibble: 0, - spendingPath: derivationPathToLedgerPath(output.derivationPath), - amountStr: output.amount.quantity.toString(), - stakingPath: utils.str_to_path("1852'/1815'/0'/2/0"), + destination: { + type: TxOutputDestinationType.DEVICE_OWNED, + params: { + type: AddressType.BASE, + params: { + spendingPath: derivationPathToLedgerPath(output.derivationPath), + stakingPath: utils.str_to_path("1852'/1815'/0'/2/0"), + }, + }, + }, + amount: output.amount.quantity.toString(), tokenBundle, }; } - - const isSheeleyAddress = addressStyle === AddressStyles.ADDRESS_SHELLEY; - const decodedAddress = isSheeleyAddress - ? utils.bech32_decodeAddress(output.address) - : utils.base58_decode(output.address); return { - amountStr: output.amount.quantity.toString(), - addressHex: utils.buf_to_hex(decodedAddress), + destination: { + type: TxOutputDestinationType.THIRD_PARTY, + params: { + addressHex: + addressStyle === AddressStyles.ADDRESS_SHELLEY + ? utils.buf_to_hex(utils.bech32_decodeAddress(output.address)) + : utils.buf_to_hex(utils.base58_decode(output.address)), + }, + }, + amount: output.amount.quantity.toString(), tokenBundle, }; }; diff --git a/yarn.lock b/yarn.lock index bac8bdafdb..1ed4c7738e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1023,13 +1023,12 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" -"@cardano-foundation/ledgerjs-hw-app-cardano@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@cardano-foundation/ledgerjs-hw-app-cardano/-/ledgerjs-hw-app-cardano-2.2.0.tgz#ac19a3ee04fb90a71bf556679afdac4775206561" +"@cardano-foundation/ledgerjs-hw-app-cardano@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@cardano-foundation/ledgerjs-hw-app-cardano/-/ledgerjs-hw-app-cardano-3.0.0.tgz#5faf169c9ce4aadfb1f4f26b7308dd031f151eed" dependencies: "@ledgerhq/hw-transport" "^5.12.0" - babel-polyfill "^6.26.0" - babel-runtime "^6.26.0" + "@types/ledgerhq__hw-transport" "^4.21.3" base-x "^3.0.5" bech32 "^1.1.4" node-int64 "^0.4.0" @@ -1884,6 +1883,12 @@ version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" +"@types/ledgerhq__hw-transport@^4.21.3": + version "4.21.3" + resolved "https://registry.yarnpkg.com/@types/ledgerhq__hw-transport/-/ledgerhq__hw-transport-4.21.3.tgz#1e658da6b5d01ffab92f9660cf57121aecfa7e2c" + dependencies: + "@types/node" "*" + "@types/lodash@^4.14.136": version "4.14.168" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" @@ -3141,14 +3146,6 @@ babel-plugin-transform-undefined-to-void@^6.9.4: version "6.9.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" -babel-polyfill@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" - dependencies: - babel-runtime "^6.26.0" - core-js "^2.5.0" - regenerator-runtime "^0.10.5" - babel-preset-jest@^20.0.3: version "20.0.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz#cbacaadecb5d689ca1e1de1360ebfc66862c178a" @@ -13077,10 +13074,6 @@ regenerator-runtime@0.13.7, regenerator-runtime@^0.13.2, regenerator-runtime@^0. version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" -regenerator-runtime@^0.10.5: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1: version "0.11.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" From 3383662cce9f51b177347b570e015aef41286ea2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomislav=20Hora=C4=8Dek?= Date: Thu, 22 Apr 2021 16:37:08 +0200 Subject: [PATCH 06/38] [DDW-658] Update trezor-connect dependency to version 8.1.26 (#2534) * [DDW-658] Introduce an update for trezor-connect lib to version 8.1.26 * [DDW-658] Changelog update Co-authored-by: Nikola Glumac --- CHANGELOG.md | 1 + package.json | 2 +- yarn.lock | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 961298efe7..333647514a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Changelog ### Chores +- Updated `trezor-connect` dependency to version `8.1.26` ([PR 2534](https://github.com/input-output-hk/daedalus/pull/2534)) - Updated `@cardano-foundation/ledgerjs-hw-app-cardano` package to version `3.0.0` ([PR 2530](https://github.com/input-output-hk/daedalus/pull/2530)) ## 4.0.5 diff --git a/package.json b/package.json index f4f917d5ad..26e5578a71 100644 --- a/package.json +++ b/package.json @@ -250,7 +250,7 @@ "source-map-support": "0.5.19", "spectron-fake-dialog": "0.0.1", "tcp-port-used": "1.0.1", - "trezor-connect": "8.1.25-extended", + "trezor-connect": "8.1.26-extended", "unorm": "1.6.0", "validator": "13.1.17" }, diff --git a/yarn.lock b/yarn.lock index 1ed4c7738e..2ec71da7f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15214,9 +15214,9 @@ tree-kill@^1.1.0, tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" -trezor-connect@8.1.25-extended: - version "8.1.25-extended" - resolved "https://registry.yarnpkg.com/trezor-connect/-/trezor-connect-8.1.25-extended.tgz#a20d7e32c56b863d16d6783db4a6538f4bc31b51" +trezor-connect@8.1.26-extended: + version "8.1.26-extended" + resolved "https://registry.yarnpkg.com/trezor-connect/-/trezor-connect-8.1.26-extended.tgz#837666ec93b2e371ed32e921f5795ea612751c71" dependencies: "@babel/runtime" "^7.12.5" "@trezor/blockchain-link" "^1.0.17" From d536fe9ae551a853c6989d03f61feb0134f4ff8c Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Thu, 22 Apr 2021 16:55:32 +0200 Subject: [PATCH 07/38] [DDW-603] Enable pasting of wallet recovery phrase (#2459) * DDW-603 - Enable pasting of wallet recovery phrase - changelog changes * DDW-602 - Enable pasting of wallet recovery phase - updating react polymorph * DDW-602 - Enable pasting of wallet recovery phase - updating react polymorph * DDW-602 - Enable pasting of wallet recovery phase - updating react polymorph - yarn lock * DDW-603 - Enable pasting of wallet recovery phase - temp enable voting * DDW-603 - Enable pasting of wallet recovery phase * DDW-605 - Display rewards address - yarn lock * [DDW-603] Fixes lockfile * DDW-603 - Enable pasting of wallet recovery phrase - yarn fix * DDW-603 - Enable pasting of wallet recovery phrase - fixing dropdown focus - updating new version * DDW-603 - Enable pasting of wallet recovery phrase - fixing yarn lock * Update CHANGELOG.md * DDW-595 - Warn user when pasting an address of the same wallet - fixing changelog * DDW-603 - Enable pasting of wallet recovery phrases - yarn.lock * [DDW-603] Improve CHANGELOG * [DDW-603] Updates RP * [DDW-603] Semver fix attempt * [DDW-603] Revert semver fix attempt * [DDW-603] Update to react-polymorph@0.9.8-rc.18 * [DDW-603] Bumps RP * DDW-603 - Enable pasting of wallet recovery phrase fixes * DDW-603 - Enable pasting of wallet recovery phrase fixes - update react-polymorph version to .21 * DDW-603 - Enable pasting of wallet recovery phrase fixes - temp update react-polymorph version to .21 for qa testing * DDW-603 - Improve pin entry component ux - update RP version * DDW-603 - Improve pin entry component ux - update RP version * DDW-603 - Improve pin entry component ux - update RP version to new release 0.9.8-rc-21 * DDW-603 - Improve pin entry component ux - update RP version to new release 0.9.8-rc-21 Co-authored-by: Nikola Glumac Co-authored-by: Dominik Guzei --- CHANGELOG.md | 7 ++++--- package.json | 2 +- .../wallet/wallet-restore/MnemonicsDialog.js | 2 +- yarn.lock | 15 ++++----------- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 333647514a..8498386710 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Changelog ## vNext +### Features + +- Enabled pasting of wallet recovery phrase ([PR 2459](https://github.com/input-output-hk/daedalus/pull/2459)) + ### Fixes - Fixed blank currency selection after updating to 4.0.5 ([PR 2529](https://github.com/input-output-hk/daedalus/pull/2529)) @@ -102,9 +106,6 @@ Changelog ### Features - Added native token support [PR 2292](https://github.com/input-output-hk/daedalus/pull/2292) - -### Features - - Enabled rewards withdrawals on hardware wallets ([PR 2408](https://github.com/input-output-hk/daedalus/pull/2408)) ### Fixes diff --git a/package.json b/package.json index 26e5578a71..2fd90d7aed 100644 --- a/package.json +++ b/package.json @@ -233,7 +233,7 @@ "react-intl": "2.7.2", "react-lottie": "1.2.3", "react-markdown": "4.3.1", - "react-polymorph": "0.9.8-rc.11", + "react-polymorph": "0.9.8-rc.21", "react-router": "5.2.0", "react-router-dom": "5.2.0", "react-svg-inline": "2.1.1", diff --git a/source/renderer/app/components/wallet/wallet-restore/MnemonicsDialog.js b/source/renderer/app/components/wallet/wallet-restore/MnemonicsDialog.js index 144df13db0..ec39377d94 100644 --- a/source/renderer/app/components/wallet/wallet-restore/MnemonicsDialog.js +++ b/source/renderer/app/components/wallet/wallet-restore/MnemonicsDialog.js @@ -115,7 +115,7 @@ export default class MnemonicsDialog extends Component { expectedWordCount, } = this.props; const recoveryPhraseField = this.form.$('recoveryPhrase'); - const canSubmit = !recoveryPhraseField.error; + const canSubmit = recoveryPhraseField.isValid && !recoveryPhraseField.error; return ( Date: Tue, 27 Apr 2021 05:36:23 -0300 Subject: [PATCH 08/38] [DDW-645] Update react-polymorph and implement the search style variables (#2512) * [DDW-645] Basic implementation * [DDW-645] RP branch version and knobs * [DDW-645] Remove incorrect pkg * [DDW-645] Add storybook store * [DDW-645] Update react-polymorph to the latest commit * [DDW-645] Correct react-polymorph version * [DDW-645] Updates react-polymorph * [DDW-645] Search highlight colors * DDW-645 - Implement search style variables * DDW-645 - Implement search style variables - prettier fixes * DDW-645 - Implement search style variables - flow fixes * DDW-645 - Implement search style variables - review fixes * DDW-645 - Implement search style variables - review fixes * DDW-645 - Implement search style variables - yarn lock update * DDW-595 - Warn user when pasting an address of the same wallet - linter errors fixed * DDW-595 - Warn user when pasting an address of the same wallet - translations fixed * DDW-645 - Implement search style variables - yarn lock update * DDW-645 - Implement search style variables - fixing remove icon position and highlight color * DDW-645 - Implement search style variables - removing search on dropdown in wallet settings * DDW-645 - Implement search style variables - updating react polymorph * DDW-645 - Implement search style variables - updates * DDW-645 - Implement search style variables - updates for changelog and yarn.lock * DDW-645 - Implement search style variables - updates border radius * DDW-645 - Implement search style variables - positioning clear btn * DDW-645 - Implement search style variables - prettier fix * DDW-645 - Implement search style variables - fixing global reference for styles * DDW-645 - Implement search style variables - fixing global reference for styles * DDW-645 - Implement search style variables - fixing global reference for styles * DDW-645 - Implement search style variables - prettier * DDW-645 - Implement search style variables - prettier * DDW-645 - Implement search style variables - prettier * [DDW-645] Bumps RP * DDW-645 - Implement search style variables - fixing scss variables * [DDW-645] Remove unused code * [DDW-645] Fix Wallet settings storybook story * DDW-645 - Implement search style variables - fixing scss variables * [DDW-645] Add overrides for Options with search and no search * [DDW-645] Move styling fixes to react-polymorph * [DDW-645] Temporary react polymorph version for testing * [DDW-645] Updates React Polymorph version * [DDW-645] Remove testing code * [DDW-645] Yarn Lock - fixYarnLock * [DDW-645] Yarn Lock - manually * [DDW-645] Flow issue * [DDW-645] Run lockfile:fix * [DDW-645] Fix build issues * [DDW-645] Add state for the Wallet Settings story * [DDW-645] Fix lint issue Co-authored-by: Aleksandar Djordjevic Co-authored-by: Nikola Glumac --- CHANGELOG.md | 1 + package.json | 1 + .../settings/categories/WalletsSettings.js | 4 + .../settings/categories/WalletsSettings.scss | 2 - .../categories/WalletsSettingsPage.js | 1 + .../renderer/app/themes/daedalus/cardano.js | 1 + .../renderer/app/themes/daedalus/dark-blue.js | 1 + .../app/themes/daedalus/dark-cardano.js | 1 + .../app/themes/daedalus/flight-candidate.js | 1 + .../themes/daedalus/incentivized-testnet.js | 1 + .../app/themes/daedalus/light-blue.js | 1 + .../app/themes/daedalus/shelley-testnet.js | 1 + source/renderer/app/themes/daedalus/white.js | 1 + source/renderer/app/themes/daedalus/yellow.js | 1 + .../themes/overrides/OptionsOverrides.scss | 23 ++- .../renderer/app/themes/utils/createTheme.js | 1 + .../settings/general/General.stories.js | 46 ++++-- .../stories/wallets/_utils/currencies.json | 97 ------------ .../wallets/summary/WalletSummary.stories.js | 19 +-- yarn.lock | 138 ++++++++++++++++-- 20 files changed, 201 insertions(+), 141 deletions(-) delete mode 100644 storybook/stories/wallets/_utils/currencies.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 8498386710..2d95c43027 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog ### Features +- Implemented select search style variables ([PR 2512](https://github.com/input-output-hk/daedalus/pull/2512)) - Enabled pasting of wallet recovery phrase ([PR 2459](https://github.com/input-output-hk/daedalus/pull/2459)) ### Fixes diff --git a/package.json b/package.json index 2fd90d7aed..0bc9435a32 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,7 @@ "@babel/preset-flow": "7.8.3", "@babel/preset-react": "7.0.0", "@babel/register": "7.0.0", + "@dump247/storybook-state": "1.6.1", "@storybook/addon-actions": "5.3.14", "@storybook/addon-knobs": "5.3.14", "@storybook/addon-links": "5.3.14", diff --git a/source/renderer/app/components/settings/categories/WalletsSettings.js b/source/renderer/app/components/settings/categories/WalletsSettings.js index e89209438e..0489ec66cc 100644 --- a/source/renderer/app/components/settings/categories/WalletsSettings.js +++ b/source/renderer/app/components/settings/categories/WalletsSettings.js @@ -52,6 +52,7 @@ type Props = { onSelectCurrency: Function, onToggleCurrencyIsActive: Function, onOpenExternalLink: Function, + hasSearch: boolean, }; @observer @@ -69,6 +70,7 @@ export default class WalletSettings extends Component { onSelectCurrency, onToggleCurrencyIsActive, onOpenExternalLink, + hasSearch, } = this.props; const currencyOptions = map(currencyList, ({ code, name }) => ({ @@ -105,6 +107,8 @@ export default class WalletSettings extends Component { value={currencySelected ? currencySelected.code : null} options={currencyOptions} onChange={onSelectCurrency} + hasSearch={hasSearch} + optionHeight={50} />
{ onSelectCurrency={this.handleSelectCurrency} onToggleCurrencyIsActive={this.handleToggleCurrencyIsActive} onOpenExternalLink={openExternalLink} + hasSearch /> ); } diff --git a/source/renderer/app/themes/daedalus/cardano.js b/source/renderer/app/themes/daedalus/cardano.js index 82f27d3051..d6901ba647 100644 --- a/source/renderer/app/themes/daedalus/cardano.js +++ b/source/renderer/app/themes/daedalus/cardano.js @@ -624,6 +624,7 @@ export const CARDANO_THEME_OUTPUT = { '--rp-option-text-color': '#5e6066', '--rp-options-border-color': 'rgba(94, 96, 102, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #2cbb69', diff --git a/source/renderer/app/themes/daedalus/dark-blue.js b/source/renderer/app/themes/daedalus/dark-blue.js index 328fe0449e..90ccb7d7ef 100644 --- a/source/renderer/app/themes/daedalus/dark-blue.js +++ b/source/renderer/app/themes/daedalus/dark-blue.js @@ -627,6 +627,7 @@ export const DARK_BLUE_THEME_OUTPUT = { '--rp-option-text-color': '#e9f4fe', '--rp-options-border-color': 'rgba(233, 244, 254, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #536370', diff --git a/source/renderer/app/themes/daedalus/dark-cardano.js b/source/renderer/app/themes/daedalus/dark-cardano.js index 8b9f3e85c7..8d7f22746c 100644 --- a/source/renderer/app/themes/daedalus/dark-cardano.js +++ b/source/renderer/app/themes/daedalus/dark-cardano.js @@ -607,6 +607,7 @@ export const DARK_CARDANO_THEME_OUTPUT = { '--rp-option-text-color': '#ffffff', '--rp-options-border-color': 'rgba(255, 255, 255, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #1fc1c3', diff --git a/source/renderer/app/themes/daedalus/flight-candidate.js b/source/renderer/app/themes/daedalus/flight-candidate.js index 773478abec..94c7ff9469 100644 --- a/source/renderer/app/themes/daedalus/flight-candidate.js +++ b/source/renderer/app/themes/daedalus/flight-candidate.js @@ -605,6 +605,7 @@ export const FLIGHT_CANDIDATE_THEME_OUTPUT = { '--rp-option-text-color': '#ffffff', '--rp-options-border-color': 'rgba(255, 255, 255, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #ffb923', diff --git a/source/renderer/app/themes/daedalus/incentivized-testnet.js b/source/renderer/app/themes/daedalus/incentivized-testnet.js index 29947ca819..73ee4ab4f4 100644 --- a/source/renderer/app/themes/daedalus/incentivized-testnet.js +++ b/source/renderer/app/themes/daedalus/incentivized-testnet.js @@ -605,6 +605,7 @@ export const INCENTIVIZED_TESTNET_THEME_OUTPUT = { '--rp-option-text-color': '#ffffff', '--rp-options-border-color': 'rgba(255, 255, 255, 0.2)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #eb2256', diff --git a/source/renderer/app/themes/daedalus/light-blue.js b/source/renderer/app/themes/daedalus/light-blue.js index 3b6af5377f..08dc2898db 100644 --- a/source/renderer/app/themes/daedalus/light-blue.js +++ b/source/renderer/app/themes/daedalus/light-blue.js @@ -622,6 +622,7 @@ export const LIGHT_BLUE_THEME_OUTPUT = { '--rp-option-text-color': '#5e6066', '--rp-options-border-color': 'rgba(94, 96, 102, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #2f496e', diff --git a/source/renderer/app/themes/daedalus/shelley-testnet.js b/source/renderer/app/themes/daedalus/shelley-testnet.js index ba3663d26c..235bcd87bd 100644 --- a/source/renderer/app/themes/daedalus/shelley-testnet.js +++ b/source/renderer/app/themes/daedalus/shelley-testnet.js @@ -605,6 +605,7 @@ export const SHELLEY_TESTNET_THEME_OUTPUT = { '--rp-option-text-color': '#ffffff', '--rp-options-border-color': 'rgba(255, 255, 255, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #898ee6', diff --git a/source/renderer/app/themes/daedalus/white.js b/source/renderer/app/themes/daedalus/white.js index e5a63c9aaa..4c2ddf4f0a 100644 --- a/source/renderer/app/themes/daedalus/white.js +++ b/source/renderer/app/themes/daedalus/white.js @@ -611,6 +611,7 @@ export const WHITE_THEME_OUTPUT = { '--rp-option-text-color': '#2d2d2d', '--rp-options-border-color': 'rgba(94, 96, 102, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(242, 162, 24, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #29b595', diff --git a/source/renderer/app/themes/daedalus/yellow.js b/source/renderer/app/themes/daedalus/yellow.js index 401ac83418..955f8f9df2 100644 --- a/source/renderer/app/themes/daedalus/yellow.js +++ b/source/renderer/app/themes/daedalus/yellow.js @@ -609,6 +609,7 @@ export const YELLOW_THEME_OUTPUT = { '--rp-option-text-color': '#2d2d2d', '--rp-options-border-color': 'rgba(45, 45, 45, 0.7)', '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': 'rgba(125, 3, 146, 0.3)', }, rpRadio: { '--rp-radio-border': '2px solid #2d2d2d', diff --git a/source/renderer/app/themes/overrides/OptionsOverrides.scss b/source/renderer/app/themes/overrides/OptionsOverrides.scss index 15d23864a1..3f8946417a 100644 --- a/source/renderer/app/themes/overrides/OptionsOverrides.scss +++ b/source/renderer/app/themes/overrides/OptionsOverrides.scss @@ -1,13 +1,26 @@ .options { margin-top: -7px; - ul { - border-radius: 4px; + &:not(.hasSearch) { + ul { + border-radius: 4px; + } } - :global { - [data-bubble-arrow] { - display: none !important; + &.hasSearch { + ul { + border-radius: 0 0 4px 4px !important; + } + + button { + background-color: var(--theme-button-flat-background-color) !important; + &:hover { + background-color: var(--theme-button-flat-background-color-hover); + } } } + + [data-bubble-arrow] { + display: none !important; + } } diff --git a/source/renderer/app/themes/utils/createTheme.js b/source/renderer/app/themes/utils/createTheme.js index 2fffeb8bab..dfee02778c 100644 --- a/source/renderer/app/themes/utils/createTheme.js +++ b/source/renderer/app/themes/utils/createTheme.js @@ -157,6 +157,7 @@ export const createReactPolymorphTheme = ( '--rp-option-text-color': `${text.primary}`, '--rp-options-border-color': `${border}`, '--rp-options-shadow': 'none', + '--rp-option-search-highlight-background-color': `rgba(242, 162, 24, 0.3)`, }, rpPopOver: { '--rp-pop-over-bg-color': '', diff --git a/storybook/stories/settings/general/General.stories.js b/storybook/stories/settings/general/General.stories.js index 10afb8d580..9feec2b4ab 100644 --- a/storybook/stories/settings/general/General.stories.js +++ b/storybook/stories/settings/general/General.stories.js @@ -4,6 +4,7 @@ import { findKey } from 'lodash'; import { boolean, number } from '@storybook/addon-knobs'; import { storiesOf } from '@storybook/react'; import { action } from '@storybook/addon-actions'; +import { withState } from '@dump247/storybook-state'; import SettingsWrapper from '../utils/SettingsWrapper'; import { DATE_ENGLISH_OPTIONS, @@ -22,6 +23,10 @@ import SupportSettings from '../../../../source/renderer/app/components/settings import TermsOfUseSettings from '../../../../source/renderer/app/components/settings/categories/TermsOfUseSettings'; import WalletsSettings from '../../../../source/renderer/app/components/settings/categories/WalletsSettings'; +// Assets and helpers +import currenciesList from '../../../../source/renderer/app/config/currenciesList.json'; +import { getLocalizedCurrenciesList } from '../../../../source/renderer/app/config/currencyConfig'; + const getParamName = (obj, itemName): any => Object.entries(obj).find((entry: [any, any]) => itemName === entry[1]); @@ -49,21 +54,32 @@ storiesOf('Settings|General', module) currentTimeFormat={TIME_OPTIONS[0].value} /> )) - .add('Wallets', () => ( - - )) + .add( + 'Wallets', + withState( + { + currencySelected: { + id: 'uniswap-state-dollar', + code: 'usd', + name: 'unified Stable Dollar', + }, + }, + (store) => ( + + store.set({ currencySelected: currenciesList[code] }) + } + onToggleCurrencyIsActive={action('onToggleCurrencyIsActive')} + onOpenExternalLink={action('onOpenExternalLink')} + hasSearch={boolean('hasSearch', true)} + /> + ) + ) + ) .add('Stake Pools', () => ( { - obj[`${currency.id} - ${currency.name}`] = currency; - return obj; - }, {}), - { - id: 'uniswap-state-dollar', - symbol: 'usd', - name: 'unified Stable Dollar', - } - ); + const currencySelected = select('currencySelected', currenciesList, { + id: 'uniswap-state-dollar', + symbol: 'usd', + name: 'unified Stable Dollar', + }); return ( =0.10.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" whatwg-fetch@^3.5.0: version "3.6.0" From e103a2f722776ed5817163287681dcc49937050a Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Thu, 29 Apr 2021 09:26:57 +0200 Subject: [PATCH 09/38] [DDW-595] Warn user when pasting an address of the same wallet (#2506) * DDW-595 - Warn user when pasting an address of the same wallet * DDW-595 - Warn user when pasting an address of the same wallet - prettier, linter * DDW-595 - Warn user when pasting an address of the same wallet - changelog * DDW-595 - Warn user when pasting an address of the same wallet - fixing tooltip show/hide * DDW-595 - Warn user when pasting an address of the same wallet - linter update * DDW-595 - Warn user when pasting an address of the same wallet - fixes for receiver input field * DDW-595 - Warn user when pasting an address of the same wallet - fixes for receiver input field * DDW-595 - Warn user when pasting an address of the same wallet - fixes for receiver input field - validity * DDW-595 - Warn user when pasting an address of the same wallet - fixes for receiver input field focus with tooltip * DDW-595 - Warn user when pasting an address of the same wallet - prettier * DDW-595 - Warn user when pasting an address of the same wallet - fixes for tooltip show/hide * DDW-595 - Warn user when pasting an address of the same wallet - fixes * DDW-595 - Warn user when pasting an address of the same wallet - fixes * DDW-595 - Warn user when pasting an address of the same wallet - changelog update * DDW-595 - Warn user when pasting an address of the same wallet - disable autofocus on warning * DDW-595 - Warn user when pasting an address of the same wallet - disable autofocus on warning * DDW-595 - Warn user when pasting an address of the same wallet - prettier fix * DDW-595 - Warn user when pasting an address of the same wallet - rename addressFromSameWallet * DDW-595 - Warn user when pasting an address of the same wallet - adding hover state on receiver input field * DDW-595 - Warn user when pasting an address of the same wallet - flow fixes * [DDW-595] Refactor wallet send form receiver field This updates to the latest react-polymorph release that includes improvements to the Input and FormField components for more flexibility regarding when and how to show error/warning messages in our forms. * DDW-595 - Warn user when pasting an address of the same wallet - fixing focus * DDW-595 - Warn user when pasting an address of the same wallet - fixing focus/blur tooltip showing * DDW-595 - Warn user when pasting an address of the same wallet - fixing error toolbar visiblity on hover * DDW-595 - Warn user when pasting an address of the same wallet - fixing error toolbar visiblity on hover - no focus * DDW-595 - Warn user when pasting an address of the same wallet - fixing error toolbar visiblity on hover - no focus fix * DDW-595 - Warn user when pasting an address of the same wallet - temp enable voting on testnet for qa testing * DDW-595 - Warn user when pasting an address of the same wallet - temp enable voting on testnet for qa testing * DDW-595 - Warn user when pasting an address of the same wallet - temp enable voting on testnet for qa testing * DDW-595 - Warn user when pasting an address of the same wallet - temp enable voting on testnet for qa testing * DDW-595 - Warn user when pasting an address of the same wallet - disable voting on testnet * DDW-595 - Warn user when pasting an address of the same wallet - disable voting on testnet * DDW-595 - Warn user when pasting an address of the same wallet - copy updates * DDW-595 - Warn user when pasting an address of the same wallet - lint fixes * [DDW-595] Runs translation manager * DDW-595 - Warn user when pasting an address of the same wallet - package.json update * DDW-595 - Warn user when pasting an address of the same wallet - package.json update * DDW-595 - Warn user when pasting an address of the same wallet - preventing focus on asset value when addresses are the same * DDW-595 - Warn user when pasting an address of the same wallet - focus on asset value * DDW-595 - Warn user when pasting an address of the same wallet - updating focus on asset value change * DDW-595 - Warn user when pasting an address of the same wallet - refactored focus/blur behavior on assets form * DDW-595 - Warn user when pasting an address of the same wallet - new updates for autoFocus * DDW-595 - Warn user when pasting an address of the same wallet - prettier * [DDW-595] Code cleanup * DDW-595 - Warn user when pasting an address of the same wallet - updates * [DDW-595] Update to react-polymorph release candidate Co-authored-by: Dominik Guzei Co-authored-by: Nikola Glumac --- CHANGELOG.md | 1 + package.json | 2 +- .../app/components/wallet/WalletSendForm.js | 50 +++++++++++-- .../app/components/wallet/WalletSendForm.scss | 6 ++ .../components/wallet/send-form/AssetInput.js | 3 + .../components/wallet/send-form/messages.js | 6 ++ .../app/containers/wallet/WalletSendPage.js | 3 +- .../app/i18n/locales/defaultMessages.json | 74 +++++++++++-------- source/renderer/app/i18n/locales/en-US.json | 1 + source/renderer/app/i18n/locales/ja-JP.json | 1 + source/renderer/app/stores/WalletsStore.js | 14 ++++ .../themes/overrides/OptionsOverrides.scss | 4 + .../wallets/send/WalletSend.stories.js | 5 ++ yarn.lock | 6 +- 14 files changed, 134 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d95c43027..7fdf15fc3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog ### Features +- Added warning message when pasting an address of the same wallet in the send form ([PR 2506](https://github.com/input-output-hk/daedalus/pull/2506)) - Implemented select search style variables ([PR 2512](https://github.com/input-output-hk/daedalus/pull/2512)) - Enabled pasting of wallet recovery phrase ([PR 2459](https://github.com/input-output-hk/daedalus/pull/2459)) diff --git a/package.json b/package.json index 0bc9435a32..b0750ad1b5 100644 --- a/package.json +++ b/package.json @@ -234,7 +234,7 @@ "react-intl": "2.7.2", "react-lottie": "1.2.3", "react-markdown": "4.3.1", - "react-polymorph": "0.9.8-rc.21", + "react-polymorph": "1.0.0-rc.1", "react-router": "5.2.0", "react-router-dom": "5.2.0", "react-svg-inline": "2.1.1", diff --git a/source/renderer/app/components/wallet/WalletSendForm.js b/source/renderer/app/components/wallet/WalletSendForm.js index 87a65d51bf..121bf02064 100755 --- a/source/renderer/app/components/wallet/WalletSendForm.js +++ b/source/renderer/app/components/wallet/WalletSendForm.js @@ -67,6 +67,7 @@ type Props = { onOpenDialogAction: Function, onUnsetActiveAssetFingerprint: Function, onExternalLinkClick: Function, + isAddressFromSameWallet: boolean, }; type State = { @@ -124,6 +125,10 @@ export default class WalletSendForm extends Component { // Read more: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html _isMounted = false; + // We need to prevent auto focus of ada and token amount fields in case user pastes + // or enters a receiver address which belongs to the same wallet he is sending from. + _isAutoFocusEnabled = true; + componentDidMount() { this._isMounted = true; this.updateFormFields(true); @@ -299,8 +304,14 @@ export default class WalletSendForm extends Component { return receiverField.value.length > 0; }; - hasAssetValue = (asset: Field) => { - return get(asset, 'value', false); + isAddressFromSameWallet = () => { + const { isAddressFromSameWallet } = this.props; + const receiverField = this.form.$('receiver'); + return ( + this.hasReceiverValue() && + isAddressFromSameWallet && + receiverField.isValid + ); }; isDisabled = () => @@ -327,6 +338,9 @@ export default class WalletSendForm extends Component { ]; } const isValid = await this.props.addressValidator(value); + if (isValid && this.isAddressFromSameWallet()) { + this._isAutoFocusEnabled = false; + } this.setReceiverValidity(isValid); const adaAmountField = form.$('adaAmount'); const isAdaAmountValid = adaAmountField.isValid; @@ -551,6 +565,7 @@ export default class WalletSendForm extends Component { selectedAssetFingerprints, }); this.resetTransactionFee(); + this._isAutoFocusEnabled = true; }; removeAssetRow = (fingerprint: string) => { @@ -628,7 +643,6 @@ export default class WalletSendForm extends Component { ]; }, ]); - this.form.$(newAsset).focus(); const assetsDropdown = `assetsDropdown_${fingerprint}`; this.form.add({ @@ -679,8 +693,8 @@ export default class WalletSendForm extends Component { const { currencyMaxFractionalDigits, walletAmount } = this.props; const { - receiver: receiverField, adaAmount: adaAmountField, + receiver: receiverField, assetFields, assetsDropdown, } = formFields.receiver; @@ -700,20 +714,39 @@ export default class WalletSendForm extends Component { !this.hasAvailableAssets ? styles.disabled : null, 'primary', ]); + + const receiverFieldClasses = classNames([ + styles.receiverInput, + this.isAddressFromSameWallet() ? styles.sameRecieverInput : null, + ]); + const minAdaRequiredTooltip = selectedAssetFingerprints.length ? messages.minAdaRequiredWithAssetTooltip : messages.minAdaRequiredWithNoAssetTooltip; + const sameWalletError = intl.formatMessage(messages.sameWalletLabel); + let receiverFieldError = receiverField.error; + let receiverFieldThemeVars = {}; + if (this.isAddressFromSameWallet()) { + receiverFieldError = sameWalletError; + receiverFieldThemeVars = { + '--rp-input-border-color-errored': + 'var(--rp-password-input-warning-score-color)', + '--rp-pop-over-bg-color': + 'var(--rp-password-input-warning-score-color)', + }; + } + return (
-
+
{ this.addFocusableField(field); }} className="receiver" - error={receiverField.error} + error={receiverFieldError} onChange={(value) => { receiverField.onChange(value || ''); this.setState({ @@ -721,6 +754,7 @@ export default class WalletSendForm extends Component { }); }} onKeyPress={this.handleSubmitOnEnter} + themeVariables={receiverFieldThemeVars} /> {this.hasReceiverValue() && (
@@ -731,6 +765,7 @@ export default class WalletSendForm extends Component {