From 125bfa0e40eb7a37de404e510be1487d18538cbd Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Thu, 17 Nov 2022 14:25:20 -0300 Subject: [PATCH 001/110] feat: remove unused state propeties subscription: - remove lastActiveTime property - remove block state subscription --- .../src/controllers/AppStateController.ts | 28 ++++++++++++++----- .../src/utils/constants/initialState.ts | 1 - .../controllers/AppStateController.test.ts | 11 -------- .../BlankProviderController.test.ts | 2 +- packages/ui/src/mock/MockBackgroundState.tsx | 3 +- packages/ui/src/router/PopupRouter.tsx | 12 ++------ 6 files changed, 25 insertions(+), 32 deletions(-) diff --git a/packages/background/src/controllers/AppStateController.ts b/packages/background/src/controllers/AppStateController.ts index 4b5ea95eb..8356e125c 100644 --- a/packages/background/src/controllers/AppStateController.ts +++ b/packages/background/src/controllers/AppStateController.ts @@ -3,6 +3,8 @@ import { BlankDepositController } from './blank-deposit/BlankDepositController'; import KeyringControllerDerivated from './KeyringControllerDerivated'; import TransactionController from './transactions/TransactionController'; +const STICKY_STORAGE_DATA_TTL = 60000 * 10; + export interface AppStateControllerState { idleTimeout: number; // Minutes until auto-lock - Zero if disabled } @@ -10,7 +12,7 @@ export interface AppStateControllerState { export interface AppStateControllerMemState { isAppUnlocked: boolean; lockedByTimeout: boolean; - lastActiveTime: number; + expiredStickyStorage: boolean; } export default class AppStateController extends BaseController< @@ -18,6 +20,8 @@ export default class AppStateController extends BaseController< AppStateControllerMemState > { private _timer: ReturnType | null; + private _stickyStorageTimer: ReturnType | undefined; + private isLoadingDeposits = false; constructor( @@ -28,8 +32,8 @@ export default class AppStateController extends BaseController< ) { super(initState, { isAppUnlocked: false, - lastActiveTime: new Date().getTime(), lockedByTimeout: false, + expiredStickyStorage: false, }); this._timer = null; @@ -54,14 +58,10 @@ export default class AppStateController extends BaseController< * */ public setLastActiveTime = (): void => { - this.UIStore.updateState({ lastActiveTime: new Date().getTime() }); this._resetTimer(); + this._resetStickyStorageTimer(); }; - public get lastActiveTime(): number { - return this.lastActiveTime; - } - /** * Set a custom time in minutes for the extension auto block * The idle timeout should be greater than zero @@ -143,6 +143,20 @@ export default class AppStateController extends BaseController< } }; + private _resetStickyStorageTimer = () => { + if (this._stickyStorageTimer) { + clearTimeout(this._stickyStorageTimer); + } + //only update UIStore when it is necessary. + if (this.UIStore.getState().expiredStickyStorage) { + this.UIStore.updateState({ expiredStickyStorage: false }); + } + + this._stickyStorageTimer = setTimeout(() => { + this.UIStore.updateState({ expiredStickyStorage: true }); + }, STICKY_STORAGE_DATA_TTL); + }; + /** * Resets the idle timer * diff --git a/packages/background/src/utils/constants/initialState.ts b/packages/background/src/utils/constants/initialState.ts index 29e927249..e0a68cc87 100644 --- a/packages/background/src/utils/constants/initialState.ts +++ b/packages/background/src/utils/constants/initialState.ts @@ -80,7 +80,6 @@ export type BlankAppUIState = { PreferencesController: PreferencesControllerState; TransactionController: TransactionVolatileControllerState; BlankDepositController: BlankDepositControllerUIStoreState; - BlockUpdatesController: BlockUpdatesControllerState; ExchangeRatesController: ExchangeRatesControllerState; GasPricesController: GasPricesControllerState; ActivityListController: IActivityListState; diff --git a/packages/background/test/controllers/AppStateController.test.ts b/packages/background/test/controllers/AppStateController.test.ts index 620ea2fb9..a3f3e52a0 100644 --- a/packages/background/test/controllers/AppStateController.test.ts +++ b/packages/background/test/controllers/AppStateController.test.ts @@ -96,17 +96,6 @@ describe('AppState Controller', function () { ); }); - it('should update the last user active time', async function () { - const initialTime = - appStateController.UIStore.getState().lastActiveTime; - expect(initialTime).to.be.greaterThan(0); - const promise = await sleep(600); - appStateController.setLastActiveTime(); - expect( - appStateController.UIStore.getState().lastActiveTime - ).to.be.greaterThan(initialTime); - }); - it('should lock and unlock properly', async function () { await mockKeyringController.createNewVaultAndKeychain('testPassword'); await appStateController.lock(); diff --git a/packages/background/test/controllers/BlankProviderController.test.ts b/packages/background/test/controllers/BlankProviderController.test.ts index 01ba4daab..b91179899 100644 --- a/packages/background/test/controllers/BlankProviderController.test.ts +++ b/packages/background/test/controllers/BlankProviderController.test.ts @@ -402,7 +402,7 @@ describe('Blank Provider Controller', function () { sinon.stub(appStateController.UIStore, 'getState').returns({ isAppUnlocked: true, - lastActiveTime: 0, + expiredStickyStorage: false, lockedByTimeout: false, }); sinon.stub(permissionsController.store, 'getState').returns({ diff --git a/packages/ui/src/mock/MockBackgroundState.tsx b/packages/ui/src/mock/MockBackgroundState.tsx index 22476f0ce..da2e8ff72 100644 --- a/packages/ui/src/mock/MockBackgroundState.tsx +++ b/packages/ui/src/mock/MockBackgroundState.tsx @@ -308,7 +308,7 @@ export const initBackgroundState: BackgroundStateType = { txSignTimeout: 0, unapprovedTransactions: {}, previousWithdrawals: [], - lastActiveTime: 0, + expiredStickyStorage: false, depositsCount: { eth: [ @@ -366,7 +366,6 @@ export const initBackgroundState: BackgroundStateType = { }, ], }, - blockData: { 5: { blockNumber: -1 } }, areDepositsPending: false, areWithdrawalsPending: false, pendingDeposits: { diff --git a/packages/ui/src/router/PopupRouter.tsx b/packages/ui/src/router/PopupRouter.tsx index fab40483e..83ed92dd1 100644 --- a/packages/ui/src/router/PopupRouter.tsx +++ b/packages/ui/src/router/PopupRouter.tsx @@ -22,9 +22,6 @@ import ProviderDownDialog from "../components/dialog/ProviderDownDialog" import useClearStickyStorage from "../context/hooks/useClearStickyStorage" import { getNonSubmittedTransactions } from "../util/getNonSubmittedTransactions" -//10 minutes -const LOCAL_STORAGE_DATA_TTL = 60000 * 10 - /** Purpose of this component is to check in Blank State if there is any pending connect to site or transaction confirm * in order to show that page always, whenever the extension is loaded and unlocked. */ @@ -35,7 +32,7 @@ const PopupComponent = () => { permissionRequests, dappRequests, transactions, - lastActiveTime, + expiredStickyStorage, } = useBlankState()! const unapprovedTransactions = getNonSubmittedTransactions( transactions, @@ -59,12 +56,7 @@ const PopupComponent = () => { ) useLayoutEffect(() => { - if ( - showPage || - showUnlock || - (lastActiveTime && - timeExceedsTTL(lastActiveTime, LOCAL_STORAGE_DATA_TTL)) - ) { + if (showPage || showUnlock || expiredStickyStorage) { // If the wallet is locked or if we're in a dApp request // We should get rid of all the localSotrage stuff. clearStickyStorage() From 1fdfb54116bd73aa04e581df38bd6e0d7bff4e2c Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Mon, 21 Nov 2022 14:26:00 -0300 Subject: [PATCH 002/110] feat: Split state and subscriptions: - Separate Gas Prices subscription from main state - Separate Activity list subscription from main state and improve its regenaration - Separate exchange rates subscription from main state --- .../controllers/AccountTrackerController.ts | 36 +- .../src/controllers/ActivityListController.ts | 57 ++- .../src/controllers/AddressBookController.ts | 24 +- .../src/controllers/BlankController.ts | 136 ++++-- .../TransactionWatcherController.ts | 4 +- .../src/utils/constants/initialState.ts | 14 + .../src/utils/types/communication.ts | 52 ++- packages/ui/src/App.tsx | 19 +- packages/ui/src/components/ActivityList.tsx | 31 -- .../ui/src/components/home/AccountAvatar.tsx | 29 ++ .../{ => home}/ActivityAssetsView.tsx | 6 +- .../ui/src/components/home/ActivityList.tsx | 29 ++ .../ui/src/components/home/DAppConnection.tsx | 82 ++++ .../{gas => home}/GasPricesInfo.tsx | 10 +- .../src/components/home/HomeBalancePanel.tsx | 135 ++++++ .../transactions/GasPriceComponent.tsx | 7 +- .../transactions/GasPriceSelector.tsx | 8 +- .../ui/src/components/transactions/Price.tsx | 6 +- .../transactions/TransactionItem.tsx | 2 - .../context/background/BackgroundState.tsx | 7 +- .../context/background/backgroundContext.tsx | 4 +- .../background/useActivityListState.tsx | 42 ++ .../background/useExchangeRatesState.tsx | 47 ++ .../context/background/useGasPricesState.tsx | 43 ++ .../background/useStateSubscription.ts | 55 +++ packages/ui/src/context/commActions.ts | 117 ++++- packages/ui/src/context/commTypes.ts | 7 + .../ui/src/context/hooks/useGasPriceData.ts | 6 +- packages/ui/src/context/hooks/useWindowId.tsx | 4 +- packages/ui/src/mock/MockBackgroundState.tsx | 34 -- packages/ui/src/router/PopupRouter.tsx | 69 +-- packages/ui/src/routes/PopupPage.tsx | 411 ++++-------------- .../ui/src/routes/bridge/BridgeSetupPage.tsx | 6 +- .../routes/dApp/TransactionConfirmPage.tsx | 13 +- .../src/routes/deposit/DepositConfirmPage.tsx | 8 +- .../ui/src/routes/send/SendConfirmPage.tsx | 6 +- .../settings/ConnectedSiteAccountsPage.tsx | 6 +- packages/ui/src/routes/swap/SwapPage.tsx | 9 +- .../routes/withdraw/WithdrawBlankConfirm.tsx | 8 +- packages/ui/src/util/gasPrice.ts | 2 +- ...tions.ts => useActivtyListTransactions.ts} | 15 +- .../ui/src/util/hooks/useCurrencyFormatter.ts | 6 +- .../ui/src/util/hooks/useTokenTransactions.ts | 4 +- packages/ui/src/util/transactionUtils.ts | 9 +- packages/ui/src/util/useMetricCollector.tsx | 64 +++ 45 files changed, 1117 insertions(+), 572 deletions(-) delete mode 100644 packages/ui/src/components/ActivityList.tsx create mode 100644 packages/ui/src/components/home/AccountAvatar.tsx rename packages/ui/src/components/{ => home}/ActivityAssetsView.tsx (91%) create mode 100644 packages/ui/src/components/home/ActivityList.tsx create mode 100644 packages/ui/src/components/home/DAppConnection.tsx rename packages/ui/src/components/{gas => home}/GasPricesInfo.tsx (97%) create mode 100644 packages/ui/src/components/home/HomeBalancePanel.tsx create mode 100644 packages/ui/src/context/background/useActivityListState.tsx create mode 100644 packages/ui/src/context/background/useExchangeRatesState.tsx create mode 100644 packages/ui/src/context/background/useGasPricesState.tsx create mode 100644 packages/ui/src/context/background/useStateSubscription.ts rename packages/ui/src/util/hooks/{useTransactions.ts => useActivtyListTransactions.ts} (92%) create mode 100644 packages/ui/src/util/useMetricCollector.tsx diff --git a/packages/background/src/controllers/AccountTrackerController.ts b/packages/background/src/controllers/AccountTrackerController.ts index e7eb42f22..c9ac94b54 100644 --- a/packages/background/src/controllers/AccountTrackerController.ts +++ b/packages/background/src/controllers/AccountTrackerController.ts @@ -23,7 +23,7 @@ import { getAddressBalances as getAddressBalancesFromSingleCallBalancesContract, isSingleCallBalancesContractAvailable, } from '../utils/balance-checker/balanceChecker'; -import { cloneDeep } from 'lodash'; +import { cloneDeep, isEqual } from 'lodash'; import { ACTIONS_TIME_INTERVALS_DEFAULT_VALUES, Network, @@ -836,7 +836,7 @@ export class AccountTrackerController extends BaseController { // If any of the following stores were updated trigger the ActivityList update this._transactionsController.UIStore.subscribe(this.onStoreUpdate); this._blankDepositsController.UIStore.subscribe(this.onStoreUpdate); - this._preferencesController.store.subscribe(this.onStoreUpdate); - this._networkController.store.subscribe(this.onStoreUpdate); - this._transactionWatcherController.store.subscribe(this.onStoreUpdate); + this._preferencesController.store.subscribe((newState, oldState) => { + if ( + !compareAddresses( + newState.selectedAddress, + oldState?.selectedAddress + ) + ) { + return this.onStoreUpdate(); + } + }); + this._networkController.store.subscribe((newState, oldState) => { + if (newState.selectedNetwork !== oldState?.selectedNetwork) { + this.onStoreUpdate(); + } + }); + this._transactionWatcherController.store.subscribe( + (newState, oldState) => { + const { selectedAddress } = + this._preferencesController.store.getState(); + + const safeGetTxsHashes = ( + txWatcherState: + | TransactionWatcherControllerState + | undefined + ) => { + if (!txWatcherState) { + return []; + } + return this.parseWatchedTransactions( + this._networkController.network.chainId, + selectedAddress, + txWatcherState.transactions + ) + .map((tx) => tx.transactionParams.hash!) + .filter(Boolean); + }; + + const oldTxs = safeGetTxsHashes(oldState); + const newTxs = safeGetTxsHashes(newState); + + //If hashes length has changed, then update the activity list. + if (oldTxs.length !== newTxs.length) { + this.onStoreUpdate(); + } + } + ); this._bridgeController.store.subscribe(this.onStoreUpdate); this.onStoreUpdate(); } @@ -212,11 +256,10 @@ export class ActivityListController extends BaseController { */ private parseWatchedTransactions( chainId: number, - selectedAddress: string + selectedAddress: string, + transactions: TransactionWatcherControllerState['transactions'] = this._transactionWatcherController.store.getState() + .transactions ): TransactionMeta[] { - const { transactions } = - this._transactionWatcherController.store.getState(); - const watchedTransactions: TransactionMeta[] = []; if (chainId in transactions) { diff --git a/packages/background/src/controllers/AddressBookController.ts b/packages/background/src/controllers/AddressBookController.ts index 36ca7bc8d..2343cd868 100644 --- a/packages/background/src/controllers/AddressBookController.ts +++ b/packages/background/src/controllers/AddressBookController.ts @@ -8,6 +8,7 @@ import { TransactionMeta, } from './transactions/utils/types'; import { PreferencesController } from './PreferencesController'; +import { isEqual } from 'lodash'; /** * @type AddressBookControllerProps @@ -338,15 +339,22 @@ export class AddressBookController extends BaseController; private readonly UIStore: ComposedStore; + private readonly exchangeRatesStore: ComposedStore; + private readonly gasPricesStore: ComposedStore; + private readonly activityListStore: ComposedStore; + private readonly STORES: Record>; private readonly _devTools: any; @@ -464,48 +475,69 @@ export default class BlankController extends EventEmitter { preferencesController: this.preferencesController, }); - this.store = new ComposedStore({ - NetworkController: this.networkController.store, - AppStateController: this.appStateController.store, - OnboardingController: this.onboardingController.store, - KeyringController: this.keyringController.store, - AccountTrackerController: this.accountTrackerController.store, - PreferencesController: this.preferencesController.store, - TransactionController: this.transactionController.store, + this.store = new ComposedStore( + { + NetworkController: this.networkController.store, + AppStateController: this.appStateController.store, + OnboardingController: this.onboardingController.store, + KeyringController: this.keyringController.store, + AccountTrackerController: this.accountTrackerController.store, + PreferencesController: this.preferencesController.store, + TransactionController: this.transactionController.store, + ExchangeRatesController: this.exchangeRatesController.store, + GasPricesController: this.gasPricesController.store, + BlankDepositController: this.blankDepositController.store, + TokenController: this.tokenController.store, + PermissionsController: this.permissionsController.store, + AddressBookController: this.addressBookController.store, + BlockUpdatesController: this.blockUpdatesController.store, + BlockFetchController: this.blockFetchController.store, + TransactionWatcherControllerState: + this.transactionWatcherController.store, + BridgeController: this.bridgeController.store, + }, + true + ); + + this.exchangeRatesStore = new ComposedStore({ ExchangeRatesController: this.exchangeRatesController.store, - GasPricesController: this.gasPricesController.store, - BlankDepositController: this.blankDepositController.store, - TokenController: this.tokenController.store, - PermissionsController: this.permissionsController.store, - AddressBookController: this.addressBookController.store, - BlockUpdatesController: this.blockUpdatesController.store, - BlockFetchController: this.blockFetchController.store, - TransactionWatcherControllerState: - this.transactionWatcherController.store, - BridgeController: this.bridgeController.store, }); - this.UIStore = new ComposedStore({ - NetworkController: this.networkController.store, - AppStateController: this.appStateController.UIStore, - OnboardingController: this.onboardingController.store, - KeyringController: this.keyringController.memStore, - AccountTrackerController: this.accountTrackerController.store, - PreferencesController: this.preferencesController.store, - TransactionController: this.transactionController.UIStore, - ExchangeRatesController: this.exchangeRatesController.store, + this.gasPricesStore = new ComposedStore({ GasPricesController: this.gasPricesController.store, - BlankDepositController: this.blankDepositController.UIStore, - TokenController: this.tokenController.store, + }); + + this.activityListStore = new ComposedStore({ ActivityListController: this.activityListController.store, - PermissionsController: this.permissionsController.store, - AddressBookController: this.addressBookController.store, - BlankProviderController: this.blankProviderController.store, - BlockUpdatesController: this.blockUpdatesController.store, - SwapController: this.swapController.UIStore, - BridgeController: this.bridgeController.UIStore, }); + this.UIStore = new ComposedStore( + { + NetworkController: this.networkController.store, + AppStateController: this.appStateController.UIStore, + OnboardingController: this.onboardingController.store, + KeyringController: this.keyringController.memStore, + AccountTrackerController: this.accountTrackerController.store, + PreferencesController: this.preferencesController.store, + TransactionController: this.transactionController.UIStore, + BlankDepositController: this.blankDepositController.UIStore, + TokenController: this.tokenController.store, + PermissionsController: this.permissionsController.store, + AddressBookController: this.addressBookController.store, + BlankProviderController: this.blankProviderController.store, + SwapController: this.swapController.UIStore, + BridgeController: this.bridgeController.UIStore, + }, + true + ); + + this.STORES = { + [StateType.APP_STATE]: this.UIStore, + [StateType.EXCHANGE_RATES]: this.exchangeRatesStore, + [StateType.GAS_PRICES]: this.gasPricesStore, + [StateType.ACTIVITY_LIST]: this.activityListStore, + }; + // Check controllers on app lock/unlock this.appStateController.UIStore.subscribe(() => { this.manageControllers(); @@ -912,7 +944,13 @@ export default class BlankController extends EventEmitter { request as RequestUpdateSitePermissions ); case Messages.STATE.GET: - return this.getState(); + return this.getState(request as RequestGetState); + case Messages.STATE.SUBSCRIBE: + return this.subscribeState( + id, + port, + (request as RequestSubscribeState).stateType + ); case Messages.TRANSACTION.CONFIRM: return this.confirmTransaction( request as RequestConfirmTransaction @@ -995,8 +1033,6 @@ export default class BlankController extends EventEmitter { return this.completeSetup(request as RequestCompleteSetup); case Messages.WALLET.REQUEST_SEED_PHRASE: return this.getSeedPhrase(request as RequestSeedPhrase); - case Messages.STATE.SUBSCRIBE: - return this.stateSubscribe(id, port); case Messages.TOKEN.GET_BALANCE: return this.getTokenBalance(request as RequestGetTokenBalance); case Messages.TOKEN.GET_TOKENS: @@ -2276,8 +2312,8 @@ export default class BlankController extends EventEmitter { * Get UI State * */ - private getState(): Flatten { - return this.UIStore.flatState; + private getState(r: RequestGetState): ResponseGetState { + return this.STORES[r.stateType].flatState; } /** @@ -2856,22 +2892,28 @@ export default class BlankController extends EventEmitter { * State subscription method * */ - private stateSubscribe(id: string, port: chrome.runtime.Port): boolean { + private subscribeState( + id: string, + port: chrome.runtime.Port, + stateType: StateType + ): boolean { + const store = this.STORES[stateType]; + const cb = this.createSubscription( id, port ); const sendState = () => { - const flatState = this.UIStore.flatState; + const flatState = store.flatState; cb(flatState); }; - this.UIStore.subscribe(sendState); + store.subscribe(sendState); port.onDisconnect.addListener((): void => { this.unsubscribe(id); - this.UIStore.unsubscribe(sendState); + store.unsubscribe(sendState); }); return true; diff --git a/packages/background/src/controllers/TransactionWatcherController.ts b/packages/background/src/controllers/TransactionWatcherController.ts index c61b7e74a..0043144f6 100644 --- a/packages/background/src/controllers/TransactionWatcherController.ts +++ b/packages/background/src/controllers/TransactionWatcherController.ts @@ -34,7 +34,7 @@ import { showIncomingTransactionNotification } from '../utils/notifications'; import { checkIfNotAllowedError } from '../utils/ethersError'; import TransactionController from './transactions/TransactionController'; import { fetchBlockWithRetries } from '../utils/blockFetch'; -import { isNil } from 'lodash'; +import { cloneDeep, isNil } from 'lodash'; import { runPromiseSafely } from '../utils/promises'; export enum TransactionTypeEnum { @@ -240,7 +240,7 @@ export class TransactionWatcherController extends BaseController = { [controller in keyof Partial]: IObservableStore>; }; diff --git a/packages/background/src/utils/types/communication.ts b/packages/background/src/utils/types/communication.ts index c8af99814..516a04b3f 100644 --- a/packages/background/src/utils/types/communication.ts +++ b/packages/background/src/utils/types/communication.ts @@ -1,6 +1,11 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ import { Flatten } from './helpers'; -import { BlankAppUIState } from '../constants/initialState'; +import { + ActivityListUIState, + BlankAppUIState, + ExchangeRatesUIState, + GasPricesUIState, +} from '../constants/initialState'; import { CurrencyAmountPair, KnownCurrencies, @@ -441,7 +446,12 @@ export interface RequestSignatures { RequestUpdateSitePermissions, boolean ]; - [Messages.STATE.GET]: [undefined, ResponseGetState]; + [Messages.STATE.GET]: [RequestGetState, ResponseGetState]; + [Messages.STATE.SUBSCRIBE]: [ + RequestSubscribeState, + boolean, + StateSubscription + ]; [Messages.ENS.RESOLVE_NAME]: [RequestEnsResolve, string | null]; [Messages.ENS.LOOKUP_ADDRESS]: [RequestEnsLookup, string | null]; [Messages.UD.RESOLVE_NAME]: [RequestUDResolve, string | null]; @@ -498,7 +508,6 @@ export interface RequestSignatures { [Messages.WALLET.REQUEST_SEED_PHRASE]: [RequestSeedPhrase, string]; [Messages.WALLET.SETUP_COMPLETE]: [RequestCompleteSetup, void]; [Messages.WALLET.RESET]: [RequestWalletReset, boolean]; - [Messages.STATE.SUBSCRIBE]: [undefined, boolean, StateSubscription]; [Messages.TOKEN.GET_BALANCE]: [RequestGetTokenBalance, BigNumber]; [Messages.TOKEN.GET_TOKENS]: [RequestGetTokens, ITokens]; [Messages.TOKEN.GET_USER_TOKENS]: [RequestGetUserTokens, ITokens]; @@ -1150,13 +1159,25 @@ export interface ResponseBlankGetWithdrawalGasCost { total: BigNumber; } -export type ResponseGetState = Flatten; +export type ResponseGetAppState = Flatten; +export type ResponseGetExchangeRatesState = Flatten; +export type ResponseGetGasPricesState = Flatten; +export type ResponseGetActivityListState = Flatten; + +export type ResponseGetState = + | ResponseGetAppState + | ResponseGetExchangeRatesState + | ResponseGetGasPricesState + | ResponseGetActivityListState; export type SubscriptionMessageTypes = { [MessageType in keyof RequestSignatures]: RequestSignatures[MessageType][2]; }; -export type StateSubscription = Flatten; +export type AppStateSubscription = Flatten; +export type ExchangeRatesStateSubscription = Flatten; +export type GasPricesStateSubscription = Flatten; +export type ActivityListStateSubscription = Flatten; export interface ExternalEventSubscription { eventName: ProviderEvents; @@ -1223,3 +1244,24 @@ export type Handlers = Record; export enum BackgroundActions { CLOSE_WINDOW = 'CLOSE_WINDOW', } + +export enum StateType { + APP_STATE = 'APP_STATE', + EXCHANGE_RATES = 'EXCHANGE_RATES', + GAS_PRICES = 'GAS_PRICES', + ACTIVITY_LIST = 'ACTIVITY_LIST', +} + +export interface RequestSubscribeState { + stateType: StateType; +} + +export interface RequestGetState { + stateType: StateType; +} + +export type StateSubscription = + | AppStateSubscription + | ExchangeRatesStateSubscription + | GasPricesStateSubscription + | ActivityListStateSubscription; diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index 733c3efec..812e1969c 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -7,8 +7,10 @@ import { isPopup } from "./context/util/isPopup" import PopupRouter from "./router/PopupRouter" import TabRouter from "./router/TabRouter" import { WindowIdProvider } from "./context/hooks/useWindowId" +import { Profiler } from "react" +import useMetricCollector from "./util/useMetricCollector" -const AppLoading = () => { +export const AppLoading = () => { return (
@@ -30,10 +32,15 @@ const App = () => { ) } -const WrappedApp = () => ( - - - -) +const WrappedApp = () => { + const collect = useMetricCollector() + return ( + + + + + + ) +} export default WrappedApp diff --git a/packages/ui/src/components/ActivityList.tsx b/packages/ui/src/components/ActivityList.tsx deleted file mode 100644 index 13299b7cd..000000000 --- a/packages/ui/src/components/ActivityList.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import TransactionsList from "./transactions/TransactionsList" - -// Context -import { useSelectedNetwork } from "../context/hooks/useSelectedNetwork" -import { useSelectedAccount } from "../context/hooks/useSelectedAccount" - -// Utils - -import useTransactions from "../util/hooks/useTransactions" - -const ActivityList = () => { - const { chainId } = useSelectedNetwork() - const { address } = useSelectedAccount() - - const { transactions } = useTransactions() - - return ( -
- -
- ) -} - -export default ActivityList diff --git a/packages/ui/src/components/home/AccountAvatar.tsx b/packages/ui/src/components/home/AccountAvatar.tsx new file mode 100644 index 000000000..1e7f3a53b --- /dev/null +++ b/packages/ui/src/components/home/AccountAvatar.tsx @@ -0,0 +1,29 @@ +import { useBlankState } from "../../context/background/backgroundHooks" +import { useSelectedAccount } from "../../context/hooks/useSelectedAccount" +import { formatHash, formatName } from "../../util/formatAccount" +import useCopyToClipboard from "../../util/hooks/useCopyToClipboard" +import CopyTooltip from "../label/СopyToClipboardTooltip" + +const AccountAvatar = () => { + const blankState = useBlankState()! + const accountAddress = blankState.selectedAddress + const account = useSelectedAccount() + const { onCopy, copied } = useCopyToClipboard() + + return ( + + ) +} +export default AccountAvatar diff --git a/packages/ui/src/components/ActivityAssetsView.tsx b/packages/ui/src/components/home/ActivityAssetsView.tsx similarity index 91% rename from packages/ui/src/components/ActivityAssetsView.tsx rename to packages/ui/src/components/home/ActivityAssetsView.tsx index 24426d188..904e02db0 100644 --- a/packages/ui/src/components/ActivityAssetsView.tsx +++ b/packages/ui/src/components/home/ActivityAssetsView.tsx @@ -1,9 +1,9 @@ import { FunctionComponent, useState } from "react" import { PopupTabs } from "@block-wallet/background/controllers/PreferencesController" -import { updatePopupTab } from "../context/commActions" +import { updatePopupTab } from "../../context/commActions" import ActivityList from "./ActivityList" -import AssetsList from "./AssetsList" -import HorizontalSelect from "./input/HorizontalSelect" +import AssetsList from "../AssetsList" +import HorizontalSelect from "../input/HorizontalSelect" const tabs = [ { diff --git a/packages/ui/src/components/home/ActivityList.tsx b/packages/ui/src/components/home/ActivityList.tsx new file mode 100644 index 000000000..eba73f425 --- /dev/null +++ b/packages/ui/src/components/home/ActivityList.tsx @@ -0,0 +1,29 @@ +import TransactionsList from "../transactions/TransactionsList" +import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" +import { useSelectedAccount } from "../../context/hooks/useSelectedAccount" +import useActivtyListTransactions from "../../util/hooks/useActivtyListTransactions" +import { Profiler } from "react" +import useMetricCollector from "../../util/useMetricCollector" + +const ActivityList = () => { + const collect = useMetricCollector() + const { chainId } = useSelectedNetwork() + const { address } = useSelectedAccount() + const { transactions } = useActivtyListTransactions() + return ( + +
+ +
+
+ ) +} + +export default ActivityList diff --git a/packages/ui/src/components/home/DAppConnection.tsx b/packages/ui/src/components/home/DAppConnection.tsx new file mode 100644 index 000000000..dd545768b --- /dev/null +++ b/packages/ui/src/components/home/DAppConnection.tsx @@ -0,0 +1,82 @@ +import { useHistory } from "react-router-dom" +import { useConnectedSite } from "../../context/hooks/useConnectedSite" +import GenericTooltip from "../label/GenericTooltip" +import classnames from "classnames" +import { HiOutlineExclamationCircle } from "react-icons/hi" +import { BiCircle } from "react-icons/bi" +import { session } from "../../context/setup" + +const DAppConnection = () => { + const dAppConnected = useConnectedSite() + const history = useHistory()! + return ( + +

+ {dAppConnected === "connected" ? ( + You are connected to the open site + ) : ( + You are not connected to the open site + )} +

+
+ } + > +
{ + if (dAppConnected !== "not-connected") { + history.push({ + pathname: + "/accounts/menu/connectedSites/accountList", + state: { + origin: session?.origin, + fromRoot: true, + }, + }) + } + }} + className={classnames( + "relative flex flex-row items-center p-1 px-2 pr-1 text-gray-600 rounded-md group border border-primary-200 text-xs cursor-pointer", + dAppConnected === "connected" && + "bg-green-100 hover:border-green-300", + dAppConnected === "connected-warning" && + "bg-yellow-100 hover:border-yellow-300", + dAppConnected === "not-connected" && "pointer-events-none" + )} + > + {dAppConnected === "connected" && ( + + )} + + {dAppConnected === "connected-warning" && ( + + )} + + {dAppConnected === "not-connected" && ( + + )} + + + {dAppConnected === "not-connected" + ? "Not connected" + : "Connected"} + +
+ + ) +} + +export default DAppConnection diff --git a/packages/ui/src/components/gas/GasPricesInfo.tsx b/packages/ui/src/components/home/GasPricesInfo.tsx similarity index 97% rename from packages/ui/src/components/gas/GasPricesInfo.tsx rename to packages/ui/src/components/home/GasPricesInfo.tsx index cbae4f5d9..d2ec579c9 100644 --- a/packages/ui/src/components/gas/GasPricesInfo.tsx +++ b/packages/ui/src/components/home/GasPricesInfo.tsx @@ -23,6 +23,7 @@ import { SEND_GAS_COST } from "../../util/constants" import car from "../../assets/images/icons/car.svg" import scooter from "../../assets/images/icons/scooter.svg" import plane from "../../assets/images/icons/plane.svg" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" export type DisplayGasPricesData = { baseFee?: string @@ -111,8 +112,10 @@ const INFO_BY_LEVEL = { const GasPricesInfo: FC = () => { const [active, setActive] = useState(false) const [calculateGasCost] = useState<"SEND">("SEND") - const { exchangeRates, nativeCurrency, localeInfo, networkNativeCurrency } = - useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() + const { nativeCurrency, localeInfo } = useBlankState()! const { showGasLevels, @@ -240,7 +243,8 @@ const GasPricesInfo: FC = () => { {gasPriceToNativeCurrency( gasPriceData.totalTransactionCost, { - exchangeRates, + exchangeRates: + exchangeRates, localeInfo: { currency: nativeCurrency, diff --git a/packages/ui/src/components/home/HomeBalancePanel.tsx b/packages/ui/src/components/home/HomeBalancePanel.tsx new file mode 100644 index 000000000..f8592d875 --- /dev/null +++ b/packages/ui/src/components/home/HomeBalancePanel.tsx @@ -0,0 +1,135 @@ +import { BigNumber } from "ethers" +import { useBlankState } from "../../context/background/backgroundHooks" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" +import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" +import { useTokensList } from "../../context/hooks/useTokensList" +import { formatCurrency, toCurrencyAmount } from "../../util/formatCurrency" +import { formatRounded } from "../../util/formatRounded" +import TokenSummary from "../token/TokenSummary" +import { formatUnits } from "ethers/lib/utils" +import { Link } from "react-router-dom" +import classnames from "classnames" +import AnimatedIcon, { AnimatedIconName } from "../AnimatedIcon" +import DoubleArrowHoverAnimation from "../icons/DoubleArrowHoverAnimation" +import ArrowHoverAnimation from "../icons/ArrowHoverAnimation" +const HomeBalancePanel = () => { + const state = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() + const { nativeToken } = useTokensList() + const { nativeCurrency, isSendEnabled, isSwapEnabled, isBridgeEnabled } = + useSelectedNetwork() + return ( + + + + {formatRounded( + formatUnits( + nativeToken.balance || "0", + nativeCurrency.decimals + ), + 5 + )}{" "} + {nativeCurrency.symbol} + + + {formatCurrency( + toCurrencyAmount( + nativeToken.balance || BigNumber.from(0), + exchangeRates[networkNativeCurrency.symbol], + nativeCurrency.decimals + ), + { + currency: state.nativeCurrency, + locale_info: state.localeInfo, + returnNonBreakingSpace: true, + showSymbol: true, + } + )} + + + + +
+ +
+ Send + + {isSwapEnabled && ( + +
+ +
+ Swap + + )} + {isBridgeEnabled && ( + +
+ +
+ Bridge + + )} +
+
+ ) +} + +export default HomeBalancePanel diff --git a/packages/ui/src/components/transactions/GasPriceComponent.tsx b/packages/ui/src/components/transactions/GasPriceComponent.tsx index ab899b136..e0981506c 100644 --- a/packages/ui/src/components/transactions/GasPriceComponent.tsx +++ b/packages/ui/src/components/transactions/GasPriceComponent.tsx @@ -42,6 +42,7 @@ import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" import { useGasPriceData } from "../../context/hooks/useGasPriceData" import WarningDialog from "../dialog/WarningDialog" import { calculateGasPricesFromTransactionFees } from "../../util/gasPrice" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" interface GasComponentProps { symbol: string @@ -552,8 +553,10 @@ const GasPriceComponent: FunctionComponent<{ useOnClickOutside(ref, () => setActive(false)) //State - const { exchangeRates, nativeCurrency, localeInfo, networkNativeCurrency } = - useBlankState()! + const { nativeCurrency, localeInfo } = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const { estimatedBaseFee: baseFeePerGas, gasPricesLevels } = useGasPriceData() diff --git a/packages/ui/src/components/transactions/GasPriceSelector.tsx b/packages/ui/src/components/transactions/GasPriceSelector.tsx index c9faf8da8..6ba292f82 100644 --- a/packages/ui/src/components/transactions/GasPriceSelector.tsx +++ b/packages/ui/src/components/transactions/GasPriceSelector.tsx @@ -41,6 +41,7 @@ import { formatRounded } from "../../util/formatRounded" import { useBlankState } from "../../context/background/backgroundHooks" import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" import { useGasPriceData } from "../../context/hooks/useGasPriceData" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" export type TransactionSpeed = { [key: string]: BigNumber @@ -444,8 +445,11 @@ export const GasPriceSelector = (props: GasPriceSelectorProps) => { ) // State variables - const { nativeCurrency, localeInfo, exchangeRates, networkNativeCurrency } = - useBlankState()! + const { nativeCurrency, localeInfo } = useBlankState()! + + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const { gasPricesLevels } = useGasPriceData() diff --git a/packages/ui/src/components/transactions/Price.tsx b/packages/ui/src/components/transactions/Price.tsx index 80f950be6..98b448567 100644 --- a/packages/ui/src/components/transactions/Price.tsx +++ b/packages/ui/src/components/transactions/Price.tsx @@ -8,6 +8,7 @@ import formatTransactionValue from "../../util/formatTransactionValue" // Hooks import { useBlankState } from "../../context/background/backgroundHooks" import { getValueByKey } from "../../util/objectUtils" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" const Price: FunctionComponent<{ title: string @@ -16,6 +17,9 @@ const Price: FunctionComponent<{ decimals: number }> = ({ title, amount, symbol, decimals }) => { const state = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const txValue = formatTransactionValue( { @@ -29,7 +33,7 @@ const Price: FunctionComponent<{ const currencyAmount = toCurrencyAmount( amount, - getValueByKey(state.exchangeRates, symbol.toUpperCase(), 0), + getValueByKey(exchangeRates, symbol.toUpperCase(), 0), decimals ) diff --git a/packages/ui/src/components/transactions/TransactionItem.tsx b/packages/ui/src/components/transactions/TransactionItem.tsx index 3e940fbf9..16a3e6296 100644 --- a/packages/ui/src/components/transactions/TransactionItem.tsx +++ b/packages/ui/src/components/transactions/TransactionItem.tsx @@ -20,9 +20,7 @@ import Tooltip from "../../components/label/Tooltip" import eth from "../../assets/images/icons/ETH.svg" import blankLogo from "../../assets/images/logo.svg" import flashbotsLogo from "../../assets/images/flashbots.png" - import { - BridgeStatus, BridgeSubstatus, MetaType, TransactionCategories, diff --git a/packages/ui/src/context/background/BackgroundState.tsx b/packages/ui/src/context/background/BackgroundState.tsx index 46c53a6f3..d8608e1a6 100644 --- a/packages/ui/src/context/background/BackgroundState.tsx +++ b/packages/ui/src/context/background/BackgroundState.tsx @@ -1,7 +1,7 @@ import { Messages } from "../commTypes" import BackgroundReducer from "./backgroundReducer" import { useReducer, useEffect } from "react" -import { subscribeState, getState } from "../commActions" +import { subscribeAppState, getAppState } from "../commActions" import BackgroundContext, { initBackgroundState } from "./backgroundContext" import { isPortConnected } from "../setup" @@ -9,7 +9,6 @@ let isContextInit = false const BackgroundState = (props: any) => { const [state, dispatch] = useReducer(BackgroundReducer, initBackgroundState) - useEffect(() => { initContext() // eslint-disable-next-line @@ -21,14 +20,14 @@ const BackgroundState = (props: any) => { } else { if (!isContextInit) { // Get initial state and dispatch - const initialState = await getState() + const initialState = await getAppState() dispatch({ type: Messages.STATE.SUBSCRIBE, payload: initialState, }) // Subscribe to state updates - subscribeState((state) => { + subscribeAppState((state) => { dispatch({ type: Messages.STATE.SUBSCRIBE, payload: state, diff --git a/packages/ui/src/context/background/backgroundContext.tsx b/packages/ui/src/context/background/backgroundContext.tsx index bd598eae4..2240a7d68 100644 --- a/packages/ui/src/context/background/backgroundContext.tsx +++ b/packages/ui/src/context/background/backgroundContext.tsx @@ -1,8 +1,8 @@ import { createContext } from "react" -import type { ResponseGetState } from "@block-wallet/background/utils/types/communication" +import type { ResponseGetAppState } from "@block-wallet/background/utils/types/communication" export type BackgroundStateType = { - blankState?: ResponseGetState + blankState?: ResponseGetAppState } export const initBackgroundState: BackgroundStateType = {} diff --git a/packages/ui/src/context/background/useActivityListState.tsx b/packages/ui/src/context/background/useActivityListState.tsx new file mode 100644 index 000000000..c15db3804 --- /dev/null +++ b/packages/ui/src/context/background/useActivityListState.tsx @@ -0,0 +1,42 @@ +import { createContext, FC, ReactNode, useContext } from "react" +import { + getActivityListState, + subscribeActivityListState, +} from "../commActions" +import { + ResponseGetActivityListState, + ResponseGetGasPricesState, +} from "@block-wallet/background/utils/types/communication" +import useSubscription, { SubscriptionContext } from "./useStateSubscription" + +type ContextType = SubscriptionContext + +const defaultState = { activityList: { pending: [], confirmed: [] } } +const ActivityListContext = createContext({ + state: defaultState, + isLoading: false, +}) + +export const ActivityListStateProvider: FC<{ children: ReactNode }> = ({ + children, +}) => { + const state = useSubscription( + //state getter + getActivityListState, + //state subcriber + subscribeActivityListState, + //inital state + defaultState, + { name: "ActivityList" } + ) + + return ( + + {children} + + ) +} + +export const useActivityListState = () => { + return useContext(ActivityListContext) as ContextType +} diff --git a/packages/ui/src/context/background/useExchangeRatesState.tsx b/packages/ui/src/context/background/useExchangeRatesState.tsx new file mode 100644 index 000000000..efcb1b918 --- /dev/null +++ b/packages/ui/src/context/background/useExchangeRatesState.tsx @@ -0,0 +1,47 @@ +import { createContext, FC, ReactNode, useContext } from "react" +import { + getExchangeRatesState, + subscribeExchangeRatesState, +} from "../commActions" +import { ResponseGetExchangeRatesState } from "@block-wallet/background/utils/types/communication" +import useSubscription, { SubscriptionContext } from "./useStateSubscription" + +type ExchangeRatesContextType = + SubscriptionContext + +const defualtState = { + exchangeRates: {}, + networkNativeCurrency: { + symbol: "ETH", + // Default Coingecko id for ETH rates + coingeckoPlatformId: "ethereum", + }, +} + +const ExchangeRatesContext = createContext({ + isLoading: false, + state: defualtState, +}) + +export const ExchangeRatesStateProvider: FC<{ children: ReactNode }> = ({ + children, +}) => { + const state = useSubscription( + //state getter + getExchangeRatesState, + //state subcriber + subscribeExchangeRatesState, + //inital state + defualtState, + { name: "Exchange rates" } + ) + return ( + + {children} + + ) +} + +export const useExchangeRatesState = () => { + return useContext(ExchangeRatesContext) as ExchangeRatesContextType +} diff --git a/packages/ui/src/context/background/useGasPricesState.tsx b/packages/ui/src/context/background/useGasPricesState.tsx new file mode 100644 index 000000000..011afa92e --- /dev/null +++ b/packages/ui/src/context/background/useGasPricesState.tsx @@ -0,0 +1,43 @@ +import { createContext, FC, ReactNode, useContext } from "react" +import { getGasPricesState, subscribeGasPricesState } from "../commActions" +import { ResponseGetGasPricesState } from "@block-wallet/background/utils/types/communication" +import useSubscription, { SubscriptionContext } from "./useStateSubscription" +import { AppLoading } from "../../App" + +type GasPricesContextType = SubscriptionContext + +const defaultState = { gasPriceData: {} } + +const GasPricesContext = createContext({ + state: defaultState, + isLoading: true, +}) + +export const GasPricesStateProvider: FC<{ children: ReactNode }> = ({ + children, +}) => { + const state = useSubscription( + //state getter + getGasPricesState, + //state subcriber + subscribeGasPricesState, + //inital state + defaultState, + { + name: "Gas prices", + //initializes the state as loading. + initLoading: true, + } + ) + + return ( + + {/** Multiple components of the app renders as the gas price is already loaded. */} + {state.isLoading ? : children} + + ) +} + +export const useGasPricesState = () => { + return useContext(GasPricesContext) as GasPricesContextType +} diff --git a/packages/ui/src/context/background/useStateSubscription.ts b/packages/ui/src/context/background/useStateSubscription.ts new file mode 100644 index 000000000..a169edbc9 --- /dev/null +++ b/packages/ui/src/context/background/useStateSubscription.ts @@ -0,0 +1,55 @@ +import React, { Dispatch, useEffect, useRef, useState } from "react" + +export interface SubscriptionContext { + state: T + isLoading: boolean +} + +type SubscribeCallback = (cb: (state: T) => void) => Promise + +interface SubscribeOptions { + name?: string + initLoading?: boolean +} + +const defaultOptions = { + name: "", + initLoading: false, +} + +function useStateSubscription( + stateGetter: () => Promise | T, + subscriber: SubscribeCallback | undefined, + initialState: T, + { name, initLoading }: SubscribeOptions = defaultOptions +) { + const initialized = useRef(false) + const [state, setState] = useState(initialState) + const [isLoading, setIsLoading] = useState(initLoading ?? false) + useEffect(() => { + const log = + (callback: Dispatch>) => (newState: T) => { + if (process.env.LOG_LEVEL === "debug") { + console.log(`Updating Store: ${name}`, newState) + } + callback(newState) + } + + async function generateSubscription() { + initialized.current = true + setIsLoading(true) + const initialState = await stateGetter() + setIsLoading(false) + setState(initialState) + if (subscriber) { + subscriber(log(setState)) + } + } + if (!initialized.current) { + generateSubscription() + } + }, []) + return { state, isLoading } +} + +export default useStateSubscription diff --git a/packages/ui/src/context/commActions.ts b/packages/ui/src/context/commActions.ts index 0d1a8f34b..3313d5abb 100644 --- a/packages/ui/src/context/commActions.ts +++ b/packages/ui/src/context/commActions.ts @@ -12,15 +12,22 @@ import { MessageTypes, RequestTypes, ResponseTypes, - ResponseGetState, StateSubscription, SubscriptionMessageTypes, ResponseBlankCurrencyDepositsCount, RequestAddNetwork, RequestEditNetwork, RequestEditNetworksOrder, + ExchangeRatesStateSubscription, + ResponseGetExchangeRatesState, + GasPricesStateSubscription, + AppStateSubscription, + ResponseGetGasPricesState, + ResponseGetAppState, + ResponseGetActivityListState, + ActivityListStateSubscription, } from "@block-wallet/background/utils/types/communication" -import { Devices, ExchangeType, Messages } from "./commTypes" +import { Devices, ExchangeType, Messages, StateType } from "./commTypes" import { IToken, ITokens, @@ -378,10 +385,47 @@ export const verifyPassword = async (password: string): Promise => { * * @returns Background state */ -export const getState = async (): Promise => { - return sendMessage(Messages.STATE.GET) +export const getAppState = async (): Promise => { + return sendMessage(Messages.STATE.GET, { + stateType: StateType.APP_STATE, + }) as Promise } +/** + * Gets the exchange rates state + * + * @returns Exchange rates state + */ +export const getExchangeRatesState = + async (): Promise => { + return sendMessage(Messages.STATE.GET, { + stateType: StateType.EXCHANGE_RATES, + }) as Promise + } + +/** + * Gets the gas prices state + * + * @returns Gas prices state + */ +export const getGasPricesState = + async (): Promise => { + return sendMessage(Messages.STATE.GET, { + stateType: StateType.GAS_PRICES, + }) as Promise + } + +/** + * Gets the activity list state + * + * @returns Activity List state + */ +export const getActivityListState = + async (): Promise => { + return sendMessage(Messages.STATE.GET, { + stateType: StateType.ACTIVITY_LIST, + }) as Promise + } /** * Resolves the address of an ENS name * @@ -1022,14 +1066,71 @@ export const getDepositTransactionGasLimit = async ( } /** - * Subscribes to state updates + * Subscribes to exchange rates state updates + * + * @param cb state update handler + */ +export const subscribeExchangeRatesState = async ( + cb: (state: ExchangeRatesStateSubscription) => void +): Promise => { + return sendMessage( + Messages.STATE.SUBSCRIBE, + { + stateType: StateType.EXCHANGE_RATES, + }, + cb as (data: StateSubscription) => void + ) +} + +/** + * Subscribes to gas prices state updates + * + * @param cb state update handler + */ +export const subscribeGasPricesState = async ( + cb: (state: GasPricesStateSubscription) => void +): Promise => { + return sendMessage( + Messages.STATE.SUBSCRIBE, + { + stateType: StateType.GAS_PRICES, + }, + cb as (data: StateSubscription) => void + ) +} + +/** + * Subscribes to activty list state updates + * + * @param cb state update handler + */ +export const subscribeActivityListState = async ( + cb: (state: ActivityListStateSubscription) => void +): Promise => { + return sendMessage( + Messages.STATE.SUBSCRIBE, + { + stateType: StateType.ACTIVITY_LIST, + }, + cb as (data: StateSubscription) => void + ) +} + +/** + * Subscribes to the app state updates * * @param cb state update handler */ -export const subscribeState = async ( - cb: (state: StateSubscription) => void +export const subscribeAppState = async ( + cb: (state: AppStateSubscription) => void ): Promise => { - return sendMessage(Messages.STATE.SUBSCRIBE, undefined, cb) + return sendMessage( + Messages.STATE.SUBSCRIBE, + { + stateType: StateType.APP_STATE, + }, + cb as (data: StateSubscription) => void + ) } /** diff --git a/packages/ui/src/context/commTypes.ts b/packages/ui/src/context/commTypes.ts index 8ba9af2b1..1d8de40fe 100644 --- a/packages/ui/src/context/commTypes.ts +++ b/packages/ui/src/context/commTypes.ts @@ -413,3 +413,10 @@ export enum QuoteFeeStatus { OK = "OK", INSUFFICIENT_BALANCE_TO_COVER_FEES = "INSUFFICIENT_BALANCE_TO_COVER_FEES", } + +export enum StateType { + APP_STATE = "APP_STATE", + EXCHANGE_RATES = "EXCHANGE_RATES", + GAS_PRICES = "GAS_PRICES", + ACTIVITY_LIST = "ACTIVITY_LIST", +} diff --git a/packages/ui/src/context/hooks/useGasPriceData.ts b/packages/ui/src/context/hooks/useGasPriceData.ts index 289593d7f..d66fcf599 100644 --- a/packages/ui/src/context/hooks/useGasPriceData.ts +++ b/packages/ui/src/context/hooks/useGasPriceData.ts @@ -1,9 +1,11 @@ import { GasPriceData } from "@block-wallet/background/controllers/GasPricesController" -import { useBlankState } from "../background/backgroundHooks" +import { useGasPricesState } from "../background/useGasPricesState" import { useSelectedNetwork } from "./useSelectedNetwork" export const useGasPriceData = () => { - const { gasPriceData } = useBlankState()! + const { + state: { gasPriceData }, + } = useGasPricesState() const { chainId } = useSelectedNetwork() if (chainId in gasPriceData) { return gasPriceData[chainId] diff --git a/packages/ui/src/context/hooks/useWindowId.tsx b/packages/ui/src/context/hooks/useWindowId.tsx index 0db406407..ce2096ed6 100644 --- a/packages/ui/src/context/hooks/useWindowId.tsx +++ b/packages/ui/src/context/hooks/useWindowId.tsx @@ -1,5 +1,5 @@ import { createContext, useContext, useEffect, useState } from "react" -import LoadingOverlay from "../../components/loading/LoadingOverlay" +import { AppLoading } from "../../App" import { getWindowId } from "../commActions" export const WindowIdContext = createContext({ @@ -23,7 +23,7 @@ const WindowIdProvider = ({ return ( - {!windowId ? : children} + {!windowId ? : children} ) } diff --git a/packages/ui/src/mock/MockBackgroundState.tsx b/packages/ui/src/mock/MockBackgroundState.tsx index da2e8ff72..3567e9de0 100644 --- a/packages/ui/src/mock/MockBackgroundState.tsx +++ b/packages/ui/src/mock/MockBackgroundState.tsx @@ -132,10 +132,6 @@ export const initBackgroundState: BackgroundStateType = { }, }, recentAddresses: {} as AddressBook, - activityList: { - confirmed: [], - pending: [], - }, hiddenAccounts: {}, accounts: { "0xd7Fd7EDcb7376c490b0e45e391e8040928F73081": { @@ -380,37 +376,7 @@ export const initBackgroundState: BackgroundStateType = { isVaultInitialized: true, isImportingDeposits: false, importingErrors: [], - exchangeRates: { ETH: 2300, DAI: 1 }, - networkNativeCurrency: { - symbol: "ETH", - // Default Coingecko id for ETH rates - coingeckoPlatformId: "ethereum", - }, isEIP1559Compatible: { 5: true }, - gasPriceData: { - 5: { - blockGasLimit: BigNumber.from(0), - estimatedBaseFee: BigNumber.from(0), - gasPricesLevels: { - slow: { - gasPrice: BigNumber.from(111111111110), - maxPriorityFeePerGas: BigNumber.from(0), - maxFeePerGas: BigNumber.from(0), - }, - average: { - gasPrice: BigNumber.from(111111111110), - maxPriorityFeePerGas: BigNumber.from(0), - maxFeePerGas: BigNumber.from(0), - }, - fast: { - gasPrice: BigNumber.from(111111111110), - maxPriorityFeePerGas: BigNumber.from(0), - maxFeePerGas: BigNumber.from(0), - }, - }, - baseFee: BigNumber.from("0x02540be400"), - }, - }, showTestNetworks: true, showWelcomeMessage: false, showDefaultWalletPreferences: false, diff --git a/packages/ui/src/router/PopupRouter.tsx b/packages/ui/src/router/PopupRouter.tsx index 83ed92dd1..26b3087c2 100644 --- a/packages/ui/src/router/PopupRouter.tsx +++ b/packages/ui/src/router/PopupRouter.tsx @@ -1,5 +1,4 @@ import { useEffect, useLayoutEffect, useMemo, useState } from "react" - import { HashRouter, Redirect, Route, useHistory } from "react-router-dom" import { useBlankState } from "../context/background/backgroundHooks" import PendingSetupPage from "../routes/setup/PendingSetupPage" @@ -17,10 +16,12 @@ import IdleComponent from "../components/IdleComponent" import WalletNews from "../components/news/WalletNews" import LocationHolder from "./LocationHolder" import { useLocationRecovery } from "../util/hooks/useLocationRecovery" -import { timeExceedsTTL } from "../util/time" import ProviderDownDialog from "../components/dialog/ProviderDownDialog" import useClearStickyStorage from "../context/hooks/useClearStickyStorage" import { getNonSubmittedTransactions } from "../util/getNonSubmittedTransactions" +import { ExchangeRatesStateProvider } from "../context/background/useExchangeRatesState" +import { GasPricesStateProvider } from "../context/background/useGasPricesState" +import { ActivityListStateProvider } from "../context/background/useActivityListState" /** Purpose of this component is to check in Blank State if there is any pending connect to site or transaction confirm * in order to show that page always, whenever the extension is loaded and unlocked. @@ -112,34 +113,42 @@ const PopupRouter = ({ return ( - - - {isOnboarded ? ( - <> - - - setShouldShowDialog(false) - } - title="No connection" - message="Please check your internet connection. Some features of the wallet will remain disabled while you’re offline." - open={shouldShowDialog} - onDone={() => setShouldShowDialog(false)} - /> - - - - - ) : ( - - )} - {children} - - + + + + + + {isOnboarded ? ( + <> + + + setShouldShowDialog(false) + } + title="No connection" + message="Please check your internet connection. Some features of the wallet will remain disabled while you’re offline." + open={shouldShowDialog} + onDone={() => + setShouldShowDialog(false) + } + /> + + + + + ) : ( + + )} + {children} + + + + + ) } diff --git a/packages/ui/src/routes/PopupPage.tsx b/packages/ui/src/routes/PopupPage.tsx index a5f4d4e12..e484e58db 100644 --- a/packages/ui/src/routes/PopupPage.tsx +++ b/packages/ui/src/routes/PopupPage.tsx @@ -1,373 +1,138 @@ -import { useState } from "react" -import classnames from "classnames" +import { Profiler, useState } from "react" import { Link, useHistory } from "react-router-dom" -import { formatUnits } from "ethers/lib/utils" -import { BigNumber } from "ethers" -import { BiCircle } from "react-icons/bi" // Components import PageLayout from "../components/PageLayout" -import CopyTooltip from "../components/label/СopyToClipboardTooltip" import GearIcon from "../components/icons/GearIcon" import QRIcon from "../components/icons/QRIcon" import NetworkSelect from "../components/input/NetworkSelect" -import ArrowHoverAnimation from "../components/icons/ArrowHoverAnimation" import ErrorDialog from "../components/dialog/ErrorDialog" import AccountIcon from "../components/icons/AccountIcon" -import ActivityAssetsView from "../components/ActivityAssetsView" +import ActivityAssetsView from "../components/home/ActivityAssetsView" import GenericTooltip from "../components/label/GenericTooltip" -import AnimatedIcon, { AnimatedIconName } from "../components/AnimatedIcon" import Tooltip from "../components/label/Tooltip" // Utils -import { formatHash, formatName } from "../util/formatAccount" -import { formatCurrency, toCurrencyAmount } from "../util/formatCurrency" import { getAccountColor } from "../util/getAccountColor" -import { formatRounded } from "../util/formatRounded" -import { HiOutlineExclamationCircle } from "react-icons/hi" // Context import { useBlankState } from "../context/background/backgroundHooks" import { useSelectedAccount } from "../context/hooks/useSelectedAccount" -import { useSelectedNetwork } from "../context/hooks/useSelectedNetwork" -import { session } from "../context/setup" -import { useConnectedSite } from "../context/hooks/useConnectedSite" -import { useTokensList } from "../context/hooks/useTokensList" // Assets -import TokenSummary from "../components/token/TokenSummary" -import GasPricesInfo from "../components/gas/GasPricesInfo" -import DoubleArrowHoverAnimation from "../components/icons/DoubleArrowHoverAnimation" - -const AccountDisplay = () => { - const blankState = useBlankState()! - const accountAddress = blankState.selectedAddress - const account = useSelectedAccount() - const [copied, setCopied] = useState(false) - const copy = async () => { - await navigator.clipboard.writeText(accountAddress) - setCopied(true) - await new Promise((resolve) => setTimeout(resolve, 1000)) - setCopied(false) - } - return ( - - ) -} - -const DAppConnection = () => { - const dAppConnected = useConnectedSite() - const history = useHistory()! - return ( - -

- {dAppConnected === "connected" ? ( - You are connected to the open site - ) : ( - You are not connected to the open site - )} -

- - } - > -
{ - if (dAppConnected !== "not-connected") { - history.push({ - pathname: - "/accounts/menu/connectedSites/accountList", - state: { - origin: session?.origin, - fromRoot: true, - }, - }) - } - }} - className={classnames( - "relative flex flex-row items-center p-1 px-2 pr-1 text-gray-600 rounded-md group border border-primary-200 text-xs cursor-pointer", - dAppConnected === "connected" && - "bg-green-100 hover:border-green-300", - dAppConnected === "connected-warning" && - "bg-yellow-100 hover:border-yellow-300", - dAppConnected === "not-connected" && "pointer-events-none" - )} - > - {dAppConnected === "connected" && ( - - )} - - {dAppConnected === "connected-warning" && ( - - )} - - {dAppConnected === "not-connected" && ( - - )} - - - {dAppConnected === "not-connected" - ? "Not connected" - : "Connected"} - -
-
- ) -} +import GasPricesInfo from "../components/home/GasPricesInfo" +import useMetricCollector from "../util/useMetricCollector" +import HomeBalancePanel from "../components/home/HomeBalancePanel" +import DAppConnection from "../components/home/DAppConnection" +import AccountAvatar from "../components/home/AccountAvatar" +import { ActivityListStateProvider } from "../context/background/useActivityListState" const PopupPage = () => { + const collect = useMetricCollector() const error = (useHistory().location.state as { error: string })?.error const state = useBlankState()! const history = useHistory() const account = useSelectedAccount() - const { nativeToken } = useTokensList() - const { nativeCurrency, isSendEnabled, isSwapEnabled, isBridgeEnabled } = - useSelectedNetwork() const [hasErrorDialog, setHasErrorDialog] = useState(!!error) return ( - - { - setHasErrorDialog(false) - }} - onDone={() => setHasErrorDialog(false)} - /> -
-
-
-
- - + + { + setHasErrorDialog(false) + }} + onDone={() => setHasErrorDialog(false)} + /> +
+
+
+
+ + + + +
+ My Accounts + + } /> - - -
- My Accounts - - } - /> +
+
+ + { + e.preventDefault() + + history.push("/accounts/menu/receive") + }} + className="p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + > + + +
-
- +
+ { e.preventDefault() - history.push("/accounts/menu/receive") + history.push("/settings") }} className="p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" > - +
-
- - { - e.preventDefault() - - history.push("/settings") - }} - className="p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" - > - - -
-
-
-
-
- - Please wait until deposits are done loading - to change networks. This can take up to 15 - minutes. -

