diff --git a/src/assets/icons/icon_etherTokens.svg b/src/config/assets/token_eth.svg similarity index 100% rename from src/assets/icons/icon_etherTokens.svg rename to src/config/assets/token_eth.svg diff --git a/src/config/assets/token_xdai.svg b/src/config/assets/token_xdai.svg new file mode 100644 index 00000000..044b3395 --- /dev/null +++ b/src/config/assets/token_xdai.svg @@ -0,0 +1,22 @@ + + + + +Group 6 +Created with Sketch. + + + + + + + + + + + + diff --git a/src/config/networks/local.ts b/src/config/networks/local.ts index ad51c883..cdf9dfa8 100644 --- a/src/config/networks/local.ts +++ b/src/config/networks/local.ts @@ -1,4 +1,4 @@ -import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' +import EtherLogo from 'src/config/assets/token_eth.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { diff --git a/src/config/networks/mainnet.ts b/src/config/networks/mainnet.ts index 89945ae6..0f69b371 100644 --- a/src/config/networks/mainnet.ts +++ b/src/config/networks/mainnet.ts @@ -1,4 +1,4 @@ -import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' +import EtherLogo from 'src/config/assets/token_eth.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { diff --git a/src/config/networks/rinkeby.ts b/src/config/networks/rinkeby.ts index 2f0650b0..aa2f2e3b 100644 --- a/src/config/networks/rinkeby.ts +++ b/src/config/networks/rinkeby.ts @@ -1,4 +1,4 @@ -import EtherLogo from 'src/assets/icons/icon_etherTokens.svg' +import EtherLogo from 'src/config/assets/token_eth.svg' import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' const baseConfig: EnvironmentSettings = { diff --git a/src/config/networks/xdai.ts b/src/config/networks/xdai.ts index c14ea16d..927edb8e 100644 --- a/src/config/networks/xdai.ts +++ b/src/config/networks/xdai.ts @@ -1,4 +1,5 @@ import { EnvironmentSettings, ETHEREUM_NETWORK, NetworkConfig } from 'src/config/networks/network.d' +import xDaiLogo from 'src/config/assets/token_xdai.svg' const baseConfig: EnvironmentSettings = { txServiceUrl: 'https://safe-transaction.xdai.gnosis.io/api/v1', @@ -32,7 +33,7 @@ const xDai: NetworkConfig = { name: 'xDai', symbol: 'xDai', decimals: 18, - logoUri: '', + logoUri: xDaiLogo, }, } } diff --git a/src/logic/currencyValues/api/fetchCurrenciesRates.ts b/src/logic/currencyValues/api/fetchCurrenciesRates.ts index 45c73c71..6f3c751d 100644 --- a/src/logic/currencyValues/api/fetchCurrenciesRates.ts +++ b/src/logic/currencyValues/api/fetchCurrenciesRates.ts @@ -1,29 +1,30 @@ import axios from 'axios' - -import { EXCHANGE_RATE_URL } from 'src/utils/constants' -import { AVAILABLE_CURRENCIES } from '../store/model/currencyValues' -import { fetchTokenCurrenciesBalances } from './fetchTokenCurrenciesBalances' import BigNumber from 'bignumber.js' +import { EXCHANGE_RATE_URL } from 'src/utils/constants' +import { fetchTokenCurrenciesBalances } from './fetchTokenCurrenciesBalances' +import { sameString } from 'src/utils/strings' +import { AVAILABLE_CURRENCIES } from '../store/model/currencyValues' + const fetchCurrenciesRates = async ( - baseCurrency: AVAILABLE_CURRENCIES, - targetCurrencyValue: AVAILABLE_CURRENCIES, + baseCurrency: string, + targetCurrencyValue: string, safeAddress: string, ): Promise => { let rate = 0 - - if (targetCurrencyValue === AVAILABLE_CURRENCIES.ETH) { + if (sameString(targetCurrencyValue, AVAILABLE_CURRENCIES.NETWORK)) { try { const result = await fetchTokenCurrenciesBalances(safeAddress) if (result?.data?.length) { rate = new BigNumber(1).div(result.data[0].fiatConversion).toNumber() } } catch (error) { - console.error('Fetching ETH data from the relayer errored', error) + console.error(`Fetching ${AVAILABLE_CURRENCIES.NETWORK} data from the relayer errored`, error) } return rate } + // National currencies try { const url = `${EXCHANGE_RATE_URL}?base=${baseCurrency}&symbols=${targetCurrencyValue}` const result = await axios.get(url) diff --git a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts index 59107c74..65b4d970 100644 --- a/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts +++ b/src/logic/currencyValues/api/fetchTokenCurrenciesBalances.ts @@ -2,7 +2,6 @@ import axios, { AxiosResponse } from 'axios' import { getTxServiceUrl } from 'src/config' import { TokenProps } from 'src/logic/tokens/store/model/token' -import { AVAILABLE_CURRENCIES } from '../store/model/currencyValues' export type BalanceEndpoint = { tokenAddress: string @@ -10,7 +9,7 @@ export type BalanceEndpoint = { balance: string fiatBalance: string fiatConversion: string - fiatCode: AVAILABLE_CURRENCIES + fiatCode: string } export const fetchTokenCurrenciesBalances = ( diff --git a/src/logic/currencyValues/store/actions/fetchCurrencyRate.ts b/src/logic/currencyValues/store/actions/fetchCurrencyRate.ts index 72f668c6..75fe3088 100644 --- a/src/logic/currencyValues/store/actions/fetchCurrencyRate.ts +++ b/src/logic/currencyValues/store/actions/fetchCurrencyRate.ts @@ -3,7 +3,7 @@ import { setCurrencyRate } from 'src/logic/currencyValues/store/actions/setCurre import { AVAILABLE_CURRENCIES } from 'src/logic/currencyValues/store/model/currencyValues' import { Dispatch } from 'redux' -const fetchCurrencyRate = (safeAddress: string, selectedCurrency: AVAILABLE_CURRENCIES) => async ( +const fetchCurrencyRate = (safeAddress: string, selectedCurrency: string) => async ( dispatch: Dispatch, ): Promise => { if (AVAILABLE_CURRENCIES.USD === selectedCurrency) { diff --git a/src/logic/currencyValues/store/actions/setSelectedCurrency.ts b/src/logic/currencyValues/store/actions/setSelectedCurrency.ts index 3b0774a0..390b9cb7 100644 --- a/src/logic/currencyValues/store/actions/setSelectedCurrency.ts +++ b/src/logic/currencyValues/store/actions/setSelectedCurrency.ts @@ -2,20 +2,16 @@ import { createAction } from 'redux-actions' import { ThunkDispatch } from 'redux-thunk' import { AnyAction } from 'redux' import { AppReduxState } from 'src/store' -import { AVAILABLE_CURRENCIES } from '../model/currencyValues' import fetchCurrencyRate from 'src/logic/currencyValues/store/actions/fetchCurrencyRate' export const SET_CURRENT_CURRENCY = 'SET_CURRENT_CURRENCY' -const setCurrentCurrency = createAction( - SET_CURRENT_CURRENCY, - (safeAddress: string, selectedCurrency: AVAILABLE_CURRENCIES) => ({ - safeAddress, - selectedCurrency, - }), -) +const setCurrentCurrency = createAction(SET_CURRENT_CURRENCY, (safeAddress: string, selectedCurrency: string) => ({ + safeAddress, + selectedCurrency, +})) -export const setSelectedCurrency = (safeAddress: string, selectedCurrency: AVAILABLE_CURRENCIES) => ( +export const setSelectedCurrency = (safeAddress: string, selectedCurrency: string) => ( dispatch: ThunkDispatch, ): void => { dispatch(setCurrentCurrency(safeAddress, selectedCurrency)) diff --git a/src/logic/currencyValues/store/model/currencyValues.ts b/src/logic/currencyValues/store/model/currencyValues.ts index eede6d5f..26618349 100644 --- a/src/logic/currencyValues/store/model/currencyValues.ts +++ b/src/logic/currencyValues/store/model/currencyValues.ts @@ -1,41 +1,45 @@ import { List, Record, RecordOf } from 'immutable' -export enum AVAILABLE_CURRENCIES { - ETH = 'ETH', - USD = 'USD', - EUR = 'EUR', - AUD = 'AUD', - BGN = 'BGN', - BRL = 'BRL', - CAD = 'CAD', - CHF = 'CHF', - CNY = 'CNY', - CZK = 'CZK', - DKK = 'DKK', - GBP = 'GBP', - HKD = 'HKD', - HRK = 'HRK', - HUF = 'HUF', - IDR = 'IDR', - ILS = 'ILS', - INR = 'INR', - ISK = 'ISK', - JPY = 'JPY', - KRW = 'KRW', - MXN = 'MXN', - MYR = 'MYR', - NOK = 'NOK', - NZD = 'NZD', - PHP = 'PHP', - PLN = 'PLN', - RON = 'RON', - RUB = 'RUB', - SEK = 'SEK', - SGD = 'SGD', - THB = 'THB', - TRY = 'TRY', - ZAR = 'ZAR', -} +import { getNetworkInfo } from 'src/config' + +const { nativeCoin } = getNetworkInfo() + +export const AVAILABLE_CURRENCIES = { + NETWORK: nativeCoin.symbol.toLocaleUpperCase(), + USD: 'USD', + EUR: 'EUR', + AUD: 'AUD', + BGN: 'BGN', + BRL: 'BRL', + CAD: 'CAD', + CHF: 'CHF', + CNY: 'CNY', + CZK: 'CZK', + DKK: 'DKK', + GBP: 'GBP', + HKD: 'HKD', + HRK: 'HRK', + HUF: 'HUF', + IDR: 'IDR', + ILS: 'ILS', + INR: 'INR', + ISK: 'ISK', + JPY: 'JPY', + KRW: 'KRW', + MXN: 'MXN', + MYR: 'MYR', + NOK: 'NOK', + NZD: 'NZD', + PHP: 'PHP', + PLN: 'PLN', + RON: 'RON', + RUB: 'RUB', + SEK: 'SEK', + SGD: 'SGD', + THB: 'THB', + TRY: 'TRY', + ZAR: 'ZAR', +} as const export type BalanceCurrencyRecord = { currencyName?: string @@ -57,6 +61,6 @@ export type BalanceCurrencyList = List export interface CurrencyRateValue { currencyRate?: number - selectedCurrency?: AVAILABLE_CURRENCIES + selectedCurrency?: string currencyBalances?: BalanceCurrencyList } diff --git a/src/logic/currencyValues/store/utils/currencyValuesStorage.ts b/src/logic/currencyValues/store/utils/currencyValuesStorage.ts index ba716349..6f91f608 100644 --- a/src/logic/currencyValues/store/utils/currencyValuesStorage.ts +++ b/src/logic/currencyValues/store/utils/currencyValuesStorage.ts @@ -1,8 +1,7 @@ import { loadFromStorage, saveToStorage } from 'src/utils/storage' -import { AVAILABLE_CURRENCIES } from '../model/currencyValues' const SELECTED_CURRENCY_STORAGE_KEY = 'SELECTED_CURRENCY' -export const saveSelectedCurrency = async (selectedCurrency: AVAILABLE_CURRENCIES): Promise => { +export const saveSelectedCurrency = async (selectedCurrency: string): Promise => { try { await saveToStorage(SELECTED_CURRENCY_STORAGE_KEY, selectedCurrency) } catch (err) { @@ -10,6 +9,6 @@ export const saveSelectedCurrency = async (selectedCurrency: AVAILABLE_CURRENCIE } } -export const loadSelectedCurrency = async (): Promise => { +export const loadSelectedCurrency = async (): Promise => { return await loadFromStorage(SELECTED_CURRENCY_STORAGE_KEY) } diff --git a/src/logic/wallets/__tests__/ethAddresses.test.ts b/src/logic/wallets/__tests__/ethAddresses.test.ts new file mode 100644 index 00000000..28bb962b --- /dev/null +++ b/src/logic/wallets/__tests__/ethAddresses.test.ts @@ -0,0 +1,285 @@ +//@ts-nocheck +import { List } from 'immutable' + +import { + isUserAnOwner, + isUserAnOwnerOfAnySafe, + isValidEnsName, + sameAddress, + shortVersionOf, +} from 'src/logic/wallets/ethAddresses' +import makeSafe from 'src/logic/safe/store/models/safe' +import { makeOwner } from 'src/logic/safe/store/models/owner' + +describe('src/logic/wallets/ethAddresses', () => { + describe('Utility function: sameAddress', () => { + it('It should return false if no address given', () => { + // given + const safeAddress = null + const safeAddress2 = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' + + // when + const result = sameAddress(safeAddress, safeAddress2) + + // then + expect(result).toBe(false) + }) + it('It should return false if not second address given', () => { + // given + const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' + const safeAddress2 = null + + // when + const result = sameAddress(safeAddress, safeAddress2) + + // then + expect(result).toBe(false) + }) + it('It should return true if two equal addresses given', () => { + // given + const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' + + // when + const result = sameAddress(safeAddress, safeAddress.toLowerCase()) + + // then + expect(result).toBe(true) + }) + it('If should return false if two different addresses given', () => { + // given + const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' + const safeAddress2 = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' + + // when + const result = sameAddress(safeAddress, safeAddress2) + + // then + expect(result).toBe(false) + }) + }) + + describe('Utility function: shortVersionOf', () => { + it('It should return Unknown if no address given', () => { + // given + const safeAddress = null + const cut = 5 + const expectedResult = 'Unknown' + + // when + const result = shortVersionOf(safeAddress, cut) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return 0x344...f0503 if given 0x344B941b1aAE2e4Be73987212FC4741687Bf0503 and a cut = 5', () => { + // given + const safeAddress = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' + const cut = 5 + const expectedResult = `0x344...f0503` + + // when + const result = shortVersionOf(safeAddress, cut) + + // then + expect(result).toBe(expectedResult) + }) + it('If should return the same address if a cut value bigger than the address length given', () => { + // given + const safeAddress = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' + const cut = safeAddress.length + const expectedResult = safeAddress + + // when + const result = shortVersionOf(safeAddress, cut) + + // then + expect(result).toBe(expectedResult) + }) + }) + + describe('Utility function: isUserAnOwner', () => { + it("Should return false if there's no Safe", () => { + // given + const userAddress = 'address1' + const safeInstance = null + const expectedResult = false + + // when + const result = isUserAnOwner(safeInstance, userAddress) + + // then + expect(result).toBe(expectedResult) + }) + it("Should return false if there's no `userAccount`", () => { + // given + const userAddress = null + const owners = List([makeOwner({ address: userAddress })]) + const safeInstance = makeSafe({ owners }) + const expectedResult = false + + // when + const result = isUserAnOwner(safeInstance, userAddress) + + // then + expect(result).toBe(expectedResult) + }) + it('Should return false if there are no owners for the Safe', () => { + // given + const userAddress = 'address1' + const owners = null + const safeInstance = makeSafe({ owners }) + const expectedResult = false + + // when + const result = isUserAnOwner(safeInstance, userAddress) + + // then + expect(result).toBe(expectedResult) + }) + it("Should return true if `userAccount` is not in the list of Safe's owners", () => { + // given + const userAddress = 'address1' + const owners = List([makeOwner({ address: userAddress })]) + const safeInstance = makeSafe({ owners }) + const expectedResult = true + + // when + const result = isUserAnOwner(safeInstance, userAddress) + + // then + expect(result).toBe(expectedResult) + }) + it("Should return false if `userAccount` is not in the list of Safe's owners", () => { + // given + const userAddress = 'address1' + const userAddress2 = 'address2' + const owners = List([makeOwner({ address: userAddress })]) + const safeInstance = makeSafe({ owners }) + const expectedResult = false + + // when + const result = isUserAnOwner(safeInstance, userAddress2) + + // then + expect(result).toBe(expectedResult) + }) + }) + + describe('Utility function: isUserAnOwnerOfAnySafe', () => { + it('Should return true if given a list of safes, one of them has an owner equal to the userAccount', () => { + // given + const userAddress = 'address1' + const userAddress2 = 'address2' + const owners1 = List([makeOwner({ address: userAddress })]) + const owners2 = List([makeOwner({ address: userAddress2 })]) + const safeInstance = makeSafe({ owners: owners1 }) + const safeInstance2 = makeSafe({ owners: owners2 }) + const safesList = List([safeInstance, safeInstance2]) + const expectedResult = true + + // when + const result = isUserAnOwnerOfAnySafe(safesList, userAddress) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return false if given a list of safes, none of them has an owner equal to the userAccount', () => { + // given + const userAddress = 'address1' + const userAddress2 = 'address2' + const userAddress3 = 'address3' + const owners1 = List([makeOwner({ address: userAddress3 })]) + const owners2 = List([makeOwner({ address: userAddress2 })]) + const safeInstance = makeSafe({ owners: owners1 }) + const safeInstance2 = makeSafe({ owners: owners2 }) + const safesList = List([safeInstance, safeInstance2]) + const expectedResult = false + + // when + const result = isUserAnOwnerOfAnySafe(safesList, userAddress) + + // then + expect(result).toBe(expectedResult) + }) + }) + + describe('Utility function: isValidEnsName', () => { + it('If should return false if given no ens name', () => { + // given + const ensName = null + const expectedResult = false + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return false for an ens without extension in format [value].[eth|test|xyz|luxe]', () => { + // given + const ensName = 'test' + const expectedResult = false + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return false for an ens without the format [value].[eth|test|xyz|luxe]', () => { + // given + const ensName = 'test.et12312' + const expectedResult = false + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return true for an ens in format [value].eth', () => { + // given + const ensName = 'test.eth' + const expectedResult = true + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return true for ens in format [value].test', () => { + // given + const ensName = 'test.test' + const expectedResult = true + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return true for an ens in the format [value].xyz', () => { + // given + const ensName = 'test.xyz' + const expectedResult = true + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + it('It should return true for an ens in format [value].luxe', () => { + // given + const ensName = 'test.luxe' + const expectedResult = true + + // when + const result = isValidEnsName(ensName) + + // then + expect(result).toBe(expectedResult) + }) + }) +}) diff --git a/src/logic/wallets/ethAddresses.ts b/src/logic/wallets/ethAddresses.ts index 300becaa..d45d0fea 100644 --- a/src/logic/wallets/ethAddresses.ts +++ b/src/logic/wallets/ethAddresses.ts @@ -1,17 +1,10 @@ import { List } from 'immutable' import { SafeRecord } from 'src/logic/safe/store/models/safe' +import { sameString } from 'src/utils/strings' export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' export const sameAddress = (firstAddress: string | undefined, secondAddress: string | undefined): boolean => { - if (!firstAddress) { - return false - } - - if (!secondAddress) { - return false - } - - return firstAddress.toLowerCase() === secondAddress.toLowerCase() + return sameString(firstAddress, secondAddress) } export const shortVersionOf = (value: string, cut: number): string => { diff --git a/src/logic/wallets/tests/ethAddresses.test.ts b/src/logic/wallets/tests/ethAddresses.test.ts deleted file mode 100644 index 5191d21b..00000000 --- a/src/logic/wallets/tests/ethAddresses.test.ts +++ /dev/null @@ -1,282 +0,0 @@ -//@ts-nocheck -import { - isUserAnOwner, - isUserAnOwnerOfAnySafe, - isValidEnsName, - sameAddress, - shortVersionOf, -} from 'src/logic/wallets/ethAddresses' -import makeSafe from 'src/logic/safe/store/models/safe' -import { makeOwner } from 'src/logic/safe/store/models/owner' -import { List } from 'immutable' - -describe('Utility function: sameAddress', () => { - it('It should return false if no address given', () => { - // given - const safeAddress = null - const safeAddress2 = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' - - // when - const result = sameAddress(safeAddress, safeAddress2) - - // then - expect(result).toBe(false) - }) - it('It should return false if not second address given', () => { - // given - const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' - const safeAddress2 = null - - // when - const result = sameAddress(safeAddress, safeAddress2) - - // then - expect(result).toBe(false) - }) - it('It should return true if two equal addresses given', () => { - // given - const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' - - // when - const result = sameAddress(safeAddress, safeAddress) - - // then - expect(result).toBe(true) - }) - it('If should return false if two different addresses given', () => { - // given - const safeAddress = '0xdfA693da0D16F5E7E78FdCBeDe8FC6eBEa44f1Cf' - const safeAddress2 = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' - - // when - const result = sameAddress(safeAddress, safeAddress2) - - // then - expect(result).toBe(false) - }) -}) - -describe('Utility function: shortVersionOf', () => { - it('It should return Unknown if no address given', () => { - // given - const safeAddress = null - const cut = 5 - const expectedResult = 'Unknown' - - // when - const result = shortVersionOf(safeAddress, cut) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return 0x344...f0503 if given 0x344B941b1aAE2e4Be73987212FC4741687Bf0503 and a cut = 5', () => { - // given - const safeAddress = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' - const cut = 5 - const expectedResult = `0x344...f0503` - - // when - const result = shortVersionOf(safeAddress, cut) - - // then - expect(result).toBe(expectedResult) - }) - it('If should return the same address if a cut value bigger than the address length given', () => { - // given - const safeAddress = '0x344B941b1aAE2e4Be73987212FC4741687Bf0503' - const cut = safeAddress.length - const expectedResult = safeAddress - - // when - const result = shortVersionOf(safeAddress, cut) - - // then - expect(result).toBe(expectedResult) - }) -}) - -describe('Utility function: isUserAnOwner', () => { - it("Should return false if there's no Safe", () => { - // given - const userAddress = 'address1' - const safeInstance = null - const expectedResult = false - - // when - const result = isUserAnOwner(safeInstance, userAddress) - - // then - expect(result).toBe(expectedResult) - }) - it("Should return false if there's no `userAccount`", () => { - // given - const userAddress = null - const owners = List([makeOwner({ address: userAddress })]) - const safeInstance = makeSafe({ owners }) - const expectedResult = false - - // when - const result = isUserAnOwner(safeInstance, userAddress) - - // then - expect(result).toBe(expectedResult) - }) - it('Should return false if there are no owners for the Safe', () => { - // given - const userAddress = 'address1' - const owners = null - const safeInstance = makeSafe({ owners }) - const expectedResult = false - - // when - const result = isUserAnOwner(safeInstance, userAddress) - - // then - expect(result).toBe(expectedResult) - }) - it("Should return true if `userAccount` is not in the list of Safe's owners", () => { - // given - const userAddress = 'address1' - const owners = List([makeOwner({ address: userAddress })]) - const safeInstance = makeSafe({ owners }) - const expectedResult = true - - // when - const result = isUserAnOwner(safeInstance, userAddress) - - // then - expect(result).toBe(expectedResult) - }) - it("Should return false if `userAccount` is not in the list of Safe's owners", () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const owners = List([makeOwner({ address: userAddress })]) - const safeInstance = makeSafe({ owners }) - const expectedResult = false - - // when - const result = isUserAnOwner(safeInstance, userAddress2) - - // then - expect(result).toBe(expectedResult) - }) -}) - -describe('Utility function: isUserAnOwnerOfAnySafe', () => { - it('Should return true if given a list of safes, one of them has an owner equal to the userAccount', () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const owners1 = List([makeOwner({ address: userAddress })]) - const owners2 = List([makeOwner({ address: userAddress2 })]) - const safeInstance = makeSafe({ owners: owners1 }) - const safeInstance2 = makeSafe({ owners: owners2 }) - const safesList = List([safeInstance, safeInstance2]) - const expectedResult = true - - // when - const result = isUserAnOwnerOfAnySafe(safesList, userAddress) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return false if given a list of safes, none of them has an owner equal to the userAccount', () => { - // given - const userAddress = 'address1' - const userAddress2 = 'address2' - const userAddress3 = 'address3' - const owners1 = List([makeOwner({ address: userAddress3 })]) - const owners2 = List([makeOwner({ address: userAddress2 })]) - const safeInstance = makeSafe({ owners: owners1 }) - const safeInstance2 = makeSafe({ owners: owners2 }) - const safesList = List([safeInstance, safeInstance2]) - const expectedResult = false - - // when - const result = isUserAnOwnerOfAnySafe(safesList, userAddress) - - // then - expect(result).toBe(expectedResult) - }) -}) - -describe('Utility function: isValidEnsName', () => { - it('If should return false if given no ens name', () => { - // given - const ensName = null - const expectedResult = false - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return false for an ens without extension in format [value].[eth|test|xyz|luxe]', () => { - // given - const ensName = 'test' - const expectedResult = false - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return false for an ens without the format [value].[eth|test|xyz|luxe]', () => { - // given - const ensName = 'test.et12312' - const expectedResult = false - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return true for an ens in format [value].eth', () => { - // given - const ensName = 'test.eth' - const expectedResult = true - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return true for ens in format [value].test', () => { - // given - const ensName = 'test.test' - const expectedResult = true - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return true for an ens in the format [value].xyz', () => { - // given - const ensName = 'test.xyz' - const expectedResult = true - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) - it('It should return true for an ens in format [value].luxe', () => { - // given - const ensName = 'test.luxe' - const expectedResult = true - - // when - const result = isValidEnsName(ensName) - - // then - expect(result).toBe(expectedResult) - }) -}) diff --git a/src/routes/safe/components/Balances/dataFetcher.ts b/src/routes/safe/components/Balances/dataFetcher.ts index 0308f30f..d2d9b7d8 100644 --- a/src/routes/safe/components/Balances/dataFetcher.ts +++ b/src/routes/safe/components/Balances/dataFetcher.ts @@ -4,25 +4,25 @@ import { getNetworkInfo } from 'src/config' import { FIXED } from 'src/components/Table/sorting' import { formatAmountInUsFormat } from 'src/logic/tokens/utils/formatAmount' import { TableColumn } from 'src/components/Table/types.d' -import { AVAILABLE_CURRENCIES, BalanceCurrencyList } from 'src/logic/currencyValues/store/model/currencyValues' +import { BalanceCurrencyList } from 'src/logic/currencyValues/store/model/currencyValues' import { Token } from 'src/logic/tokens/store/model/token' export const BALANCE_TABLE_ASSET_ID = 'asset' export const BALANCE_TABLE_BALANCE_ID = 'balance' export const BALANCE_TABLE_VALUE_ID = 'value' +const { nativeCoin } = getNetworkInfo() + const getTokenPriceInCurrency = ( token: Token, - currencySelected?: AVAILABLE_CURRENCIES, + currencySelected?: string, currencyValues?: BalanceCurrencyList, currencyRate?: number, ): string => { if (!currencySelected) { return '' } - const currencyValue = currencyValues?.find(({ tokenAddress }) => { - const { nativeCoin } = getNetworkInfo() if (token.address === nativeCoin.address && !tokenAddress) { return true } @@ -51,7 +51,7 @@ export interface BalanceData { export const getBalanceData = ( activeTokens: List, - currencySelected?: AVAILABLE_CURRENCIES, + currencySelected?: string, currencyValues?: BalanceCurrencyList, currencyRate?: number, ): List => { diff --git a/src/routes/safe/components/CurrencyDropdown/index.tsx b/src/routes/safe/components/CurrencyDropdown/index.tsx index 862c0251..2304aa69 100644 --- a/src/routes/safe/components/CurrencyDropdown/index.tsx +++ b/src/routes/safe/components/CurrencyDropdown/index.tsx @@ -20,16 +20,20 @@ import { safeParamAddressFromStateSelector } from 'src/logic/safe/store/selector import { DropdownListTheme } from 'src/theme/mui' import { setImageToPlaceholder } from '../Balances/utils' import Img from 'src/components/layout/Img/index' -import etherIcon from 'src/assets/icons/icon_etherTokens.svg' +import { getNetworkInfo } from 'src/config' +import { sameString } from 'src/utils/strings' + +const { nativeCoin } = getNetworkInfo() const CurrencyDropdown = (): React.ReactElement | null => { - const currenciesList = Object.values(AVAILABLE_CURRENCIES) const safeAddress = useSelector(safeParamAddressFromStateSelector) as string const dispatch = useDispatch() const [anchorEl, setAnchorEl] = useState(null) const selectedCurrency = useSelector(currentCurrencySelector) - const [searchParams, setSearchParams] = useState('') + + const currenciesList = Object.values(AVAILABLE_CURRENCIES) + const tokenImage = nativeCoin.logoUri const classes = useDropdownStyles() const currenciesListFiltered = currenciesList.filter((currency) => currency.toLowerCase().includes(searchParams.toLowerCase()), @@ -103,11 +107,11 @@ const CurrencyDropdown = (): React.ReactElement | null => { value={currencyName} > - {currencyName === AVAILABLE_CURRENCIES.ETH ? ( + {sameString(currencyName, nativeCoin.symbol) ? ( ether ) : ( diff --git a/src/utils/strings.ts b/src/utils/strings.ts index ec142be7..0d2f86f1 100644 --- a/src/utils/strings.ts +++ b/src/utils/strings.ts @@ -44,3 +44,17 @@ export const textShortener = ({ charsEnd = 10, charsStart = 10, ellipsis = '...' * @returns {string} string without side whitespaces */ export const trimSpaces = (value: string): string => (value === undefined ? '' : value.trim()) + +/** + * Util to compare two strings, comparison is case insensitive + * @param str1 + * @param str2 + * @returns {boolean} + */ +export const sameString = (str1: string | undefined, str2: string | undefined): boolean => { + if (!str1 || !str2) { + return false + } + + return str1.toLowerCase() === str2.toLowerCase() +}