From 13ebf1c54f147bfb0ad754abc24271caf97c3775 Mon Sep 17 00:00:00 2001 From: Francisco Ramos Date: Mon, 17 Jul 2023 17:12:28 +0200 Subject: [PATCH] feat(bridge-ui-v2): Processing Fee (#14170) Co-authored-by: Korbinian --- packages/bridge-ui-v2/src/app.config.ts | 10 ++ .../AccountConnectionToast.svelte | 17 +- .../components/Activities/Activities.svelte | 4 +- .../components/AmountInput/AmountInput.svelte | 71 --------- .../src/components/AmountInput/index.ts | 1 - .../Bridge/AmountInput/AmountInput.svelte | 26 +++ .../Bridge/AmountInput/Balance.svelte | 56 +++++++ .../components/Bridge/AmountInput/index.ts | 1 + .../src/components/Bridge/Bridge.svelte | 54 +++++-- .../Bridge/ProcessingFee/NoneOption.svelte | 51 ++++++ .../ProcessingFee/ProcessingFee.svelte | 150 +++++++++++------- .../ProcessingFee/RecommendedFee.svelte | 48 ++++++ .../{ => Bridge}/ProcessingFee/index.ts | 0 .../RecipientInput/RecipientInput.svelte | 0 .../{ => Bridge}/RecipientInput/index.ts | 0 .../Bridge/SwitchChainsButton.svelte | 20 +++ .../src/components/Bridge/state.ts | 17 ++ .../ChainSelector/ChainSelector.svelte | 36 +++-- .../src/components/Faucet/Faucet.svelte | 12 +- .../components/LoadingText/LoadingText.svelte | 13 +- .../src/components/LoadingText/index.ts | 1 + .../src/components/OnAccount/OnAccount.svelte | 14 ++ .../src/components/OnAccount/index.ts | 1 + .../src/components/OnNetwork/OnNetwork.svelte | 14 ++ .../src/components/OnNetwork/index.ts | 1 + packages/bridge-ui-v2/src/i18n/en.json | 3 +- .../bridge-ui-v2/src/libs/chain/chains.ts | 4 +- .../src/libs/fee/recommendProcessingFee.ts | 48 +++++- .../src/libs/token/getAddress.test.ts | 14 +- .../bridge-ui-v2/src/libs/token/getAddress.ts | 16 +- .../src/libs/token/getBalance.test.ts | 28 +++- .../bridge-ui-v2/src/libs/token/getBalance.ts | 18 ++- .../bridge-ui-v2/src/libs/util/parseToWei.ts | 7 + .../bridge-ui-v2/src/libs/wagmi/watcher.ts | 4 +- packages/bridge-ui-v2/src/stores/account.ts | 4 +- packages/bridge-ui-v2/src/stores/index.ts | 2 + packages/bridge-ui-v2/src/stores/network.ts | 4 +- packages/bridge-ui-v2/tsconfig.json | 2 + 38 files changed, 563 insertions(+), 209 deletions(-) create mode 100644 packages/bridge-ui-v2/src/app.config.ts delete mode 100644 packages/bridge-ui-v2/src/components/AmountInput/AmountInput.svelte delete mode 100644 packages/bridge-ui-v2/src/components/AmountInput/index.ts create mode 100644 packages/bridge-ui-v2/src/components/Bridge/AmountInput/AmountInput.svelte create mode 100644 packages/bridge-ui-v2/src/components/Bridge/AmountInput/Balance.svelte create mode 100644 packages/bridge-ui-v2/src/components/Bridge/AmountInput/index.ts create mode 100644 packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/NoneOption.svelte rename packages/bridge-ui-v2/src/components/{ => Bridge}/ProcessingFee/ProcessingFee.svelte (53%) create mode 100644 packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/RecommendedFee.svelte rename packages/bridge-ui-v2/src/components/{ => Bridge}/ProcessingFee/index.ts (100%) rename packages/bridge-ui-v2/src/components/{ => Bridge}/RecipientInput/RecipientInput.svelte (100%) rename packages/bridge-ui-v2/src/components/{ => Bridge}/RecipientInput/index.ts (100%) create mode 100644 packages/bridge-ui-v2/src/components/Bridge/SwitchChainsButton.svelte create mode 100644 packages/bridge-ui-v2/src/components/Bridge/state.ts create mode 100644 packages/bridge-ui-v2/src/components/OnAccount/OnAccount.svelte create mode 100644 packages/bridge-ui-v2/src/components/OnAccount/index.ts create mode 100644 packages/bridge-ui-v2/src/components/OnNetwork/OnNetwork.svelte create mode 100644 packages/bridge-ui-v2/src/components/OnNetwork/index.ts create mode 100644 packages/bridge-ui-v2/src/libs/util/parseToWei.ts create mode 100644 packages/bridge-ui-v2/src/stores/index.ts diff --git a/packages/bridge-ui-v2/src/app.config.ts b/packages/bridge-ui-v2/src/app.config.ts new file mode 100644 index 0000000000..5584560c84 --- /dev/null +++ b/packages/bridge-ui-v2/src/app.config.ts @@ -0,0 +1,10 @@ +export const recommentProcessingFee = { + ethGasLimit: BigInt(900000), + erc20NotDeployedGasLimit: BigInt(3100000), + erc20DeployedGasLimit: BigInt(1100000), +}; + +export const processingFeeComponent = { + closingDelayOptionClick: 300, + intervalComputeRecommendedFee: 20000, +}; diff --git a/packages/bridge-ui-v2/src/components/AccountConnectionToast/AccountConnectionToast.svelte b/packages/bridge-ui-v2/src/components/AccountConnectionToast/AccountConnectionToast.svelte index 4dfec03c35..eabcab394c 100644 --- a/packages/bridge-ui-v2/src/components/AccountConnectionToast/AccountConnectionToast.svelte +++ b/packages/bridge-ui-v2/src/components/AccountConnectionToast/AccountConnectionToast.svelte @@ -2,22 +2,21 @@ import { t } from 'svelte-i18n'; import { successToast, warningToast } from '$components/NotificationToast'; - import { account } from '$stores/account'; - - let prevAccount = $account; + import { OnAccount } from '$components/OnAccount'; + import type { Account } from '$stores/account'; // Listen to changes in the account state and notify the user // when the account is connected or disconnected via toast - account.subscribe((_account) => { - if (_account?.isConnected) { + function onAccountChange(newAccount: Account, oldAccount?: Account) { + if (newAccount?.isConnected) { successToast($t('messages.account.connected')); - } else if (prevAccount && _account?.isDisconnected) { + } else if (oldAccount && newAccount?.isDisconnected) { // We check if there was previous account, if not // the user just hit the app, and there is no need // to show the message. warningToast($t('messages.account.disconnected')); } - - prevAccount = _account; - }); + } + + diff --git a/packages/bridge-ui-v2/src/components/Activities/Activities.svelte b/packages/bridge-ui-v2/src/components/Activities/Activities.svelte index 4582e16867..9e3633b7dc 100644 --- a/packages/bridge-ui-v2/src/components/Activities/Activities.svelte +++ b/packages/bridge-ui-v2/src/components/Activities/Activities.svelte @@ -3,7 +3,7 @@ import { Card } from '$components/Card'; import { ChainSelector } from '$components/ChainSelector'; - import { srcChain } from '$stores/network'; + import { network } from '$stores/network'; import ListWithDetailsView from './ListWithDetailsView.svelte'; import TableView from './TableView.svelte'; @@ -11,7 +11,7 @@
- +
diff --git a/packages/bridge-ui-v2/src/components/AmountInput/AmountInput.svelte b/packages/bridge-ui-v2/src/components/AmountInput/AmountInput.svelte deleted file mode 100644 index 2aaf0434c7..0000000000 --- a/packages/bridge-ui-v2/src/components/AmountInput/AmountInput.svelte +++ /dev/null @@ -1,71 +0,0 @@ - - -
-
- -
- {$t('amount_input.balance')}: - - {#if computingTokenBalance} - - - {:else} - {renderTokenBalance(tokenBalance)} - {/if} - -
-
-
- - -
-
diff --git a/packages/bridge-ui-v2/src/components/AmountInput/index.ts b/packages/bridge-ui-v2/src/components/AmountInput/index.ts deleted file mode 100644 index e49f595a9a..0000000000 --- a/packages/bridge-ui-v2/src/components/AmountInput/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './AmountInput.svelte'; diff --git a/packages/bridge-ui-v2/src/components/Bridge/AmountInput/AmountInput.svelte b/packages/bridge-ui-v2/src/components/Bridge/AmountInput/AmountInput.svelte new file mode 100644 index 0000000000..d2cd50a02c --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/AmountInput/AmountInput.svelte @@ -0,0 +1,26 @@ + + +
+
+ + +
+
+ + +
+
diff --git a/packages/bridge-ui-v2/src/components/Bridge/AmountInput/Balance.svelte b/packages/bridge-ui-v2/src/components/Bridge/AmountInput/Balance.svelte new file mode 100644 index 0000000000..18000188fa --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/AmountInput/Balance.svelte @@ -0,0 +1,56 @@ + + +
+ {$t('amount_input.balance')}: + + {#if computingTokenBalance} + + + {:else} + {renderTokenBalance(tokenBalance)} + {/if} + +
diff --git a/packages/bridge-ui-v2/src/components/Bridge/AmountInput/index.ts b/packages/bridge-ui-v2/src/components/Bridge/AmountInput/index.ts new file mode 100644 index 0000000000..ff5cf90c7c --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/AmountInput/index.ts @@ -0,0 +1 @@ +export { default as AmountInput } from './AmountInput.svelte'; diff --git a/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte b/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte index 0a42443ab8..770e2c091a 100644 --- a/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/Bridge.svelte @@ -1,38 +1,58 @@
- - + +
- +
- +
- +
@@ -46,3 +66,7 @@
+ + + + diff --git a/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/NoneOption.svelte b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/NoneOption.svelte new file mode 100644 index 0000000000..fb5dbd614f --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/NoneOption.svelte @@ -0,0 +1,51 @@ + diff --git a/packages/bridge-ui-v2/src/components/ProcessingFee/ProcessingFee.svelte b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte similarity index 53% rename from packages/bridge-ui-v2/src/components/ProcessingFee/ProcessingFee.svelte rename to packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte index 2301879269..18b8fcb099 100644 --- a/packages/bridge-ui-v2/src/components/ProcessingFee/ProcessingFee.svelte +++ b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/ProcessingFee.svelte @@ -1,84 +1,106 @@
@@ -92,16 +114,16 @@ {#if calculatingRecommendedAmount} - {$t('processing_fee.recommended.calculating')} + ETH {:else if errorCalculatingRecommendedAmount} {$t('processing_fee.recommended.error')} {:else} - {selectedAmount} ETH + {formatEther($processingFee ?? BigInt(0))} ETH {/if} -
+ + + + diff --git a/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/RecommendedFee.svelte b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/RecommendedFee.svelte new file mode 100644 index 0000000000..4e63211415 --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/RecommendedFee.svelte @@ -0,0 +1,48 @@ + diff --git a/packages/bridge-ui-v2/src/components/ProcessingFee/index.ts b/packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/index.ts similarity index 100% rename from packages/bridge-ui-v2/src/components/ProcessingFee/index.ts rename to packages/bridge-ui-v2/src/components/Bridge/ProcessingFee/index.ts diff --git a/packages/bridge-ui-v2/src/components/RecipientInput/RecipientInput.svelte b/packages/bridge-ui-v2/src/components/Bridge/RecipientInput/RecipientInput.svelte similarity index 100% rename from packages/bridge-ui-v2/src/components/RecipientInput/RecipientInput.svelte rename to packages/bridge-ui-v2/src/components/Bridge/RecipientInput/RecipientInput.svelte diff --git a/packages/bridge-ui-v2/src/components/RecipientInput/index.ts b/packages/bridge-ui-v2/src/components/Bridge/RecipientInput/index.ts similarity index 100% rename from packages/bridge-ui-v2/src/components/RecipientInput/index.ts rename to packages/bridge-ui-v2/src/components/Bridge/RecipientInput/index.ts diff --git a/packages/bridge-ui-v2/src/components/Bridge/SwitchChainsButton.svelte b/packages/bridge-ui-v2/src/components/Bridge/SwitchChainsButton.svelte new file mode 100644 index 0000000000..3197b75995 --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/SwitchChainsButton.svelte @@ -0,0 +1,20 @@ + + + diff --git a/packages/bridge-ui-v2/src/components/Bridge/state.ts b/packages/bridge-ui-v2/src/components/Bridge/state.ts new file mode 100644 index 0000000000..834e104573 --- /dev/null +++ b/packages/bridge-ui-v2/src/components/Bridge/state.ts @@ -0,0 +1,17 @@ +import type { Chain } from '@wagmi/core'; +import { writable } from 'svelte/store'; + +import type { Token } from '$libs/token'; + +// Note: we could combine this with Context API, but since we'll only +// have one Bridge component, it would be an overkill. If we wanted to +// instantiate multiple Bridge components, then we'd need to use +// Context API to avoid having multiple instances of the same store. +// One could argue that we only want this store to be used by the Bridge +// and its descendants, in which case Context API would be the one to use, +// but once again, we don't need such level of security that we have to +// prevent other components outside the Bridge from accessing this store. + +export const selectedToken = writable>(); +export const destNetwork = writable>(); +export const processingFee = writable(); diff --git a/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte b/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte index ab2e071186..a95f2fcb20 100644 --- a/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte +++ b/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelector.svelte @@ -15,6 +15,8 @@ export let label: string; export let value: Maybe = null; + export let switchWallet = false; + export let readOnly = false; let chainToIconMap: Record = { [PUBLIC_L1_CHAIN_ID]: EthIcon, @@ -31,6 +33,8 @@ } function openModal() { + if (readOnly) return; + // We want to inform the user that they need to connect // their wallet if they want to change the network if (!$account.isConnected) { @@ -44,19 +48,26 @@ async function selectChain(chain: Chain) { if (chain.id === value?.id) return; - switchingNetwork = true; - - try { - await switchNetwork({ chainId: chain.id }); - closeModal(); - } catch (error) { - console.error(error); - - if (error instanceof UserRejectedRequestError) { - warningToast($t('messages.network.rejected')); + if (switchWallet) { + // We want to switch the wallet to the selected network. + // This will trigger the network switch in the UI also + switchingNetwork = true; + + try { + await switchNetwork({ chainId: chain.id }); + closeModal(); + } catch (error) { + console.error(error); + + if (error instanceof UserRejectedRequestError) { + warningToast($t('messages.network.rejected')); + } + } finally { + switchingNetwork = false; } - } finally { - switchingNetwork = false; + } else { + value = chain; + closeModal(); } } @@ -77,6 +88,7 @@