- } - > - -
- -
- - - +
+
+ + Please wait until deposits are done + loading to change networks. This can + take up to 15 minutes. +

} > - {formatRounded( - formatUnits( - nativeToken.balance || "0", - nativeCurrency.decimals - ), - 5 - )}{" "} - {nativeCurrency.symbol} - - - {formatCurrency( - toCurrencyAmount( - nativeToken.balance || - BigNumber.from(0), - state.exchangeRates[ - state.networkNativeCurrency.symbol - ], - nativeCurrency.decimals - ), - { - currency: state.nativeCurrency, - locale_info: state.localeInfo, - returnNonBreakingSpace: true, - showSymbol: true, - } - )} - - - - -
- -
- - Send - - - {isSwapEnabled && ( - -
- -
- - Swap - - - )} - {isBridgeEnabled && ( - -
- -
- - Bridge - - - )} -
- - + +
+ +
+ + +
-
- + + ) } diff --git a/packages/ui/src/routes/bridge/BridgeSetupPage.tsx b/packages/ui/src/routes/bridge/BridgeSetupPage.tsx index 30fcbe64b..6b7bc228b 100644 --- a/packages/ui/src/routes/bridge/BridgeSetupPage.tsx +++ b/packages/ui/src/routes/bridge/BridgeSetupPage.tsx @@ -46,7 +46,6 @@ import { } from "@block-wallet/background/controllers/BridgeController" import { ApproveOperation } from "../transaction/ApprovePage" import { BridgeAllowanceCheck, QuoteFeeStatus } from "../../context/commTypes" -import { defaultAdvancedSettings } from "../../components/transactions/AdvancedSettings" import { BridgeNotFoundQuoteDetails } from "../../components/transactions/BridgeNotFoundQuoteDetails" import { formatRounded } from "../../util/formatRounded" import FeeDetails from "../../components/FeeDetails" @@ -56,6 +55,7 @@ import { populateBridgeTransaction } from "../../util/bridgeUtils" import BridgeErrorMessage, { BridgeErrorType } from "./BridgeErrorMessage" import usePersistedLocalStorageForm from "../../util/hooks/usePersistedLocalStorageForm" import { secondsToEstimatedMinutes } from "../../util/time" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" interface SetupBridgePageLocalState { amount?: string @@ -86,11 +86,13 @@ const BridgeSetupPage: FunctionComponent<{}> = () => { selectedAddress, nativeCurrency, localeInfo, - exchangeRates, availableNetworks, selectedNetwork, availableBridgeChains, } = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const { nativeToken } = useTokensList() const [bridgeDetails, setBridgeDetails] = useState<{ diff --git a/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx b/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx index 3d2782876..1367e9b45 100644 --- a/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx +++ b/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx @@ -77,6 +77,7 @@ import TransactionDetails from "../../components/transactions/TransactionDetails import { useTransactionWaitingDialog } from "../../context/hooks/useTransactionWaitingDialog" import { canUserSubmitTransaction } from "../../util/transactionUtils" import DAppPopupHeader from "../../components/dApp/DAppPopupHeader" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" const TransactionConfirmPage = () => { //Retrieves all the transactions to be processed @@ -111,15 +112,11 @@ const TransactionConfirm: React.FC<{ transactionCount: number }> = ({ transactionId, transactionCount }) => { //Hooks + const { accounts, nativeCurrency, localeInfo, selectedAddress, settings } = + useBlankState()! const { - accounts, - exchangeRates, - nativeCurrency, - localeInfo, - networkNativeCurrency, - selectedAddress, - settings, - } = useBlankState()! + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const { isEIP1559Compatible, defaultNetworkLogo } = useSelectedNetwork() const [gasPriceThresholdWarning, setGasPriceThresholdWarning] = useState<{ message?: string diff --git a/packages/ui/src/routes/deposit/DepositConfirmPage.tsx b/packages/ui/src/routes/deposit/DepositConfirmPage.tsx index adb01f3ea..845a278bc 100644 --- a/packages/ui/src/routes/deposit/DepositConfirmPage.tsx +++ b/packages/ui/src/routes/deposit/DepositConfirmPage.tsx @@ -51,6 +51,7 @@ import { isHardwareWallet } from "../../util/account" import { HardwareWalletOpTypes } from "../../context/commTypes" import { rejectTransaction } from "../../context/commActions" import { TransactionAdvancedData } from "@block-wallet/background/controllers/transactions/utils/types" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" let freezedAmounts = { amountInNativeCurrency: 0, @@ -104,8 +105,11 @@ const DepositConfirmPage = () => { const [isUpdating, setIsUpdating] = useState(false) const [customNonce, setCustomNonce] = useState() - const { exchangeRates, nativeCurrency, localeInfo, networkNativeCurrency } = - useBlankState()! + const { nativeCurrency, localeInfo } = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() + const { isDeviceUnlinked, checkDeviceIsLinked, resetDeviceLinkStatus } = useCheckAccountDeviceLinked() const { isEIP1559Compatible } = useSelectedNetwork() diff --git a/packages/ui/src/routes/send/SendConfirmPage.tsx b/packages/ui/src/routes/send/SendConfirmPage.tsx index 40a2f0586..e2df8a6f1 100644 --- a/packages/ui/src/routes/send/SendConfirmPage.tsx +++ b/packages/ui/src/routes/send/SendConfirmPage.tsx @@ -68,6 +68,7 @@ import { HardwareWalletOpTypes } from "../../context/commTypes" import { useInProgressInternalTransaction } from "../../context/hooks/useInProgressInternalTransaction" import { rejectTransaction } from "../../context/commActions" import { getValueByKey } from "../../util/objectUtils" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" // Schema const GetAmountYupSchema = ( @@ -299,6 +300,9 @@ const SendConfirmPage = () => { // Blank Hooks const { clear: clearLocationRecovery } = useLocationRecovery() const blankState = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const network = useSelectedNetwork() const history: any = useOnMountHistory() const balance = useSelectedAccountBalance() @@ -419,7 +423,7 @@ const SendConfirmPage = () => { setNativeCurrency( toCurrencyAmount( txAmount, - getValueByKey(blankState.exchangeRates, symbol, 0), + getValueByKey(exchangeRates, symbol, 0), decimals ) ) diff --git a/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx b/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx index 4f6b70a5d..706ac1a2d 100644 --- a/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx +++ b/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx @@ -25,6 +25,7 @@ import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" import { formatHashLastChars, formatName } from "../../util/formatAccount" import Icon, { IconName } from "../../components/ui/Icon" import Dropdown from "../../components/ui/Dropdown/Dropdown" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" export type ConnectedSiteAccountsLocationState = { origin: string @@ -48,7 +49,10 @@ const ConnectedSiteAccount: FunctionComponent<{ }) => { const [hasDialog, setHasDialog] = useState(false) - const { selectedAddress, networkNativeCurrency } = useBlankState()! + const { selectedAddress } = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const { chainId } = useSelectedNetwork() return ( diff --git a/packages/ui/src/routes/swap/SwapPage.tsx b/packages/ui/src/routes/swap/SwapPage.tsx index 2aeadb028..0af8bb418 100644 --- a/packages/ui/src/routes/swap/SwapPage.tsx +++ b/packages/ui/src/routes/swap/SwapPage.tsx @@ -30,8 +30,6 @@ import { useOnMountHistory } from "../../context/hooks/useOnMount" import { useTokensList } from "../../context/hooks/useTokensList" import { yupResolver } from "@hookform/resolvers/yup" import useCountdown from "../../util/hooks/useCountdown" -import GenericTooltip from "../../components/label/GenericTooltip" -import { AiFillInfoCircle } from "react-icons/ai" import { formatNumberLength } from "../../util/formatNumberLength" import RefreshLabel from "../../components/swaps/RefreshLabel" import { capitalize } from "../../util/capitalize" @@ -40,6 +38,7 @@ import { useCallback } from "react" import { useTokenBalance } from "../../context/hooks/useTokenBalance" import { GetAmountYupSchema } from "../../util/yup/GetAmountSchema" import { ApproveOperation } from "../transaction/ApprovePage" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" interface SwapPageLocalState { fromToken?: Token @@ -72,8 +71,10 @@ const SwapPage = () => { SWAP_QUOTE_REFRESH_TIMEOUT ) - const { selectedAddress, nativeCurrency, localeInfo, exchangeRates } = - useBlankState()! + const { selectedAddress, nativeCurrency, localeInfo } = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const { nativeToken } = useTokensList() diff --git a/packages/ui/src/routes/withdraw/WithdrawBlankConfirm.tsx b/packages/ui/src/routes/withdraw/WithdrawBlankConfirm.tsx index 3813ab7cd..e483344ea 100644 --- a/packages/ui/src/routes/withdraw/WithdrawBlankConfirm.tsx +++ b/packages/ui/src/routes/withdraw/WithdrawBlankConfirm.tsx @@ -48,6 +48,7 @@ import { TokenWithBalance } from "../../context/hooks/useTokensList" import { useDepositTokens } from "../../context/hooks/useDepositTokens" import { useLocationRecovery } from "../../util/hooks/useLocationRecovery" import { getValueByKey } from "../../util/objectUtils" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" const WITHDRAWAL_ERROR = "There was an error.\nCould not initiate the withdrawal." @@ -104,11 +105,14 @@ const WithdrawBlankConfirm = () => { }, []) const state = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const network = useSelectedNetwork() const { gasPricesLevels } = useGasPriceData() const amountInNativeCurrency = toCurrencyAmount( utils.parseUnits(pair.amount, network.nativeCurrency.decimals), - getValueByKey(state.exchangeRates, pair.currency.toUpperCase(), 0), + getValueByKey(exchangeRates, pair.currency.toUpperCase(), 0), network.nativeCurrency.decimals ) @@ -148,7 +152,7 @@ const WithdrawBlankConfirm = () => { // If no exchange rate available, display zero const symbol = pair.currency.toUpperCase() - const exchangeRate = getValueByKey(state.exchangeRates, symbol, 0) + const exchangeRate = getValueByKey(exchangeRates, symbol, 0) if (BigNumber.from(totalFee).gt(parseUnits(pair.amount, decimals))) { setError("Fees are higher than the amount to withdraw") diff --git a/packages/ui/src/util/gasPrice.ts b/packages/ui/src/util/gasPrice.ts index c72f00235..2c807afcc 100644 --- a/packages/ui/src/util/gasPrice.ts +++ b/packages/ui/src/util/gasPrice.ts @@ -4,7 +4,7 @@ import { BigNumber, utils } from "ethers" import { DEFAULT_TRANSACTION_GAS_PERCENTAGE_THRESHOLD } from "./constants" import { formatCurrency, toCurrencyAmount } from "./formatCurrency" import { FeeData } from "@ethersproject/abstract-provider" -import { DisplayGasPricesData } from "../components/gas/GasPricesInfo" +import { DisplayGasPricesData } from "../components/home/GasPricesInfo" interface GasFeesCalculation { minValue: BigNumber diff --git a/packages/ui/src/util/hooks/useTransactions.ts b/packages/ui/src/util/hooks/useActivtyListTransactions.ts similarity index 92% rename from packages/ui/src/util/hooks/useTransactions.ts rename to packages/ui/src/util/hooks/useActivtyListTransactions.ts index d47c76141..039dad40c 100644 --- a/packages/ui/src/util/hooks/useTransactions.ts +++ b/packages/ui/src/util/hooks/useActivtyListTransactions.ts @@ -1,5 +1,6 @@ import { BigNumber } from "ethers" import { useBlankState } from "../../context/background/backgroundHooks" +import { useActivityListState } from "../../context/background/useActivityListState" import { MetaType, TransactionCategories, @@ -15,12 +16,14 @@ const failedStatuses = [ TransactionStatus.REJECTED, ] -const useTransactions = () => { - const { confirmed, pending } = useBlankState()!.activityList +const useActivtyListTransactions = () => { const { - nativeCurrency: networkNativeCurrency, - defaultNetworkLogo, - } = useSelectedNetwork() + state: { + activityList: { confirmed, pending }, + }, + } = useActivityListState() + const { nativeCurrency: networkNativeCurrency, defaultNetworkLogo } = + useSelectedNetwork() const allTransactions = pending .concat(confirmed) @@ -142,4 +145,4 @@ const useTransactions = () => { } } -export default useTransactions +export default useActivtyListTransactions diff --git a/packages/ui/src/util/hooks/useCurrencyFormatter.ts b/packages/ui/src/util/hooks/useCurrencyFormatter.ts index 6cb590ebf..b3845137c 100644 --- a/packages/ui/src/util/hooks/useCurrencyFormatter.ts +++ b/packages/ui/src/util/hooks/useCurrencyFormatter.ts @@ -1,10 +1,14 @@ import { BigNumber } from "ethers" import { useBlankState } from "../../context/background/backgroundHooks" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" import { formatCurrency, toCurrencyAmount } from "../formatCurrency" import { getValueByKey } from "../objectUtils" const useCurrencyFromatter = () => { const state = useBlankState()! + const { + state: { exchangeRates, networkNativeCurrency }, + } = useExchangeRatesState() const format = ( balance: BigNumber, tokenSymbol: string, @@ -14,7 +18,7 @@ const useCurrencyFromatter = () => { const currencyAmount = toCurrencyAmount( balance || BigNumber.from(0), getValueByKey( - state.exchangeRates, + exchangeRates, isNativeCurrency ? tokenSymbol.toUpperCase() : tokenSymbol, 0 ), diff --git a/packages/ui/src/util/hooks/useTokenTransactions.ts b/packages/ui/src/util/hooks/useTokenTransactions.ts index af08468a6..923b2ecb1 100644 --- a/packages/ui/src/util/hooks/useTokenTransactions.ts +++ b/packages/ui/src/util/hooks/useTokenTransactions.ts @@ -1,7 +1,7 @@ -import useTransactions from "./useTransactions" +import useActivtyListTransactions from "./useActivtyListTransactions" const useTokenTransactions = (tokenSymbol: string | undefined) => { - const { transactions } = useTransactions() + const { transactions } = useActivtyListTransactions() return transactions.filter(({ transferType }) => { return tokenSymbol ? transferType?.currency === tokenSymbol : false }) diff --git a/packages/ui/src/util/transactionUtils.ts b/packages/ui/src/util/transactionUtils.ts index a03c997cd..5a67dac86 100644 --- a/packages/ui/src/util/transactionUtils.ts +++ b/packages/ui/src/util/transactionUtils.ts @@ -94,20 +94,23 @@ export const getUITransactionParams = ( gasPrice: !isEIP1559Compatible ? BigNumber.from( transaction?.transactionParams.gasPrice ?? - gasPricesLevels.average.gasPrice + gasPricesLevels.average?.gasPrice ?? + 0 ) : undefined, //EIP-1559 maxPriorityFeePerGas: isEIP1559Compatible ? BigNumber.from( transaction?.transactionParams.maxPriorityFeePerGas ?? - gasPricesLevels.average.maxPriorityFeePerGas + gasPricesLevels.average?.maxPriorityFeePerGas ?? + 0 ) : undefined, maxFeePerGas: isEIP1559Compatible ? BigNumber.from( transaction?.transactionParams.maxFeePerGas ?? - gasPricesLevels.average.maxFeePerGas + gasPricesLevels.average?.maxFeePerGas ?? + 0 ) : undefined, } diff --git a/packages/ui/src/util/useMetricCollector.tsx b/packages/ui/src/util/useMetricCollector.tsx new file mode 100644 index 000000000..1cc28d3a3 --- /dev/null +++ b/packages/ui/src/util/useMetricCollector.tsx @@ -0,0 +1,64 @@ +import { useRef, useEffect, useCallback } from "react" + +const defaultData = { + print: true, + timeFrameInMillis: 60000, +} + +const useMetricCollector = ({ print, timeFrameInMillis } = defaultData) => { + const timing = useRef<{ + id: string + actualDuration: number + }>({ + id: "app", + actualDuration: 0, + }) + + useEffect(() => { + let timeRef: NodeJS.Timeout + if (print) { + timeRef = setInterval(() => { + const actualDuration = timing.current.actualDuration + if ( + process.env.NODE_ENV === "development" && + process.env.LOG_LEVEL === "debug" + ) { + console.log( + `Collecting ${timing.current.id}: `, + actualDuration + ) + } + + timing.current = { + id: timing.current.id, + actualDuration: 0, + } + }, timeFrameInMillis) + } + + return () => { + clearInterval(timeRef) + } + }, []) + + const collect = useCallback( + ( + id: string, // the "id" prop of the Profiler tree that has just committed + phase: "mount" | "update", // either "mount" (if the tree just mounted) or "update" (if it re-rendered) + actualDuration: number // time spent rendering the committed update + ) => { + if (phase === "mount") { + return + } + timing.current = { + id, + actualDuration: timing.current.actualDuration + actualDuration, + } + }, + [] + ) + + return collect +} + +export default useMetricCollector From c0a38967e6ec3c4b910c40f8c6636a64c2341613 Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 23 Nov 2022 15:09:43 -0300 Subject: [PATCH 003/110] feat: prune transactions receipt --- packages/background/package.json | 4 +- .../src/controllers/BridgeController.ts | 5 +- .../transactions/TransactionController.ts | 8 +- .../controllers/transactions/utils/utils.ts | 15 ++- .../stores/migrator/migrations/index.ts | 2 + .../migrator/migrations/migration-52.ts | 106 ++++++++++++++++++ .../src/utils/constants/initialState.ts | 3 - 7 files changed, 132 insertions(+), 11 deletions(-) create mode 100644 packages/background/src/infrastructure/stores/migrator/migrations/migration-52.ts diff --git a/packages/background/package.json b/packages/background/package.json index 13069567d..9bbea25b4 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@block-wallet/background", - "version": "0.8.2", + "version": "0.8.3", "private": true, "dependencies": { "@block-wallet/chains-assets": "https://github.com/block-wallet/chains-assets#v0.0.19", @@ -96,4 +96,4 @@ "lint": "prettier --check src/ '!**/*.json'", "lint:fix": "prettier --write src/ '!**/*.json'" } -} +} \ No newline at end of file diff --git a/packages/background/src/controllers/BridgeController.ts b/packages/background/src/controllers/BridgeController.ts index 8e747a7fd..c7ab4fbe5 100644 --- a/packages/background/src/controllers/BridgeController.ts +++ b/packages/background/src/controllers/BridgeController.ts @@ -45,6 +45,7 @@ import { BaseController } from '../infrastructure/BaseController'; import TokenAllowanceController from './erc-20/transactions//TokenAllowanceController'; import { fillTokenData, isNativeTokenAddress } from '../utils/token'; import { AccountTrackerController } from './AccountTrackerController'; +import { pruneTransaction } from './transactions/utils/utils'; const TIMEOUT_FETCH_RECEIVING_TX = 2 * HOUR; const STATUS_API_CALLS_DELAY = 30 * SECOND; const BRIDGE_STATUS_INVALID_MAX_COUNT = 10; @@ -648,10 +649,10 @@ export default class BridgeController extends BaseController< }; const chainTx = stateTransactions[chainId] || {}; const addrTransactions = chainTx[address] || {}; - const newTransaction = { + const newTransaction = pruneTransaction({ ...(addrTransactions[txHash] || {}), ...updates, - }; + }); this.store.updateState({ bridgeReceivingTransactions: { ...stateTransactions, diff --git a/packages/background/src/controllers/transactions/TransactionController.ts b/packages/background/src/controllers/transactions/TransactionController.ts index 262e98390..cefcebb80 100644 --- a/packages/background/src/controllers/transactions/TransactionController.ts +++ b/packages/background/src/controllers/transactions/TransactionController.ts @@ -34,6 +34,7 @@ import { isFeeMarketEIP1559Values, isGasPriceValue, normalizeTransaction, + pruneTransaction, validateGasValues, validateTransaction, } from './utils/utils'; @@ -293,7 +294,7 @@ export class TransactionController extends BaseController< } ); - // Instantiate contract signature parser + // Instantiate contrafact signature parser this._contractSignatureParser = new ContractSignatureParser( _networkController ); @@ -1658,7 +1659,7 @@ export class TransactionController extends BaseController< transactionMeta.methodSignature = methodSignature; } - transactions[index] = transactionMeta; + transactions[index] = pruneTransaction(transactionMeta); this.store.updateState({ transactions: this.trimTransactionsForState(transactions), @@ -2348,8 +2349,9 @@ export class TransactionController extends BaseController< ): void => { const transactions = this.store.getState().transactions.map((tx) => { if (tx.id === txId) { + const prunedTx = pruneTransaction(tx); return { - ...tx, + ...prunedTx, ...updates, }; } diff --git a/packages/background/src/controllers/transactions/utils/utils.ts b/packages/background/src/controllers/transactions/utils/utils.ts index bfac11b77..c36807fae 100644 --- a/packages/background/src/controllers/transactions/utils/utils.ts +++ b/packages/background/src/controllers/transactions/utils/utils.ts @@ -1,6 +1,6 @@ import { addHexPrefix, isHexString, isValidAddress } from 'ethereumjs-util'; import { BigNumber } from 'ethers'; -import { TransactionParams, TransactionType } from './types'; +import { TransactionMeta, TransactionParams, TransactionType } from './types'; import ensNamehash from 'eth-ens-namehash'; import { FeeMarketEIP1559Values, @@ -357,3 +357,16 @@ export function normalizeEnsName(ensName: string): string | null { } return null; } + +export function pruneTransaction(tx: TransactionMeta): TransactionMeta { + if (tx.transactionReceipt) { + return { + ...tx, + transactionReceipt: { + ...tx.transactionReceipt, + logs: [], + }, + }; + } + return tx; +} diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts index 81b4aed3b..2bb6c742d 100644 --- a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts +++ b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts @@ -50,6 +50,7 @@ import migration48 from './migration-48'; import migration49 from './migration-49'; import migration50 from './migration-50'; import migration51 from './migration-51'; +import migration52 from './migration-52'; const migrations: IMigration[] = [ migration01, @@ -103,5 +104,6 @@ const migrations: IMigration[] = [ migration49, migration50, migration51, + migration52, ]; export default (): IMigration[] => migrations; diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/migration-52.ts b/packages/background/src/infrastructure/stores/migrator/migrations/migration-52.ts new file mode 100644 index 000000000..2d5ed7362 --- /dev/null +++ b/packages/background/src/infrastructure/stores/migrator/migrations/migration-52.ts @@ -0,0 +1,106 @@ +import { BridgeControllerState } from '@block-wallet/background/controllers/BridgeController'; +import { pruneTransaction } from '../../../../controllers/transactions/utils/utils'; +import { + TransactionTypeEnum, + TransactionWatcherControllerState, +} from '../../../../controllers/TransactionWatcherController'; +import { BlankAppState } from '@block-wallet/background/utils/constants/initialState'; +import { IMigration } from '../IMigration'; + +const pruneBridgeTxs = ( + txs: BridgeControllerState['bridgeReceivingTransactions'] +): BridgeControllerState['bridgeReceivingTransactions'] => { + const newTxs = { ...txs }; + for (const chainId in newTxs) { + const chainTxs = newTxs[chainId]; + if (chainTxs) { + for (const addr in chainTxs) { + const addrTxs = chainTxs[addr]; + if (addrTxs) { + newTxs[chainId][addr] = Object.entries(addrTxs).reduce( + (acc, [txHash, tx]) => { + return { + ...acc, + [txHash]: pruneTransaction(tx), + }; + }, + addrTxs + ); + } + } + } + } + return newTxs; +}; + +const pruneWatchedTxs = ( + txs: TransactionWatcherControllerState['transactions'] +): TransactionWatcherControllerState['transactions'] => { + const newTxs = { ...txs }; + for (const chainId in newTxs) { + const chainTxs = newTxs[chainId]; + if (chainTxs) { + for (const addr in chainTxs) { + const addrTxs = chainTxs[addr]; + if (addrTxs) { + for (const type in addrTxs) { + const typeTxs = addrTxs[type as TransactionTypeEnum]; + if (typeTxs && typeTxs.transactions) { + newTxs[chainId][addr][ + type as TransactionTypeEnum + ].transactions = Object.entries( + typeTxs.transactions + ).reduce((acc, [txHash, tx]) => { + return { + ...acc, + [txHash]: pruneTransaction(tx), + }; + }, typeTxs.transactions); + } + } + } + } + } + } + return newTxs; +}; + +/** + * This migration fixes zksync block explorer + */ +export default { + migrate: async (persistedState: BlankAppState) => { + const { transactions } = persistedState.TransactionController; + const { bridgeReceivingTransactions } = persistedState.BridgeController; + const { transactions: watchedTx } = + persistedState.TransactionWatcherControllerState; + + const newTxsState = transactions + ? transactions.map(pruneTransaction) + : transactions; + + const newBridgeReceivingTxState = bridgeReceivingTransactions + ? pruneBridgeTxs(bridgeReceivingTransactions) + : bridgeReceivingTransactions; + + const newWatchedTxsState = watchedTx + ? pruneWatchedTxs(watchedTx) + : watchedTx; + + return { + ...persistedState, + TransactionController: { + ...persistedState.TransactionController, + transactions: newTxsState, + }, + BridgeController: { + ...persistedState.BridgeController, + bridgeReceivingTransactions: newBridgeReceivingTxState, + }, + TransactionWatcherControllerState: { + transactions: newWatchedTxsState, + }, + }; + }, + version: '0.8.3', +} as IMigration; diff --git a/packages/background/src/utils/constants/initialState.ts b/packages/background/src/utils/constants/initialState.ts index 8ac806303..75949b386 100644 --- a/packages/background/src/utils/constants/initialState.ts +++ b/packages/background/src/utils/constants/initialState.ts @@ -80,9 +80,6 @@ export type BlankAppUIState = { PreferencesController: PreferencesControllerState; TransactionController: TransactionVolatileControllerState; BlankDepositController: BlankDepositControllerUIStoreState; - ExchangeRatesController: ExchangeRatesControllerState; - GasPricesController: GasPricesControllerState; - ActivityListController: IActivityListState; TokenController: TokenControllerState; PermissionsController: PermissionsControllerState; NetworkController: NetworkControllerState; From 38426574d0d4fcf84b5750fcc5ff37604e449211 Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 23 Nov 2022 15:57:26 -0300 Subject: [PATCH 004/110] feat: virtualized list for transactions --- .../src/controllers/BlankController.ts | 80 ++++--- packages/ui/src/components/AssetsList.tsx | 41 ++-- .../components/assets/AssetDetailsPage.tsx | 209 +++++++++--------- .../components/home/ActivityAssetsView.tsx | 8 +- .../transactions/TransactionItem.tsx | 27 +-- .../transactions/TransactionsList.tsx | 108 +++++++-- packages/ui/src/context/hooks/useWindowId.tsx | 3 +- packages/ui/src/router/PopupRouter.tsx | 70 +++--- packages/ui/src/routes/PopupPage.tsx | 12 +- 9 files changed, 301 insertions(+), 257 deletions(-) diff --git a/packages/background/src/controllers/BlankController.ts b/packages/background/src/controllers/BlankController.ts index 3ca5bac9e..55d26f55b 100644 --- a/packages/background/src/controllers/BlankController.ts +++ b/packages/background/src/controllers/BlankController.ts @@ -130,7 +130,7 @@ import { BigNumber, utils } from 'ethers'; import BlankStorageStore from '../infrastructure/stores/BlankStorageStore'; import { Messages } from '../utils/types/communication'; import { TransactionMeta } from './transactions/utils/types'; -import initialState, { +import { ActivityListUIState, BlankAppState, BlankAppUIState, @@ -475,29 +475,26 @@ export default class BlankController extends EventEmitter { preferencesController: this.preferencesController, }); - this.store = new ComposedStore( - { - NetworkController: this.networkController.store, - AppStateController: this.appStateController.store, - OnboardingController: this.onboardingController.store, - KeyringController: this.keyringController.store, - AccountTrackerController: this.accountTrackerController.store, - PreferencesController: this.preferencesController.store, - TransactionController: this.transactionController.store, - ExchangeRatesController: this.exchangeRatesController.store, - GasPricesController: this.gasPricesController.store, - BlankDepositController: this.blankDepositController.store, - TokenController: this.tokenController.store, - PermissionsController: this.permissionsController.store, - AddressBookController: this.addressBookController.store, - BlockUpdatesController: this.blockUpdatesController.store, - BlockFetchController: this.blockFetchController.store, - TransactionWatcherControllerState: - this.transactionWatcherController.store, - BridgeController: this.bridgeController.store, - }, - true - ); + this.store = new ComposedStore({ + NetworkController: this.networkController.store, + AppStateController: this.appStateController.store, + OnboardingController: this.onboardingController.store, + KeyringController: this.keyringController.store, + AccountTrackerController: this.accountTrackerController.store, + PreferencesController: this.preferencesController.store, + TransactionController: this.transactionController.store, + ExchangeRatesController: this.exchangeRatesController.store, + GasPricesController: this.gasPricesController.store, + BlankDepositController: this.blankDepositController.store, + TokenController: this.tokenController.store, + PermissionsController: this.permissionsController.store, + AddressBookController: this.addressBookController.store, + BlockUpdatesController: this.blockUpdatesController.store, + BlockFetchController: this.blockFetchController.store, + TransactionWatcherControllerState: + this.transactionWatcherController.store, + BridgeController: this.bridgeController.store, + }); this.exchangeRatesStore = new ComposedStore({ ExchangeRatesController: this.exchangeRatesController.store, @@ -511,25 +508,22 @@ export default class BlankController extends EventEmitter { ActivityListController: this.activityListController.store, }); - this.UIStore = new ComposedStore( - { - NetworkController: this.networkController.store, - AppStateController: this.appStateController.UIStore, - OnboardingController: this.onboardingController.store, - KeyringController: this.keyringController.memStore, - AccountTrackerController: this.accountTrackerController.store, - PreferencesController: this.preferencesController.store, - TransactionController: this.transactionController.UIStore, - BlankDepositController: this.blankDepositController.UIStore, - TokenController: this.tokenController.store, - PermissionsController: this.permissionsController.store, - AddressBookController: this.addressBookController.store, - BlankProviderController: this.blankProviderController.store, - SwapController: this.swapController.UIStore, - BridgeController: this.bridgeController.UIStore, - }, - true - ); + this.UIStore = new ComposedStore({ + NetworkController: this.networkController.store, + AppStateController: this.appStateController.UIStore, + OnboardingController: this.onboardingController.store, + KeyringController: this.keyringController.memStore, + AccountTrackerController: this.accountTrackerController.store, + PreferencesController: this.preferencesController.store, + TransactionController: this.transactionController.UIStore, + BlankDepositController: this.blankDepositController.UIStore, + TokenController: this.tokenController.store, + PermissionsController: this.permissionsController.store, + AddressBookController: this.addressBookController.store, + BlankProviderController: this.blankProviderController.store, + SwapController: this.swapController.UIStore, + BridgeController: this.bridgeController.UIStore, + }); this.STORES = { [StateType.APP_STATE]: this.UIStore, diff --git a/packages/ui/src/components/AssetsList.tsx b/packages/ui/src/components/AssetsList.tsx index 56348e1c4..f4f262818 100644 --- a/packages/ui/src/components/AssetsList.tsx +++ b/packages/ui/src/components/AssetsList.tsx @@ -118,7 +118,7 @@ const SubAssetList: FunctionComponent<{ assets: TokenList }> = ({ assets }) => { return (
@@ -134,38 +134,37 @@ const SubAssetList: FunctionComponent<{ assets: TokenList }> = ({ assets }) => { ) } +const AddTokenButton = () => { + return ( +
+ +
+ ) +} + const AssetsList = () => { const { currentNetworkTokens, nativeToken } = useTokensList() const tokens = [nativeToken].concat(currentNetworkTokens) - // Top spacing for network labels: "pt-6" + const addTokenTop = tokens.length > 5 + return (
- {tokens.length > 9 && ( -
- -
- )} -
+ {addTokenTop && } +
{/* Network label */} - {/* ETHEREUM */}
-
- -
+ {!addTokenTop && }
) } diff --git a/packages/ui/src/components/assets/AssetDetailsPage.tsx b/packages/ui/src/components/assets/AssetDetailsPage.tsx index 9057f5f00..af96de116 100644 --- a/packages/ui/src/components/assets/AssetDetailsPage.tsx +++ b/packages/ui/src/components/assets/AssetDetailsPage.tsx @@ -165,126 +165,131 @@ const AssetDetailsPage = () => { timeout={1000} /> -
- - - - - +
+ + + + - {`${roundedTokenBalance} ${token.symbol}`} - - - - {currencyFormatter.format( - balance, - token.symbol, - token.decimals, - isNative - )} - - - - - - Send - - - {isSwapEnabled && ( + + {`${roundedTokenBalance} ${token.symbol}`} + + + + {currencyFormatter.format( + balance, + token.symbol, + token.decimals, + isNative + )} + + + -
+ Send + + + {isSwapEnabled && ( + - -
- - Swap - - - )} - {isBridgeEnabled && ( - -
+ +
+ + Swap + + + )} + {isBridgeEnabled && ( + - -
- - Bridge - - - )} - -
-
+
+ +
+ + Bridge + + + )} + + +
+
{tokenTransactions.length > 0 ? ( ) : ( diff --git a/packages/ui/src/components/home/ActivityAssetsView.tsx b/packages/ui/src/components/home/ActivityAssetsView.tsx index 904e02db0..fc10c9c9f 100644 --- a/packages/ui/src/components/home/ActivityAssetsView.tsx +++ b/packages/ui/src/components/home/ActivityAssetsView.tsx @@ -29,12 +29,12 @@ const ActivityAssetsView: FunctionComponent<{ initialTab: PopupTabs }> = ({ } return ( -
+
t.label} + display={({ label }) => label} disableStyles optionClassName={(value) => `flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-300 ${ @@ -43,10 +43,8 @@ const ActivityAssetsView: FunctionComponent<{ initialTab: PopupTabs }> = ({ : "border-gray-200 text-gray-500 border-b hover:text-primary-300 hover:font-medium" }` } - containerClassName="flex flex-row -ml-6" - containerStyle={{ width: "calc(100% + 2 * 1.5rem)" }} /> -
+
diff --git a/packages/ui/src/components/transactions/TransactionItem.tsx b/packages/ui/src/components/transactions/TransactionItem.tsx index 16a3e6296..429990a33 100644 --- a/packages/ui/src/components/transactions/TransactionItem.tsx +++ b/packages/ui/src/components/transactions/TransactionItem.tsx @@ -410,7 +410,9 @@ const getTransactionTimeOrStatus = ( const TransactionItem: React.FC<{ transaction: RichedTransactionMeta index: number -}> = ({ index, transaction }) => { + itemHeight: number + onClick: () => void +}> = ({ index, transaction, onClick, itemHeight }) => { const { transactionParams: { value, hash }, transactionCategory, @@ -506,36 +508,19 @@ const TransactionItem: React.FC<{ transactionCategory !== TransactionCategories.INCOMING_BRIDGE_PLACEHOLDER && !isBlankWithdraw - - const OperationDetails = - transactionCategory && - [ - TransactionCategories.BRIDGE, - TransactionCategories.INCOMING_BRIDGE_REFUND, - TransactionCategories.INCOMING_BRIDGE, - ].includes(transactionCategory) - ? BridgeDetails - : TransactionDetails - return ( <> - setHasDetails(false)} - /> -
{ if (txHash && transaction.transactionParams.from) { - setHasDetails(true) + onClick() } }} ref={contextMenuRef} diff --git a/packages/ui/src/components/transactions/TransactionsList.tsx b/packages/ui/src/components/transactions/TransactionsList.tsx index d012c3544..a6e762fd8 100644 --- a/packages/ui/src/components/transactions/TransactionsList.tsx +++ b/packages/ui/src/components/transactions/TransactionsList.tsx @@ -1,9 +1,34 @@ -import { Fragment, useRef, useState } from "react" +import { useRef, useState } from "react" +import AutoSizer from "react-virtualized-auto-sizer" +import { VariableSizeList as List } from "react-window" import useDOMElementObserver from "../../util/hooks/useDOMElementObserver" import { RichedTransactionMeta } from "../../util/transactionUtils" -import dotLoading from "../../assets/images/icons/dot_loading.svg" -import { classnames } from "../../styles" import TransactionItem from "./TransactionItem" +import { + TransactionCategories, + TransactionStatus, +} from "../../context/commTypes" +import BridgeDetails from "../bridge/BridgeDetails" +import TransactionDetails from "./TransactionDetails" +import { BRIDGE_PENDING_STATUS } from "../../util/bridgeUtils" +import { TransactionMeta } from "@block-wallet/background/controllers/transactions/utils/types" +const DEFAULT_TX_HEIGHT_IN_PX = 76 +const getItemHeightInPx = (tx: TransactionMeta) => { + if (tx.id) { + if (tx.status === TransactionStatus.SUBMITTED) { + return 110 + } else if (tx.transactionCategory === TransactionCategories.BRIDGE) { + return BRIDGE_PENDING_STATUS.includes(tx.bridgeParams!.status!) + ? 95 + : DEFAULT_TX_HEIGHT_IN_PX + } + } + return DEFAULT_TX_HEIGHT_IN_PX +} + +interface watchDetailsType { + transaction: TransactionMeta +} const getInitialCount = (transactions: RichedTransactionMeta[]) => transactions.length > 10 ? 10 : transactions.length @@ -11,6 +36,10 @@ const getInitialCount = (transactions: RichedTransactionMeta[]) => const TransactionsList: React.FC<{ transactions: RichedTransactionMeta[] }> = ({ transactions }) => { + const [watchDetails, setWatchDetails] = useState< + watchDetailsType | undefined + >() + const [transactionCount, setTransactionCount] = useState(() => getInitialCount(transactions) ) @@ -32,27 +61,62 @@ const TransactionsList: React.FC<{ [transactionCount, transactions] ) + const OperationDetails = watchDetails + ? watchDetails.transaction.transactionCategory + ? [ + TransactionCategories.BRIDGE, + TransactionCategories.INCOMING_BRIDGE_REFUND, + TransactionCategories.INCOMING_BRIDGE, + ].includes(watchDetails.transaction.transactionCategory) + ? BridgeDetails + : TransactionDetails + : undefined + : undefined + return ( - <> - {transactions.slice(0, transactionCount).map((t, i) => ( - - {i > 0 ?
: null} - -
- ))} - Loader + {OperationDetails && watchDetails?.transaction && ( + setWatchDetails(undefined)} + /> + )} + + {({ width, height }) => ( + { + const tx = transactions[index] + return getItemHeightInPx(tx) + }} // height in px + itemData={transactions} + className="hide-scroll" + > + {({ style, data, index }) => ( +
+ {index > 0 ?
: null} + + setWatchDetails({ + transaction: data[index], + }) + } + itemHeight={getItemHeightInPx(data[index])} + transaction={data[index]} + index={index} + /> +
+ )} +
)} - /> - +
+
) } diff --git a/packages/ui/src/context/hooks/useWindowId.tsx b/packages/ui/src/context/hooks/useWindowId.tsx index ce2096ed6..a403c4e66 100644 --- a/packages/ui/src/context/hooks/useWindowId.tsx +++ b/packages/ui/src/context/hooks/useWindowId.tsx @@ -1,5 +1,4 @@ import { createContext, useContext, useEffect, useState } from "react" -import { AppLoading } from "../../App" import { getWindowId } from "../commActions" export const WindowIdContext = createContext({ @@ -23,7 +22,7 @@ const WindowIdProvider = ({ return ( - {!windowId ? : children} + {children} ) } diff --git a/packages/ui/src/router/PopupRouter.tsx b/packages/ui/src/router/PopupRouter.tsx index 26b3087c2..d6f853c76 100644 --- a/packages/ui/src/router/PopupRouter.tsx +++ b/packages/ui/src/router/PopupRouter.tsx @@ -113,42 +113,40 @@ const PopupRouter = ({ return ( - - - - - - {isOnboarded ? ( - <> - - - setShouldShowDialog(false) - } - title="No connection" - message="Please check your internet connection. Some features of the wallet will remain disabled while you’re offline." - open={shouldShowDialog} - onDone={() => - setShouldShowDialog(false) - } - /> - - - - - ) : ( - - )} - {children} - - - - - + + + {isOnboarded ? ( + + + + + + setShouldShowDialog(false) + } + title="No connection" + message="Please check your internet connection. Some features of the wallet will remain disabled while you’re offline." + open={shouldShowDialog} + onDone={() => + setShouldShowDialog(false) + } + /> + + + + + + + ) : ( + + )} + {children} + + ) } diff --git a/packages/ui/src/routes/PopupPage.tsx b/packages/ui/src/routes/PopupPage.tsx index e484e58db..f8e3fc43f 100644 --- a/packages/ui/src/routes/PopupPage.tsx +++ b/packages/ui/src/routes/PopupPage.tsx @@ -49,7 +49,7 @@ const PopupPage = () => { onDone={() => setHasErrorDialog(false)} />
@@ -109,9 +109,9 @@ const PopupPage = () => {
-
-
-
+
+
+
{
- +
+ +
From a0cb8eaf6441e5e563f77860fed1addc8ffc37de Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 30 Nov 2022 10:04:01 -0300 Subject: [PATCH 005/110] fix: grab loading flag from exchange rate state --- packages/ui/src/components/AssetsList.tsx | 7 +++++-- packages/ui/src/components/home/HomeBalancePanel.tsx | 8 ++++++-- packages/ui/src/components/input/NetworkSelect.tsx | 5 +---- packages/ui/src/components/token/TokenSummary.tsx | 3 +-- .../ui/src/context/background/useExchangeRatesState.tsx | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/ui/src/components/AssetsList.tsx b/packages/ui/src/components/AssetsList.tsx index 1b52e6f67..1ff2236da 100644 --- a/packages/ui/src/components/AssetsList.tsx +++ b/packages/ui/src/components/AssetsList.tsx @@ -15,6 +15,7 @@ import AssetsLoadingSkeleton from "./skeleton/AssetsLoadingSkeleton" import useCurrencyFromatter from "../util/hooks/useCurrencyFormatter" import { isNativeTokenAddress } from "../util/tokenUtils" import { useBlankState } from "../context/background/backgroundHooks" +import { useExchangeRatesState } from "../context/background/useExchangeRatesState" export type AssetItem = { token: Token balance: BigNumber @@ -103,9 +104,11 @@ const Asset: FunctionComponent<{ const SubAssetList: FunctionComponent<{ assets: TokenList }> = ({ assets }) => { const state = useBlankState()! - + const { + state: { isRatesChangingAfterNetworkChange }, + } = useExchangeRatesState() const isLoading = - state.isNetworkChanging || state.isRatesChangingAfterNetworkChange + state.isNetworkChanging || isRatesChangingAfterNetworkChange const [deletedTokens, setDeletedTokens] = useState([] as string[]) const pushDeleteTokens = (deleteToken: string) => { diff --git a/packages/ui/src/components/home/HomeBalancePanel.tsx b/packages/ui/src/components/home/HomeBalancePanel.tsx index 730f2c16a..e48ab25f7 100644 --- a/packages/ui/src/components/home/HomeBalancePanel.tsx +++ b/packages/ui/src/components/home/HomeBalancePanel.tsx @@ -26,14 +26,18 @@ const LoadingBlueIcon = () => { const HomeBalancePanel = () => { const state = useBlankState()! const { - state: { exchangeRates, networkNativeCurrency }, + state: { + exchangeRates, + networkNativeCurrency, + isRatesChangingAfterNetworkChange, + }, } = useExchangeRatesState() const { nativeToken } = useTokensList() const { nativeCurrency, isSendEnabled, isSwapEnabled, isBridgeEnabled } = useSelectedNetwork() const isLoading = - state.isNetworkChanging || state.isRatesChangingAfterNetworkChange + state.isNetworkChanging || isRatesChangingAfterNetworkChange return ( diff --git a/packages/ui/src/components/input/NetworkSelect.tsx b/packages/ui/src/components/input/NetworkSelect.tsx index 93cc00337..f34d8a95e 100644 --- a/packages/ui/src/components/input/NetworkSelect.tsx +++ b/packages/ui/src/components/input/NetworkSelect.tsx @@ -52,7 +52,6 @@ const NetworkSelect: FunctionComponent<{ availableNetworks, showTestNetworks, isNetworkChanging, - isRatesChangingAfterNetworkChange, isImportingDeposits, isUserNetworkOnline, } = useBlankState()! @@ -76,9 +75,7 @@ const NetworkSelect: FunctionComponent<{ role="menu" data-testid="network-selector" > - {(isNetworkChanging || isRatesChangingAfterNetworkChange) && ( - - )} + {isNetworkChanging && }
{ if (!isImportingDeposits) { diff --git a/packages/ui/src/components/token/TokenSummary.tsx b/packages/ui/src/components/token/TokenSummary.tsx index e31e7cd61..78bb64879 100644 --- a/packages/ui/src/components/token/TokenSummary.tsx +++ b/packages/ui/src/components/token/TokenSummary.tsx @@ -32,8 +32,7 @@ const TokenSummary: FC<{ const Balances = ({ children }: { children: React.ReactNode }) => { const state = useBlankState()! - const isLoading = - state.isNetworkChanging || state.isRatesChangingAfterNetworkChange + const isLoading = state.isNetworkChanging return ( <> diff --git a/packages/ui/src/context/background/useExchangeRatesState.tsx b/packages/ui/src/context/background/useExchangeRatesState.tsx index efcb1b918..bbdf53bbb 100644 --- a/packages/ui/src/context/background/useExchangeRatesState.tsx +++ b/packages/ui/src/context/background/useExchangeRatesState.tsx @@ -16,6 +16,7 @@ const defualtState = { // Default Coingecko id for ETH rates coingeckoPlatformId: "ethereum", }, + isRatesChangingAfterNetworkChange: false, } const ExchangeRatesContext = createContext({ From e10182603ec68caeca37dc59c40a55a3e323134d Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Thu, 1 Dec 2022 17:10:34 -0300 Subject: [PATCH 006/110] feat: Improve loading styles and scroll --- packages/ui/src/components/AssetsList.tsx | 189 ---------------- .../components/assets/AssetDetailsPage.tsx | 11 +- .../src/components/assets/AssetSelection.tsx | 4 +- .../{AssetList.tsx => AssetsDropdownList.tsx} | 4 +- .../ui/src/components/button/ActionButton.tsx | 5 +- .../components/home/ActivityAssetsView.tsx | 13 +- .../ui/src/components/home/ActivityList.tsx | 2 +- packages/ui/src/components/home/AssetItem.tsx | 90 ++++++++ .../ui/src/components/home/AssetsList.tsx | 49 +++++ .../ui/src/components/home/AssetsOverview.tsx | 50 +++++ .../src/components/home/HomeBalancePanel.tsx | 205 +++++++++--------- .../skeleton/AssetsLoadingSkeleton.tsx | 6 +- .../skeleton/TransactionsLoadingSkeleton.tsx | 2 +- .../ui/src/components/token/TokenSummary.tsx | 70 +++--- .../transactions/TransactionItem.tsx | 46 ++-- .../transactions/TransactionsList.tsx | 50 +---- packages/ui/src/routes/PopupPage.tsx | 4 +- packages/ui/src/util/balance.ts | 46 ++++ .../ui/src/util/hooks/useCurrencyFormatter.ts | 2 +- 19 files changed, 443 insertions(+), 405 deletions(-) delete mode 100644 packages/ui/src/components/AssetsList.tsx rename packages/ui/src/components/assets/{AssetList.tsx => AssetsDropdownList.tsx} (97%) create mode 100644 packages/ui/src/components/home/AssetItem.tsx create mode 100644 packages/ui/src/components/home/AssetsList.tsx create mode 100644 packages/ui/src/components/home/AssetsOverview.tsx create mode 100644 packages/ui/src/util/balance.ts diff --git a/packages/ui/src/components/AssetsList.tsx b/packages/ui/src/components/AssetsList.tsx deleted file mode 100644 index 1ff2236da..000000000 --- a/packages/ui/src/components/AssetsList.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import { BigNumber } from "ethers" -import { Fragment, FunctionComponent, useState } from "react" -import { useOnMountHistory } from "../context/hooks/useOnMount" -import { Token } from "@block-wallet/background/controllers/erc-20/Token" -import { TokenList, useTokensList } from "../context/hooks/useTokensList" -import { formatUnits } from "@ethersproject/units" - -import { Classes } from "../styles/classes" -import plus from "../assets/images/icons/plus.svg" -import unknownTokenIcon from "../assets/images/unknown_token.svg" -import ChevronRightIcon from "./icons/ChevronRightIcon" -import { formatRounded } from "../util/formatRounded" -import { ActionButton } from "./button/ActionButton" -import AssetsLoadingSkeleton from "./skeleton/AssetsLoadingSkeleton" -import useCurrencyFromatter from "../util/hooks/useCurrencyFormatter" -import { isNativeTokenAddress } from "../util/tokenUtils" -import { useBlankState } from "../context/background/backgroundHooks" -import { useExchangeRatesState } from "../context/background/useExchangeRatesState" -export type AssetItem = { - token: Token - balance: BigNumber -} - -export const AssetIcon: FunctionComponent<{ - asset: Partial - filled?: boolean -}> = ({ asset, filled }) => ( -
- { - { - ;(e.target as any).onerror = null - ;(e.target as any).src = unknownTokenIcon - }} - alt={asset.symbol || ""} - className="rounded-full" - /> - } -
-) - -const Asset: FunctionComponent<{ - asset: AssetItem - pushDeleteTokens: Function -}> = ({ asset }) => { - const history: any = useOnMountHistory() - const formatter = useCurrencyFromatter() - return ( -
- history.push({ - pathname: `/asset/details`, - state: { - address: asset.token.address, - transitionDirection: "left", - }, - }) - } - className="flex flex-row items-center justify-between px-6 py-5 -ml-6 transition duration-300 hover:bg-primary-100 hover:bg-opacity-50 active:bg-primary-200 active:bg-opacity-50 cursor-pointer" - style={{ width: "calc(100% + 2 * 1.5rem)" }} - role="listitem" - aria-label={asset.token.symbol} - > -
- -
- - {` - ${formatRounded( - formatUnits( - asset.balance || "0", - asset.token.decimals - ), - 4 - )} - ${asset.token.symbol} - `} - - - {formatter.format( - asset.balance || BigNumber.from(0), - asset.token.symbol, - asset.token.decimals, - isNativeTokenAddress(asset.token.address) - )} - -
-
-
- -
-
- ) -} - -const SubAssetList: FunctionComponent<{ assets: TokenList }> = ({ assets }) => { - const state = useBlankState()! - const { - state: { isRatesChangingAfterNetworkChange }, - } = useExchangeRatesState() - const isLoading = - state.isNetworkChanging || isRatesChangingAfterNetworkChange - - const [deletedTokens, setDeletedTokens] = useState([] as string[]) - const pushDeleteTokens = (deleteToken: string) => { - setDeletedTokens([...deletedTokens, deleteToken]) - } - - // the action of delete a token is not sync, we include this blick of code for not showing deleted tokens while they are being deleted. - const newDeleted: string[] = [] - deletedTokens.forEach((t) => { - if (assets.map((a) => a.token.address).includes(t)) { - newDeleted.push(t) - } - }) - if (deletedTokens.length !== newDeleted.length) { - setDeletedTokens(newDeleted) - } - - return ( -
- {isLoading ? ( - - ) : ( - assets - .filter((t) => !deletedTokens.includes(t.token.address)) - .map((a, i) => ( - - {i > 0 ?
: null} - -
- )) - )} -
- ) -} - -const AddTokenButton = () => { - return ( -
- -
- ) -} - -const AssetsList = () => { - const { currentNetworkTokens, nativeToken } = useTokensList() - - const tokens = [nativeToken].concat(currentNetworkTokens) - - const addTokenTop = tokens.length > 5 - - return ( -
- {addTokenTop && } -
- {/* Network label */} - -
- {!addTokenTop && } -
- ) -} - -export default AssetsList diff --git a/packages/ui/src/components/assets/AssetDetailsPage.tsx b/packages/ui/src/components/assets/AssetDetailsPage.tsx index af96de116..7a324ba82 100644 --- a/packages/ui/src/components/assets/AssetDetailsPage.tsx +++ b/packages/ui/src/components/assets/AssetDetailsPage.tsx @@ -5,14 +5,13 @@ import { deleteCustomToken } from "../../context/commActions" import { useOnMountHistory } from "../../context/hooks/useOnMount" import { useSelectedAccount } from "../../context/hooks/useSelectedAccount" import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" -import { classnames } from "../../styles" +import { Classes, classnames } from "../../styles" import { formatRounded } from "../../util/formatRounded" import useCurrencyFromatter from "../../util/hooks/useCurrencyFormatter" import useGetAssetByTokenAddress from "../../util/hooks/useGetAssetByTokenAddress" import useTokenTransactions from "../../util/hooks/useTokenTransactions" import { useBlankState } from "../../context/background/backgroundHooks" import { generateExplorerLink, getExplorerTitle } from "../../util/getExplorer" -import { AssetIcon } from "../AssetsList" import RoundedIconButton from "../button/RoundedIconButton" import AnimatedIcon, { AnimatedIconName } from "../../components/AnimatedIcon" import ArrowHoverAnimation from "../icons/ArrowHoverAnimation" @@ -21,7 +20,6 @@ import PopupHeader from "../popup/PopupHeader" import PopupLayout from "../popup/PopupLayout" import TokenSummary from "../token/TokenSummary" import TransactionsList from "../transactions/TransactionsList" - import log from "loglevel" import ConfirmDialog from "../dialog/ConfirmDialog" import { isNativeTokenAddress } from "../../util/tokenUtils" @@ -29,6 +27,7 @@ import SuccessDialog from "../dialog/SuccessDialog" import { formatName } from "../../util/formatAccount" import Icon, { IconName } from "../ui/Icon" import DoubleArrowHoverAnimation from "../icons/DoubleArrowHoverAnimation" +import TokenLogo from "../token/TokenLogo" const AssetDetailsPage = () => { const state = useBlankState()! @@ -169,7 +168,11 @@ const AssetDetailsPage = () => {
- + = ({ defaultValue={search ?? ""} />
- void onAssetClick: (asset: TokenWithBalance, setActive?: () => void) => void selectedAddress?: string @@ -70,4 +70,4 @@ const AssetList: FC<{ ) } -export default AssetList +export default AssetsDropdownList diff --git a/packages/ui/src/components/button/ActionButton.tsx b/packages/ui/src/components/button/ActionButton.tsx index a514bf588..99effc5dc 100644 --- a/packages/ui/src/components/button/ActionButton.tsx +++ b/packages/ui/src/components/button/ActionButton.tsx @@ -8,10 +8,11 @@ export const ActionButton: FunctionComponent<{ label: string to: string state?: any -}> = ({ icon, label, to, state }) => { + className?: string +}> = ({ icon, label, to, state, className }) => { return ( diff --git a/packages/ui/src/components/home/ActivityAssetsView.tsx b/packages/ui/src/components/home/ActivityAssetsView.tsx index fc10c9c9f..a875b28dd 100644 --- a/packages/ui/src/components/home/ActivityAssetsView.tsx +++ b/packages/ui/src/components/home/ActivityAssetsView.tsx @@ -2,8 +2,8 @@ import { FunctionComponent, useState } from "react" import { PopupTabs } from "@block-wallet/background/controllers/PreferencesController" import { updatePopupTab } from "../../context/commActions" import ActivityList from "./ActivityList" -import AssetsList from "../AssetsList" import HorizontalSelect from "../input/HorizontalSelect" +import AssetsOverview from "./AssetsOverview" const tabs = [ { @@ -12,7 +12,7 @@ const tabs = [ }, { label: "Assets", - component: AssetsList, + component: AssetsOverview, }, ] @@ -29,13 +29,14 @@ const ActivityAssetsView: FunctionComponent<{ initialTab: PopupTabs }> = ({ } return ( -
+ <> label} disableStyles + containerClassName="sticky flex-row flex" optionClassName={(value) => `flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-300 ${ tab === value @@ -44,10 +45,8 @@ const ActivityAssetsView: FunctionComponent<{ initialTab: PopupTabs }> = ({ }` } /> -
- -
-
+ + ) } diff --git a/packages/ui/src/components/home/ActivityList.tsx b/packages/ui/src/components/home/ActivityList.tsx index eba73f425..7e1f404d9 100644 --- a/packages/ui/src/components/home/ActivityList.tsx +++ b/packages/ui/src/components/home/ActivityList.tsx @@ -13,7 +13,7 @@ const ActivityList = () => { return (
= ({ asset: { balance, token } }) => { + const history: any = useOnMountHistory() + const formatter = useCurrencyFromatter() + const { + state: { isRatesChangingAfterNetworkChange }, + } = useExchangeRatesState() + + return ( +
+ history.push({ + pathname: `/asset/details`, + state: { + address: token.address, + transitionDirection: "left", + }, + }) + } + className="flex flex-row items-center justify-between px-6 py-5 -ml-6 transition duration-300 hover:bg-primary-100 hover:bg-opacity-50 active:bg-primary-200 active:bg-opacity-50 cursor-pointer" + style={{ width: "calc(100% + 2 * 1.5rem)" }} + role="listitem" + aria-label={token.symbol} + > +
+ +
+ + {formatAssetBalance(balance, token, { + rounded: true, + dislpaySymbol: true, + roundedDecimals: 4, + })} + + + {isRatesChangingAfterNetworkChange ? ( + + ) : ( + formatter.format( + balance || BigNumber.from(0), + token.symbol, + token.decimals, + isNativeTokenAddress(token.address) + ) + )} + +
+
+
+ +
+
+ ) +} + +export default AssetItem diff --git a/packages/ui/src/components/home/AssetsList.tsx b/packages/ui/src/components/home/AssetsList.tsx new file mode 100644 index 000000000..6242abbbd --- /dev/null +++ b/packages/ui/src/components/home/AssetsList.tsx @@ -0,0 +1,49 @@ +import { Fragment, FunctionComponent, useState } from "react" +import { TokenList } from "../../context/hooks/useTokensList" +import AssetsLoadingSkeleton from "../skeleton/AssetsLoadingSkeleton" +import { useBlankState } from "../../context/background/backgroundHooks" +import AssetItem from "./AssetItem" + +const AssetsList: FunctionComponent<{ assets: TokenList }> = ({ assets }) => { + const state = useBlankState()! + + const [deletedTokens, setDeletedTokens] = useState([] as string[]) + const pushDeleteTokens = (deleteToken: string) => { + setDeletedTokens([...deletedTokens, deleteToken]) + } + + // the action of delete a token is not sync, we include this blick of code for not showing deleted tokens while they are being deleted. + const newDeleted: string[] = [] + deletedTokens.forEach((t) => { + if (assets.map((a) => a.token.address).includes(t)) { + newDeleted.push(t) + } + }) + if (deletedTokens.length !== newDeleted.length) { + setDeletedTokens(newDeleted) + } + + return ( +
+ {assets + .filter((t) => !deletedTokens.includes(t.token.address)) + .map((asset, i) => ( + + {i > 0 ?
: null} +
+ +
+
+ ))} +
+ ) +} + +export default AssetsList diff --git a/packages/ui/src/components/home/AssetsOverview.tsx b/packages/ui/src/components/home/AssetsOverview.tsx new file mode 100644 index 000000000..8f423ca6c --- /dev/null +++ b/packages/ui/src/components/home/AssetsOverview.tsx @@ -0,0 +1,50 @@ +import { ActionButton } from "../button/ActionButton" +import plus from "../../assets/images/icons/plus.svg" +import AssetsList from "./AssetsList" +import classnames from "classnames" +import { useTokensList } from "../../context/hooks/useTokensList" +import { useBlankState } from "../../context/background/backgroundHooks" +import AssetsLoadingSkeleton from "../skeleton/AssetsLoadingSkeleton" + +const AddTokenButton = () => { + return ( +
+ +
+ ) +} + +const AssetsOverview = () => { + const { currentNetworkTokens, nativeToken } = useTokensList() + const { isNetworkChanging } = useBlankState()! + const tokens = [nativeToken].concat(currentNetworkTokens) + + const dislpayTopButton = tokens.length > 8 + + if (isNetworkChanging) { + return ( +
+ +
+ ) + } + + return ( +
+ {dislpayTopButton && } + + +
+ ) +} + +export default AssetsOverview diff --git a/packages/ui/src/components/home/HomeBalancePanel.tsx b/packages/ui/src/components/home/HomeBalancePanel.tsx index e48ab25f7..cfef5a0ba 100644 --- a/packages/ui/src/components/home/HomeBalancePanel.tsx +++ b/packages/ui/src/components/home/HomeBalancePanel.tsx @@ -1,9 +1,7 @@ -import { BigNumber } from "ethers" import { useBlankState } from "../../context/background/backgroundHooks" import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" import { useSelectedNetwork } from "../../context/hooks/useSelectedNetwork" import { useTokensList } from "../../context/hooks/useTokensList" -import { formatCurrency, toCurrencyAmount } from "../../util/formatCurrency" import { formatRounded } from "../../util/formatRounded" import TokenSummary from "../token/TokenSummary" import { formatUnits } from "ethers/lib/utils" @@ -12,6 +10,7 @@ import classnames from "classnames" import AnimatedIcon, { AnimatedIconName } from "../AnimatedIcon" import DoubleArrowHoverAnimation from "../icons/DoubleArrowHoverAnimation" import ArrowHoverAnimation from "../icons/ArrowHoverAnimation" +import useCurrencyFromatter from "../../util/hooks/useCurrencyFormatter" const LoadingBlueIcon = () => { return ( @@ -24,141 +23,139 @@ const LoadingBlueIcon = () => { ) } const HomeBalancePanel = () => { - const state = useBlankState()! + const { isNetworkChanging, isUserNetworkOnline } = useBlankState()! + const formatter = useCurrencyFromatter() const { - state: { - exchangeRates, - networkNativeCurrency, - isRatesChangingAfterNetworkChange, - }, + state: { networkNativeCurrency, isRatesChangingAfterNetworkChange }, } = useExchangeRatesState() const { nativeToken } = useTokensList() const { nativeCurrency, isSendEnabled, isSwapEnabled, isBridgeEnabled } = useSelectedNetwork() - const isLoading = - state.isNetworkChanging || isRatesChangingAfterNetworkChange return ( - - - - {formatRounded( - formatUnits( - nativeToken.balance || "0", - nativeCurrency.decimals - ), - 5 - )}{" "} - {nativeCurrency.symbol} - - - {formatCurrency( - toCurrencyAmount( - nativeToken.balance || BigNumber.from(0), - exchangeRates[networkNativeCurrency.symbol], - nativeCurrency.decimals - ), - { - currency: state.nativeCurrency, - locale_info: state.localeInfo, - returnNonBreakingSpace: true, - showSymbol: true, +
+ + + - - - -
- {isLoading ? ( - - ) : ( - + {formatRounded( + formatUnits( + nativeToken.balance || "0", + nativeCurrency.decimals + ), + 5 + )}{" "} + {nativeCurrency.symbol} + + + {formatter.format( + nativeToken.balance, + networkNativeCurrency.symbol, + nativeCurrency.decimals, + true )} -
- Send - - {isSwapEnabled && ( + + +
- {isLoading ? ( + {isNetworkChanging ? ( ) : ( - + )}
- Swap + Send - )} - {isBridgeEnabled && ( - -
- {isLoading ? ( - - ) : ( - +
+ {isNetworkChanging ? ( + + ) : ( + + )} +
+ Swap + + )} + {isBridgeEnabled && ( + - Bridge - - )} - - + > +
+ {isNetworkChanging ? ( + + ) : ( + + )} +
+ Bridge + + )} + + +
) } diff --git a/packages/ui/src/components/skeleton/AssetsLoadingSkeleton.tsx b/packages/ui/src/components/skeleton/AssetsLoadingSkeleton.tsx index 51b4bee7f..ce7297232 100644 --- a/packages/ui/src/components/skeleton/AssetsLoadingSkeleton.tsx +++ b/packages/ui/src/components/skeleton/AssetsLoadingSkeleton.tsx @@ -9,7 +9,7 @@ const AssetsLoadingSkeleton = () => {
{index > 0 ?
: null} -
+
{ icon={ AnimatedIconName.GreyLineLoadingSkeleton } - className="mb-2 h-3 w-16 rotate-180" + className="mb-2 h-3 w-24 rotate-180" svgClassName="rounded-md" />
diff --git a/packages/ui/src/components/skeleton/TransactionsLoadingSkeleton.tsx b/packages/ui/src/components/skeleton/TransactionsLoadingSkeleton.tsx index 749288968..fc441e9fa 100644 --- a/packages/ui/src/components/skeleton/TransactionsLoadingSkeleton.tsx +++ b/packages/ui/src/components/skeleton/TransactionsLoadingSkeleton.tsx @@ -7,7 +7,7 @@ const TransactionsLoadingSkeleton = () => { {[...Array(3)].map((x, index) => (
{index > 0 ?
: null} -
+
- TokenBalance: FC<{ - title?: string - children: React.ReactNode - className?: string - }> - ExchangeRateBalance: FC<{ title?: string; children: React.ReactNode }> + TokenBalance: FC + ExchangeRateBalance: FC Actions: FC<{ children: React.ReactNode }> } @@ -30,28 +32,26 @@ const TokenSummary: FC<{ } const Balances = ({ children }: { children: React.ReactNode }) => { - const state = useBlankState()! - - const isLoading = state.isNetworkChanging - return ( - <> - {isLoading ? ( - - ) : ( -
- {children} -
- )} - +
{children}
) } -const TokenBalance: FC<{ - title?: string - className?: string - children: React.ReactNode -}> = ({ children, title, className }) => { +const TokenBalance: FC = ({ + children, + title, + className, + isLoading, +}) => { + if (isLoading) { + return ( + + ) + } return ( = ({ children, title }) => { +const ExchangeRateBalance: FC = ({ + children, + title, + isLoading, +}) => { + if (isLoading) { + return ( + + ) + } return ( {children} diff --git a/packages/ui/src/components/transactions/TransactionItem.tsx b/packages/ui/src/components/transactions/TransactionItem.tsx index 429990a33..810af1d49 100644 --- a/packages/ui/src/components/transactions/TransactionItem.tsx +++ b/packages/ui/src/components/transactions/TransactionItem.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, useRef, useState } from "react" +import { CSSProperties, useRef } from "react" import { FaExchangeAlt } from "react-icons/fa" import { FiUpload } from "react-icons/fi" import { RiCopperCoinFill } from "react-icons/ri" @@ -13,7 +13,6 @@ import { Classes, classnames } from "../../styles" // Components import ComplianceMenu from "../privacy/ComplianceMenu" -import { AssetIcon } from "./../AssetsList" import Tooltip from "../../components/label/Tooltip" // Asset @@ -46,11 +45,13 @@ import Dots from "../loading/LoadingDots" import useContextMenu from "../../util/hooks/useContextMenu" import useCurrencyFromatter from "../../util/hooks/useCurrencyFormatter" import useGetBridgeTransactionsData from "../../util/hooks/useGetBridgeTransactionsData" -import BridgeDetails from "../bridge/BridgeDetails" import { BRIDGE_PENDING_STATUS, getBridgePendingMessage, } from "../../util/bridgeUtils" +import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" +import AnimatedIcon, { AnimatedIconName } from "../AnimatedIcon" +import TokenLogo from "../token/TokenLogo" const transactionMessages = { [TransactionCategories.BLANK_DEPOSIT]: "Privacy Pool Deposit", @@ -140,7 +141,7 @@ const getTransactionItemStyles = ( return { formattedLabel, typeCss, amountCss } } -const transactionIcons = { +const transactionIcons: Record = { [TransactionCategories.BLANK_DEPOSIT]: blank, [TransactionCategories.BLANK_WITHDRAWAL]: ( BlockWallet @@ -200,11 +201,10 @@ const TransactionIcon: React.FC<{
{transactionStatus !== TransactionStatus.SUBMITTED ? ( transactionIcon ? ( - ) : category ? (
@@ -433,12 +433,13 @@ const TransactionItem: React.FC<{ const history: any = useOnMountHistory() const formatter = useCurrencyFromatter() + const { + state: { isRatesChangingAfterNetworkChange }, + } = useExchangeRatesState() const { nativeCurrency: networkNativeCurrency, defaultNetworkLogo } = useSelectedNetwork() - const [hasDetails, setHasDetails] = useState(false) - const txHash = hash const transfer = transferType ?? { amount: value ? value : BigNumber.from("0"), @@ -525,7 +526,6 @@ const TransactionItem: React.FC<{ }} ref={contextMenuRef} > - {/* Type */}
- - {transferCurrencyAmount} - + {isRatesChangingAfterNetworkChange ? ( + + ) : ( + + {transferCurrencyAmount} + + )}
)} diff --git a/packages/ui/src/components/transactions/TransactionsList.tsx b/packages/ui/src/components/transactions/TransactionsList.tsx index 9eb4ff341..18b783eb5 100644 --- a/packages/ui/src/components/transactions/TransactionsList.tsx +++ b/packages/ui/src/components/transactions/TransactionsList.tsx @@ -1,4 +1,4 @@ -import { useRef, useState } from "react" +import { useMemo, useRef, useState } from "react" import AutoSizer from "react-virtualized-auto-sizer" import { VariableSizeList as List } from "react-window" import useDOMElementObserver from "../../util/hooks/useDOMElementObserver" @@ -14,7 +14,6 @@ import { BRIDGE_PENDING_STATUS } from "../../util/bridgeUtils" import { TransactionMeta } from "@block-wallet/background/controllers/transactions/utils/types" import { useBlankState } from "../../context/background/backgroundHooks" import TransactionsLoadingSkeleton from "../skeleton/TransactionsLoadingSkeleton" -import { useExchangeRatesState } from "../../context/background/useExchangeRatesState" const DEFAULT_TX_HEIGHT_IN_PX = 76 const getItemHeightInPx = (tx: TransactionMeta) => { @@ -34,44 +33,13 @@ interface watchDetailsType { transaction: TransactionMeta } -const getInitialCount = (transactions: RichedTransactionMeta[]) => - transactions.length > 10 ? 10 : transactions.length - const TransactionsList: React.FC<{ transactions: RichedTransactionMeta[] }> = ({ transactions }) => { const [watchDetails, setWatchDetails] = useState< watchDetailsType | undefined >() - const state = useBlankState()! - const { - state: { isRatesChangingAfterNetworkChange }, - } = useExchangeRatesState() - - const isLoading = - state.isNetworkChanging || isRatesChangingAfterNetworkChange - - const [transactionCount, setTransactionCount] = useState(() => - getInitialCount(transactions) - ) - const [isLoadingMoreTransactions, setIsLoadingMoreTransactions] = - useState(false) - const loaderRef = useRef(null) - - useDOMElementObserver( - loaderRef, - async () => { - const countToLoad = transactions.length - transactionCount - if (countToLoad === 0) return - setIsLoadingMoreTransactions(true) - await new Promise((resolve) => setTimeout(resolve, 300)) - setTransactionCount( - transactionCount + (countToLoad > 10 ? 10 : countToLoad) - ) - setIsLoadingMoreTransactions(false) - }, - [transactionCount, transactions] - ) + const { isNetworkChanging } = useBlankState()! const OperationDetails = watchDetails ? watchDetails.transaction.transactionCategory @@ -85,8 +53,12 @@ const TransactionsList: React.FC<{ : undefined : undefined - if (isLoading) { - return + if (isNetworkChanging) { + return ( +
+ +
+ ) } return ( @@ -98,12 +70,14 @@ const TransactionsList: React.FC<{ onClose={() => setWatchDetails(undefined)} /> )} - + {({ width, height }) => ( {
-
- -
+
diff --git a/packages/ui/src/util/balance.ts b/packages/ui/src/util/balance.ts new file mode 100644 index 000000000..da299bf3e --- /dev/null +++ b/packages/ui/src/util/balance.ts @@ -0,0 +1,46 @@ +import { BigNumber } from "ethers" +import { formatUnits } from "ethers/lib/utils" +import { formatRounded } from "./formatRounded" + +interface TokenInfo { + decimals: number + symbol?: string +} + +interface DisplayOptions { + dislpaySymbol?: boolean + rounded?: boolean + roundedDecimals?: number +} + +const defaultOptions: DisplayOptions = { + dislpaySymbol: true, + rounded: true, + roundedDecimals: 4, +} + +export const formatAssetBalance = ( + balance: BigNumber = BigNumber.from(0), + tokenInfo: TokenInfo, + displayOptions: DisplayOptions = defaultOptions +): string => { + const safeOptions = { + ...defaultOptions, + displayOptions, + } + + let formatedBalance = formatUnits(balance || "0", tokenInfo.decimals) + + if (safeOptions.rounded) { + formatedBalance = formatRounded( + formatedBalance, + safeOptions.roundedDecimals + ) + } + + if (safeOptions.dislpaySymbol) { + formatedBalance = `${formatedBalance} ${tokenInfo.symbol}` + } + + return formatedBalance +} diff --git a/packages/ui/src/util/hooks/useCurrencyFormatter.ts b/packages/ui/src/util/hooks/useCurrencyFormatter.ts index b3845137c..f0a3bb17b 100644 --- a/packages/ui/src/util/hooks/useCurrencyFormatter.ts +++ b/packages/ui/src/util/hooks/useCurrencyFormatter.ts @@ -7,7 +7,7 @@ import { getValueByKey } from "../objectUtils" const useCurrencyFromatter = () => { const state = useBlankState()! const { - state: { exchangeRates, networkNativeCurrency }, + state: { exchangeRates }, } = useExchangeRatesState() const format = ( balance: BigNumber, From 1df0f55b7ed82ca8c101f2a47121606600813471 Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 21 Dec 2022 10:46:25 -0300 Subject: [PATCH 007/110] fix: styles --- packages/ui/src/components/assets/AssetDetailsPage.tsx | 2 +- packages/ui/src/components/home/HomeBalancePanel.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/assets/AssetDetailsPage.tsx b/packages/ui/src/components/assets/AssetDetailsPage.tsx index e4043ef59..4902f44e0 100644 --- a/packages/ui/src/components/assets/AssetDetailsPage.tsx +++ b/packages/ui/src/components/assets/AssetDetailsPage.tsx @@ -201,7 +201,7 @@ const AssetDetailsPage = () => { )} - + { return (
- + Date: Wed, 21 Dec 2022 10:46:46 -0300 Subject: [PATCH 008/110] feat: use UIStore in the AppStateController --- .../src/controllers/AppStateController.ts | 37 ++++++++++++++----- .../BlankProviderController.test.ts | 1 + 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/background/src/controllers/AppStateController.ts b/packages/background/src/controllers/AppStateController.ts index 7b89e9d5a..5b70157ee 100644 --- a/packages/background/src/controllers/AppStateController.ts +++ b/packages/background/src/controllers/AppStateController.ts @@ -11,6 +11,7 @@ export interface AppStateControllerMemState { expiredStickyStorage: boolean; isAppUnlocked: boolean; lockedByTimeout: boolean; + idleTimeout: number; } export interface AppStateControllerState { @@ -37,7 +38,12 @@ export default class AppStateController extends BaseController< private readonly _keyringController: KeyringControllerDerivated, private readonly _transactionController: TransactionController ) { - super(initState); + super(initState, { + idleTimeout: initState.idleTimeout, + isAppUnlocked: initState.isAppUnlocked, + lockedByTimeout: initState.lockedByTimeout, + expiredStickyStorage: false, + }); this._timer = null; @@ -56,15 +62,28 @@ export default class AppStateController extends BaseController< } this._resetTimer(); - this.store.subscribe((newState, oldState) => { - //To avoid sending the lastActiveTime to the UI, update the UIStore based on the store data. - if (newState.isAppUnlocked !== oldState?.isAppUnlocked) { - this.UIStore.updateState({ - isAppUnlocked: newState.isAppUnlocked, - lockedByTimeout: newState.lockedByTimeout, - }); + this.store.subscribe( + ( + newState: AppStateControllerState, + oldState?: AppStateControllerState + ) => { + //To avoid sending the lastActiveTime to the UI, update the UIStore based on the store data. + + if (newState.isAppUnlocked !== oldState?.isAppUnlocked) { + this.UIStore.updateState({ + isAppUnlocked: newState.isAppUnlocked, + lockedByTimeout: newState.lockedByTimeout, + }); + return; + } + + if (newState.idleTimeout !== oldState?.idleTimeout) { + this.UIStore.updateState({ + idleTimeout: newState.idleTimeout, + }); + } } - }); + ); } /** diff --git a/packages/background/test/controllers/BlankProviderController.test.ts b/packages/background/test/controllers/BlankProviderController.test.ts index 2224ebe73..eb2b9cdbb 100644 --- a/packages/background/test/controllers/BlankProviderController.test.ts +++ b/packages/background/test/controllers/BlankProviderController.test.ts @@ -404,6 +404,7 @@ describe('Blank Provider Controller', function () { isAppUnlocked: true, expiredStickyStorage: false, lockedByTimeout: false, + idleTimeout: 2000, }); sinon.stub(appStateController.store, 'getState').returns({ isAppUnlocked: true, From fc87f458a6696712ef668c980f656d15b8d89db6 Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 21 Dec 2022 11:48:14 -0300 Subject: [PATCH 009/110] refactor: move state subscriptions outside router --- packages/ui/src/App.tsx | 15 ++++++++++- packages/ui/src/router/PopupRouter.tsx | 36 +++++++++++--------------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index 812e1969c..9c5146655 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -9,6 +9,9 @@ import TabRouter from "./router/TabRouter" import { WindowIdProvider } from "./context/hooks/useWindowId" import { Profiler } from "react" import useMetricCollector from "./util/useMetricCollector" +import { GasPricesStateProvider } from "./context/background/useGasPricesState" +import { ExchangeRatesStateProvider } from "./context/background/useExchangeRatesState" +import { ActivityListStateProvider } from "./context/background/useActivityListState" export const AppLoading = () => { return ( @@ -24,7 +27,17 @@ const App = () => { - {isPopup() ? : } + {isPopup() ? ( + + + + + + + + ) : ( + + )} ) : ( diff --git a/packages/ui/src/router/PopupRouter.tsx b/packages/ui/src/router/PopupRouter.tsx index d6f853c76..5b077f840 100644 --- a/packages/ui/src/router/PopupRouter.tsx +++ b/packages/ui/src/router/PopupRouter.tsx @@ -120,27 +120,21 @@ const PopupRouter = ({ resetKeys={[state.isAppUnlocked]} > {isOnboarded ? ( - - - - - - setShouldShowDialog(false) - } - title="No connection" - message="Please check your internet connection. Some features of the wallet will remain disabled while you’re offline." - open={shouldShowDialog} - onDone={() => - setShouldShowDialog(false) - } - /> - - - - - - + <> + + + setShouldShowDialog(false) + } + title="No connection" + message="Please check your internet connection. Some features of the wallet will remain disabled while you’re offline." + open={shouldShowDialog} + onDone={() => setShouldShowDialog(false)} + /> + + + + ) : ( )} From 5acc879fe4cc835bf45514658461d9cfe7cb5d7d Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 21 Dec 2022 11:48:36 -0300 Subject: [PATCH 010/110] tests: Add mock context --- .../background/useActivityListState.tsx | 9 +-- .../background/useExchangeRatesState.tsx | 8 +-- .../context/background/useGasPricesState.tsx | 2 +- .../ui/src/mock/MockActivityListState.tsx | 36 +++++++++++ packages/ui/src/mock/MockApp.tsx | 40 ++++++++++-- packages/ui/src/mock/MockBackgroundState.tsx | 27 -------- .../ui/src/mock/MockExchangeRatesState.tsx | 36 +++++++++++ packages/ui/src/mock/MockGasPricesState.tsx | 62 +++++++++++++++++++ 8 files changed, 178 insertions(+), 42 deletions(-) create mode 100644 packages/ui/src/mock/MockActivityListState.tsx create mode 100644 packages/ui/src/mock/MockExchangeRatesState.tsx create mode 100644 packages/ui/src/mock/MockGasPricesState.tsx diff --git a/packages/ui/src/context/background/useActivityListState.tsx b/packages/ui/src/context/background/useActivityListState.tsx index c15db3804..409e853e6 100644 --- a/packages/ui/src/context/background/useActivityListState.tsx +++ b/packages/ui/src/context/background/useActivityListState.tsx @@ -3,16 +3,13 @@ import { getActivityListState, subscribeActivityListState, } from "../commActions" -import { - ResponseGetActivityListState, - ResponseGetGasPricesState, -} from "@block-wallet/background/utils/types/communication" +import { ResponseGetActivityListState } from "@block-wallet/background/utils/types/communication" import useSubscription, { SubscriptionContext } from "./useStateSubscription" type ContextType = SubscriptionContext -const defaultState = { activityList: { pending: [], confirmed: [] } } -const ActivityListContext = createContext({ +export const defaultState = { activityList: { pending: [], confirmed: [] } } +export const ActivityListContext = createContext({ state: defaultState, isLoading: false, }) diff --git a/packages/ui/src/context/background/useExchangeRatesState.tsx b/packages/ui/src/context/background/useExchangeRatesState.tsx index bbdf53bbb..9e0b1a00e 100644 --- a/packages/ui/src/context/background/useExchangeRatesState.tsx +++ b/packages/ui/src/context/background/useExchangeRatesState.tsx @@ -9,7 +9,7 @@ import useSubscription, { SubscriptionContext } from "./useStateSubscription" type ExchangeRatesContextType = SubscriptionContext -const defualtState = { +export const defaultState = { exchangeRates: {}, networkNativeCurrency: { symbol: "ETH", @@ -19,9 +19,9 @@ const defualtState = { isRatesChangingAfterNetworkChange: false, } -const ExchangeRatesContext = createContext({ +export const ExchangeRatesContext = createContext({ isLoading: false, - state: defualtState, + state: defaultState, }) export const ExchangeRatesStateProvider: FC<{ children: ReactNode }> = ({ @@ -33,7 +33,7 @@ export const ExchangeRatesStateProvider: FC<{ children: ReactNode }> = ({ //state subcriber subscribeExchangeRatesState, //inital state - defualtState, + defaultState, { name: "Exchange rates" } ) return ( diff --git a/packages/ui/src/context/background/useGasPricesState.tsx b/packages/ui/src/context/background/useGasPricesState.tsx index 011afa92e..c996af284 100644 --- a/packages/ui/src/context/background/useGasPricesState.tsx +++ b/packages/ui/src/context/background/useGasPricesState.tsx @@ -8,7 +8,7 @@ type GasPricesContextType = SubscriptionContext const defaultState = { gasPriceData: {} } -const GasPricesContext = createContext({ +export const GasPricesContext = createContext({ state: defaultState, isLoading: true, }) diff --git a/packages/ui/src/mock/MockActivityListState.tsx b/packages/ui/src/mock/MockActivityListState.tsx new file mode 100644 index 000000000..308740da5 --- /dev/null +++ b/packages/ui/src/mock/MockActivityListState.tsx @@ -0,0 +1,36 @@ +import { FunctionComponent, useState } from "react" +import { SubscriptionContext } from "../context/background/useStateSubscription" +import { ResponseGetActivityListState } from "@block-wallet/background/utils/types/communication" +import { + ActivityListContext, + defaultState, +} from "../context/background/useActivityListState" + +export const initActivityListState: SubscriptionContext = + { + isLoading: false, + state: defaultState, + } + +const MockActivityListState: FunctionComponent<{ + assignActivityListState?: Partial + children: React.ReactNode | undefined +}> = ({ assignActivityListState = {}, children }) => { + const [state] = useState({ + ...initActivityListState.state, + ...assignActivityListState, + }) + + return ( + + {children} + + ) +} + +export default MockActivityListState diff --git a/packages/ui/src/mock/MockApp.tsx b/packages/ui/src/mock/MockApp.tsx index 3b05b2562..e4678dc17 100644 --- a/packages/ui/src/mock/MockApp.tsx +++ b/packages/ui/src/mock/MockApp.tsx @@ -4,6 +4,14 @@ import MockBackgroundState from "./MockBackgroundState" import PopupRouter from "../router/PopupRouter" import { BackgroundStateType } from "../context/background/backgroundContext" import TabRouter from "../router/TabRouter" +import MockGasPricesState from "./MockGasPricesState" +import MockActivityListState from "./MockActivityListState" +import MockExchangeRatesState from "./MockExchangeRatesState" +import { + ResponseGetActivityListState, + ResponseGetExchangeRatesState, + ResponseGetGasPricesState, +} from "@block-wallet/background/utils/types/communication" const MockTab: FunctionComponent<{ location: string @@ -32,7 +40,17 @@ const MockPopup: FunctionComponent<{ location: string state?: any // location state assignBlankState?: Partial -}> = ({ location, state, assignBlankState }) => { + assignGasPricesState?: Partial + assignActivityListState?: Partial + assignExchangeRatesState?: Partial +}> = ({ + location, + state, + assignBlankState, + assignGasPricesState, + assignActivityListState, + assignExchangeRatesState, +}) => { const HistoryInjector = () => { const history = useHistory() useEffect(() => { @@ -46,9 +64,23 @@ const MockPopup: FunctionComponent<{ style={{ width: 357, height: 600 }} > - - - + + + + + + + + +
) diff --git a/packages/ui/src/mock/MockBackgroundState.tsx b/packages/ui/src/mock/MockBackgroundState.tsx index 63da56edc..93510aa64 100644 --- a/packages/ui/src/mock/MockBackgroundState.tsx +++ b/packages/ui/src/mock/MockBackgroundState.tsx @@ -377,33 +377,6 @@ export const initBackgroundState: BackgroundStateType = { isImportingDeposits: false, importingErrors: [], isEIP1559Compatible: { 5: true }, - /* gasPriceData: { - 5: { - blockGasLimit: BigNumber.from(0), - estimatedBaseFee: BigNumber.from(0), - gasPricesLevels: { - slow: { - gasPrice: BigNumber.from(111111111110), - maxPriorityFeePerGas: BigNumber.from(0), - maxFeePerGas: BigNumber.from(0), - lastBaseFeePerGas: null, - }, - average: { - gasPrice: BigNumber.from(111111111110), - maxPriorityFeePerGas: BigNumber.from(0), - maxFeePerGas: BigNumber.from(0), - lastBaseFeePerGas: null, - }, - fast: { - gasPrice: BigNumber.from(111111111110), - maxPriorityFeePerGas: BigNumber.from(0), - maxFeePerGas: BigNumber.from(0), - lastBaseFeePerGas: null, - }, - }, - baseFee: BigNumber.from("0x02540be400"), - }, - }, */ showTestNetworks: true, showWelcomeMessage: false, showDefaultWalletPreferences: false, diff --git a/packages/ui/src/mock/MockExchangeRatesState.tsx b/packages/ui/src/mock/MockExchangeRatesState.tsx new file mode 100644 index 000000000..b1fa2172e --- /dev/null +++ b/packages/ui/src/mock/MockExchangeRatesState.tsx @@ -0,0 +1,36 @@ +import { FunctionComponent, useState } from "react" +import { SubscriptionContext } from "../context/background/useStateSubscription" +import { ResponseGetExchangeRatesState } from "@block-wallet/background/utils/types/communication" +import { + ExchangeRatesContext, + defaultState, +} from "../context/background/useExchangeRatesState" + +export const initExchangeRatesState: SubscriptionContext = + { + isLoading: false, + state: defaultState, + } + +const MockExchangeRatesState: FunctionComponent<{ + assignExchangeRatesState?: Partial + children: React.ReactNode | undefined +}> = ({ assignExchangeRatesState = {}, children }) => { + const [state] = useState({ + ...initExchangeRatesState.state, + ...assignExchangeRatesState, + }) + + return ( + + {children} + + ) +} + +export default MockExchangeRatesState diff --git a/packages/ui/src/mock/MockGasPricesState.tsx b/packages/ui/src/mock/MockGasPricesState.tsx new file mode 100644 index 000000000..aed08d3d5 --- /dev/null +++ b/packages/ui/src/mock/MockGasPricesState.tsx @@ -0,0 +1,62 @@ +import { FunctionComponent, useState } from "react" +import { BigNumber } from "@ethersproject/bignumber" +import { SubscriptionContext } from "../context/background/useStateSubscription" +import { ResponseGetGasPricesState } from "@block-wallet/background/utils/types/communication" +import { GasPricesContext } from "../context/background/useGasPricesState" + +export const initGasPricesState: SubscriptionContext = + { + isLoading: false, + state: { + gasPriceData: { + 5: { + blockGasLimit: BigNumber.from(0), + estimatedBaseFee: BigNumber.from(0), + gasPricesLevels: { + slow: { + gasPrice: BigNumber.from(111111111110), + maxPriorityFeePerGas: BigNumber.from(0), + maxFeePerGas: BigNumber.from(0), + lastBaseFeePerGas: null, + }, + average: { + gasPrice: BigNumber.from(111111111110), + maxPriorityFeePerGas: BigNumber.from(0), + maxFeePerGas: BigNumber.from(0), + lastBaseFeePerGas: null, + }, + fast: { + gasPrice: BigNumber.from(111111111110), + maxPriorityFeePerGas: BigNumber.from(0), + maxFeePerGas: BigNumber.from(0), + lastBaseFeePerGas: null, + }, + }, + baseFee: BigNumber.from("0x02540be400"), + }, + }, + }, + } + +const MockGasPricesState: FunctionComponent<{ + assignGasPricesState?: Partial + children: React.ReactNode | undefined +}> = ({ assignGasPricesState = {}, children }) => { + const [state] = useState({ + ...initGasPricesState.state, + ...assignGasPricesState, + }) + + return ( + + {children} + + ) +} + +export default MockGasPricesState From 7b5af9d68e020770385391da742ad0469c99f514 Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 21 Dec 2022 14:09:18 -0300 Subject: [PATCH 011/110] tests: fix test --- .../test/controllers/transactions/TransactionController.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/background/test/controllers/transactions/TransactionController.test.ts b/packages/background/test/controllers/transactions/TransactionController.test.ts index e78cac127..81b5cf93a 100644 --- a/packages/background/test/controllers/transactions/TransactionController.test.ts +++ b/packages/background/test/controllers/transactions/TransactionController.test.ts @@ -1525,6 +1525,7 @@ describe('Transactions Controller', () => { .transactionReceipt ).to.be.deep.equal({ status: 0, + logs: [], }); }); From c218a74b37bcdc1c55a8bd00af9827e139390d4b Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Wed, 21 Dec 2022 14:09:24 -0300 Subject: [PATCH 012/110] bump version --- packages/background/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/background/package.json b/packages/background/package.json index 985122d14..0888d81bb 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@block-wallet/background", - "version": "1.0.0", + "version": "1.1.0", "private": true, "dependencies": { "@block-wallet/chains-assets": "https://github.com/block-wallet/chains-assets#v0.0.24", From 84b0014795e82c76ed761b392c3a0d0122b77a48 Mon Sep 17 00:00:00 2001 From: Julian Ariel Martinez Date: Tue, 24 Jan 2023 13:38:00 -0300 Subject: [PATCH 013/110] lint: fixed lint. --- packages/ui/src/routes/dApp/TransactionConfirmPage.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx b/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx index f5c3fb986..fd9918ff8 100644 --- a/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx +++ b/packages/ui/src/routes/dApp/TransactionConfirmPage.tsx @@ -113,8 +113,14 @@ const TransactionConfirm: React.FC<{ transactionCount: number }> = ({ transactionId, transactionCount }) => { //Hooks - const { accounts, nativeCurrency, localeInfo, selectedAddress, settings, defaultGasOption } = - useBlankState()! + const { + accounts, + nativeCurrency, + localeInfo, + selectedAddress, + settings, + defaultGasOption, + } = useBlankState()! const { state: { exchangeRates, networkNativeCurrency }, } = useExchangeRatesState() From e5027eef03618c514ac157e7f4c73626cdda2cb6 Mon Sep 17 00:00:00 2001 From: Julian Ariel Martinez Date: Wed, 25 Jan 2023 11:54:58 -0300 Subject: [PATCH 014/110] fix: fixed tests, added missing migration import. --- .../src/infrastructure/stores/migrator/migrations/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts index 5f14e4987..1e6129dcc 100644 --- a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts +++ b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts @@ -57,6 +57,7 @@ import migration55 from './migration-55'; import migration56 from './migration-56'; import migration57 from './migration-57'; import migration58 from './migration-58'; +import migration59 from './migration-59'; const migrations: IMigration[] = [ migration01, @@ -117,5 +118,6 @@ const migrations: IMigration[] = [ migration56, migration57, migration58, + migration59 ]; export default (): IMigration[] => migrations; From c95805cb3ff5a795db02c4976256df27c7c13a1f Mon Sep 17 00:00:00 2001 From: Facundo Pezzola Date: Mon, 27 Feb 2023 12:45:37 -0300 Subject: [PATCH 015/110] feat: add migration and improve code --- packages/background/package.json | 2 +- .../migrator/migrations/migration-61.ts | 104 ++++++++++++++++++ .../src/components/account/AccountDisplay.tsx | 1 - .../assets/ActivityAllowancesView.tsx | 7 +- .../src/components/home/HomeBalancePanel.tsx | 34 ++++-- 5 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts diff --git a/packages/background/package.json b/packages/background/package.json index 18206845e..5a5323122 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@block-wallet/background", - "version": "1.1.0", + "version": "2.0.0", "private": true, "dependencies": { "@block-wallet/chains-assets": "https://github.com/block-wallet/chains-assets#v0.0.27", diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts b/packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts new file mode 100644 index 000000000..7093d5098 --- /dev/null +++ b/packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts @@ -0,0 +1,104 @@ +import { BridgeControllerState } from '@block-wallet/background/controllers/BridgeController'; +import { pruneTransaction } from '../../../../controllers/transactions/utils/utils'; +import { TransactionWatcherControllerState } from '../../../../controllers/TransactionWatcherController'; +import { BlankAppState } from '@block-wallet/background/utils/constants/initialState'; +import { IMigration } from '../IMigration'; +import { WatchedTransactionType } from '../../../../controllers/transactions/utils/types'; + +const pruneBridgeTxs = ( + txs: BridgeControllerState['bridgeReceivingTransactions'] +): BridgeControllerState['bridgeReceivingTransactions'] => { + const newTxs = { ...txs }; + for (const chainId in newTxs) { + const chainTxs = newTxs[chainId]; + if (chainTxs) { + for (const addr in chainTxs) { + const addrTxs = chainTxs[addr]; + if (addrTxs) { + newTxs[chainId][addr] = Object.entries(addrTxs).reduce( + (acc, [txHash, tx]) => { + return { + ...acc, + [txHash]: pruneTransaction(tx), + }; + }, + addrTxs + ); + } + } + } + } + return newTxs; +}; + +const pruneWatchedTxs = ( + txs: TransactionWatcherControllerState['transactions'] +): TransactionWatcherControllerState['transactions'] => { + const newTxs = { ...txs }; + for (const chainId in newTxs) { + const chainTxs = newTxs[chainId]; + if (chainTxs) { + for (const addr in chainTxs) { + const addrTxs = chainTxs[addr]; + if (addrTxs) { + for (const type in addrTxs) { + const typeTxs = addrTxs[type as WatchedTransactionType]; + if (typeTxs && typeTxs.transactions) { + newTxs[chainId][addr][ + type as WatchedTransactionType + ].transactions = Object.entries( + typeTxs.transactions + ).reduce((acc, [txHash, tx]) => { + return { + ...acc, + [txHash]: pruneTransaction(tx), + }; + }, typeTxs.transactions); + } + } + } + } + } + } + return newTxs; +}; + +/** + * This migration fixes zksync block explorer + */ +export default { + migrate: async (persistedState: BlankAppState) => { + const { transactions } = persistedState.TransactionController; + const { bridgeReceivingTransactions } = persistedState.BridgeController; + const { transactions: watchedTx } = + persistedState.TransactionWatcherControllerState; + + const newTxsState = transactions + ? transactions.map(pruneTransaction) + : transactions; + + const newBridgeReceivingTxState = bridgeReceivingTransactions + ? pruneBridgeTxs(bridgeReceivingTransactions) + : bridgeReceivingTransactions; + + const newWatchedTxsState = watchedTx + ? pruneWatchedTxs(watchedTx) + : watchedTx; + + return { + ...persistedState, + TransactionController: { + ...persistedState.TransactionController, + transactions: newTxsState, + }, + BridgeController: { + ...persistedState.BridgeController, + bridgeReceivingTransactions: newBridgeReceivingTxState, + }, + TransactionWatcherControllerState: { + transactions: newWatchedTxsState, + }, + }; + }, + version: '2.0.0', +} as IMigration; diff --git a/packages/ui/src/components/account/AccountDisplay.tsx b/packages/ui/src/components/account/AccountDisplay.tsx index 3c0d69f8e..cc4248a8b 100644 --- a/packages/ui/src/components/account/AccountDisplay.tsx +++ b/packages/ui/src/components/account/AccountDisplay.tsx @@ -27,7 +27,6 @@ import Tag from "../ui/Tag" import { isInternalAccount } from "../../util/account" import useCopyToClipboard from "../../util/hooks/useCopyToClipboard" import Dropdown from "../ui/Dropdown/Dropdown" -import { toChecksumAddress } from "ethereumjs-util" import { useAddressWithChainIdChecksum } from "../../util/hooks/useSelectedAddressWithChainIdChecksum" interface ConfirmDialogState { diff --git a/packages/ui/src/components/assets/ActivityAllowancesView.tsx b/packages/ui/src/components/assets/ActivityAllowancesView.tsx index a499b7d9a..02c1d1117 100644 --- a/packages/ui/src/components/assets/ActivityAllowancesView.tsx +++ b/packages/ui/src/components/assets/ActivityAllowancesView.tsx @@ -1,4 +1,4 @@ -import { useState } from "react" +import { FC, useState } from "react" import { classnames } from "../../styles" import useAccountAllowances from "../../context/hooks/useAccountAllowances" @@ -25,14 +25,15 @@ const tabs = [ }, ] -const ActivityAllowancesView = () => { +const ActivityAllowancesView: FC<{ tokenAddress: string }> = ({ + tokenAddress, +}) => { const history = useOnMountHistory() const [tab, setTab] = useState( history.location.state.tab === TabLabels.ALLOWANCES ? tabs[1] : tabs[0] ) const TabComponent = tab.component - const tokenAddress: string = history.location.state.address const allowances = useAccountAllowances( AllowancesFilters.TOKEN, diff --git a/packages/ui/src/components/home/HomeBalancePanel.tsx b/packages/ui/src/components/home/HomeBalancePanel.tsx index dfe3f4bb1..debd0b66e 100644 --- a/packages/ui/src/components/home/HomeBalancePanel.tsx +++ b/packages/ui/src/components/home/HomeBalancePanel.tsx @@ -11,6 +11,7 @@ import AnimatedIcon, { AnimatedIconName } from "../AnimatedIcon" import DoubleArrowHoverAnimation from "../icons/DoubleArrowHoverAnimation" import ArrowHoverAnimation from "../icons/ArrowHoverAnimation" import useCurrencyFromatter from "../../util/hooks/useCurrencyFormatter" +import Icon, { IconName } from "../ui/Icon" const LoadingBlueIcon = () => { return ( @@ -32,6 +33,8 @@ const HomeBalancePanel = () => { const { nativeCurrency, isSendEnabled, isSwapEnabled, isBridgeEnabled } = useSelectedNetwork() + const disabledActions = !isSendEnabled || !isUserNetworkOnline + return (
@@ -74,13 +77,13 @@ const HomeBalancePanel = () => { draggable={false} className={classnames( "flex flex-col items-center space-y-2 group", - !isSendEnabled && "pointer-events-none" + disabledActions && "pointer-events-none" )} >
{ draggable={false} className={classnames( "flex flex-col items-center space-y-2 group", - (!isSendEnabled || !isUserNetworkOnline) && - "pointer-events-none" + disabledActions && "pointer-events-none" )} >
{ draggable={false} className={classnames( "flex flex-col items-center space-y-2 group", - (!isBridgeEnabled || !isUserNetworkOnline) && - "pointer-events-none" + disabledActions && "pointer-events-none" )} >
{ {isNetworkChanging ? ( ) : ( - + <> + {disabledActions ? ( + + ) : ( + + )} + )}
Bridge From c167ad48fc30d91371e01e7dacfaf70374a8775f Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Tue, 28 Feb 2023 01:23:36 +0200 Subject: [PATCH 016/110] feat: new brand stylesheet --- packages/ui/src/assets/images/icons/about.svg | 13 +- .../src/assets/images/icons/account_add.svg | 12 +- .../ui/src/assets/images/icons/accounts.svg | 13 +- packages/ui/src/assets/images/icons/bell.svg | 16 ++- .../images/icons/bluecircle_skeleton.json | 136 +++++++++++++++++- packages/ui/src/assets/images/icons/book.svg | 17 ++- .../assets/images/icons/connected_sites.svg | 11 +- .../ui/src/assets/images/icons/export.svg | 13 +- packages/ui/src/assets/images/icons/gas.svg | 10 +- packages/ui/src/assets/images/icons/news.svg | 13 +- .../src/assets/images/icons/open_external.svg | 13 +- packages/ui/src/assets/images/icons/pin.svg | 16 +-- .../ui/src/assets/images/icons/shield.svg | 5 +- .../ui/src/assets/images/icons/spanner.svg | 17 ++- packages/ui/src/assets/images/icons/usb.svg | 12 +- packages/ui/src/assets/images/icons/world.svg | 14 +- .../ui/src/components/ActivityAssetsView.tsx | 6 +- packages/ui/src/components/FeeDetails.tsx | 2 +- packages/ui/src/components/LogoHeader.tsx | 2 +- .../components/account/AccountDisplayMenu.tsx | 6 +- .../src/components/account/AccountFilters.tsx | 2 +- .../ui/src/components/account/AccountMenu.tsx | 2 +- .../components/account/AccountSearchBar.tsx | 2 +- .../account/AccountSearchResults.tsx | 2 +- .../src/components/account/AccountSelect.tsx | 2 +- .../components/allowances/AllowanceItem.tsx | 2 +- .../allowances/AllowancesFilterButton.tsx | 4 +- .../allowances/AllowancesRefetchButton.tsx | 2 +- .../assets/ActivityAllowancesView.tsx | 4 +- .../components/assets/AssetDetailsPage.tsx | 4 +- .../ui/src/components/assets/AssetList.tsx | 2 +- .../src/components/bridge/BridgeDetails.tsx | 4 +- .../bridge/BridgeDetailsSummary.tsx | 2 +- .../components/button/RoundedIconButton.tsx | 2 +- .../ui/src/components/button/ToggleButton.tsx | 2 +- .../button/ViewOnExplorerButtons.tsx | 4 +- .../ui/src/components/chain/ChainDisplay.tsx | 2 +- .../components/chain/ChainFiltersButton.tsx | 4 +- .../components/chain/NetworkDisplayBadge.tsx | 2 +- .../src/components/dApp/DAppPopupHeader.tsx | 2 +- .../src/components/dialog/CheckboxDialog.tsx | 2 +- .../src/components/dialog/ConfirmDialog.tsx | 4 +- .../src/components/dialog/DetailsDialog.tsx | 2 +- .../dialog/HardwareDeviceNotLinkedDialog.tsx | 2 +- .../components/dialog/ProviderDownDialog.tsx | 2 +- .../src/components/dialog/SuccessDialog.tsx | 2 +- .../ui/src/components/gas/GasPricesInfo.tsx | 6 +- .../ui/src/components/icons/ArrowUpDown.tsx | 2 +- .../src/components/icons/EmptyDrawerIcon.tsx | 41 ++++-- .../ui/src/components/icons/ImportIcon.tsx | 24 ++-- packages/ui/src/components/icons/UsbIcon.tsx | 52 +++---- .../ui/src/components/icons/WalletIcon.tsx | 97 +++++++++---- .../src/components/info/ReleaseNotesInfo.tsx | 2 +- .../src/components/input/DropDownSelector.tsx | 6 +- .../src/components/input/HorizontalSelect.tsx | 4 +- .../ui/src/components/input/NetworkSelect.tsx | 4 +- packages/ui/src/components/input/Select.tsx | 2 +- .../ui/src/components/input/TextInput.tsx | 4 +- .../src/components/input/VerticalSelect.tsx | 6 +- .../src/components/loading/LoadingOverlay.tsx | 2 +- .../components/network/NetworkSelector.tsx | 2 +- .../components/networks/NetworkDisplay.tsx | 4 +- .../src/components/phishing/AntiPhishing.tsx | 2 +- .../ui/src/components/popup/PopupHeader.tsx | 6 +- .../ui/src/components/setup/SeedImport.tsx | 4 +- .../ui/src/components/spinner/Spinner.tsx | 2 +- .../ui/src/components/spinner/ThinSpinner.tsx | 4 +- .../components/swaps/PriceImpactDialog.tsx | 8 +- .../src/components/token/AddTokenListView.tsx | 2 +- .../components/token/AddTokenManualView.tsx | 6 +- .../ui/src/components/token/TokenDisplay.tsx | 6 +- .../src/components/token/TokenSearchView.tsx | 2 +- .../ui/src/components/token/TokenSummary.tsx | 2 +- .../transactions/AdvancedSettings.tsx | 6 +- .../transactions/AllowanceInput.tsx | 14 +- .../BridgeNotFoundQuoteDetails.tsx | 6 +- .../transactions/GasPriceComponent.tsx | 16 +-- .../transactions/GasPriceSelector.tsx | 16 +-- .../ui/src/components/transactions/Price.tsx | 2 +- .../transactions/TransactionDetails.tsx | 4 +- .../TransactionDetailsAdvanced.tsx | 2 +- .../transactions/TransactionDetailsBasic.tsx | 2 +- .../transactions/TransactionItem.tsx | 7 +- packages/ui/src/components/ui/Badge.tsx | 2 +- .../components/ui/Dropdown/DropdownMenu.tsx | 2 +- .../ui/Pagination/PaginationControls.tsx | 2 +- packages/ui/src/components/ui/Typography.tsx | 2 +- packages/ui/src/routes/PopupPage.tsx | 14 +- packages/ui/src/routes/ReceivePage.tsx | 2 +- packages/ui/src/routes/UnlockPage.tsx | 2 +- .../ui/src/routes/bridge/BridgeSetupPage.tsx | 6 +- .../ui/src/routes/connect/ConnectPage.tsx | 2 +- .../ui/src/routes/dApp/AddEthereumChain.tsx | 12 +- packages/ui/src/routes/dApp/ApproveAsset.tsx | 6 +- packages/ui/src/routes/dApp/ApproveNFT.tsx | 2 +- .../src/routes/dApp/SwitchEthereumChain.tsx | 2 +- packages/ui/src/routes/dApp/WatchAsset.tsx | 2 +- .../routes/hardware-wallet/AccountsPage.tsx | 6 +- .../ConnectDeviceStepsLayout.tsx | 2 +- .../routes/hardware-wallet/RemoveDevice.tsx | 8 +- .../routes/hardware-wallet/VendorsPage.tsx | 10 +- .../src/routes/networks/NetworkFormPage.tsx | 2 +- .../preferences/DefaultGasPreferencesPage.tsx | 4 +- .../ui/src/routes/send/SendConfirmPage.tsx | 4 +- .../src/routes/settings/AddressBookPage.tsx | 2 +- .../settings/ConnectedSiteAccountsPage.tsx | 4 +- .../routes/settings/ConnectedSitesPage.tsx | 7 +- .../ui/src/routes/setup/BackupConfirmPage.tsx | 2 +- packages/ui/src/routes/swap/SwapPage.tsx | 6 +- .../ui/src/routes/transaction/ApprovePage.tsx | 4 +- packages/ui/src/stories/Button.stories.tsx | 4 +- packages/ui/src/styles/classes.ts | 24 ++-- packages/ui/tailwind.config.js | 21 +++ 113 files changed, 628 insertions(+), 330 deletions(-) diff --git a/packages/ui/src/assets/images/icons/about.svg b/packages/ui/src/assets/images/icons/about.svg index 8dd7332c4..75aebdefb 100644 --- a/packages/ui/src/assets/images/icons/about.svg +++ b/packages/ui/src/assets/images/icons/about.svg @@ -1,5 +1,12 @@ - - - + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/account_add.svg b/packages/ui/src/assets/images/icons/account_add.svg index a3512f381..9692a5189 100644 --- a/packages/ui/src/assets/images/icons/account_add.svg +++ b/packages/ui/src/assets/images/icons/account_add.svg @@ -1,12 +1,12 @@ - - - - - + + + + + - + diff --git a/packages/ui/src/assets/images/icons/accounts.svg b/packages/ui/src/assets/images/icons/accounts.svg index 5a18ded1e..39201afa7 100644 --- a/packages/ui/src/assets/images/icons/accounts.svg +++ b/packages/ui/src/assets/images/icons/accounts.svg @@ -1,13 +1,12 @@ - - - - - - + + + + + - + diff --git a/packages/ui/src/assets/images/icons/bell.svg b/packages/ui/src/assets/images/icons/bell.svg index 5c9c3de7b..ab7d96081 100644 --- a/packages/ui/src/assets/images/icons/bell.svg +++ b/packages/ui/src/assets/images/icons/bell.svg @@ -1,7 +1,11 @@ - - - - - - + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/bluecircle_skeleton.json b/packages/ui/src/assets/images/icons/bluecircle_skeleton.json index 7e2c1b348..0c9cf663c 100644 --- a/packages/ui/src/assets/images/icons/bluecircle_skeleton.json +++ b/packages/ui/src/assets/images/icons/bluecircle_skeleton.json @@ -1 +1,135 @@ -{"v":"5.7.13","fr":60,"ip":0,"op":120,"w":14,"h":14,"nm":"Bluecircle1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Ellipse 288","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-180,"ix":10},"p":{"a":0,"k":[7,7,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[-107,-107,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[13.027,13.027],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":5,"k":{"a":0,"k":[0,0.504,0.702,1,0.242,0.621,0.772,1,0.484,0.738,0.842,1,0.742,0.622,0.772,1,1,0.506,0.702,1],"ix":9}},"s":{"a":1,"k":[{"i":{"x":0.348,"y":1},"o":{"x":0.531,"y":0},"t":0,"s":[-10.451,0.598],"to":[0,0],"ti":[0,0]},{"i":{"x":0.348,"y":1},"o":{"x":0.531,"y":0},"t":60,"s":[-1.013,0.473],"to":[0,0],"ti":[0,0]},{"t":120,"s":[-10.451,0.598]}],"ix":5},"e":{"a":1,"k":[{"i":{"x":0.348,"y":1},"o":{"x":0.531,"y":0},"t":0,"s":[0.451,0.624],"to":[0,0],"ti":[0,0]},{"i":{"x":0.348,"y":1},"o":{"x":0.531,"y":0},"t":60,"s":[9.701,0.436],"to":[0,0],"ti":[0,0]},{"t":120,"s":[0.451,0.624]}],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 288","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file +{ + "v": "5.7.13", + "fr": 60, + "ip": 0, + "op": 120, + "w": 14, + "h": 14, + "nm": "Bluecircle1", + "ddd": 0, + "assets": [], + "layers": [ + { + "ddd": 0, + "ind": 1, + "ty": 4, + "nm": "Ellipse 288", + "sr": 1, + "ks": { + "o": { "a": 0, "k": 100, "ix": 11 }, + "r": { "a": 0, "k": -180, "ix": 10 }, + "p": { "a": 0, "k": [7, 7, 0], "ix": 2, "l": 2 }, + "a": { "a": 0, "k": [0, 0, 0], "ix": 1, "l": 2 }, + "s": { "a": 0, "k": [-107, -107, 100], "ix": 6, "l": 2 } + }, + "ao": 0, + "shapes": [ + { + "ty": "gr", + "it": [ + { + "d": 1, + "ty": "el", + "s": { "a": 0, "k": [13.027, 13.027], "ix": 2 }, + "p": { "a": 0, "k": [0, 0], "ix": 3 }, + "nm": "Ellipse Path 1", + "mn": "ADBE Vector Shape - Ellipse", + "hd": false + }, + { + "ty": "gf", + "o": { "a": 0, "k": 100, "ix": 10 }, + "r": 1, + "bm": 0, + "g": { + "p": 5, + "k": { + "a": 0, + "k": [ + 0, 0.504, 0.702, 1, 0.242, 0.621, 0.772, + 1, 0.484, 0.738, 0.842, 1, 0.742, 0.622, + 0.772, 1, 1, 0.506, 0.702, 1 + ], + "ix": 9 + } + }, + "s": { + "a": 1, + "k": [ + { + "i": { "x": 0.348, "y": 1 }, + "o": { "x": 0.531, "y": 0 }, + "t": 0, + "s": [-10.451, 0.598], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.348, "y": 1 }, + "o": { "x": 0.531, "y": 0 }, + "t": 60, + "s": [-1.013, 0.473], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 120, "s": [-10.451, 0.598] } + ], + "ix": 5 + }, + "e": { + "a": 1, + "k": [ + { + "i": { "x": 0.348, "y": 1 }, + "o": { "x": 0.531, "y": 0 }, + "t": 0, + "s": [0.451, 0.624], + "to": [0, 0], + "ti": [0, 0] + }, + { + "i": { "x": 0.348, "y": 1 }, + "o": { "x": 0.531, "y": 0 }, + "t": 60, + "s": [9.701, 0.436], + "to": [0, 0], + "ti": [0, 0] + }, + { "t": 120, "s": [0.451, 0.624] } + ], + "ix": 6 + }, + "t": 1, + "nm": "Gradient Fill 1", + "mn": "ADBE Vector Graphic - G-Fill", + "hd": false + }, + { + "ty": "tr", + "p": { "a": 0, "k": [0, 0], "ix": 2 }, + "a": { "a": 0, "k": [0, 0], "ix": 1 }, + "s": { "a": 0, "k": [100, 100], "ix": 3 }, + "r": { "a": 0, "k": 0, "ix": 6 }, + "o": { "a": 0, "k": 100, "ix": 7 }, + "sk": { "a": 0, "k": 0, "ix": 4 }, + "sa": { "a": 0, "k": 0, "ix": 5 }, + "nm": "Transform" + } + ], + "nm": "Ellipse 288", + "np": 2, + "cix": 2, + "bm": 0, + "ix": 1, + "mn": "ADBE Vector Group", + "hd": false + } + ], + "ip": 0, + "op": 600, + "st": 0, + "bm": 0 + } + ], + "markers": [] +} diff --git a/packages/ui/src/assets/images/icons/book.svg b/packages/ui/src/assets/images/icons/book.svg index d62469e8e..89e5f4613 100644 --- a/packages/ui/src/assets/images/icons/book.svg +++ b/packages/ui/src/assets/images/icons/book.svg @@ -1,7 +1,14 @@ - - - - - + + + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/connected_sites.svg b/packages/ui/src/assets/images/icons/connected_sites.svg index f91656c54..0b8ca36b5 100644 --- a/packages/ui/src/assets/images/icons/connected_sites.svg +++ b/packages/ui/src/assets/images/icons/connected_sites.svg @@ -1,4 +1,11 @@ - - + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/export.svg b/packages/ui/src/assets/images/icons/export.svg index 1839fab8c..18258713c 100644 --- a/packages/ui/src/assets/images/icons/export.svg +++ b/packages/ui/src/assets/images/icons/export.svg @@ -1,5 +1,12 @@ - - - + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/gas.svg b/packages/ui/src/assets/images/icons/gas.svg index 0f786c2f3..9c5438ef6 100644 --- a/packages/ui/src/assets/images/icons/gas.svg +++ b/packages/ui/src/assets/images/icons/gas.svg @@ -1,11 +1,11 @@ - - - - + + + + - + diff --git a/packages/ui/src/assets/images/icons/news.svg b/packages/ui/src/assets/images/icons/news.svg index 2be53e13c..eea7eccc6 100644 --- a/packages/ui/src/assets/images/icons/news.svg +++ b/packages/ui/src/assets/images/icons/news.svg @@ -1 +1,12 @@ - \ No newline at end of file + + + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/open_external.svg b/packages/ui/src/assets/images/icons/open_external.svg index 82d9d8d38..e2a66227f 100644 --- a/packages/ui/src/assets/images/icons/open_external.svg +++ b/packages/ui/src/assets/images/icons/open_external.svg @@ -1,5 +1,12 @@ - - - + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/pin.svg b/packages/ui/src/assets/images/icons/pin.svg index 2ee05a64f..77430a8e4 100644 --- a/packages/ui/src/assets/images/icons/pin.svg +++ b/packages/ui/src/assets/images/icons/pin.svg @@ -1,12 +1,4 @@ - - - - - - - - - - \ No newline at end of file + + + + diff --git a/packages/ui/src/assets/images/icons/shield.svg b/packages/ui/src/assets/images/icons/shield.svg index 17d56fa44..e52104725 100644 --- a/packages/ui/src/assets/images/icons/shield.svg +++ b/packages/ui/src/assets/images/icons/shield.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/packages/ui/src/assets/images/icons/spanner.svg b/packages/ui/src/assets/images/icons/spanner.svg index 6034adb98..332994a33 100644 --- a/packages/ui/src/assets/images/icons/spanner.svg +++ b/packages/ui/src/assets/images/icons/spanner.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + diff --git a/packages/ui/src/assets/images/icons/usb.svg b/packages/ui/src/assets/images/icons/usb.svg index 83c6f7a95..d19b7a64b 100644 --- a/packages/ui/src/assets/images/icons/usb.svg +++ b/packages/ui/src/assets/images/icons/usb.svg @@ -1,8 +1,8 @@ - - - - - - + + + + + + diff --git a/packages/ui/src/assets/images/icons/world.svg b/packages/ui/src/assets/images/icons/world.svg index 0dfce2838..bb3de6ffc 100644 --- a/packages/ui/src/assets/images/icons/world.svg +++ b/packages/ui/src/assets/images/icons/world.svg @@ -1 +1,13 @@ - \ No newline at end of file + + + + + + + + + + + + + diff --git a/packages/ui/src/components/ActivityAssetsView.tsx b/packages/ui/src/components/ActivityAssetsView.tsx index 24426d188..003cf626b 100644 --- a/packages/ui/src/components/ActivityAssetsView.tsx +++ b/packages/ui/src/components/ActivityAssetsView.tsx @@ -37,10 +37,10 @@ const ActivityAssetsView: FunctionComponent<{ initialTab: PopupTabs }> = ({ display={(t) => t.label} disableStyles optionClassName={(value) => - `flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-300 ${ + `flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-blue-default ${ tab === value - ? "border-primary-300 border-b-2 text-primary-300 font-bold" - : "border-gray-200 text-gray-500 border-b hover:text-primary-300 hover:font-medium" + ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" + : "border-gray-200 text-gray-500 border-b hover:text-primary-blue-default hover:font-medium" }` } containerClassName="flex flex-row -ml-6" diff --git a/packages/ui/src/components/FeeDetails.tsx b/packages/ui/src/components/FeeDetails.tsx index d0b02944e..f86029328 100644 --- a/packages/ui/src/components/FeeDetails.tsx +++ b/packages/ui/src/components/FeeDetails.tsx @@ -20,7 +20,7 @@ const FeeDetails: FC = ({ summary, details }) => { > )} diff --git a/packages/ui/src/components/LogoHeader.tsx b/packages/ui/src/components/LogoHeader.tsx index 7f4b6a512..f30db7bb4 100644 --- a/packages/ui/src/components/LogoHeader.tsx +++ b/packages/ui/src/components/LogoHeader.tsx @@ -1,7 +1,7 @@ import logo from "../assets/images/logo.svg" const LogoHeader = () => ( -
+
logo BlockWallet
diff --git a/packages/ui/src/components/account/AccountDisplayMenu.tsx b/packages/ui/src/components/account/AccountDisplayMenu.tsx index 7083efc75..583f15f2f 100644 --- a/packages/ui/src/components/account/AccountDisplayMenu.tsx +++ b/packages/ui/src/components/account/AccountDisplayMenu.tsx @@ -34,7 +34,7 @@ const RemoveOption: React.FC = ({ onClick }) => { const EditOption: React.FC = ({ onClick }) => { return (
@@ -49,7 +49,7 @@ const HideAccountOption: React.FC = ({ onClick, disabled }) => { return (
= ({ onClick, disabled }) => { return (
= ({ selected={selectedFilters.includes( value )} - className="p-2 font-normal text-black" + className="p-2 font-normal text-primary-black-default" > {label} diff --git a/packages/ui/src/components/account/AccountMenu.tsx b/packages/ui/src/components/account/AccountMenu.tsx index be67e95d1..affabcfad 100644 --- a/packages/ui/src/components/account/AccountMenu.tsx +++ b/packages/ui/src/components/account/AccountMenu.tsx @@ -130,7 +130,7 @@ const AccountMenu = () => { }, }) }} - className="cursor-pointer p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className="cursor-pointer p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" > Edit
, diff --git a/packages/ui/src/components/account/AccountSearchBar.tsx b/packages/ui/src/components/account/AccountSearchBar.tsx index d7a1a12ba..3fa116c63 100644 --- a/packages/ui/src/components/account/AccountSearchBar.tsx +++ b/packages/ui/src/components/account/AccountSearchBar.tsx @@ -82,7 +82,7 @@ const AccountSearchBar: FunctionComponent<{ />
+
No results found.
)} diff --git a/packages/ui/src/components/account/AccountSelect.tsx b/packages/ui/src/components/account/AccountSelect.tsx index 3ccaf8e3b..0c51a6868 100644 --- a/packages/ui/src/components/account/AccountSelect.tsx +++ b/packages/ui/src/components/account/AccountSelect.tsx @@ -220,7 +220,7 @@ const AccountSelect: FunctionComponent = ({ }, }) }} - className="cursor-pointer p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className="cursor-pointer p-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
, diff --git a/packages/ui/src/components/allowances/AllowanceItem.tsx b/packages/ui/src/components/allowances/AllowanceItem.tsx index 6899416e2..4131fead0 100644 --- a/packages/ui/src/components/allowances/AllowanceItem.tsx +++ b/packages/ui/src/components/allowances/AllowanceItem.tsx @@ -1,5 +1,5 @@ import { BigNumber } from "@ethersproject/bignumber" -import { useMemo, useState } from "react" +import { useState } from "react" import { formatUnits } from "@ethersproject/units" import { TokenAllowance } from "@block-wallet/background/controllers/AccountTrackerController" import { Classes, classnames } from "../../styles" diff --git a/packages/ui/src/components/allowances/AllowancesFilterButton.tsx b/packages/ui/src/components/allowances/AllowancesFilterButton.tsx index 9e7bdf7c8..a9ecf2d40 100644 --- a/packages/ui/src/components/allowances/AllowancesFilterButton.tsx +++ b/packages/ui/src/components/allowances/AllowancesFilterButton.tsx @@ -21,7 +21,7 @@ const AllowancesFilterButton = ({ onChangeFilter: (newFilter: AllowancesFilters) => void }) => { return ( -
+
{ onChangeFilter(selected) @@ -40,7 +40,7 @@ const AllowancesFilterButton = ({ {label} diff --git a/packages/ui/src/components/allowances/AllowancesRefetchButton.tsx b/packages/ui/src/components/allowances/AllowancesRefetchButton.tsx index 1b61440f6..971e798dc 100644 --- a/packages/ui/src/components/allowances/AllowancesRefetchButton.tsx +++ b/packages/ui/src/components/allowances/AllowancesRefetchButton.tsx @@ -5,7 +5,7 @@ import OutlinedButton from "../ui/OutlinedButton" const AllowancesFilterButton = ({ onClick }: { onClick: () => void }) => { return (
diff --git a/packages/ui/src/components/assets/ActivityAllowancesView.tsx b/packages/ui/src/components/assets/ActivityAllowancesView.tsx index a499b7d9a..cdf080ce5 100644 --- a/packages/ui/src/components/assets/ActivityAllowancesView.tsx +++ b/packages/ui/src/components/assets/ActivityAllowancesView.tsx @@ -57,9 +57,9 @@ const ActivityAllowancesView = () => { disableStyles optionClassName={(value) => classnames( - "flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-300", + "flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-primary-blue-default", tab === value - ? "border-primary-300 border-b-2 text-primary-300 font-bold" + ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" : "border-gray-200 text-gray-500 border-b hover:font-medium" ) } diff --git a/packages/ui/src/components/assets/AssetDetailsPage.tsx b/packages/ui/src/components/assets/AssetDetailsPage.tsx index b10b8acc7..6fa5432f2 100644 --- a/packages/ui/src/components/assets/AssetDetailsPage.tsx +++ b/packages/ui/src/components/assets/AssetDetailsPage.tsx @@ -233,7 +233,7 @@ const AssetDetailsPage = () => { "w-8 h-8 overflow-hidden transition duration-300 rounded-full group-hover:opacity-75", disabledActions ? "bg-gray-300" - : "bg-primary-300" + : "bg-primary-blue-default" )} style={{ transform: "scaleY(-1)" }} > @@ -265,7 +265,7 @@ const AssetDetailsPage = () => { "w-8 h-8 overflow-hidden transition duration-300 rounded-full group-hover:opacity-75", disabledActions ? "bg-gray-300" - : "bg-primary-300" + : "bg-primary-blue-default" )} style={{ transform: "scaleY(-1)" }} > diff --git a/packages/ui/src/components/assets/AssetList.tsx b/packages/ui/src/components/assets/AssetList.tsx index 32b5318fd..787de4746 100644 --- a/packages/ui/src/components/assets/AssetList.tsx +++ b/packages/ui/src/components/assets/AssetList.tsx @@ -51,7 +51,7 @@ const AssetList: FC<{ })} {searchValue && assets.length === 0 && (
-

+

The asset couldn’t be found, try adding it manually.

diff --git a/packages/ui/src/components/bridge/BridgeDetails.tsx b/packages/ui/src/components/bridge/BridgeDetails.tsx index 4d922580c..4f0a775bd 100644 --- a/packages/ui/src/components/bridge/BridgeDetails.tsx +++ b/packages/ui/src/components/bridge/BridgeDetails.tsx @@ -72,7 +72,7 @@ const BridgeDetails: FC<{
@@ -108,7 +108,7 @@ const BridgeDetails: FC<{ `flex-1 flex flex-row items-center justify-center p-3 text-sm group ${ selectedTab.label === value.label - ? "border-primary-300 border-b-2 text-primary-300 font-bold" + ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" : "border-gray-200 text-gray-500 border-b" }`, value.disabled && "cursor-default" diff --git a/packages/ui/src/components/bridge/BridgeDetailsSummary.tsx b/packages/ui/src/components/bridge/BridgeDetailsSummary.tsx index 4b1802a13..9074dbf32 100644 --- a/packages/ui/src/components/bridge/BridgeDetailsSummary.tsx +++ b/packages/ui/src/components/bridge/BridgeDetailsSummary.tsx @@ -39,7 +39,7 @@ const Explorer = ({ className="flex flex-row items-center space-x-1" title={explorerName} > - + {explorerName} Open icon diff --git a/packages/ui/src/components/button/RoundedIconButton.tsx b/packages/ui/src/components/button/RoundedIconButton.tsx index 31cc31c01..2295a79a9 100644 --- a/packages/ui/src/components/button/RoundedIconButton.tsx +++ b/packages/ui/src/components/button/RoundedIconButton.tsx @@ -17,7 +17,7 @@ const RoundedIconButton: FC = ({
diff --git a/packages/ui/src/components/button/ToggleButton.tsx b/packages/ui/src/components/button/ToggleButton.tsx index 373448cee..6e12fb376 100644 --- a/packages/ui/src/components/button/ToggleButton.tsx +++ b/packages/ui/src/components/button/ToggleButton.tsx @@ -35,7 +35,7 @@ const ToggleButton: FunctionComponent<{ const backgroundStyle = disabled ? "bg-gray-200" : isChecked - ? "bg-primary-300" + ? "bg-primary-blue-default" : "bg-primary-200" const onClick = () => { diff --git a/packages/ui/src/components/button/ViewOnExplorerButtons.tsx b/packages/ui/src/components/button/ViewOnExplorerButtons.tsx index 216043ff7..5f5e7fc02 100644 --- a/packages/ui/src/components/button/ViewOnExplorerButtons.tsx +++ b/packages/ui/src/components/button/ViewOnExplorerButtons.tsx @@ -20,7 +20,7 @@ export const ViewOnExplorerButton: FunctionComponent<{ return mode === "button" ? ( ) : ( = ({ />
- + {name} diff --git a/packages/ui/src/components/chain/ChainFiltersButton.tsx b/packages/ui/src/components/chain/ChainFiltersButton.tsx index cd6af2d45..70b79df75 100644 --- a/packages/ui/src/components/chain/ChainFiltersButton.tsx +++ b/packages/ui/src/components/chain/ChainFiltersButton.tsx @@ -41,7 +41,7 @@ const ChainFiltersButton: React.FC = ({ onChangeFilters, }) => { return ( -
+
{ return onChangeFilters(handleOnChange(selected, filters)) @@ -57,7 +57,7 @@ const ChainFiltersButton: React.FC = ({ {label} diff --git a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx index 7cf31f88b..f2ecbe45e 100644 --- a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx +++ b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx @@ -28,7 +28,7 @@ const NetworkDisplayBadge = ({ return (
= ({
onClose()} - className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
diff --git a/packages/ui/src/components/dialog/ConfirmDialog.tsx b/packages/ui/src/components/dialog/ConfirmDialog.tsx index c33df7c12..5cac81f53 100644 --- a/packages/ui/src/components/dialog/ConfirmDialog.tsx +++ b/packages/ui/src/components/dialog/ConfirmDialog.tsx @@ -55,7 +55,7 @@ const ConfirmDialog: FunctionComponent<{ return (
-

+

{title}

@@ -67,7 +67,7 @@ const ConfirmDialog: FunctionComponent<{ e.stopPropagation() onClose() }} - className="cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className="cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
diff --git a/packages/ui/src/components/dialog/DetailsDialog.tsx b/packages/ui/src/components/dialog/DetailsDialog.tsx index cb4354cb3..82bc15f1b 100644 --- a/packages/ui/src/components/dialog/DetailsDialog.tsx +++ b/packages/ui/src/components/dialog/DetailsDialog.tsx @@ -91,7 +91,7 @@ const DetailsDialog: FunctionComponent = ({
onClose()} - className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
diff --git a/packages/ui/src/components/dialog/HardwareDeviceNotLinkedDialog.tsx b/packages/ui/src/components/dialog/HardwareDeviceNotLinkedDialog.tsx index 2b82c03b7..b82aad407 100644 --- a/packages/ui/src/components/dialog/HardwareDeviceNotLinkedDialog.tsx +++ b/packages/ui/src/components/dialog/HardwareDeviceNotLinkedDialog.tsx @@ -78,7 +78,7 @@ const HardwareDeviceNotLinkedDialog: React.FC<{
{

If the problem persists, try{" "} history.push({ pathname: "/settings/networks", diff --git a/packages/ui/src/components/dialog/SuccessDialog.tsx b/packages/ui/src/components/dialog/SuccessDialog.tsx index 5708c1030..ca6ddeb1b 100644 --- a/packages/ui/src/components/dialog/SuccessDialog.tsx +++ b/packages/ui/src/components/dialog/SuccessDialog.tsx @@ -66,7 +66,7 @@ const SuccessDialog: FunctionComponent< )} target="_blank" rel="noopener noreferrer" - className="flex flex-row items-center space-x-2 text-sm font-bold text-primary-300" + className="flex flex-row items-center space-x-2 text-sm font-bold text-primary-blue-default" > View on {explorerName} {

{ @@ -177,7 +177,7 @@ const GasPricesInfo: FC = () => {
setActive(false)} - className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
@@ -195,7 +195,7 @@ const GasPricesInfo: FC = () => { >
= ({ className }) => { className={classnames("w-20 h-20", className)} xmlns="http://www.w3.org/2000/svg" > - - - - - - + + + + + + + + + + + + + ) } diff --git a/packages/ui/src/components/icons/ImportIcon.tsx b/packages/ui/src/components/icons/ImportIcon.tsx index c83d61fc6..582d5831a 100644 --- a/packages/ui/src/components/icons/ImportIcon.tsx +++ b/packages/ui/src/components/icons/ImportIcon.tsx @@ -9,24 +9,24 @@ const ImportIcon: React.FC<{ className?: string }> = ({ className }) => { xmlns="http://www.w3.org/2000/svg" > ) diff --git a/packages/ui/src/components/icons/UsbIcon.tsx b/packages/ui/src/components/icons/UsbIcon.tsx index aa6440b98..a36300f80 100644 --- a/packages/ui/src/components/icons/UsbIcon.tsx +++ b/packages/ui/src/components/icons/UsbIcon.tsx @@ -9,43 +9,43 @@ const UsbIcon: React.FC<{ className?: string }> = ({ className }) => { xmlns="http://www.w3.org/2000/svg" > ) diff --git a/packages/ui/src/components/icons/WalletIcon.tsx b/packages/ui/src/components/icons/WalletIcon.tsx index 4c9396bb4..997a06a61 100644 --- a/packages/ui/src/components/icons/WalletIcon.tsx +++ b/packages/ui/src/components/icons/WalletIcon.tsx @@ -8,38 +8,75 @@ const WalletIcon: React.FC<{ className?: string }> = ({ className }) => { fill="none" xmlns="http://www.w3.org/2000/svg" > - - - - - + + + + + + + - + + + + + + + + + + + diff --git a/packages/ui/src/components/info/ReleaseNotesInfo.tsx b/packages/ui/src/components/info/ReleaseNotesInfo.tsx index 82ae1e937..6d41ba177 100644 --- a/packages/ui/src/components/info/ReleaseNotesInfo.tsx +++ b/packages/ui/src/components/info/ReleaseNotesInfo.tsx @@ -76,7 +76,7 @@ const ReleaseNotesInfo: FC = ({ href={LINKS.ARTICLES.CHANGELOG} target="_blank" rel="noreferrer" - className="text-primary-300 hover:underline" + className="text-primary-blue-default hover:underline" > Find full release notes here.
diff --git a/packages/ui/src/components/input/DropDownSelector.tsx b/packages/ui/src/components/input/DropDownSelector.tsx index 39b9b8a09..ce8296a95 100644 --- a/packages/ui/src/components/input/DropDownSelector.tsx +++ b/packages/ui/src/components/input/DropDownSelector.tsx @@ -98,11 +98,11 @@ const DropDownSelector: FC = ({ {/* Display */}
= ({ alt="active-arrow" src={arrowDown} className={classnames( - "w-3 h-2 text-black", + "w-3 h-2 text-primary-black-default", active && "rotate-180" )} /> diff --git a/packages/ui/src/components/input/HorizontalSelect.tsx b/packages/ui/src/components/input/HorizontalSelect.tsx index 02e8237bb..941c5e377 100644 --- a/packages/ui/src/components/input/HorizontalSelect.tsx +++ b/packages/ui/src/components/input/HorizontalSelect.tsx @@ -31,8 +31,8 @@ const HorizontalSelect: FunctionComponent<{ !disableStyles ? `flex-1 flex flex-row items-center justify-center p-4 border-b-2 text-sm ${ option === value - ? "border-primary-300 text-primary-300 font-bold" - : "border-transparent text-gray-500 hover:text-primary-300 hover:font-medium" + ? "border-primary-blue-default text-primary-blue-default font-bold" + : "border-transparent text-gray-500 hover:text-primary-blue-default hover:font-medium" }` : optionClassName ? optionClassName(option) diff --git a/packages/ui/src/components/input/NetworkSelect.tsx b/packages/ui/src/components/input/NetworkSelect.tsx index 32ba54be3..9c0f96f3a 100644 --- a/packages/ui/src/components/input/NetworkSelect.tsx +++ b/packages/ui/src/components/input/NetworkSelect.tsx @@ -89,11 +89,11 @@ const NetworkSelect: FunctionComponent<{ } }} className={classNames( - "relative flex flex-row items-center justify-start p-1 text-gray-600 border rounded-md group border-primary-200 w-44 text-xs hover:border-primary-300", + "relative flex flex-row items-center justify-start p-1 text-gray-600 bg-primary-grey-default rounded-md group border-primary-200 w-44 text-xs hover:border-primary-blue-default", !isImportingDeposits ? "cursor-pointer select-none" : "disabled:pointer-events-none opacity-50", - networkList && "border-primary-300" + networkList && "border-primary-blue-default" )} > ( return (
( size={16} onClick={onClickInfo} className={classnames( - "text-primary-200 hover:text-primary-300 cursor-default", + "text-primary-200 hover:text-primary-blue-default cursor-default", onClickInfo && "!cursor-pointer" )} /> diff --git a/packages/ui/src/components/input/VerticalSelect.tsx b/packages/ui/src/components/input/VerticalSelect.tsx index 5f011bee0..85ce4af2e 100644 --- a/packages/ui/src/components/input/VerticalSelect.tsx +++ b/packages/ui/src/components/input/VerticalSelect.tsx @@ -47,12 +47,12 @@ const VerticalSelect: FunctionComponent<{ key={option.label || option.name || option} className={ !disableStyles - ? `w-full flex flex-row items-center justify-between p-4 rounded-md text-sm transform transition-all duration-300 active:scale-95 + ? `w-full flex flex-row items-center justify-between p-4 rounded-md text-sm text-primary-black-default transform transition-all duration-300 active:scale-95 disabled:pointer-events-none ${ isActive(option) - ? "bg-primary-300 text-white font-bold" - : "bg-primary-100 hover:bg-primary-200" + ? "bg-primary-grey-hover text-white font-bold" + : "bg-primary-grey-default hover:bg-primary-grey-hover" } ${ isDisabled(option, i) diff --git a/packages/ui/src/components/loading/LoadingOverlay.tsx b/packages/ui/src/components/loading/LoadingOverlay.tsx index 5603a64ed..766871e80 100644 --- a/packages/ui/src/components/loading/LoadingOverlay.tsx +++ b/packages/ui/src/components/loading/LoadingOverlay.tsx @@ -4,7 +4,7 @@ const LoadingOverlay = () => (
) diff --git a/packages/ui/src/components/network/NetworkSelector.tsx b/packages/ui/src/components/network/NetworkSelector.tsx index 51b2b9ff4..89cc10ff1 100644 --- a/packages/ui/src/components/network/NetworkSelector.tsx +++ b/packages/ui/src/components/network/NetworkSelector.tsx @@ -122,7 +122,7 @@ export const NetworkSelector: FunctionComponent = ({
{search && searchResult.length === 0 ? (
-

+

No available networks match with the search.

diff --git a/packages/ui/src/components/networks/NetworkDisplay.tsx b/packages/ui/src/components/networks/NetworkDisplay.tsx index 3b018e5ba..b34b001cc 100644 --- a/packages/ui/src/components/networks/NetworkDisplay.tsx +++ b/packages/ui/src/components/networks/NetworkDisplay.tsx @@ -228,7 +228,7 @@ const NetworkDisplay = ({ ) : (
setConfirmSwitchNetwork(true)} > @@ -237,7 +237,7 @@ const NetworkDisplay = ({ )}
diff --git a/packages/ui/src/components/phishing/AntiPhishing.tsx b/packages/ui/src/components/phishing/AntiPhishing.tsx index 67e53b511..37348663a 100644 --- a/packages/ui/src/components/phishing/AntiPhishing.tsx +++ b/packages/ui/src/components/phishing/AntiPhishing.tsx @@ -31,7 +31,7 @@ const AntiPhishing: FunctionComponent<{ > anti-phishing = ({ }} disabled={disabled || !mounted} className={classnames( - "p-2 -ml-2 mr-1 cursor-pointer transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300", + "p-2 -ml-2 mr-1 cursor-pointer transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default", disabled && "pointer-events-none text-gray-300" )} > @@ -136,7 +136,7 @@ const PopupHeader: FunctionComponent = ({ = ({ }} disabled={disabled} className={classnames( - "p-2 -mr-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300", + "p-2 -mr-2 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default", disabled && "pointer-events-none text-gray-300" )} type="button" diff --git a/packages/ui/src/components/setup/SeedImport.tsx b/packages/ui/src/components/setup/SeedImport.tsx index 8f06745b7..a4317dfa0 100644 --- a/packages/ui/src/components/setup/SeedImport.tsx +++ b/packages/ui/src/components/setup/SeedImport.tsx @@ -279,7 +279,7 @@ const SeedImport: FunctionComponent<{ href="https://blockwallet.io/terms-of-use-of-block-wallet.html" target="_blank" rel="noopener noreferrer" - className="text-primary-300" + className="text-primary-blue-default" > Terms of Use @@ -302,7 +302,7 @@ const SeedImport: FunctionComponent<{ type="submit" className={classnames( Classes.button, - "w-1/2 font-bold border-2 border-primary-300", + "w-1/2 font-bold border-2 border-primary-blue-default", (isLoading || isImportDisabled) && "opacity-50 pointer-events-none" )} diff --git a/packages/ui/src/components/spinner/Spinner.tsx b/packages/ui/src/components/spinner/Spinner.tsx index dcaa76b69..a6ac02490 100644 --- a/packages/ui/src/components/spinner/Spinner.tsx +++ b/packages/ui/src/components/spinner/Spinner.tsx @@ -15,7 +15,7 @@ const Spinner: FunctionComponent<{ > {text} diff --git a/packages/ui/src/components/swaps/PriceImpactDialog.tsx b/packages/ui/src/components/swaps/PriceImpactDialog.tsx index a75155098..f8fb23008 100644 --- a/packages/ui/src/components/swaps/PriceImpactDialog.tsx +++ b/packages/ui/src/components/swaps/PriceImpactDialog.tsx @@ -37,7 +37,9 @@ const HighPriceImpactExplained: FC< difference in the values you are about to swap.
- You pay + + You pay +
{`${formatToken(fromToken.token, fromToken.amount)} ~= ${format( @@ -47,7 +49,9 @@ const HighPriceImpactExplained: FC< )}`}
- You get + + You get +
{`${formatToken( toToken.token, diff --git a/packages/ui/src/components/token/AddTokenListView.tsx b/packages/ui/src/components/token/AddTokenListView.tsx index 5b9920dfd..0d60be034 100644 --- a/packages/ui/src/components/token/AddTokenListView.tsx +++ b/packages/ui/src/components/token/AddTokenListView.tsx @@ -131,7 +131,7 @@ const AddTokenListView = ({
{results.length < 1 && selected.length <= 0 ? ( -
+
No match
) : ( diff --git a/packages/ui/src/components/token/AddTokenManualView.tsx b/packages/ui/src/components/token/AddTokenManualView.tsx index 67b4e82bf..5a5e44430 100644 --- a/packages/ui/src/components/token/AddTokenManualView.tsx +++ b/packages/ui/src/components/token/AddTokenManualView.tsx @@ -208,16 +208,16 @@ const AddTokenManualView = ({ onSubmit={onSubmit} >
-
+
Custom Token
{ diff --git a/packages/ui/src/components/token/TokenDisplay.tsx b/packages/ui/src/components/token/TokenDisplay.tsx index dc554f7e3..53bd2b21a 100644 --- a/packages/ui/src/components/token/TokenDisplay.tsx +++ b/packages/ui/src/components/token/TokenDisplay.tsx @@ -55,7 +55,11 @@ const TokenDisplay: FunctionComponent = ({ >
- + {formatName(data.name, 22)} {balance && ( diff --git a/packages/ui/src/components/token/TokenSearchView.tsx b/packages/ui/src/components/token/TokenSearchView.tsx index d75ff9c0b..f36bc4767 100644 --- a/packages/ui/src/components/token/TokenSearchView.tsx +++ b/packages/ui/src/components/token/TokenSearchView.tsx @@ -160,7 +160,7 @@ const SearchedTokenView = ({
{results.length < 1 && selected.length <= 0 ? ( -
+
No match
) : ( diff --git a/packages/ui/src/components/token/TokenSummary.tsx b/packages/ui/src/components/token/TokenSummary.tsx index b3c3f18a2..78bc6dca3 100644 --- a/packages/ui/src/components/token/TokenSummary.tsx +++ b/packages/ui/src/components/token/TokenSummary.tsx @@ -24,7 +24,7 @@ const TokenSummary: FC<{ return (
= ({ ) : (
setIsOpen(true)} > {label} @@ -371,7 +371,7 @@ export const AdvancedSettings: FunctionComponent = ({ onClick={() => { setIsOpen(false) }} - className="cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className="cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
@@ -452,7 +452,7 @@ export const AdvancedSettings: FunctionComponent = ({
setShowOptionsInfo(true)} />
@@ -254,7 +254,7 @@ const AllowanceInput = ({
setShowOptionsInfo(false)} - className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
@@ -402,7 +402,7 @@ const AllowanceInput = ({ Allowance Options
-
+

Allowances let DApps automate transactions for you. These are your options. @@ -412,7 +412,7 @@ const AllowanceInput = ({ className="flex flex-col space-y-1" key={index} > -

+

{item.title}

diff --git a/packages/ui/src/components/transactions/BridgeNotFoundQuoteDetails.tsx b/packages/ui/src/components/transactions/BridgeNotFoundQuoteDetails.tsx index c16af307c..dfb368fd8 100644 --- a/packages/ui/src/components/transactions/BridgeNotFoundQuoteDetails.tsx +++ b/packages/ui/src/components/transactions/BridgeNotFoundQuoteDetails.tsx @@ -47,7 +47,7 @@ export const BridgeNotFoundQuoteDetails: FunctionComponent<

@@ -111,7 +111,7 @@ export const BridgeNotFoundQuoteDetails: FunctionComponent< href={LINKS.ARTICLES.BRIDGES} target="_blank" rel="noopener noreferrer" - className="flex flex-row items-center space-x-2 text-xs font-bold text-primary-300" + className="flex flex-row items-center space-x-2 text-xs font-bold text-primary-blue-default" > Read about bridges Download report { className={classnames( "text-base font-semibold cursor-pointer capitalize", selectedOption.label === option.label && - "text-primary-300" + "text-primary-blue-default" )} > {option.label} @@ -122,7 +122,7 @@ const GasSelectorBasic = (props: GasComponentProps) => { "text-xs", selectedOption.label === option.label && - "text-primary-300" + "text-primary-blue-default" )} > {option.totalNativeCurrencyCostRange} @@ -133,7 +133,7 @@ const GasSelectorBasic = (props: GasComponentProps) => { "text-sm", selectedOption.label === option.label - ? "text-primary-300" + ? "text-primary-blue-default" : "hidden" )} /> @@ -145,7 +145,7 @@ const GasSelectorBasic = (props: GasComponentProps) => { "text-gray-600 text-xs", selectedOption.label === option.label && - "!text-primary-300" + "!text-primary-blue-default" )} > {option.totalETHCostRange} @@ -757,7 +757,7 @@ const GasPriceComponent: FunctionComponent<{ {/* Label */}
setActive(false)} - className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
@@ -868,7 +868,7 @@ const GasPriceComponent: FunctionComponent<{ > { className={classnames( "text-base font-semibold mb-2 cursor-pointer capitalize", selectedGasPrice.label === price.label && - "text-primary-300" + "text-primary-blue-default" )} > {price.label} @@ -360,7 +360,7 @@ const GasSelectorBasic = (props: GasTabProps) => { "text-sm", selectedGasPrice.label === price.label && - "text-primary-300" + "text-primary-blue-default" )} > {price.nativeCurrencyAmount} @@ -381,7 +381,7 @@ const GasSelectorBasic = (props: GasTabProps) => { "text-sm", selectedGasPrice.label === price.label && - "text-primary-300" + "text-primary-blue-default" )} > {price.ethTotalCost} @@ -395,7 +395,7 @@ const GasSelectorBasic = (props: GasTabProps) => { className={classnames( "text-sm", selectedGasPrice.label === price.label - ? "text-primary-300" + ? "text-primary-blue-default" : "hidden" )} /> @@ -584,7 +584,7 @@ export const GasPriceSelector = (props: GasPriceSelectorProps) => { <>
{
setActive(false)} - className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-300" + className=" cursor-pointer p-2 ml-auto -mr-2 text-gray-900 transition duration-300 rounded-full hover:bg-primary-100 hover:text-primary-blue-default" >
@@ -665,7 +665,7 @@ export const GasPriceSelector = (props: GasPriceSelectorProps) => { > { `flex-1 flex flex-row items-center justify-center p-3 text-sm ${ tab === value - ? "border-primary-300 border-b-2 text-primary-300 font-bold" + ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" : "border-gray-200 text-gray-500 border-b" }` } diff --git a/packages/ui/src/components/transactions/Price.tsx b/packages/ui/src/components/transactions/Price.tsx index 19f756fee..476b3d217 100644 --- a/packages/ui/src/components/transactions/Price.tsx +++ b/packages/ui/src/components/transactions/Price.tsx @@ -41,7 +41,7 @@ const Price: FunctionComponent<{
{txValue[0]} diff --git a/packages/ui/src/components/transactions/TransactionDetails.tsx b/packages/ui/src/components/transactions/TransactionDetails.tsx index 8864871b0..5b0a64f59 100644 --- a/packages/ui/src/components/transactions/TransactionDetails.tsx +++ b/packages/ui/src/components/transactions/TransactionDetails.tsx @@ -47,7 +47,7 @@ export const TransactionDetails: FunctionComponent = ({
@@ -83,7 +83,7 @@ export const TransactionDetails: FunctionComponent = ({ `flex-1 flex flex-row items-center justify-center p-3 text-sm group ${ tab.label === value.label - ? "border-primary-300 border-b-2 text-primary-300 font-bold" + ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" : "border-gray-200 text-gray-500 border-b" }` } diff --git a/packages/ui/src/components/transactions/TransactionDetailsAdvanced.tsx b/packages/ui/src/components/transactions/TransactionDetailsAdvanced.tsx index 0483fe346..be3b9b7a2 100644 --- a/packages/ui/src/components/transactions/TransactionDetailsAdvanced.tsx +++ b/packages/ui/src/components/transactions/TransactionDetailsAdvanced.tsx @@ -159,7 +159,7 @@ export const TransactionDetails: FunctionComponent< {signature.args.map((arg, i) => (
- {`\u00A0\u00A0\u00A0\u00A0${arg.type}`} + {`\u00A0\u00A0\u00A0\u00A0${arg.type}`} {arg.name ? ` ${arg.name}` : ""} {i !== signature.args.length - 1 ? "," : ""}
diff --git a/packages/ui/src/components/transactions/TransactionDetailsBasic.tsx b/packages/ui/src/components/transactions/TransactionDetailsBasic.tsx index fc78f0aa1..87e4e9ebb 100644 --- a/packages/ui/src/components/transactions/TransactionDetailsBasic.tsx +++ b/packages/ui/src/components/transactions/TransactionDetailsBasic.tsx @@ -483,7 +483,7 @@ export const TransactionDetailsBasic: FunctionComponent< )} target="_blank" rel="noopener noreferrer" - className="flex flex-row items-center space-x-2 text-sm font-bold text-primary-300" + className="flex flex-row items-center space-x-2 text-sm font-bold text-primary-blue-default" > View on {explorerName} = ({ size = "1rem" }) => ( - + ) const TransactionIcon: React.FC<{ @@ -608,7 +611,7 @@ const TransactionItem: React.FC<{ > > = ( const offset = offsets[position || "top-right"] return (
{children}
diff --git a/packages/ui/src/components/ui/Dropdown/DropdownMenu.tsx b/packages/ui/src/components/ui/Dropdown/DropdownMenu.tsx index 85ea93835..37e3a1149 100644 --- a/packages/ui/src/components/ui/Dropdown/DropdownMenu.tsx +++ b/packages/ui/src/components/ui/Dropdown/DropdownMenu.tsx @@ -65,7 +65,7 @@ export const DropdownMenuItem: React.FC< className={classnames( "flex flex-row justify-between items-center w-full cursor-pointer hover:bg-gray-100", className || "", - selected && "text-primary-300" + selected && "text-primary-blue-default" )} > {children} diff --git a/packages/ui/src/components/ui/Pagination/PaginationControls.tsx b/packages/ui/src/components/ui/Pagination/PaginationControls.tsx index e49f6cbc7..a68b943a8 100644 --- a/packages/ui/src/components/ui/Pagination/PaginationControls.tsx +++ b/packages/ui/src/components/ui/Pagination/PaginationControls.tsx @@ -12,7 +12,7 @@ const PageControlButton: React.FC< return (
Search the networks you want to add by name or diff --git a/packages/ui/src/routes/send/SendConfirmPage.tsx b/packages/ui/src/routes/send/SendConfirmPage.tsx index de2218cbb..d3f567e98 100644 --- a/packages/ui/src/routes/send/SendConfirmPage.tsx +++ b/packages/ui/src/routes/send/SendConfirmPage.tsx @@ -804,7 +804,7 @@ const SendConfirmPage = () => {
@@ -856,8 +856,8 @@ const SendConfirmPage = () => { className={classnames( "float-right rounded-md cursor-pointer border p-1", usingMax - ? "bg-primary-blue-default border-primary-blue-default text-white hover:bg-blue-600 hover:border-blue-600" - : "bg-blue-200 border-blue-200 hover:bg-blue-300 hover:border-blue-300", + ? "bg-gray-500 border-gray-500 text-white hover:bg-gray-400 hover:border-gray-400" + : "bg-gray-300 border-gray-300 hover:bg-gray-400 hover:border-gray-400", !HasBalance(selectedToken) && "pointer-events-none text-gray-600" )} diff --git a/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx b/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx index f222653bc..1d03c1b5b 100644 --- a/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx +++ b/packages/ui/src/routes/settings/ConnectedSiteAccountsPage.tsx @@ -135,7 +135,7 @@ const ConnectedSiteAccount: FunctionComponent<{ {account.address !== selectedAddress && ( diff --git a/packages/ui/src/routes/settings/ExportDonePage.tsx b/packages/ui/src/routes/settings/ExportDonePage.tsx index 213b878e2..fae30bf5c 100644 --- a/packages/ui/src/routes/settings/ExportDonePage.tsx +++ b/packages/ui/src/routes/settings/ExportDonePage.tsx @@ -51,7 +51,7 @@ const ExportDonePage = () => { />
-
+
{Array.from({ length: numberOfWords }, (v, i) => { const wordnN = i + 1 return ( diff --git a/packages/ui/src/routes/IntroductionPage.tsx b/packages/ui/src/routes/IntroductionPage.tsx index fb03e0afb..c4a43399a 100644 --- a/packages/ui/src/routes/IntroductionPage.tsx +++ b/packages/ui/src/routes/IntroductionPage.tsx @@ -12,7 +12,7 @@ const IntroductionPage = () => ( Welcome to BlockWallet
- Protecting you on Web3 without compromises. + Protecting you on Web3 without compromise.
{
} - className="!-mb-4 !text-primary-black-default" + className="!-mb-4 !text-primary-black-default !-translate-x-[37.3%]" />
diff --git a/packages/ui/src/routes/setup/SetupPage.tsx b/packages/ui/src/routes/setup/SetupPage.tsx index 1467e8d0d..f060efb92 100644 --- a/packages/ui/src/routes/setup/SetupPage.tsx +++ b/packages/ui/src/routes/setup/SetupPage.tsx @@ -63,15 +63,6 @@ const SetupPage = () => { linkLabel="Create new wallet" />
- - - BlockWallet Blog - ) } From 7c0cb2bac97b44eade7e7bdf2dcb389d5b5921bb Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Mon, 6 Mar 2023 12:27:21 +0200 Subject: [PATCH 029/110] feat: backup in settings in top --- .../ui/src/routes/settings/SettingsPage.tsx | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/ui/src/routes/settings/SettingsPage.tsx b/packages/ui/src/routes/settings/SettingsPage.tsx index b1ff4a02d..f7e84df6a 100644 --- a/packages/ui/src/routes/settings/SettingsPage.tsx +++ b/packages/ui/src/routes/settings/SettingsPage.tsx @@ -126,6 +126,21 @@ const SettingsPage = () => { } >
+ {!isSeedPhraseBackedUp && ( +
+ + Back up your seed phrase to secure your funds. + + +
+ )}
{ ) }} /> - {!isSeedPhraseBackedUp && ( -
- - Back your seed phrase up and store it in a - safe place. - - -
- )}
From e5993c82d3b69101c347b3c1de2264ade346cd41 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Mon, 6 Mar 2023 15:15:13 +0200 Subject: [PATCH 030/110] fix: remove net worth symbol --- packages/ui/src/context/hooks/useNetWorthBalance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/src/context/hooks/useNetWorthBalance.ts b/packages/ui/src/context/hooks/useNetWorthBalance.ts index 88abe13f9..744766777 100644 --- a/packages/ui/src/context/hooks/useNetWorthBalance.ts +++ b/packages/ui/src/context/hooks/useNetWorthBalance.ts @@ -30,7 +30,7 @@ const useNetWorthBalance = () => { currency: state.nativeCurrency, locale_info: state.localeInfo, returnNonBreakingSpace: true, - showSymbol: true, + showSymbol: false, }) } From d412c4924eed59067b4ab7f4c923a79e81e81484 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Tue, 7 Mar 2023 10:22:46 +0200 Subject: [PATCH 031/110] merge master into extension redesign --- packages/background/package.json | 2 +- .../src/controllers/PreferencesController.ts | 1 + .../TransactionWatcherController.ts | 47 +- .../transactions/TransactionController.ts | 11 +- .../stores/migrator/migrations/index.ts | 2 + .../migrator/migrations/migration-61.ts | 24 + .../src/utils/constants/initialState.ts | 1 + .../background/src/utils/notifications.ts | 442 +++++++++++------- packages/background/src/utils/token.ts | 25 + .../stores/migrator/reconciler.test.ts | 2 + .../background/test/mocks/mock-preferences.ts | 1 + .../test/utils/userPreferences.test.ts | 3 + packages/ui/src/mock/MockBackgroundState.tsx | 1 + packages/ui/src/router/routes.ts | 6 +- ...e.tsx => NotificationsAndWarningsPage.tsx} | 58 ++- .../src/routes/settings/PreferencesPage.tsx | 4 +- 16 files changed, 409 insertions(+), 221 deletions(-) create mode 100644 packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts rename packages/ui/src/routes/preferences/{WarningsPreferencesPage.tsx => NotificationsAndWarningsPage.tsx} (67%) diff --git a/packages/background/package.json b/packages/background/package.json index 18206845e..3c247f220 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@block-wallet/background", - "version": "1.1.0", + "version": "1.1.1", "private": true, "dependencies": { "@block-wallet/chains-assets": "https://github.com/block-wallet/chains-assets#v0.0.27", diff --git a/packages/background/src/controllers/PreferencesController.ts b/packages/background/src/controllers/PreferencesController.ts index d5c974558..f37cb1bbd 100644 --- a/packages/background/src/controllers/PreferencesController.ts +++ b/packages/background/src/controllers/PreferencesController.ts @@ -5,6 +5,7 @@ export interface UserSettings { // Setting that indicates if a warning is shown when receiving a transaction from an address different from the selected one. hideAddressWarning: boolean; subscribedToReleaseaNotes: boolean; + subscribedToNotifications: boolean; useAntiPhishingProtection: boolean; defaultBrowserWallet: boolean; hideEstimatedGasExceedsThresholdWarning: boolean; diff --git a/packages/background/src/controllers/TransactionWatcherController.ts b/packages/background/src/controllers/TransactionWatcherController.ts index d1f461015..3ca3ffdb1 100644 --- a/packages/background/src/controllers/TransactionWatcherController.ts +++ b/packages/background/src/controllers/TransactionWatcherController.ts @@ -30,7 +30,7 @@ import { import { Block, Log } from '@ethersproject/abstract-provider'; import { SignedTransaction } from './erc-20/transactions/SignedTransaction'; import { TransactionArgument } from './transactions/ContractSignatureParser'; -import { showIncomingTransactionNotification } from '../utils/notifications'; +import { showTransactionNotification } from '../utils/notifications'; import TransactionController from './transactions/TransactionController'; import { fetchBlockWithRetries } from '../utils/blockFetch'; import { isNil } from 'lodash'; @@ -95,7 +95,7 @@ export interface TransactionWatcherControllerState { export const TRANSACTION_TYPE_STATUS: { [type in WatchedTransactionType]: boolean; } = { - txlist: false, + txlist: true, tokentx: true, tokennfttx: false, token1155tx: false, @@ -204,29 +204,18 @@ export class TransactionWatcherController extends BaseController { - let section: - | '' - | 'tokentxns' - | 'tokentxnsErc721' - | 'tokentxnsErc1155' = ''; - switch (transactionType) { - case WatchedTransactionType.ERC20: - section = 'tokentxns'; - break; - case WatchedTransactionType.ERC721: - section = 'tokentxnsErc721'; - break; - case WatchedTransactionType.ERC1155: - section = 'tokentxnsErc1155'; - break; - } - showIncomingTransactionNotification(address, chainId, section); + if ( + this._preferencesController.settings + .subscribedToNotifications + ) + showTransactionNotification(txMeta); } ); @@ -1470,19 +1459,29 @@ export class TransactionWatcherController extends BaseController { + const allTransactions = this._transactionController.getTransactions(); + if (Object.keys(currentTransactions).length) { for (const transactionHash in newTransactions) { if ( this._sameAddress( newTransactions[transactionHash].transactionParams.to, address + ) && + // Discard incoming transaction if it's from a BlockWallet swap + !allTransactions.find( + (tx) => + tx.transactionParams.hash === transactionHash && + tx.transactionCategory === + TransactionCategories.EXCHANGE ) ) { this.emit( TransactionWatcherControllerEvents.INCOMING_TRANSACTION, chainId, address, - transactionType + transactionType, + newTransactions[transactionHash] ); break; } diff --git a/packages/background/src/controllers/transactions/TransactionController.ts b/packages/background/src/controllers/transactions/TransactionController.ts index 55226be8a..29628f283 100644 --- a/packages/background/src/controllers/transactions/TransactionController.ts +++ b/packages/background/src/controllers/transactions/TransactionController.ts @@ -427,9 +427,16 @@ export class TransactionController extends BaseController< this.on( TransactionEvents.STATUS_UPDATE, (transactionMeta: TransactionMeta) => { + const notificationTxStatuses = [ + TransactionStatus.CONFIRMED, + TransactionStatus.FAILED, + TransactionStatus.CANCELLED, + ]; + if ( - transactionMeta.status === TransactionStatus.CONFIRMED || - transactionMeta.status === TransactionStatus.FAILED + this._preferencesController.settings + .subscribedToNotifications && + notificationTxStatuses.includes(transactionMeta.status) ) { showTransactionNotification(transactionMeta); } diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts index 6a73648df..f0bb6cabd 100644 --- a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts +++ b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts @@ -59,6 +59,7 @@ import migration57 from './migration-57'; import migration58 from './migration-58'; import migration59 from './migration-59'; import migration60 from './migration-60'; +import migration61 from './migration-61'; const migrations: IMigration[] = [ migration01, @@ -121,5 +122,6 @@ const migrations: IMigration[] = [ migration58, migration59, migration60, + migration61, ]; export default (): IMigration[] => migrations; diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts b/packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts new file mode 100644 index 000000000..f88e30f46 --- /dev/null +++ b/packages/background/src/infrastructure/stores/migrator/migrations/migration-61.ts @@ -0,0 +1,24 @@ +import { BlankAppState } from '@block-wallet/background/utils/constants/initialState'; +import { IMigration } from '../IMigration'; + +/** + * This migration adds the subscribedToNotifications flag with true value to the user preferences + */ +export default { + migrate: async (persistedState: BlankAppState) => { + return { + ...persistedState, + PreferencesController: { + ...persistedState.PreferencesController, + settings: { + ...persistedState.PreferencesController.settings, + + subscribedToNotifications: + persistedState.PreferencesController.settings + .subscribedToNotifications ?? true, + }, + }, + }; + }, + version: '1.1.1', +} as IMigration; diff --git a/packages/background/src/utils/constants/initialState.ts b/packages/background/src/utils/constants/initialState.ts index 24fc2af0a..ecd9d16a4 100644 --- a/packages/background/src/utils/constants/initialState.ts +++ b/packages/background/src/utils/constants/initialState.ts @@ -151,6 +151,7 @@ const initialState: BlankAppState = { settings: { hideAddressWarning: false, // Shown by default, subscribedToReleaseaNotes: true, + subscribedToNotifications: true, useAntiPhishingProtection: true, defaultBrowserWallet: true, hideEstimatedGasExceedsThresholdWarning: false, // Shown by default, diff --git a/packages/background/src/utils/notifications.ts b/packages/background/src/utils/notifications.ts index 3e6474c6b..707b36755 100644 --- a/packages/background/src/utils/notifications.ts +++ b/packages/background/src/utils/notifications.ts @@ -1,217 +1,317 @@ +import { BigNumber } from '@ethersproject/bignumber'; +import { createCustomExplorerLink } from '@block-wallet/explorer-link'; +import { ChainListItem, getChainListItem } from './chainlist'; import { + MetaType, TransactionCategories, TransactionMeta, TransactionStatus, } from '../controllers/transactions/utils/types'; -import { - createCustomAccountLink, - createCustomExplorerLink, -} from '@block-wallet/explorer-link'; -import { getChainListItem } from './chainlist'; +import { formatTokenAmount } from './token'; +import { fetchContractDetails } from './contractsInfo'; + +//TODO: change this to a class with static methods to make use of other controllers like accounts(account name) + +interface ChainListItemWithExplorerUrl extends ChainListItem { + explorerUrl: string; +} -export const showSetUpCompleteNotification = (): void => { +/** + * Shows a notification when the user has completed the set-up process. + */ +export const showSetUpCompleteNotification = () => { const url = ''; - const title = 'Block Wallet is ready!'; + const title = 'BlockWallet is ready!'; const message = "You've completed the set-up process. Check the extension in the upper right corner of your browser."; showNotification(title, message, url); }; -export const showTransactionNotification = (txMeta: TransactionMeta): void => { - const { status, transactionCategory } = txMeta; - - if ( - transactionCategory === TransactionCategories.BLANK_DEPOSIT || - transactionCategory === TransactionCategories.BLANK_WITHDRAWAL - ) { - showBlankContractNotification(txMeta); - } else if (status === TransactionStatus.CONFIRMED) { - showSucceededTransaction(txMeta); - } else if (status === TransactionStatus.FAILED) { - showFailedTransaction(txMeta); - } else if (status === TransactionStatus.REJECTED) { - showRejectedTransaction(txMeta.error?.message ?? ''); - } -}; +/** + * Shows a notification including the transaction info and open link to explorer on click. + * @param txMeta - The transaction meta object. + */ +export const showTransactionNotification = async (txMeta: TransactionMeta) => { + const network = getNetworkData(txMeta.chainId); + if (!network) return; -export const showBlankContractNotification = ( - txMeta: TransactionMeta -): void => { - const { status } = txMeta; - - if (status === TransactionStatus.CONFIRMED) { - showSucceededBlankInteraction(txMeta); - } else if (status === TransactionStatus.FAILED) { - showFailedBlankInteraction(txMeta); - } else if (status === TransactionStatus.REJECTED) { - showRejectedBlankInteraction(txMeta.error?.message ?? ''); - } -}; + // the cancel transaction is not shown in the notification only the cancelation + if (txMeta.metaType === MetaType.CANCEL) return; -export const showIncomingTransactionNotification = ( - account: string, - chainId: number, - section?: '' | 'tokentxns' | 'tokentxnsErc721' | 'tokentxnsErc1155' -): void => { - const explorerUrl = getExplorerUrl(chainId); - if (!explorerUrl) { - return; - } - - addOnClickListener(); - - const url = createCustomAccountLink( - account as string, - explorerUrl, - section + const { title, message, url } = await getTxNotificationData( + txMeta, + network ); - const title = 'Incoming Transaction'; - const message = 'An incoming transaction to your address was confirmed!'; - showNotification(title, message, url); + const accountAddress = txMeta.transactionParams.from; + const accountName = accountAddress + ? `Account (${accountAddress?.slice(0, 6)}...${accountAddress?.slice( + accountAddress.length - 4 + )})` + : undefined; + showNotification(title, message, url, accountName); }; -const showSucceededTransaction = (txMeta: TransactionMeta) => { - const { chainId, transactionParams } = txMeta; - if (!chainId) { - return; +/** + * Shows a browser notification and open link on click. + * + * @param title - The notification title. + * @param message - The notification message. + * @param url - The url to open on click. + * @param contextMessage - The context message. + * + */ +const showNotification = ( + title: string, + message: string, + url: string, + contextMessage?: string +) => { + let notificationUrl = url; + if (url) { + addOnClickListener(); + + // To prevent duplicate notifications id which causes the notification to not show (overrides the old one) + const urlObject = new URL(url); + urlObject.searchParams.set('timestamp', Date.now().toString()); + notificationUrl = urlObject.toString(); } - - const explorerUrl = getExplorerUrl(chainId); - if (!explorerUrl) { - return; - } - - addOnClickListener(); - - const { hash, nonce } = transactionParams; - - const url = createCustomExplorerLink(hash as string, explorerUrl); - const title = 'Transaction confirmed'; - const message = `Transaction with nonce ${nonce} confirmed!`; - - showNotification(title, message, url); + chrome.notifications.create(notificationUrl, { + title: title, + message: message, + iconUrl: chrome.runtime.getURL('icons/icon-48.png'), + type: 'basic', + isClickable: url ? true : false, + contextMessage: contextMessage, + }); }; -const showSucceededBlankInteraction = (txMeta: TransactionMeta) => { - const { chainId, transactionParams } = txMeta; - if (!chainId) { - return; - } +const addOnClickListener = () => { + const onClickListener = chrome.notifications.onClicked; - const explorerUrl = getExplorerUrl(chainId); - if (!explorerUrl) { - return; + if (!onClickListener.hasListener(linkToExplorer)) { + onClickListener.addListener(linkToExplorer); } - - addOnClickListener(); - - const { hash } = transactionParams; - - const url = createCustomExplorerLink(hash as string, explorerUrl); - const title = 'Blank interaction succeeded'; - const message = 'Privacy Smart Contract interaction has been confirmed!'; - - showNotification(title, message, url); }; -const showFailedTransaction = (txMeta: TransactionMeta) => { - const { chainId, transactionParams } = txMeta; - if (!chainId) { - return; - } - - const explorerUrl = getExplorerUrl(chainId); - if (!explorerUrl) { - return; +const linkToExplorer = (url: string) => { + if (url.startsWith('https://')) { + chrome.tabs.create({ url: url }); } - - addOnClickListener(); - - const { hash, nonce } = transactionParams; - - const url = createCustomExplorerLink(hash as string, explorerUrl); - const title = 'Transaction failed'; - const message = `Transaction with nonce ${nonce} failed!`; - - showNotification(title, message, url); }; -const showFailedBlankInteraction = (txMeta: TransactionMeta) => { - const { chainId, transactionParams } = txMeta; - if (!chainId) { - return; - } - - const explorerUrl = getExplorerUrl(chainId); - if (!explorerUrl) { - return; - } - - addOnClickListener(); - - const { hash } = transactionParams; +/** + * Gets the network data from the chain list. + * @param chainId - The chain id. + * @returns The network data. + * + */ +const getNetworkData = (chainId: number | undefined) => { + if (!chainId || isNaN(chainId)) return undefined; - const url = createCustomExplorerLink(hash as string, explorerUrl); - const title = 'Blank interaction failed'; - const message = 'Privacy Smart Contract interaction failed!'; + const networkData = getChainListItem(chainId); - showNotification(title, message, url); -}; - -const showRejectedTransaction = (message: string) => { - addOnClickListener(); + if (!networkData || !networkData.explorers || !networkData.explorers.length) + return undefined; - const title = 'Transaction was rejected'; + const explorerUrl = networkData.explorers.find((e) => e.url)?.url; + if (!explorerUrl) return undefined; - showNotification(title, message, ''); + return { ...networkData, explorerUrl } as ChainListItemWithExplorerUrl; }; -const showRejectedBlankInteraction = (message: string) => { - addOnClickListener(); - - const title = 'Blank interaction rejected'; - - showNotification(title, message, ''); -}; +const getTxNotificationData = async ( + txMeta: TransactionMeta, + network: ChainListItemWithExplorerUrl +) => { + const { + transactionParams: txParams, + transactionCategory, + status, + exchangeParams, + bridgeParams, + approveAllowanceParams, + transferType, + chainId, + } = txMeta; + + const { + name: txNetworkName, + nativeCurrency: txNetworkNativeToken, + explorerUrl, + } = network; -const showNotification = (title: string, message: string, url: string) => { - chrome.notifications.create(url, { - title: title, - message: message, - iconUrl: chrome.runtime.getURL('icons/icon-48.png'), - type: 'basic', - }); -}; + let title = ''; + let message = ''; + let url = ''; -const addOnClickListener = () => { - if (!chrome.notifications.onClicked.hasListener(linkToEtherscan)) { - chrome.notifications.onClicked.addListener(linkToEtherscan); + if (txParams.hash) { + url = createCustomExplorerLink(txParams.hash, explorerUrl); } -}; -const linkToEtherscan = (url: string) => { - if (url.startsWith('https://')) { - chrome.tabs.create({ url: url }); + const isTxFailed = status === TransactionStatus.FAILED; + const isTxCancelled = status === TransactionStatus.CANCELLED; + + // Used when the transaction category is not supported or there is no data for the transaction category. + let showDefaultNotification = false; + + switch (transactionCategory) { + case TransactionCategories.EXCHANGE: + if (!exchangeParams) { + showDefaultNotification = true; + break; + } + title = `Swap`; + message = `${exchangeParams.fromToken.symbol} to ${exchangeParams.toToken.symbol} swap on ${txNetworkName}`; + break; + case TransactionCategories.BRIDGE: + if (!bridgeParams) { + showDefaultNotification = true; + break; + } + title = `Bridge`; + message = `${getNetworkData(bridgeParams.fromChainId)?.name} to ${ + getNetworkData(bridgeParams.toChainId)?.name + } bridge`; + break; + case TransactionCategories.TOKEN_METHOD_APPROVE: { + if (!approveAllowanceParams) { + showDefaultNotification = true; + break; + } + const { + spenderAddress, + spenderInfo, + token, + allowanceValue, + isUnlimited, + } = approveAllowanceParams; + const isRevoke = BigNumber.from(allowanceValue).eq(0); + const spenderName = + spenderInfo?.name ?? + `Spender (${spenderAddress?.slice( + 0, + 6 + )}...${spenderAddress?.slice(spenderAddress.length - 4)})`; + if (!isRevoke) { + title = `Token Approval`; + message = `Approval of ${ + isUnlimited + ? `unlimited ${token.symbol}` + : formatTokenAmount( + allowanceValue, + token.decimals, + token.symbol + ) + } for use with ${spenderName} on ${txNetworkName}`; + } else { + title = `Approval Revoke`; + message = `${token.symbol} approval revoke for ${spenderName} on ${txNetworkName}`; + } + break; + } + case TransactionCategories.SENT_ETHER: + title = `Transaction`; + message = `${txNetworkNativeToken.symbol} transfer on ${txNetworkName}`; + break; + case TransactionCategories.TOKEN_METHOD_TRANSFER: + if (!transferType) { + showDefaultNotification = true; + break; + } + title = `Transaction`; + message = `${transferType.currency} transfer on ${txNetworkName}`; + break; + case TransactionCategories.INCOMING: + if (!txParams || !txParams.value) { + showDefaultNotification = true; + break; + } + title = `Incoming Transaction`; + message = `Received ${formatTokenAmount( + txParams.value, + txNetworkNativeToken.decimals, + txNetworkNativeToken.symbol + )} on ${txNetworkName}.`; + break; + case TransactionCategories.TOKEN_METHOD_INCOMING_TRANSFER: { + if (!transferType) { + showDefaultNotification = true; + break; + } + + title = 'Incoming Transaction'; + message = `Received ${formatTokenAmount( + transferType.amount, + transferType.decimals, + transferType.currency + )} on ${txNetworkName}.`; + break; + } + case TransactionCategories.CONTRACT_INTERACTION: { + if (!txParams || !txParams.to || !chainId) { + showDefaultNotification = true; + break; + } + const contractAddress = txParams.to; + const contractDetails = await fetchContractDetails( + chainId, + contractAddress + ); + const contractName = + contractDetails?.name ?? + `Contract (${contractAddress?.slice( + 0, + 6 + )}...${contractAddress?.slice(contractAddress.length - 4)})`; + + title = `Contract Interaction`; + message = `Transaction with ${contractName} on ${txNetworkName}`; + break; + } + case TransactionCategories.CONTRACT_DEPLOYMENT: + title = `Contract Deploy`; + message = `Contract deployment on ${txNetworkName}`; + break; + default: + showDefaultNotification = true; + break; } -}; -const getExplorerUrl = (chainId: number) => { - if (isNaN(chainId)) { - return undefined; + if (showDefaultNotification) { + title = 'Transaction'; + message = `Transaction on ${txNetworkName}`; } - const network = getChainListItem(chainId); - if (!network) { - return undefined; - } - if (!network.explorers || !network.explorers.length) { - return undefined; - } - if (!network.explorers.some((e) => e.url)) { - return undefined; + const incomingTxCategories = [ + TransactionCategories.INCOMING, + TransactionCategories.TOKEN_METHOD_INCOMING_TRANSFER, + ]; + + if ( + transactionCategory && + !incomingTxCategories.includes(transactionCategory) + ) { + title = + title + + (!isTxFailed && !isTxCancelled + ? ' Completed' + : isTxCancelled + ? ' Cancelled' + : ' Failed'); + message = + message + + (!isTxFailed && !isTxCancelled + ? ' completed.' + : isTxCancelled + ? ' cancelled.' + : ' failed.'); } - return network.explorers.find((e) => e.url)?.url; + return { + title, + message, + url, + }; }; diff --git a/packages/background/src/utils/token.ts b/packages/background/src/utils/token.ts index 4e1f47a4a..15d3ad9cb 100644 --- a/packages/background/src/utils/token.ts +++ b/packages/background/src/utils/token.ts @@ -12,6 +12,8 @@ import { } from './types/ethereum'; import { BigNumber } from 'ethers'; import { MaxUint256 } from '@ethersproject/constants'; +import { formatUnits } from '@ethersproject/units'; +import { FixedNumber } from '@ethersproject/bignumber'; const IS_BASE64_IMAGE = 'IS_BASE64_IMAGE'; @@ -168,3 +170,26 @@ export function mergeTokens( totalSupply: baseToken.totalSupply || mergeToken.totalSupply, }; } + +/** + * Formats the token amount. + * @param amount - The token amount. + * @param decimals - The token decimals. + * @param symbol - The token symbol. + * @returns The formatted token amount + symbol. + * @example + * formatTokenAmount('1000000000000000000', 18, 'ETH') // '1 ETH' + * formatTokenAmount('2000000000000000000', 18) // '2 tokens' + * formatTokenAmount('1000000000000000000') // 'some tokens' + * formatTokenAmount() // 'some tokens' + * formatTokenAmount(undefined, 18, 'ETH') // 'some ETH' + */ +export const formatTokenAmount = ( + amount: BigNumber | string, + decimals: number, + symbol: string +) => { + return `${FixedNumber.fromString(formatUnits(amount, decimals)) + .round(5) + .toString()} ${symbol}`; +}; diff --git a/packages/background/test/infrastructure/stores/migrator/reconciler.test.ts b/packages/background/test/infrastructure/stores/migrator/reconciler.test.ts index 0028de578..02e8089e9 100644 --- a/packages/background/test/infrastructure/stores/migrator/reconciler.test.ts +++ b/packages/background/test/infrastructure/stores/migrator/reconciler.test.ts @@ -226,6 +226,7 @@ const initialState: newBlankAppState = { settings: { hideAddressWarning: false, subscribedToReleaseaNotes: true, + subscribedToNotifications: true, useAntiPhishingProtection: true, defaultBrowserWallet: true, hideEstimatedGasExceedsThresholdWarning: false, @@ -450,6 +451,7 @@ describe('State reconciler', () => { showDefaultWalletPreferences: false, popupTab: 'activity', settings: { + subscribedToNotifications: true, subscribedToReleaseaNotes: true, hideAddressWarning: false, useAntiPhishingProtection: true, diff --git a/packages/background/test/mocks/mock-preferences.ts b/packages/background/test/mocks/mock-preferences.ts index c4d8d62f6..4dd578d9d 100644 --- a/packages/background/test/mocks/mock-preferences.ts +++ b/packages/background/test/mocks/mock-preferences.ts @@ -28,6 +28,7 @@ testInitState = { settings: { hideAddressWarning: false, // Shown by default subscribedToReleaseaNotes: true, + subscribedToNotifications: true, useAntiPhishingProtection: true, defaultBrowserWallet: true, hideEstimatedGasExceedsThresholdWarning: false, diff --git a/packages/background/test/utils/userPreferences.test.ts b/packages/background/test/utils/userPreferences.test.ts index 24a18b71d..904a56dc8 100644 --- a/packages/background/test/utils/userPreferences.test.ts +++ b/packages/background/test/utils/userPreferences.test.ts @@ -51,6 +51,7 @@ describe('userPreferences tests', () => { { settings: { subscribedToReleaseaNotes: false, + subscribedToNotifications: true, hideAddressWarning: false, useAntiPhishingProtection: true, defaultBrowserWallet: true, @@ -74,6 +75,7 @@ describe('userPreferences tests', () => { { settings: { subscribedToReleaseaNotes: true, + subscribedToNotifications: true, hideAddressWarning: false, useAntiPhishingProtection: true, defaultBrowserWallet: true, @@ -101,6 +103,7 @@ describe('userPreferences tests', () => { { settings: { subscribedToReleaseaNotes: true, + subscribedToNotifications: true, hideAddressWarning: false, useAntiPhishingProtection: true, defaultBrowserWallet: true, diff --git a/packages/ui/src/mock/MockBackgroundState.tsx b/packages/ui/src/mock/MockBackgroundState.tsx index 9628ed3cb..c58e2f578 100644 --- a/packages/ui/src/mock/MockBackgroundState.tsx +++ b/packages/ui/src/mock/MockBackgroundState.tsx @@ -428,6 +428,7 @@ export const initBackgroundState: BackgroundStateType = { popupTab: "activity", settings: { hideAddressWarning: false, + subscribedToNotifications: true, subscribedToReleaseaNotes: false, useAntiPhishingProtection: false, defaultBrowserWallet: true, diff --git a/packages/ui/src/router/routes.ts b/packages/ui/src/router/routes.ts index 972378c23..416424c80 100644 --- a/packages/ui/src/router/routes.ts +++ b/packages/ui/src/router/routes.ts @@ -42,7 +42,7 @@ import DefaultGasPreferencesPage from "../routes/preferences/DefaultGasPreferenc import ReleaseNotesPreferencesPage from "../routes/preferences/ReleaseNotesPreferencesPage" import OnDemandReleaseNotesPage from "../components/releaseNotes/OnDemandReleaseNotesPage" import WelcomeInfo from "../components/info/WelcomeInfo" -import WarningsPreferencesPage from "../routes/preferences/WarningsPreferencesPage" +import NotificationsAndWarningsPage from "../routes/preferences/NotificationsAndWarningsPage" import { TransitionRouteProps } from "./TransitionRoute" import ApprovePage from "../routes/transaction/ApprovePage" import AddAccountPage from "../routes/account/AddAccountPage" @@ -160,9 +160,9 @@ export const ROUTES_DEFINITION = [ }, { - path: "/settings/preferences/warnings", + path: "/settings/preferences/notificationsAndWarnings", exact: true, - component: WarningsPreferencesPage, + component: NotificationsAndWarningsPage, }, { diff --git a/packages/ui/src/routes/preferences/WarningsPreferencesPage.tsx b/packages/ui/src/routes/preferences/NotificationsAndWarningsPage.tsx similarity index 67% rename from packages/ui/src/routes/preferences/WarningsPreferencesPage.tsx rename to packages/ui/src/routes/preferences/NotificationsAndWarningsPage.tsx index f53bae865..b58d1468d 100644 --- a/packages/ui/src/routes/preferences/WarningsPreferencesPage.tsx +++ b/packages/ui/src/routes/preferences/NotificationsAndWarningsPage.tsx @@ -13,17 +13,19 @@ import { deepEqual } from "../../util/objectUtils" import { mergeReducer } from "../../util/reducerUtils" interface State { + subscribedToNotifications: boolean hideAddressWarning: boolean hideEstimatedGasExceedsThresholdWarning: boolean hideBridgeInsufficientNativeTokenWarning: boolean } -const WarningsPreferencesPage = () => { +const NotificationsAndWarningsPage = () => { const { settings } = useBlankState()! const { run, isSuccess, isError, isLoading } = useAsyncInvoke() const history = useHistory() const initialState = useRef({ + subscribedToNotifications: settings.subscribedToNotifications, hideAddressWarning: settings.hideAddressWarning, hideEstimatedGasExceedsThresholdWarning: settings.hideEstimatedGasExceedsThresholdWarning, @@ -31,7 +33,7 @@ const WarningsPreferencesPage = () => { settings.hideBridgeInsufficientNativeTokenWarning, }) - const [warningsConfig, setWarningsConfig] = useReducer( + const [preferencesConfig, setPreferencesConfig] = useReducer( mergeReducer(), initialState.current ) @@ -40,27 +42,31 @@ const WarningsPreferencesPage = () => { run( setUserSettings({ ...settings, - hideAddressWarning: warningsConfig.hideAddressWarning, + subscribedToNotifications: + preferencesConfig.subscribedToNotifications, + hideAddressWarning: preferencesConfig.hideAddressWarning, hideEstimatedGasExceedsThresholdWarning: - warningsConfig.hideEstimatedGasExceedsThresholdWarning, + preferencesConfig.hideEstimatedGasExceedsThresholdWarning, hideBridgeInsufficientNativeTokenWarning: - warningsConfig.hideBridgeInsufficientNativeTokenWarning, + preferencesConfig.hideBridgeInsufficientNativeTokenWarning, }) ) } if (isError) { - throw new Error("Could not update the address warning configuration.") + throw new Error( + "Could not update the address notifications and warning configuration." + ) } return ( } + header={} footer={ { } >
+ + Receive BlockWallet's browser notifications. + + + + setPreferencesConfig({ + subscribedToNotifications: value, + }) + } + /> + +
Warn me when my selected account address is different from transaction's address. - setWarningsConfig({ + setPreferencesConfig({ hideAddressWarning: !value, }) } @@ -92,13 +115,12 @@ const WarningsPreferencesPage = () => { - setWarningsConfig({ + setPreferencesConfig({ hideEstimatedGasExceedsThresholdWarning: !value, }) } @@ -113,10 +135,10 @@ const WarningsPreferencesPage = () => { id="bridgeNativeTokenWarning" label="Show Bridging Warning" defaultChecked={ - !warningsConfig.hideBridgeInsufficientNativeTokenWarning + !preferencesConfig.hideBridgeInsufficientNativeTokenWarning } onToggle={(value) => - setWarningsConfig({ + setPreferencesConfig({ hideBridgeInsufficientNativeTokenWarning: !value, }) } @@ -124,13 +146,13 @@ const WarningsPreferencesPage = () => {
) } -export default WarningsPreferencesPage +export default NotificationsAndWarningsPage diff --git a/packages/ui/src/routes/settings/PreferencesPage.tsx b/packages/ui/src/routes/settings/PreferencesPage.tsx index e7e68d1df..921785382 100644 --- a/packages/ui/src/routes/settings/PreferencesPage.tsx +++ b/packages/ui/src/routes/settings/PreferencesPage.tsx @@ -41,8 +41,8 @@ const PreferencesPage = () => { }, { icon: bell, - label: "Warnings", - to: "/settings/preferences/warnings", + label: "Notifications & Warnings", + to: "/settings/preferences/notificationsAndWarnings", }, { icon: shield, From 329792919840d9e3182fd33789f363fbcbcc6f6c Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Wed, 8 Mar 2023 13:06:08 +0200 Subject: [PATCH 032/110] feat: network indicator redesign UI --- .../components/chain/NetworkDisplayBadge.tsx | 45 ++++++++++++---- .../ui/src/components/input/NetworkSelect.tsx | 53 ++++++++++++------- .../components/networks/NetworkDisplay.tsx | 23 +++++--- .../ui/src/context/hooks/useTokensList.ts | 3 +- .../ui/src/routes/dApp/AddEthereumChain.tsx | 6 +-- 5 files changed, 92 insertions(+), 38 deletions(-) diff --git a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx index f2ecbe45e..2511a5fef 100644 --- a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx +++ b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx @@ -2,6 +2,7 @@ import { Network } from "@block-wallet/background/utils/constants/networks" import { classnames } from "../../styles" import { getNetworkColor } from "../../util/getNetworkColor" import GenericTooltip from "../label/GenericTooltip" +import useIsHovering from "../../util/hooks/useIsHovering" const NetworkDisplayBadge = ({ network, @@ -16,6 +17,7 @@ const NetworkDisplayBadge = ({ }) => { const networkDesc = network.desc const networkColor = getNetworkColor(network) + const { isHovering, getIsHoveringProps } = useIsHovering() // We limit the string chars here regardless of the truncate flag // and the truncate class to prevent issues with the animated bullet size @@ -25,8 +27,15 @@ const NetworkDisplayBadge = ({ ? `${networkDesc.slice(0, 42)}...` : networkDesc : networkDesc + + const displayFull = + isHovering || + !(network.iconUrls && network.iconUrls.length > 0) || + !truncate + return (
- + {network.iconUrls && network.iconUrls.length > 0 ? ( + network icon + ) : ( + + )} + {formattedNetworkName} diff --git a/packages/ui/src/components/input/NetworkSelect.tsx b/packages/ui/src/components/input/NetworkSelect.tsx index 9c0f96f3a..b3b76e915 100644 --- a/packages/ui/src/components/input/NetworkSelect.tsx +++ b/packages/ui/src/components/input/NetworkSelect.tsx @@ -1,4 +1,4 @@ -import { FunctionComponent, useRef, useState } from "react" +import { FunctionComponent, useMemo, useRef, useState } from "react" import { RiArrowDownSLine, RiArrowUpSLine } from "react-icons/ri" import { BsCheck } from "react-icons/bs" import { useHistory } from "react-router-dom" @@ -31,10 +31,19 @@ const NetworkOption: FunctionComponent<{ )} onClick={async () => await handleNetworkChange(option.name)} > - + {option.iconUrls && option.iconUrls.length > 0 ? ( + network icon + ) : ( + + )} + { - const network = availableNetworks[selectedNetwork.toUpperCase()] - const color = getNetworkColor(network) - return { color: color, desc: network.desc } - } + const networkData = availableNetworks[selectedNetwork.toUpperCase()] + + const networkColor = useMemo(() => { + return getNetworkColor(networkData) + }, [networkData]) return (
- + {networkData.iconUrls && networkData.iconUrls.length > 0 ? ( + network icon + ) : ( + + )} - {getNetworkData().desc} + {networkData.desc} {networkList ? ( diff --git a/packages/ui/src/components/networks/NetworkDisplay.tsx b/packages/ui/src/components/networks/NetworkDisplay.tsx index 19f20e987..4b3e06133 100644 --- a/packages/ui/src/components/networks/NetworkDisplay.tsx +++ b/packages/ui/src/components/networks/NetworkDisplay.tsx @@ -203,12 +203,23 @@ const NetworkDisplay = ({ className="text-gray-500 mr-2" size={20} /> - + {networkInfo.iconUrls && + networkInfo.iconUrls.length > 0 ? ( + network icon + ) : ( + + )}
{networkInfo.desc} diff --git a/packages/ui/src/context/hooks/useTokensList.ts b/packages/ui/src/context/hooks/useTokensList.ts index fce6d679d..2ba03dab2 100644 --- a/packages/ui/src/context/hooks/useTokensList.ts +++ b/packages/ui/src/context/hooks/useTokensList.ts @@ -22,7 +22,8 @@ export const useTokensList = (): TokenListInfo => { decimals: nativeCurrency.decimals, name: nativeCurrency.name, symbol: nativeCurrency.symbol, - logo: defaultNetworkLogo, + // Use Network Logo if nativeCurrency logo is not available + logo: nativeCurrency.logo ?? defaultNetworkLogo, } if (chainId in balances) { diff --git a/packages/ui/src/routes/dApp/AddEthereumChain.tsx b/packages/ui/src/routes/dApp/AddEthereumChain.tsx index e4c752ce4..84948bc00 100644 --- a/packages/ui/src/routes/dApp/AddEthereumChain.tsx +++ b/packages/ui/src/routes/dApp/AddEthereumChain.tsx @@ -232,7 +232,7 @@ const AddEthereumChain: FunctionComponent = ({ expandable: true, }, { - title: "Currency Icon URL", + title: "Network Icon URL", content: iconUrl, expandable: true, }, @@ -337,8 +337,8 @@ const AddEthereumChain: FunctionComponent = ({

{validations.knownIcon - ? "Currency Icon" - : "Currency Icon URL"} + ? "Network Icon" + : "Network Icon URL"}

{!validations.knownIcon && ( Date: Wed, 8 Mar 2023 13:06:24 +0200 Subject: [PATCH 033/110] feat: network indicator redesign Background --- packages/background/package.json | 2 +- .../src/controllers/NetworkController.ts | 13 +++- .../stores/migrator/migrations/index.ts | 2 + .../migrator/migrations/migration-62.ts | 78 +++++++++++++++++++ .../src/utils/constants/networks.ts | 23 +++++- 5 files changed, 112 insertions(+), 6 deletions(-) create mode 100644 packages/background/src/infrastructure/stores/migrator/migrations/migration-62.ts diff --git a/packages/background/package.json b/packages/background/package.json index 3c247f220..b1e9c8aa8 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@block-wallet/background", - "version": "1.1.1", + "version": "1.1.2", "private": true, "dependencies": { "@block-wallet/chains-assets": "https://github.com/block-wallet/chains-assets#v0.0.27", diff --git a/packages/background/src/controllers/NetworkController.ts b/packages/background/src/controllers/NetworkController.ts index 7943ad020..b73833c46 100644 --- a/packages/background/src/controllers/NetworkController.ts +++ b/packages/background/src/controllers/NetworkController.ts @@ -407,10 +407,16 @@ export default class NetworkController extends BaseController n.test === network.test) .map((c) => c.order) .sort((a, b) => b - a)[0] + 1, - iconUrls: nativeCurrencyIcon ? [nativeCurrencyIcon] : undefined, + iconUrls: networkIcon ? [networkIcon] : undefined, nativelySupported: false, hasFixedGasCost: false, etherscanApiUrl: chainDataFromList?.scanApi, diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts index f0bb6cabd..e38e4f1b9 100644 --- a/packages/background/src/infrastructure/stores/migrator/migrations/index.ts +++ b/packages/background/src/infrastructure/stores/migrator/migrations/index.ts @@ -60,6 +60,7 @@ import migration58 from './migration-58'; import migration59 from './migration-59'; import migration60 from './migration-60'; import migration61 from './migration-61'; +import migration62 from './migration-62'; const migrations: IMigration[] = [ migration01, @@ -123,5 +124,6 @@ const migrations: IMigration[] = [ migration59, migration60, migration61, + migration62 ]; export default (): IMigration[] => migrations; diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/migration-62.ts b/packages/background/src/infrastructure/stores/migrator/migrations/migration-62.ts new file mode 100644 index 000000000..c47f92dda --- /dev/null +++ b/packages/background/src/infrastructure/stores/migrator/migrations/migration-62.ts @@ -0,0 +1,78 @@ +import { BlankAppState } from '@block-wallet/background/utils/constants/initialState'; +import { IMigration } from '../IMigration'; +import { INITIAL_NETWORKS } from '../../../../utils/constants/networks'; +import { normalizeNetworksOrder } from '../../../../utils/networks'; + +/** + * Update Network and native currency logos + */ +export default { + migrate: async (persistedState: BlankAppState) => { + const { availableNetworks } = persistedState.NetworkController; + const updatedNetworks = { ...availableNetworks }; + + updatedNetworks.MAINNET = { + ...updatedNetworks.MAINNET, + iconUrls: INITIAL_NETWORKS.MAINNET.iconUrls, + }; + + updatedNetworks.ARBITRUM = { + ...updatedNetworks.ARBITRUM, + iconUrls: INITIAL_NETWORKS.ARBITRUM.iconUrls, + nativeCurrency: { + ...updatedNetworks.ARBITRUM.nativeCurrency, + logo: INITIAL_NETWORKS.ARBITRUM.nativeCurrency.logo, + }, + }; + + updatedNetworks.OPTIMISM = { + ...updatedNetworks.OPTIMISM, + iconUrls: INITIAL_NETWORKS.OPTIMISM.iconUrls, + nativeCurrency: { + ...updatedNetworks.OPTIMISM.nativeCurrency, + logo: INITIAL_NETWORKS.OPTIMISM.nativeCurrency.logo, + }, + }; + + updatedNetworks.XDAI = { + ...updatedNetworks.XDAI, + iconUrls: INITIAL_NETWORKS.XDAI.iconUrls, + nativeCurrency: { + ...updatedNetworks.XDAI.nativeCurrency, + logo: INITIAL_NETWORKS.XDAI.nativeCurrency.logo, + }, + }; + + updatedNetworks.GOERLI = { + ...updatedNetworks.GOERLI, + iconUrls: INITIAL_NETWORKS.GOERLI.iconUrls, + }; + + updatedNetworks.ZKSYNC_ALPHA_TESTNET = { + ...updatedNetworks.ZKSYNC_ALPHA_TESTNET, + nativeCurrency: { + ...updatedNetworks.ZKSYNC_ALPHA_TESTNET.nativeCurrency, + logo: INITIAL_NETWORKS.ZKSYNC_ALPHA_TESTNET.nativeCurrency.logo, + }, + }; + + updatedNetworks.LOCALHOST = { + ...updatedNetworks.LOCALHOST, + nativeCurrency: { + ...updatedNetworks.LOCALHOST.nativeCurrency, + logo: INITIAL_NETWORKS.LOCALHOST.nativeCurrency.logo, + }, + }; + + const orderedNetworks = normalizeNetworksOrder(updatedNetworks); + + return { + ...persistedState, + NetworkController: { + ...persistedState.NetworkController, + availableNetworks: { ...orderedNetworks }, + }, + }; + }, + version: '1.1.2', +} as IMigration; diff --git a/packages/background/src/utils/constants/networks.ts b/packages/background/src/utils/constants/networks.ts index 9faad26ab..b5d586aa5 100644 --- a/packages/background/src/utils/constants/networks.ts +++ b/packages/background/src/utils/constants/networks.ts @@ -20,9 +20,10 @@ export type Network = { name: string; symbol: string; decimals: number; + logo?: string; // Used if the native currency logo is different from network logo }; hasFixedGasCost?: boolean; - iconUrls?: string[]; + iconUrls?: string[]; // Network logo enable: boolean; features: BlankSupportedFeatures[]; test: boolean; @@ -69,6 +70,7 @@ export interface AddNetworkType { symbol: string; name?: string; decimals?: number; + logo?: string; }; rpcUrls?: string[]; test: boolean; @@ -163,6 +165,9 @@ export const INITIAL_NETWORKS: Networks = { ens: true, showGasLevels: true, rpcUrls: [`https://mainnet-node.blockwallet.io`], + iconUrls: [ + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', + ], defaultRpcUrl: `https://mainnet-node.blockwallet.io`, blockExplorerUrls: ['https://etherscan.io'], blockExplorerName: 'Etherscan', @@ -185,6 +190,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Ether', symbol: 'ETH', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', }, hasFixedGasCost: false, enable: true, @@ -194,6 +200,9 @@ export const INITIAL_NETWORKS: Networks = { ens: false, showGasLevels: false, rpcUrls: ['https://arbitrum-node.blockwallet.io'], + iconUrls: [ + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/arbitrum/info/logo.png', + ], defaultRpcUrl: 'https://arbitrum-node.blockwallet.io', blockExplorerUrls: ['https://arbiscan.io'], blockExplorerName: 'Arbiscan', @@ -216,6 +225,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Ether', symbol: 'ETH', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', }, hasFixedGasCost: false, gasLowerCap: { @@ -228,6 +238,9 @@ export const INITIAL_NETWORKS: Networks = { ens: false, showGasLevels: false, rpcUrls: ['https://optimism-node.blockwallet.io'], + iconUrls: [ + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/optimism/info/logo.png', + ], defaultRpcUrl: 'https://optimism-node.blockwallet.io', blockExplorerUrls: ['https://optimistic.etherscan.io'], blockExplorerName: 'Etherscan', @@ -388,6 +401,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'xDAI', symbol: 'xDAI', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/xdai/assets/0x/logo.png', }, hasFixedGasCost: false, enable: true, @@ -397,7 +411,7 @@ export const INITIAL_NETWORKS: Networks = { ens: false, showGasLevels: false, iconUrls: [ - 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/xdai/assets/0x/logo.png', + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/xdai/info/logo.png', ], rpcUrls: ['https://xdai-node.blockwallet.io'], defaultRpcUrl: 'https://xdai-node.blockwallet.io', @@ -460,6 +474,9 @@ export const INITIAL_NETWORKS: Networks = { ens: true, showGasLevels: true, rpcUrls: [`https://goerli-node.blockwallet.io`], + iconUrls: [ + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', + ], defaultRpcUrl: `https://goerli-node.blockwallet.io`, blockExplorerUrls: ['https://goerli.etherscan.io'], blockExplorerName: 'Etherscan', @@ -541,6 +558,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Ether', symbol: 'ETH', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', }, iconUrls: [ 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/zksync/info/logo.png', @@ -664,6 +682,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Ether', symbol: 'ETH', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', }, hasFixedGasCost: false, enable: true, From a70b35d49df1bd5ebfdb10e445ee6f40dfea5d16 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Thu, 9 Mar 2023 11:03:37 +0200 Subject: [PATCH 034/110] fix: handle wrong network image URL --- .../ui/src/components/input/NetworkSelect.tsx | 21 +++++++++++++++---- .../components/networks/NetworkDisplay.tsx | 7 ++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/packages/ui/src/components/input/NetworkSelect.tsx b/packages/ui/src/components/input/NetworkSelect.tsx index b3b76e915..eed63cd10 100644 --- a/packages/ui/src/components/input/NetworkSelect.tsx +++ b/packages/ui/src/components/input/NetworkSelect.tsx @@ -20,6 +20,8 @@ const NetworkOption: FunctionComponent<{ disabled?: boolean }> = ({ option, selectedNetwork, handleNetworkChange, disabled = false }) => { const networkColor = getNetworkColor(option) + const [hasImageError, setHasImageError] = useState(false) + return (
  • await handleNetworkChange(option.name)} > - {option.iconUrls && option.iconUrls.length > 0 ? ( + {!hasImageError && option.iconUrls && option.iconUrls.length > 0 ? ( network icon { + setHasImageError(true) + }} /> ) : ( = ({ className, optionsContainerClassName }) => { const history = useHistory()! const [networkList, setNetworkList] = useState(false) + const [hasImageError, setHasImageError] = useState(false) + const { selectedNetwork, availableNetworks, @@ -73,9 +80,10 @@ const NetworkSelect: FunctionComponent<{ const ref = useRef(null) useOnClickOutside(ref, () => setNetworkList(false)) - const handleNetworkChange = (network: string) => { + const handleNetworkChange = async (network: string) => { setNetworkList(false) - changeNetwork(network) + await changeNetwork(network) + setHasImageError(false) } const networkData = availableNetworks[selectedNetwork.toUpperCase()] @@ -105,11 +113,16 @@ const NetworkSelect: FunctionComponent<{ networkList && "border-primary-blue-default" )} > - {networkData.iconUrls && networkData.iconUrls.length > 0 ? ( + {!hasImageError && + networkData.iconUrls && + networkData.iconUrls.length > 0 ? ( network icon { + setHasImageError(true) + }} /> ) : ( (null) @@ -203,12 +204,16 @@ const NetworkDisplay = ({ className="text-gray-500 mr-2" size={20} /> - {networkInfo.iconUrls && + {!hasImageError && + networkInfo.iconUrls && networkInfo.iconUrls.length > 0 ? ( network icon { + setHasImageError(true) + }} /> ) : ( Date: Thu, 9 Mar 2023 12:03:59 +0200 Subject: [PATCH 035/110] fix: NetworkDisplayBadge Network icon url error --- .../ui/src/components/chain/NetworkDisplayBadge.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx index 2511a5fef..e804e2901 100644 --- a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx +++ b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx @@ -3,6 +3,7 @@ import { classnames } from "../../styles" import { getNetworkColor } from "../../util/getNetworkColor" import GenericTooltip from "../label/GenericTooltip" import useIsHovering from "../../util/hooks/useIsHovering" +import { useState } from "react" const NetworkDisplayBadge = ({ network, @@ -18,6 +19,7 @@ const NetworkDisplayBadge = ({ const networkDesc = network.desc const networkColor = getNetworkColor(network) const { isHovering, getIsHoveringProps } = useIsHovering() + const [hasImageError, setHasImageError] = useState(false) // We limit the string chars here regardless of the truncate flag // and the truncate class to prevent issues with the animated bullet size @@ -31,7 +33,8 @@ const NetworkDisplayBadge = ({ const displayFull = isHovering || !(network.iconUrls && network.iconUrls.length > 0) || - !truncate + !truncate || + hasImageError return (
    - {network.iconUrls && network.iconUrls.length > 0 ? ( + {!hasImageError && + network.iconUrls && + network.iconUrls.length > 0 ? ( network icon { + setHasImageError(true) + }} /> ) : ( Date: Fri, 10 Mar 2023 17:27:38 +0200 Subject: [PATCH 036/110] fix: UI inconsistencies and improvements --- .../ui/src/components/ActivityAssetsView.tsx | 2 +- .../ui/src/components/CancelSpeedUpCommon.tsx | 2 +- .../assets/ActivityAllowancesView.tsx | 2 +- .../src/components/bridge/BridgeDetails.tsx | 2 +- .../ui/src/components/button/ActionButton.tsx | 2 +- .../ui/src/components/chain/ChainDisplay.tsx | 2 +- .../components/chain/NetworkDisplayBadge.tsx | 61 ++++++------------- .../chain/RPCValidationEndLabelInfo.tsx | 22 +++---- .../src/components/dApp/DAppPopupHeader.tsx | 2 +- .../src/components/dialog/CheckboxDialog.tsx | 2 +- .../src/components/dialog/ConfirmDialog.tsx | 2 +- .../components/error/ErrorFallbackPage.tsx | 2 +- .../ui/src/components/gas/GasPricesInfo.tsx | 4 +- packages/ui/src/components/input/Checkbox.tsx | 2 +- .../src/components/input/DropDownSelector.tsx | 2 +- .../ui/src/components/input/NetworkSelect.tsx | 32 ++++++---- .../ui/src/components/popup/PopupHeader.tsx | 2 +- .../ui/src/components/popup/PopupLayout.tsx | 4 +- .../transactions/GasPriceComponent.tsx | 4 +- .../transactions/GasPriceSelector.tsx | 4 +- .../transactions/TransactionDetails.tsx | 2 +- .../ui/src/components/ui/OutlinedButton.tsx | 2 +- .../ui/Pagination/PaginationControls.tsx | 2 +- .../ui/src/routes/account/AddAccountPage.tsx | 2 +- .../src/routes/account/CreateAccountPage.tsx | 2 +- .../src/routes/account/ImportAccountPage.tsx | 2 +- .../src/routes/account/ResetAccountPage.tsx | 2 +- .../ui/src/routes/dApp/AddEthereumChain.tsx | 2 +- .../src/routes/dApp/SwitchEthereumChain.tsx | 8 +-- .../routes/hardware-wallet/AccountsPage.tsx | 2 +- packages/ui/src/routes/send/SendPage.tsx | 2 +- packages/ui/src/routes/settings/AboutPage.tsx | 6 +- .../ui/src/routes/settings/AddContactPage.tsx | 2 +- .../ui/src/routes/settings/AddTokensPage.tsx | 2 +- .../ui/src/routes/settings/SettingsPage.tsx | 2 +- packages/ui/src/styles/classes.ts | 10 +-- 36 files changed, 94 insertions(+), 113 deletions(-) diff --git a/packages/ui/src/components/ActivityAssetsView.tsx b/packages/ui/src/components/ActivityAssetsView.tsx index 003cf626b..99dea366e 100644 --- a/packages/ui/src/components/ActivityAssetsView.tsx +++ b/packages/ui/src/components/ActivityAssetsView.tsx @@ -40,7 +40,7 @@ const ActivityAssetsView: FunctionComponent<{ initialTab: PopupTabs }> = ({ `flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-blue-default ${ tab === value ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" - : "border-gray-200 text-gray-500 border-b hover:text-primary-blue-default hover:font-medium" + : "border-primary-grey-hover text-gray-500 border-b hover:text-primary-blue-default hover:font-medium" }` } containerClassName="flex flex-row -ml-6" diff --git a/packages/ui/src/components/CancelSpeedUpCommon.tsx b/packages/ui/src/components/CancelSpeedUpCommon.tsx index a50d167c3..2b4f905c2 100644 --- a/packages/ui/src/components/CancelSpeedUpCommon.tsx +++ b/packages/ui/src/components/CancelSpeedUpCommon.tsx @@ -689,7 +689,7 @@ const CancelAndSpeedUpComponent = ({ )}

    { "flex-1 flex flex-row items-center justify-center p-3 text-sm hover:text-primary-primary-blue-default", tab === value ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" - : "border-gray-200 text-gray-500 border-b hover:font-medium" + : "border-primary-grey-hover text-gray-500 border-b hover:font-medium" ) } containerClassName="flex flex-row -ml-6 !mt-0 w-[calc(100%+3rem)]" diff --git a/packages/ui/src/components/bridge/BridgeDetails.tsx b/packages/ui/src/components/bridge/BridgeDetails.tsx index 02dcdb5b8..e577497aa 100644 --- a/packages/ui/src/components/bridge/BridgeDetails.tsx +++ b/packages/ui/src/components/bridge/BridgeDetails.tsx @@ -109,7 +109,7 @@ const BridgeDetails: FC<{ ${ selectedTab.label === value.label ? "border-primary-blue-default border-b-2 text-primary-blue-default font-bold" - : "border-gray-200 text-gray-500 border-b" + : "border-primary-grey-hover text-gray-500 border-b" }`, value.disabled && "cursor-default" ) diff --git a/packages/ui/src/components/button/ActionButton.tsx b/packages/ui/src/components/button/ActionButton.tsx index 5d093a714..0f9490900 100644 --- a/packages/ui/src/components/button/ActionButton.tsx +++ b/packages/ui/src/components/button/ActionButton.tsx @@ -1,5 +1,5 @@ import classnames from "classnames" -import { FunctionComponent, ReactElement } from "react" +import { FunctionComponent } from "react" import { Link } from "react-router-dom" import { Classes } from "../../styles" diff --git a/packages/ui/src/components/chain/ChainDisplay.tsx b/packages/ui/src/components/chain/ChainDisplay.tsx index be6d9a78d..30e080072 100644 --- a/packages/ui/src/components/chain/ChainDisplay.tsx +++ b/packages/ui/src/components/chain/ChainDisplay.tsx @@ -43,7 +43,7 @@ const ChainDisplay: FC = ({ className="flex justify-start items-center flex-row py-3" title={name} > -
    +
    { diff --git a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx index e804e2901..985734104 100644 --- a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx +++ b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx @@ -2,46 +2,25 @@ import { Network } from "@block-wallet/background/utils/constants/networks" import { classnames } from "../../styles" import { getNetworkColor } from "../../util/getNetworkColor" import GenericTooltip from "../label/GenericTooltip" -import useIsHovering from "../../util/hooks/useIsHovering" import { useState } from "react" const NetworkDisplayBadge = ({ network, className, - fill = false, - truncate = false, + showName = false, }: { network: Network - fill?: boolean - truncate?: boolean className?: string + showName?: boolean }) => { const networkDesc = network.desc const networkColor = getNetworkColor(network) - const { isHovering, getIsHoveringProps } = useIsHovering() const [hasImageError, setHasImageError] = useState(false) - // We limit the string chars here regardless of the truncate flag - // and the truncate class to prevent issues with the animated bullet size - // and to have a limit on huge network descriptions. - const formattedNetworkName = truncate - ? networkDesc.length > 42 - ? `${networkDesc.slice(0, 42)}...` - : networkDesc - : networkDesc - - const displayFull = - isHovering || - !(network.iconUrls && network.iconUrls.length > 0) || - !truncate || - hasImageError - return (
    { setHasImageError(true) }} @@ -60,32 +39,26 @@ const NetworkDisplayBadge = ({ ) : ( )} - - {formattedNetworkName} - + {showName && ( + + {networkDesc} + + )} + {networkDesc}

    } />
    diff --git a/packages/ui/src/components/chain/RPCValidationEndLabelInfo.tsx b/packages/ui/src/components/chain/RPCValidationEndLabelInfo.tsx index adb9e68cd..5848ab3a6 100644 --- a/packages/ui/src/components/chain/RPCValidationEndLabelInfo.tsx +++ b/packages/ui/src/components/chain/RPCValidationEndLabelInfo.tsx @@ -77,7 +77,7 @@ const RPCValidationEndLabelInfo = ({ = ({
    )} {showNetworkIndicator && ( - + )} ) diff --git a/packages/ui/src/components/dialog/CheckboxDialog.tsx b/packages/ui/src/components/dialog/CheckboxDialog.tsx index 9dd4bdf3d..e95327daa 100644 --- a/packages/ui/src/components/dialog/CheckboxDialog.tsx +++ b/packages/ui/src/components/dialog/CheckboxDialog.tsx @@ -67,7 +67,7 @@ const CheckBoxDialog: FunctionComponent<{
    -
    +
    {showCloseButton && (
    -
    +
    Download state logs for support diff --git a/packages/ui/src/components/gas/GasPricesInfo.tsx b/packages/ui/src/components/gas/GasPricesInfo.tsx index da68963f1..bafdbb191 100644 --- a/packages/ui/src/components/gas/GasPricesInfo.tsx +++ b/packages/ui/src/components/gas/GasPricesInfo.tsx @@ -229,14 +229,14 @@ const GasPricesInfo: FC = () => { ] return (
    { diff --git a/packages/ui/src/components/input/DropDownSelector.tsx b/packages/ui/src/components/input/DropDownSelector.tsx index ce8296a95..62183aaa5 100644 --- a/packages/ui/src/components/input/DropDownSelector.tsx +++ b/packages/ui/src/components/input/DropDownSelector.tsx @@ -127,7 +127,7 @@ const DropDownSelector: FC = ({ {/* Popup */}
    { setNetworkList(false) - await changeNetwork(network) - setHasImageError(false) + changeNetwork(network) } const networkData = availableNetworks[selectedNetwork.toUpperCase()] @@ -92,6 +91,20 @@ const NetworkSelect: FunctionComponent<{ return getNetworkColor(networkData) }, [networkData]) + // Check if the network icon is valid before render. if not show the colored circle + useEffect(() => { + if (networkData.iconUrls && networkData.iconUrls.length > 0) { + const image = new Image() + image.src = networkData.iconUrls[0] + image.onerror = () => { + setHasImageError(true) + } + image.onload = () => { + setHasImageError(false) + } + } + }, [networkData]) + return (
    { - setHasImageError(true) - }} + className="w-4 h-4 mr-2 ml-1" /> ) : ( {}} /> diff --git a/packages/ui/src/components/popup/PopupHeader.tsx b/packages/ui/src/components/popup/PopupHeader.tsx index 724ad5983..da1855123 100644 --- a/packages/ui/src/components/popup/PopupHeader.tsx +++ b/packages/ui/src/components/popup/PopupHeader.tsx @@ -160,7 +160,7 @@ const PopupHeader: FunctionComponent = ({ )} {networkIndicator && ( - + )} {close && (
    {footer ? ( <> -
    +
    {footer} ) : null} diff --git a/packages/ui/src/components/transactions/GasPriceComponent.tsx b/packages/ui/src/components/transactions/GasPriceComponent.tsx index fadeb3fab..630325edd 100644 --- a/packages/ui/src/components/transactions/GasPriceComponent.tsx +++ b/packages/ui/src/components/transactions/GasPriceComponent.tsx @@ -522,7 +522,7 @@ const GasSelectorAdvanced = (props: GasComponentProps) => {
    -
    +
    -
    +
    -
    +
    diff --git a/packages/ui/src/routes/account/ImportAccountPage.tsx b/packages/ui/src/routes/account/ImportAccountPage.tsx index de80d057b..01f3316ec 100644 --- a/packages/ui/src/routes/account/ImportAccountPage.tsx +++ b/packages/ui/src/routes/account/ImportAccountPage.tsx @@ -231,7 +231,7 @@ const ImportAccountPage = () => {
    )}
    -
    +
    { your seed phrase and your on-chain balance will not change. You will be able to use your account normally. -
    +
    Download state logs for support diff --git a/packages/ui/src/routes/dApp/AddEthereumChain.tsx b/packages/ui/src/routes/dApp/AddEthereumChain.tsx index 84948bc00..dd144cefb 100644 --- a/packages/ui/src/routes/dApp/AddEthereumChain.tsx +++ b/packages/ui/src/routes/dApp/AddEthereumChain.tsx @@ -284,7 +284,7 @@ const AddEthereumChain: FunctionComponent = ({ BlockWallet
    -
    +

    Network Name diff --git a/packages/ui/src/routes/dApp/SwitchEthereumChain.tsx b/packages/ui/src/routes/dApp/SwitchEthereumChain.tsx index ccb5bafb6..7ff6d1953 100644 --- a/packages/ui/src/routes/dApp/SwitchEthereumChain.tsx +++ b/packages/ui/src/routes/dApp/SwitchEthereumChain.tsx @@ -165,8 +165,7 @@ const SwitchEthereumChain: FunctionComponent = ({ )} @@ -177,7 +176,7 @@ const SwitchEthereumChain: FunctionComponent = ({ style={{ width: "calc(100%)" }} >

    {/* Arrow icon */} -
    +
    @@ -187,8 +186,7 @@ const SwitchEthereumChain: FunctionComponent = ({ )}
    diff --git a/packages/ui/src/routes/hardware-wallet/AccountsPage.tsx b/packages/ui/src/routes/hardware-wallet/AccountsPage.tsx index c4859e00e..964671249 100644 --- a/packages/ui/src/routes/hardware-wallet/AccountsPage.tsx +++ b/packages/ui/src/routes/hardware-wallet/AccountsPage.tsx @@ -522,7 +522,7 @@ const AdvancedSettings = ({
    -
    +
    -
    +
    Date: Mon, 13 Mar 2023 17:31:17 +0200 Subject: [PATCH 038/110] fix: edit background version --- packages/background/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/background/package.json b/packages/background/package.json index b1e9c8aa8..dcb71c418 100644 --- a/packages/background/package.json +++ b/packages/background/package.json @@ -1,6 +1,6 @@ { "name": "@block-wallet/background", - "version": "1.1.2", + "version": "1.1.3", "private": true, "dependencies": { "@block-wallet/chains-assets": "https://github.com/block-wallet/chains-assets#v0.0.27", From 81fcfb4d36a978417bc901d8489e233889bc7f26 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Tue, 14 Mar 2023 18:06:53 +0200 Subject: [PATCH 039/110] fix: unlock tooltip --- packages/ui/src/routes/UnlockPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/src/routes/UnlockPage.tsx b/packages/ui/src/routes/UnlockPage.tsx index cdf5073f5..9456bfe9a 100644 --- a/packages/ui/src/routes/UnlockPage.tsx +++ b/packages/ui/src/routes/UnlockPage.tsx @@ -121,7 +121,7 @@ const UnlockPage = () => { className="pl-2 text-primary-200 cursor-pointer hover:text-primary-blue-default" /> From 49068bbccdbbabf10e2f6dd3f1aa6324df239bd2 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Tue, 14 Mar 2023 18:07:12 +0200 Subject: [PATCH 040/110] fix: origin app icon size bug --- packages/ui/src/components/icons/AppIcon.tsx | 41 +++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/packages/ui/src/components/icons/AppIcon.tsx b/packages/ui/src/components/icons/AppIcon.tsx index 6612b871d..61fc28171 100644 --- a/packages/ui/src/components/icons/AppIcon.tsx +++ b/packages/ui/src/components/icons/AppIcon.tsx @@ -14,24 +14,27 @@ const AppIcon = ({ iconSize, background = true, title, -}: AppIconProps) => ( -
    - {iconURL ? ( - icon - ) : null} -
    -) +}: AppIconProps) => { + const imgClassName = iconSize ? `max-h-${iconSize}` : `max-h-${size - 3}` + return ( +
    + {iconURL ? ( + icon + ) : null} +
    + ) +} export default AppIcon From 585e4f3fe1aa99d8e0ffc64663b030dc1aaaa206 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Tue, 14 Mar 2023 18:54:38 +0200 Subject: [PATCH 041/110] fix: new network logos --- .../migrator/migrations/migration-63.ts | 27 +++++++++++++++++++ .../src/utils/constants/networks.ts | 7 +++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/background/src/infrastructure/stores/migrator/migrations/migration-63.ts b/packages/background/src/infrastructure/stores/migrator/migrations/migration-63.ts index 2113fd8ab..f5df52615 100644 --- a/packages/background/src/infrastructure/stores/migrator/migrations/migration-63.ts +++ b/packages/background/src/infrastructure/stores/migrator/migrations/migration-63.ts @@ -43,6 +43,24 @@ export default { }, }; + updatedNetworks.ZKSYNC_ERA_MAINNET = { + ...updatedNetworks.ZKSYNC_ERA_MAINNET, + iconUrls: INITIAL_NETWORKS.ZKSYNC_ERA_MAINNET.iconUrls, + nativeCurrency: { + ...updatedNetworks.ZKSYNC_ERA_MAINNET.nativeCurrency, + logo: INITIAL_NETWORKS.ZKSYNC_ERA_MAINNET.nativeCurrency.logo, + }, + }; + + updatedNetworks.RSK = { + ...updatedNetworks.RSK, + iconUrls: INITIAL_NETWORKS.RSK.iconUrls, + nativeCurrency: { + ...updatedNetworks.RSK.nativeCurrency, + logo: INITIAL_NETWORKS.RSK.nativeCurrency.logo, + }, + }; + updatedNetworks.GOERLI = { ...updatedNetworks.GOERLI, iconUrls: INITIAL_NETWORKS.GOERLI.iconUrls, @@ -56,6 +74,15 @@ export default { }, }; + updatedNetworks.RSK_TESTNET = { + ...updatedNetworks.RSK_TESTNET, + iconUrls: INITIAL_NETWORKS.RSK_TESTNET.iconUrls, + nativeCurrency: { + ...updatedNetworks.RSK_TESTNET.nativeCurrency, + logo: INITIAL_NETWORKS.RSK_TESTNET.nativeCurrency.logo, + }, + }; + updatedNetworks.LOCALHOST = { ...updatedNetworks.LOCALHOST, nativeCurrency: { diff --git a/packages/background/src/utils/constants/networks.ts b/packages/background/src/utils/constants/networks.ts index 782644fe5..8e1e0b018 100644 --- a/packages/background/src/utils/constants/networks.ts +++ b/packages/background/src/utils/constants/networks.ts @@ -434,6 +434,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Smart Bitcoin', symbol: 'RBTC', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/rsk/assets/0x/logo.png', }, hasFixedGasCost: false, enable: true, @@ -443,7 +444,7 @@ export const INITIAL_NETWORKS: Networks = { ens: false, showGasLevels: false, // "Slow" gas level might be lower than the minimumGasPrice so the tx will be rejected iconUrls: [ - 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/rsk/assets/0x/logo.png', + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/rsk/info/logo.png', ], rpcUrls: ['https://rsk-node.blockwallet.io'], defaultRpcUrl: 'https://rsk-node.blockwallet.io', @@ -465,6 +466,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Ether', symbol: 'ETH', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/assets/0x/logo.png', }, iconUrls: [ 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/zksync/info/logo.png', @@ -652,6 +654,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Testnet Smart Bitcoin', symbol: 'tRBTC', decimals: 18, + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/rsk/assets/0x/logo.png', }, hasFixedGasCost: false, enable: true, @@ -661,7 +664,7 @@ export const INITIAL_NETWORKS: Networks = { ens: false, showGasLevels: true, iconUrls: [ - 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/rsk/assets/0x/logo.png', + 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/rsk/info/logo.png', ], rpcUrls: ['https://did.testnet.rsk.co:4444'], blockExplorerName: 'RSK Testnet Explorer', From a276884b0d88d0586e01606e60652860155d46cd Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Tue, 14 Mar 2023 19:36:34 +0200 Subject: [PATCH 042/110] fix: new preferences icon --- packages/ui/src/assets/images/icons/spanner.svg | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/ui/src/assets/images/icons/spanner.svg b/packages/ui/src/assets/images/icons/spanner.svg index 332994a33..e8b834614 100644 --- a/packages/ui/src/assets/images/icons/spanner.svg +++ b/packages/ui/src/assets/images/icons/spanner.svg @@ -1,15 +1,14 @@ - - - - + + + - + - + From dad8e173ed0d98ddf54882a402968591959f6f83 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Wed, 15 Mar 2023 14:21:49 +0200 Subject: [PATCH 043/110] fix: network indicator height in dap requests --- packages/ui/src/components/dApp/DAppPopupHeader.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/dApp/DAppPopupHeader.tsx b/packages/ui/src/components/dApp/DAppPopupHeader.tsx index c301bf44d..15c1db405 100644 --- a/packages/ui/src/components/dApp/DAppPopupHeader.tsx +++ b/packages/ui/src/components/dApp/DAppPopupHeader.tsx @@ -44,7 +44,10 @@ const DAppPopupHeader: React.FC = ({
    )} {showNetworkIndicator && ( - + )} ) From 72acec99c8037a69194bc7fef715a91012f3fe75 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Wed, 15 Mar 2023 15:48:24 +0200 Subject: [PATCH 044/110] fix: eth logo url in network const --- packages/background/src/utils/constants/networks.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/background/src/utils/constants/networks.ts b/packages/background/src/utils/constants/networks.ts index 8e1e0b018..a97208938 100644 --- a/packages/background/src/utils/constants/networks.ts +++ b/packages/background/src/utils/constants/networks.ts @@ -466,7 +466,7 @@ export const INITIAL_NETWORKS: Networks = { name: 'Ether', symbol: 'ETH', decimals: 18, - logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/assets/0x/logo.png', + logo: 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/ethereum/info/logo.png', }, iconUrls: [ 'https://raw.githubusercontent.com/block-wallet/assets/master/blockchains/zksync/info/logo.png', From ae12583b07353075d50376b2258bc8bf463d569d Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Wed, 15 Mar 2023 18:20:11 +0200 Subject: [PATCH 045/110] fix: insufficient --- packages/ui/src/routes/dApp/ApproveAsset.tsx | 2 +- packages/ui/src/routes/dApp/ApproveNFT.tsx | 2 +- packages/ui/src/routes/transaction/ApprovePage.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/routes/dApp/ApproveAsset.tsx b/packages/ui/src/routes/dApp/ApproveAsset.tsx index 015e2893b..653444781 100644 --- a/packages/ui/src/routes/dApp/ApproveAsset.tsx +++ b/packages/ui/src/routes/dApp/ApproveAsset.tsx @@ -499,7 +499,7 @@ const ApproveAsset: FunctionComponent = ({ buttonDisplay={false} transactionId={transaction.id} /> -
    +
    {!hasBalance && "Insufficient funds."}
    diff --git a/packages/ui/src/routes/dApp/ApproveNFT.tsx b/packages/ui/src/routes/dApp/ApproveNFT.tsx index 6037e3164..24f647659 100644 --- a/packages/ui/src/routes/dApp/ApproveNFT.tsx +++ b/packages/ui/src/routes/dApp/ApproveNFT.tsx @@ -458,7 +458,7 @@ const ApproveNFT: FunctionComponent = ({ }) }} /> -
    +
    {!hasBalance && "Insufficient funds."}
    diff --git a/packages/ui/src/routes/transaction/ApprovePage.tsx b/packages/ui/src/routes/transaction/ApprovePage.tsx index 612bcfa0c..ab3756cde 100644 --- a/packages/ui/src/routes/transaction/ApprovePage.tsx +++ b/packages/ui/src/routes/transaction/ApprovePage.tsx @@ -587,7 +587,7 @@ const ApprovePage: FunctionComponent<{}> = () => { }} buttonDisplay={false} /> - + {hasBalance ? undefined : "Insufficient funds"}
    From 82a913c51cf06148243221ae1fe74c4ea8e352c7 Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Wed, 15 Mar 2023 22:49:19 +0200 Subject: [PATCH 046/110] fix: allowance decimals rounding up --- .../transactions/AllowanceInput.tsx | 7 +++++-- packages/ui/src/routes/dApp/ApproveAsset.tsx | 8 +++++--- .../ui/src/routes/transaction/ApprovePage.tsx | 4 ++-- packages/ui/src/util/formatRounded.ts | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/ui/src/components/transactions/AllowanceInput.tsx b/packages/ui/src/components/transactions/AllowanceInput.tsx index f2472c91b..d6236c760 100644 --- a/packages/ui/src/components/transactions/AllowanceInput.tsx +++ b/packages/ui/src/components/transactions/AllowanceInput.tsx @@ -10,6 +10,7 @@ import { Classes } from "../../styles" import ErrorMessage from "../error/ErrorMessage" import Dialog from "../dialog/Dialog" import CloseIcon from "../icons/CloseIcon" +import { formatRoundedUp } from "../../util/formatRounded" const UNLIMITED_ALLOWANCE = MaxUint256 @@ -139,7 +140,7 @@ const AllowanceInput = ({ currentAllowance?: BigNumber }) => { const [allowanceAmount, setAllowanceAmount] = useState( - formatUnits(defaultValue, tokenDecimals) + formatRoundedUp(formatUnits(defaultValue, tokenDecimals)) ) const [error, setError] = useState("") @@ -230,7 +231,9 @@ const AllowanceInput = ({ setUsingRevoke(isRevoke) setUsingUnlimited(isUnlimited) - setAllowanceAmount(formatUnits(defaultValue, tokenDecimals)) + setAllowanceAmount( + formatRoundedUp(formatUnits(defaultValue, tokenDecimals)) + ) // Needed in dependency array to update the input value when the defaultValue changes if there is multiple allowance approvals in the queue }, [defaultValue]) diff --git a/packages/ui/src/routes/dApp/ApproveAsset.tsx b/packages/ui/src/routes/dApp/ApproveAsset.tsx index 653444781..6317d8834 100644 --- a/packages/ui/src/routes/dApp/ApproveAsset.tsx +++ b/packages/ui/src/routes/dApp/ApproveAsset.tsx @@ -56,7 +56,7 @@ import { formatHashLastChars, formatName, } from "../../util/formatAccount" -import { formatRounded } from "../../util/formatRounded" +import { formatRounded, formatRoundedUp } from "../../util/formatRounded" import { getAccountColor } from "../../util/getAccountColor" import { parseAllowance } from "../../util/approval" import useDebouncedState from "../../util/hooks/useDebouncedState" @@ -213,11 +213,13 @@ const ApproveAsset: FunctionComponent = ({ const defaultAllowance = transaction.advancedData?.allowance! const [allowance, setAllowance] = useState( - formatUnits(defaultAllowance, tokenDecimals) + formatRoundedUp(formatUnits(defaultAllowance, tokenDecimals)) ) useEffect(() => { // To reset the default value if there is multiple queued transactions - setAllowance(formatUnits(defaultAllowance, tokenDecimals)) + setAllowance( + formatRoundedUp(formatUnits(defaultAllowance, tokenDecimals)) + ) }, [defaultAllowance]) const [isAllowanceValid, setIsAllowanceValid] = useState(true) diff --git a/packages/ui/src/routes/transaction/ApprovePage.tsx b/packages/ui/src/routes/transaction/ApprovePage.tsx index ab3756cde..5449085e7 100644 --- a/packages/ui/src/routes/transaction/ApprovePage.tsx +++ b/packages/ui/src/routes/transaction/ApprovePage.tsx @@ -31,7 +31,7 @@ import { formatHashLastChars, formatName, } from "../../util/formatAccount" -import { formatRounded } from "../../util/formatRounded" +import { formatRounded, formatRoundedUp } from "../../util/formatRounded" import { formatUnits, parseUnits } from "@ethersproject/units" import { getAccountColor } from "../../util/getAccountColor" import { useGasPriceData } from "../../context/hooks/useGasPriceData" @@ -166,7 +166,7 @@ const ApprovePage: FunctionComponent<{}> = () => { const [isAllowanceValid, setIsAllowanceValid] = useState(true) const [allowanceAmount, setAllowanceAmount] = useState( minAllowance - ? formatUnits(minAllowance, assetDecimals) + ? formatRoundedUp(formatUnits(minAllowance, assetDecimals)) : formatUnits(UNLIMITED_ALLOWANCE, assetDecimals) ) diff --git a/packages/ui/src/util/formatRounded.ts b/packages/ui/src/util/formatRounded.ts index 4a8244602..d175996e2 100644 --- a/packages/ui/src/util/formatRounded.ts +++ b/packages/ui/src/util/formatRounded.ts @@ -9,3 +9,22 @@ import { FixedNumber } from "@ethersproject/bignumber" export const formatRounded = (value: string, decimals: number = 4): string => { return FixedNumber.fromString(value).round(decimals).toString() } + +/** + * Receives a string containing numbers with decimals and applies ceil according to param. + * @param value string to ceil + * @param decimals number of decimals to ceil. Defaults to 4. + * @returns ceiled string + * @example + * formatRoundedUp('1.00009', 4) // '1.0001' + * formatRoundedUp('1.001', 2) // '1.01' + */ +export const formatRoundedUp = ( + value: string, + decimals: number = 4 +): string => { + const fixedNum = FixedNumber.fromString(value) + const factor = FixedNumber.from(Math.pow(10, decimals)) + const roundedNum = fixedNum.mulUnsafe(factor).ceiling().divUnsafe(factor) + return roundedNum.toString() +} From b0ed098da1d81cc91a7363377b1b235b1cb502aa Mon Sep 17 00:00:00 2001 From: Antony Ayoub Date: Mon, 20 Mar 2023 19:51:50 +0200 Subject: [PATCH 047/110] fix: weird recent accounts in address book --- packages/ui/src/components/account/AccountDisplay.tsx | 5 ++++- packages/ui/src/routes/settings/AddressBookPage.tsx | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/account/AccountDisplay.tsx b/packages/ui/src/components/account/AccountDisplay.tsx index caf684071..5d27f40f9 100644 --- a/packages/ui/src/components/account/AccountDisplay.tsx +++ b/packages/ui/src/components/account/AccountDisplay.tsx @@ -42,6 +42,7 @@ interface AccountDisplayProps { selected?: boolean showSelectedCheckmark?: boolean showAddress?: boolean + truncateName?: boolean showConnected?: boolean copyAddressToClipboard?: boolean menu?: AccountDisplayMenuOption[] @@ -54,6 +55,7 @@ const AccountDisplay: FunctionComponent = ({ selected, showSelectedCheckmark = true, showAddress = false, + truncateName = true, showConnected = false, copyAddressToClipboard = false, actionButtons, @@ -121,7 +123,8 @@ const AccountDisplay: FunctionComponent = ({
  • - {d} + {d}
  • ))}
    diff --git a/packages/ui/src/components/bridge/BridgeQuoteNotFoundErrorDetails.tsx b/packages/ui/src/components/bridge/BridgeQuoteNotFoundErrorDetails.tsx index 06fbb74d8..b48a98636 100644 --- a/packages/ui/src/components/bridge/BridgeQuoteNotFoundErrorDetails.tsx +++ b/packages/ui/src/components/bridge/BridgeQuoteNotFoundErrorDetails.tsx @@ -32,7 +32,9 @@ const BridgeErrorDisplay = ({ return (
    - {tool} + + {tool} + {Array.from(errors.keys()).map((code) => { const errorSummary = errors.get(code) return ( diff --git a/packages/ui/src/components/bridge/FeeItem.tsx b/packages/ui/src/components/bridge/FeeItem.tsx index 8f25339eb..553e2fcbc 100644 --- a/packages/ui/src/components/bridge/FeeItem.tsx +++ b/packages/ui/src/components/bridge/FeeItem.tsx @@ -33,7 +33,7 @@ const FeeItem = ({ + {detail.description ?? detail.name} } diff --git a/packages/ui/src/components/bridge/FeeTokenSummaryDisplay.tsx b/packages/ui/src/components/bridge/FeeTokenSummaryDisplay.tsx index 8b3cf2347..e7f315010 100644 --- a/packages/ui/src/components/bridge/FeeTokenSummaryDisplay.tsx +++ b/packages/ui/src/components/bridge/FeeTokenSummaryDisplay.tsx @@ -13,7 +13,7 @@ const FeeTokenSummaryDisplay = ({ }) => { return (
    - + {formatRounded( formatUnits(feeDetail.total, feeDetail.token.decimals), 4 diff --git a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx index 985734104..aaa742077 100644 --- a/packages/ui/src/components/chain/NetworkDisplayBadge.tsx +++ b/packages/ui/src/components/chain/NetworkDisplayBadge.tsx @@ -20,7 +20,7 @@ const NetworkDisplayBadge = ({ return (
    = ({
    = ({ wideMargins ? "px-5 " : "px-1" )} > - + {message}
    diff --git a/packages/ui/src/components/gas/GasPricesInfo.tsx b/packages/ui/src/components/gas/GasPricesInfo.tsx index bafdbb191..388cdf6ac 100644 --- a/packages/ui/src/components/gas/GasPricesInfo.tsx +++ b/packages/ui/src/components/gas/GasPricesInfo.tsx @@ -87,7 +87,7 @@ const GasDataInfo: FC<{ label: string; value: string }> = ({ return (
  • {label}: - {value} + {value}
  • ) } @@ -195,7 +195,7 @@ const GasPricesInfo: FC = () => { >
    { }{" "} GWEI - + ~ {gasPriceToNativeCurrency( gasPriceData.totalTransactionCost, diff --git a/packages/ui/src/components/icons/UsbIcon.tsx b/packages/ui/src/components/icons/UsbIcon.tsx index a36300f80..550d5e071 100644 --- a/packages/ui/src/components/icons/UsbIcon.tsx +++ b/packages/ui/src/components/icons/UsbIcon.tsx @@ -3,45 +3,46 @@ import classnames from "classnames" const UsbIcon: React.FC<{ className?: string }> = ({ className }) => { return ( = ({ className }) => { /> - - - - - - - - - ) } diff --git a/packages/ui/src/components/info/Info.tsx b/packages/ui/src/components/info/Info.tsx index 5fd8eff17..36a3278ea 100644 --- a/packages/ui/src/components/info/Info.tsx +++ b/packages/ui/src/components/info/Info.tsx @@ -24,11 +24,7 @@ const Info: FC<{ children: React.ReactNode }> & InfoComponents = ({ } const Title = ({ children }: { children: React.ReactNode }) => { - return ( - - {children} - - ) + return {children} } const InfoList: FC = ({ diff --git a/packages/ui/src/components/input/EndLabel.tsx b/packages/ui/src/components/input/EndLabel.tsx index cbb71a64d..e378dd329 100644 --- a/packages/ui/src/components/input/EndLabel.tsx +++ b/packages/ui/src/components/input/EndLabel.tsx @@ -17,7 +17,7 @@ const EndLabel = ({ className )} > - {label} + {label}
    ) diff --git a/packages/ui/src/components/input/HorizontalSelect.tsx b/packages/ui/src/components/input/HorizontalSelect.tsx index 941c5e377..426edab9d 100644 --- a/packages/ui/src/components/input/HorizontalSelect.tsx +++ b/packages/ui/src/components/input/HorizontalSelect.tsx @@ -32,7 +32,7 @@ const HorizontalSelect: FunctionComponent<{ ? `flex-1 flex flex-row items-center justify-center p-4 border-b-2 text-sm ${ option === value ? "border-primary-blue-default text-primary-blue-default font-bold" - : "border-transparent text-gray-500 hover:text-primary-blue-default hover:font-medium" + : "border-transparent text-primary-grey-dark hover:text-primary-blue-default hover:font-medium" }` : optionClassName ? optionClassName(option) diff --git a/packages/ui/src/components/input/NetworkSelect.tsx b/packages/ui/src/components/input/NetworkSelect.tsx index 0b0c1f6f5..22e663b52 100644 --- a/packages/ui/src/components/input/NetworkSelect.tsx +++ b/packages/ui/src/components/input/NetworkSelect.tsx @@ -119,7 +119,7 @@ const NetworkSelect: FunctionComponent<{ } }} className={classNames( - "relative flex flex-row items-center justify-start p-1 text-gray-600 bg-primary-grey-default rounded-md group border-primary-200 w-44 text-xs hover:bg-primary-grey-hover", + "relative flex flex-row items-center justify-start p-1 text-primary-grey-dark bg-primary-grey-default rounded-md group border-primary-200 w-[151px] text-xs hover:bg-primary-grey-hover", !isImportingDeposits ? "cursor-pointer select-none" : "disabled:pointer-events-none opacity-50", @@ -150,15 +150,15 @@ const NetworkSelect: FunctionComponent<{ {networkData.desc} {networkList ? ( - + ) : ( - + )}