diff --git a/packages/desktop/components/AccountSummary.svelte b/packages/desktop/components/AccountSummary.svelte index ce26c8652e..5178f302ab 100644 --- a/packages/desktop/components/AccountSummary.svelte +++ b/packages/desktop/components/AccountSummary.svelte @@ -1,5 +1,5 @@ - - - - - diff --git a/packages/desktop/components/buttons/menu-buttons/TokenListMenuButton.svelte b/packages/desktop/components/buttons/menu-buttons/TokenListMenuButton.svelte deleted file mode 100644 index 927c51cd90..0000000000 --- a/packages/desktop/components/buttons/menu-buttons/TokenListMenuButton.svelte +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/packages/desktop/components/buttons/menu-buttons/index.js b/packages/desktop/components/buttons/menu-buttons/index.js deleted file mode 100644 index 37f32a1b1f..0000000000 --- a/packages/desktop/components/buttons/menu-buttons/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as AccountActionsButton } from './AccountActionsButton.svelte' -export { default as TokenListMenuButton } from './TokenListMenuButton.svelte' diff --git a/packages/desktop/components/index.js b/packages/desktop/components/index.js index 249296a407..d6e632b06a 100644 --- a/packages/desktop/components/index.js +++ b/packages/desktop/components/index.js @@ -1,7 +1,7 @@ export * from './buttons' export * from './drawers' export * from './filter' -export * from './menu-buttons' +export * from './menus' export * from './modals' export * from './panes' export * from './popups' @@ -14,6 +14,7 @@ export { default as ContactCard } from './ContactCard.svelte' export { default as ContactMetadataTable } from './ContactMetadataTable.svelte' export { default as OnboardingLayout } from './OnboardingLayout.svelte' export { default as NetworkCard } from './NetworkCard.svelte' +export { default as NodeListTable } from './NodeListTable.svelte' export { default as Proposals } from './Proposals.svelte' export { default as ProposalAnswer } from './ProposalAnswer.svelte' export { default as ProposalCard } from './ProposalCard.svelte' diff --git a/packages/desktop/components/menu-buttons/index.js b/packages/desktop/components/menu-buttons/index.js deleted file mode 100644 index 0ace218590..0000000000 --- a/packages/desktop/components/menu-buttons/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as ProposalDetailsButton } from './ProposalDetailsButton.svelte' diff --git a/packages/desktop/components/modals/AccountActionsMenu.svelte b/packages/desktop/components/menus/AccountActionsMenu.svelte similarity index 50% rename from packages/desktop/components/modals/AccountActionsMenu.svelte rename to packages/desktop/components/menus/AccountActionsMenu.svelte index e82c4a3601..71653fb1a7 100644 --- a/packages/desktop/components/modals/AccountActionsMenu.svelte +++ b/packages/desktop/components/menus/AccountActionsMenu.svelte @@ -5,9 +5,9 @@ import { deleteAccount } from '@core/profile-manager/actions' import { activeAccounts, visibleActiveAccounts } from '@core/profile/stores' import { PopupId, openPopup } from '@desktop/auxiliary/popup' - import { MenuItem, Modal, ToggleHiddenAccountMenuItem } from '@ui' + import { MeatballMenuButton, MenuItem, Modal, ToggleHiddenAccountMenuItem } from '@ui' - export let modal: Modal = undefined + let modal: Modal = undefined const showDeleteAccount = $selectedAccount?.index === $activeAccounts?.length - 1 && $visibleActiveAccounts?.length > 1 @@ -34,19 +34,26 @@ } - - - - - -
- {#if showDeleteAccount} + + + + + - {/if} - - + +
+ {#if showDeleteAccount} + + {/if} +
+
+ diff --git a/packages/shared/src/components/modals/CollectibleDetailsMenu.svelte b/packages/desktop/components/menus/CollectibleDetailsMenu.svelte similarity index 66% rename from packages/shared/src/components/modals/CollectibleDetailsMenu.svelte rename to packages/desktop/components/menus/CollectibleDetailsMenu.svelte index a9b52a8f26..eba5e7fcd7 100644 --- a/packages/shared/src/components/modals/CollectibleDetailsMenu.svelte +++ b/packages/desktop/components/menus/CollectibleDetailsMenu.svelte @@ -7,8 +7,8 @@ import { activeProfile, updateActiveProfile } from '@core/profile/stores' import { CollectiblesRoute, collectiblesRouter } from '@core/router' import { burnNft } from '@core/wallet' - import { MenuItem, Modal } from '@ui' - import { PopupId, closePopup, openPopup } from '../../../../desktop/lib/auxiliary/popup' + import { PopupId, closePopup, openPopup } from '@desktop/auxiliary/popup' + import { MeatballMenuButton, MenuItem, Modal } from '@ui' export let modal: Modal = undefined export let nft: INft @@ -75,30 +75,33 @@ } - -
- {}} - /> - - - -
-
+ + + +
+ {}} + /> + + + +
+
+
diff --git a/packages/shared/src/components/modals/NodeActionsMenu.svelte b/packages/desktop/components/menus/NodeActionsMenu.svelte similarity index 72% rename from packages/shared/src/components/modals/NodeActionsMenu.svelte rename to packages/desktop/components/menus/NodeActionsMenu.svelte index c2ca7d3b39..3cefbc292d 100644 --- a/packages/shared/src/components/modals/NodeActionsMenu.svelte +++ b/packages/desktop/components/menus/NodeActionsMenu.svelte @@ -1,6 +1,4 @@ - - - - -
- -
+ + + + + + +
+ +
+
diff --git a/packages/desktop/components/menu-buttons/ProposalDetailsButton.svelte b/packages/desktop/components/menus/ProposalDetailsMenu.svelte similarity index 87% rename from packages/desktop/components/menu-buttons/ProposalDetailsButton.svelte rename to packages/desktop/components/menus/ProposalDetailsMenu.svelte index 98a30f9c89..c8892a0c04 100644 --- a/packages/desktop/components/menu-buttons/ProposalDetailsButton.svelte +++ b/packages/desktop/components/menus/ProposalDetailsMenu.svelte @@ -1,6 +1,6 @@ - - -
- {#each buttons as button} - - {/each} -
-
+ + + +
+ {#each buttons as button} + + {/each} +
+
+
diff --git a/packages/shared/src/components/modals/TokenActionsMenuModal.svelte b/packages/desktop/components/menus/TokenActionsMenu.svelte similarity index 54% rename from packages/shared/src/components/modals/TokenActionsMenuModal.svelte rename to packages/desktop/components/menus/TokenActionsMenu.svelte index 1302ae2069..a95fdbc155 100644 --- a/packages/shared/src/components/modals/TokenActionsMenuModal.svelte +++ b/packages/desktop/components/menus/TokenActionsMenu.svelte @@ -5,10 +5,10 @@ import { ITokenWithBalance, NotVerifiedStatus, VerifiedStatus } from '@core/token' import { removeTrackedTokenFromActiveProfile } from '@core/token/actions' import { hideToken, unhideToken, unverifyToken, verifyToken } from '@core/token/stores' + import { PopupId, closePopup, openPopup, updatePopupProps } from '@desktop/auxiliary/popup' import features from '@features/features' import { Icon } from '@lib/auxiliary/icon' - import { MenuItem, Modal } from '@ui' - import { closePopup, openPopup, PopupId, updatePopupProps } from '../../../../desktop/lib/auxiliary/popup' + import { MeatballMenuButton, MenuItem, Modal } from '@ui' export let modal: Modal | undefined = undefined export let token: ITokenWithBalance @@ -61,36 +61,39 @@ } - -
- {#if isTrackedToken} - - {/if} - {#if token.verification?.status === VerifiedStatus.SelfVerified} + + + +
+ {#if isTrackedToken} + + {/if} + {#if token.verification?.status === VerifiedStatus.SelfVerified} + + {:else} + + {/if} + {#if token.hidden} + + {:else} + + {/if} - {:else} - - {/if} - {#if token.hidden} - - {:else} - - {/if} - -
-
+
+
+ diff --git a/packages/desktop/components/menus/TokenListMenu.svelte b/packages/desktop/components/menus/TokenListMenu.svelte new file mode 100644 index 0000000000..c956deffa3 --- /dev/null +++ b/packages/desktop/components/menus/TokenListMenu.svelte @@ -0,0 +1,29 @@ + + + + + +
+ +
+
+
diff --git a/packages/desktop/components/menus/index.js b/packages/desktop/components/menus/index.js new file mode 100644 index 0000000000..32c324af2a --- /dev/null +++ b/packages/desktop/components/menus/index.js @@ -0,0 +1,6 @@ +export { default as AccountActionsMenu } from './AccountActionsMenu.svelte' +export { default as CollectibleDetailsMenu } from './CollectibleDetailsMenu.svelte' +export { default as NodeActionsMenu } from './NodeActionsMenu.svelte' +export { default as ProposalDetailsMenu } from './ProposalDetailsMenu.svelte' +export { default as TokenActionsMenu } from './TokenActionsMenu.svelte' +export { default as TokenListMenu } from './TokenListMenu.svelte' diff --git a/packages/desktop/components/modals/ProfileActionsMenuModal.svelte b/packages/desktop/components/modals/ProfileActionsModal.svelte similarity index 100% rename from packages/desktop/components/modals/ProfileActionsMenuModal.svelte rename to packages/desktop/components/modals/ProfileActionsModal.svelte diff --git a/packages/desktop/components/modals/TokenListMenu.svelte b/packages/desktop/components/modals/TokenListMenu.svelte deleted file mode 100644 index c899e8a315..0000000000 --- a/packages/desktop/components/modals/TokenListMenu.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - - -
- -
-
diff --git a/packages/desktop/components/modals/index.js b/packages/desktop/components/modals/index.js index 1a0efa4eb4..c556709f3e 100644 --- a/packages/desktop/components/modals/index.js +++ b/packages/desktop/components/modals/index.js @@ -1,5 +1,3 @@ -export { default as AccountActionsMenu } from './AccountActionsMenu.svelte' export { default as AccountSwitcherModal } from './AccountSwitcherModal.svelte' -export { default as TokenListMenu } from './TokenListMenu.svelte' export { default as FilterModal } from './FilterModal.svelte' -export { default as ProfileActionsMenuModal } from './ProfileActionsMenuModal.svelte' +export { default as ProfileActionsModal } from './ProfileActionsModal.svelte' diff --git a/packages/desktop/components/popups/TokenInformationPopup.svelte b/packages/desktop/components/popups/TokenInformationPopup.svelte index e8cf32b1b9..c66b7fd4c1 100644 --- a/packages/desktop/components/popups/TokenInformationPopup.svelte +++ b/packages/desktop/components/popups/TokenInformationPopup.svelte @@ -6,8 +6,9 @@ import { SendFlowType, setSendFlowParameters } from '@core/wallet' import { PopupId, openPopup, updatePopupProps } from '@desktop/auxiliary/popup' import { Icon as IconEnum } from '@lib/auxiliary/icon' - import { Button, FontWeight, Text, TextHint, TextType, TokenActionsButton, TokenAmountTile, TooltipIcon } from '@ui' + import { Button, FontWeight, Text, TextHint, TextType, TokenAmountTile, TooltipIcon } from '@ui' import { SendFlowRoute, SendFlowRouter, sendFlowRouter } from '@views/dashboard/send-flow' + import { TokenActionsMenu } from '../menus' export let token: ITokenWithBalance | undefined export let activityId: string = undefined @@ -80,7 +81,7 @@ {/if} {#if token.standard === TokenStandard.Irc30 || token.standard === TokenStandard.Erc20} - + {/if} diff --git a/packages/desktop/views/dashboard/Sidebar.svelte b/packages/desktop/views/dashboard/Sidebar.svelte index 543db2767a..b8adf1c588 100644 --- a/packages/desktop/views/dashboard/Sidebar.svelte +++ b/packages/desktop/views/dashboard/Sidebar.svelte @@ -1,7 +1,7 @@ diff --git a/packages/desktop/views/dashboard/send-flow/views/SelectRecipientView.svelte b/packages/desktop/views/dashboard/send-flow/views/SelectRecipientView.svelte index a8b5704e01..fdc9e67f05 100644 --- a/packages/desktop/views/dashboard/send-flow/views/SelectRecipientView.svelte +++ b/packages/desktop/views/dashboard/send-flow/views/SelectRecipientView.svelte @@ -3,7 +3,15 @@ import { selectedAccountIndex } from '@core/account/stores' import { ContactManager } from '@core/contact/classes' import { localize } from '@core/i18n' - import { IChain, IIscpChainConfiguration, INetwork, NetworkId, getActiveNetworkId, network } from '@core/network' + import { + IChain, + IIscpChainConfiguration, + INetwork, + NetworkId, + getActiveNetworkId, + network, + isEvmChain, + } from '@core/network' import { visibleActiveAccounts } from '@core/profile/stores' import { SendFlowType, @@ -16,24 +24,40 @@ import { closePopup } from '@desktop/auxiliary/popup' import features from '@features/features' import { INetworkRecipientSelectorOption, NetworkRecipientSelector } from '@ui' - import { onMount } from 'svelte' + import { onDestroy, onMount } from 'svelte' import { sendFlowRouter } from '../send-flow.router' import SendFlowTemplate from './SendFlowTemplate.svelte' import { getTokenStandardFromSendFlowParameters } from '@core/wallet/utils' import { TokenStandard } from '@core/token' - import { canAccountMakeEvmTransaction } from 'shared/src/lib/core/layer-2/actions' - import { handleError } from 'shared/src/lib/core/error/handlers' + import { + canAccountMakeEvmTransaction, + pollEvmChainGasPrices, + stopPollingEvmChainGasPrices, + } from '@core/layer-2/actions' let selector: NetworkRecipientSelector let selectorOptions: INetworkRecipientSelectorOption[] = [] let selectedIndex = -1 - let hasNetworkRecipientError: boolean = false - const assetName = getAssetName() - $: selectedRecipient = selectorOptions[selectedIndex]?.selectedRecipient + let selectedNetworkId: NetworkId $: selectedNetworkId = selectorOptions[selectedIndex]?.networkId + $: selectedRecipient = selectorOptions[selectedIndex]?.selectedRecipient + + let hasNetworkRecipientError: boolean = false + $: { + const originNetworkId = getNetworkIdFromSendFlowParameters($sendFlowParameters) + if (isEvmChain(originNetworkId)) { + hasNetworkRecipientError = !canAccountMakeEvmTransaction( + $selectedAccountIndex, + originNetworkId, + $sendFlowParameters?.type + ) + } else { + hasNetworkRecipientError = false + } + } function getAssetName(): string | undefined { if ($sendFlowParameters?.type === SendFlowType.BaseCoinTransfer) { @@ -158,7 +182,7 @@ } else if (sourceChain) { // if we are on layer 2 networkRecipientOptions = [ - ...(features.wallet.assets.unwrapToken && [getLayer1RecipientOption($network)]), + ...(features.wallet.assets.unwrapToken.enabled && [getLayer1RecipientOption($network)]), getRecipientOptionFromChain(sourceChain, $selectedAccountIndex), ] } @@ -173,18 +197,12 @@ return networkRecipientOptions } - async function onNetworkClick(): Promise { - try { - const originNetworkId = getNetworkIdFromSendFlowParameters($sendFlowParameters) - hasNetworkRecipientError = - (await canAccountMakeEvmTransaction( - $selectedAccountIndex, - originNetworkId, - $sendFlowParameters.type - )) ?? false - } catch (err) { - handleError(err) - } + function startPollingEvmChainGasPrices(): void { + const activeNetworkId = getActiveNetworkId() + const networkIdsToPoll = selectorOptions + .filter((option) => option.networkId !== activeNetworkId) + .map((option) => option.networkId) + pollEvmChainGasPrices(networkIdsToPoll) } function onContinueClick(): void { @@ -220,6 +238,11 @@ } onMount(() => { buildNetworkRecipientOptions() + startPollingEvmChainGasPrices() + }) + onDestroy(() => { + const chainsToIgnore = isEvmChain(selectedNetworkId) ? [selectedNetworkId] : [] + stopPollingEvmChainGasPrices(chainsToIgnore) }) @@ -238,7 +261,6 @@ }} > { + function onTokenClick(token: ITokenWithBalance): void { try { selectedToken = token - hasTokenError = - (await canAccountMakeEvmTransaction( - $selectedAccountIndex, - token.networkId, - SendFlowType.BaseCoinTransfer - )) ?? false } catch (err) { handleError(err) } diff --git a/packages/desktop/views/dashboard/settings/views/network/ConfigureNodeList.svelte b/packages/desktop/views/dashboard/settings/views/network/ConfigureNodeList.svelte index ec01504f09..3b1754e6d7 100644 --- a/packages/desktop/views/dashboard/settings/views/network/ConfigureNodeList.svelte +++ b/packages/desktop/views/dashboard/settings/views/network/ConfigureNodeList.svelte @@ -1,11 +1,11 @@ - - - - - - diff --git a/packages/shared/src/components/badges/VerificationBadge.svelte b/packages/shared/src/components/badges/VerificationBadge.svelte deleted file mode 100644 index 718c2fcf9e..0000000000 --- a/packages/shared/src/components/badges/VerificationBadge.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - - - {#if status === NotVerifiedStatus.New || status === NotVerifiedStatus.Skipped} - - {:else if status === VerifiedStatus.SelfVerified} - - {:else if status === VerifiedStatus.Official} - - {/if} - diff --git a/packages/shared/src/components/badges/index.js b/packages/shared/src/components/badges/index.js index 28f126cc7a..c49c431358 100644 --- a/packages/shared/src/components/badges/index.js +++ b/packages/shared/src/components/badges/index.js @@ -1,3 +1,2 @@ export { default as NetworkBadge } from './NetworkBadge.svelte' export { default as StrongholdBadge } from './StrongholdBadge.svelte' -export { default as VerificationBadge } from './VerificationBadge.svelte' diff --git a/packages/shared/src/components/buttons/NodeActionsButton.svelte b/packages/shared/src/components/buttons/NodeActionsButton.svelte deleted file mode 100644 index c549e115f8..0000000000 --- a/packages/shared/src/components/buttons/NodeActionsButton.svelte +++ /dev/null @@ -1,14 +0,0 @@ - - -
- - -
diff --git a/packages/shared/src/components/buttons/TokenActionsButton.svelte b/packages/shared/src/components/buttons/TokenActionsButton.svelte deleted file mode 100644 index bce54a08dc..0000000000 --- a/packages/shared/src/components/buttons/TokenActionsButton.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - -
- - -
diff --git a/packages/shared/src/components/buttons/index.js b/packages/shared/src/components/buttons/index.js index 0e6cb20dee..6076f7a734 100644 --- a/packages/shared/src/components/buttons/index.js +++ b/packages/shared/src/components/buttons/index.js @@ -1,7 +1,5 @@ export { default as AddInputButton } from './AddInputButton.svelte' -export { default as TokenActionsButton } from './TokenActionsButton.svelte' export { default as ExportStrongholdButton } from './ExportStrongholdButton.svelte' -export { default as NodeActionsButton } from './NodeActionsButton.svelte' export { default as OnboardingButton } from './OnboardingButton.svelte' export { default as ReceiveAddressButton } from './ReceiveAddressButton.svelte' export { default as ReceiveButton } from './ReceiveButton.svelte' diff --git a/packages/shared/src/components/index.js b/packages/shared/src/components/index.js index b499199d42..dfe475cebc 100644 --- a/packages/shared/src/components/index.js +++ b/packages/shared/src/components/index.js @@ -14,7 +14,6 @@ export { default as ProgressBar } from './ProgressBar.svelte' export { default as QR } from './QR.svelte' export { default as RecoveryPhrase } from './RecoveryPhrase.svelte' export { default as Spinner } from './Spinner.svelte' -export { default as Swiper } from './Swiper.svelte' export { default as Text } from './Text.svelte' export { default as TextHint } from './TextHint.svelte' export { default as ToastContainer } from './ToastContainer.svelte' diff --git a/packages/shared/src/components/inputs/NftInput.svelte b/packages/shared/src/components/inputs/NftInput.svelte deleted file mode 100644 index ea39f260aa..0000000000 --- a/packages/shared/src/components/inputs/NftInput.svelte +++ /dev/null @@ -1,57 +0,0 @@ - - - - - diff --git a/packages/shared/src/components/inputs/TokenAmountWithSliderInput.svelte b/packages/shared/src/components/inputs/TokenAmountWithSliderInput.svelte index 50162e85b0..aeb29ca839 100644 --- a/packages/shared/src/components/inputs/TokenAmountWithSliderInput.svelte +++ b/packages/shared/src/components/inputs/TokenAmountWithSliderInput.svelte @@ -1,6 +1,5 @@ {#if token}
- +
- import { Link, Text } from '@ui' - import { openUrlInBrowser } from '@core/app' - - -
- Conditions of Use for the Firefly App - - - These conditions of use (the "Conditions") apply to you (hereinafter, "User" - or "you") and the IOTA Foundation, a non-profit foundation with its registered address at - Pappelallee 78/79, 10437 Berlin (hereinafter, "IOTA" or "we/us"), regarding - your use of the "Firefly App" (the "App"). Use of the App is also governed by the App's Privacy - Policy (the "Privacy Policy"). - - - These Conditions and the Privacy Policy form a legally binding agreement between you and IOTA in relation to - your use of the App (the "Agreement"). BY USING THE APP OR CLICKING THE BUTTON OR CHECKBOX TO - ACCEPT THIS AGREEMENT, YOU DECLARE THAT YOU AGREE TO THE TERMS SET OUT HEREIN. - - - 1. General - -
    -
  • - - The App is a piece of software offered by IOTA and functions as a digital wallet for crypto-assets. - -
  • -
  • - - As the User, you are responsible for the safekeeping of your private keys, passwords, back-up - phrases and any other information used to access your crypto-assets. You are responsible for taking - appropriate action to back up any necessary information that you need to access your crypto-assets - and to keep such information safe. IOTA does not have access to your private keys, passwords or - other information used to access your crypto-assets. If you lose your private keys, passwords or - backup phrases, your crypto-assets will become inaccessible. - -
  • -
  • - - By providing the App, IOTA or any other third party does not act as a financial intermediary or - safekeeper of the Users' crypto-assets. - -
  • -
  • - - IOTA acts, in association with the App, as a software provider and is not a place for buying or - selling crypto-assets, and it is not another form of payment service provider in terms of § 1 - of the German Payment Services Supervision Act (Zahlungsdiensteaufsichtsgesetz). - -
  • -
  • - - IOTA does not provide services related to the custody, management or protection of crypto-assets and - is not a crypto custody business within the meaning of § 1(1a) sentence 2 no. 6 of the German - Banking Act (Kreditwesengesetz). - -
  • -
  • - - Although the App has been subjected to beta testing and has been further improved using feedback - from respected developers, IOTA cannot guarantee that the software is entirely free of errors. You - acknowledge that you shall be using this software at your own risk and in compliance with this - Agreement. - -
  • -
  • - - We do not have any control over goods or services which are paid for using the App. We are not - responsible for the successful completion of business transactions. We do not accept any liability - for such transactions, including, but not limited to, any use of the App by minors or persons using - a false name. - -
  • -
  • - - Occasionally, we may make changes to these conditions. When we make material changes or any other - change that could negatively affect your rights, we will notify you at least 30 days in advance by - displaying a prominent notice in our communication channels or by any other reasonable means. If you - do not agree to these changes, you can terminate the contract without notice. Your continued use of - the App after the changes have taken effect will constitute an acceptance of the new terms. - -
  • -
  • - - You also declare that you agree to the provision of any updates for the App and realise that failure - to update can result in a security risk or even loss of your crypto-assets. - -
  • -
  • - - Any use of the App is conditional on your acceptance of the terms of this Agreement, including any - modifications or updates to the Agreement. If you do not agree to the terms of the Agreement, then - you may not use the App. In addition, the General Terms and Conditions of the app store or platform - where the User downloads the App must be observed in addition to the terms of this Agreement. - -
  • -
-
- - 2. Data Protection - - IOTA does not collect any of your personal data through the App. Please refer to the Firefly Privacy Policy ( - openUrlInBrowser('https://firefly.iota.org/privacy')}> - https://firefly.iota.org/privacy - ) for information on how we and our third-party service providers process data in relation to the App. - - - 3. Use of the App - -
    -
  • - - By using the App and entering into this Agreement, you represent to us that you are lawfully able to - enter into this Agreement. - -
  • -
  • - - The App must be downloaded and saved to your desktop device in order for you to use the App; - -
  • -
  • - - Crypto-asset transactions are irreversible. As the User, it is your responsibility to ensure that - any crypto-assets that you send with the App are sent to the correct address. We do not have access - to the wallets and we are not able to assist you in case you send crypto-assets to the wrong - address; you are using the App at your own risk. - -
  • -
  • - - You guarantee that you will use the App in accordance with the laws and regulations of all relevant - jurisdictions. - -
  • -
-
- - 4. Security - -
    -
  • - - You agree that you are and shall at all times be responsible for the safekeeping, confidentiality - and use of your password(s) for the App. This includes keeping access data secret from third - parties. IOTA will never ask you to reveal your password(s). - -
  • -
  • - - As a User, you are responsible for ensuring that the equipment that you intend to use with the App - is compatible with the App. This includes all hardware, software, electrical, telecommunications - solutions, including internet access. - -
  • -
-
- - 5. Fees - - The App is provided free of charge. Any costs or taxes incurred by the User through the use, sale or purchase of - crypto-assets shall be the sole responsibility of the User. - - - 6. Right of Withdrawal and Termination - -
    -
  • - - By entering into this Agreement you hereby waive your right of withdrawal from it. You may simply - stop using it. - -
  • -
  • - - You may terminate this Agreement for any reason by ceasing use of the App. - -
  • -
-
- - 7. Grant of Licence - - The IOTA Foundation retains all right, title and interest in and to the App, including all intellectual property - rights, such as copyright, trademarks, designs, brands. Subject to the terms of this Agreement, the IOTA - Foundation grants to you a revocable, non-exclusive, non-sublicensable, non-transferrable, free and limited - licence for personal use of, and access to, the App (including all updates, upgrades, new versions and - replacement software). You are not permitted to lend or pledge these usage rights or transfer them in any other - way to a third party. - - - 8. Warranty and Disclaimer - - The App is provided "as is", and the IOTA Foundation makes no representations or warranties of any kind, whether - express or implied, regarding the App or its use. The IOTA Foundation does not warrant that the use of the App - will be uninterrupted or error free and expressly disclaims any representations and warranties as to the - merchantability, fitness for a particular purpose, and non-infringement of third-party rights, the absence of - security flaws or security breaches, bugs, software errors, including errors in the technology stacks used, - including programming languages and open-source libraries. No representations or warranties are made that the - App or any third-party services made available through the App will be free from malfunctions, errors, or - harmful components. All use of the App is therefore at the sole risk of the User. - - - 9. Limitation of Liability - -
    -
  • - - The IOTA Foundation shall only be liable for damages, irrespective of the legal basis, in cases of - its own intent and gross negligence. - -
  • -
  • - - In case of a violation against fundamental contractual duties, so called cardinal duties, the IOTA - Foundation's liability is limited to the foreseeable damages. - -
  • -
  • - - Liability claims are excluded if the circumstances justifying a claim are based on abnormal and - unforeseeable circumstances which are beyond the control of the party invoking those circumstances - and whose consequences could not have been avoided in spite of the exercise of due diligence. The - IOTA Foundation shall specifically bear no liability for damage arising from force majeure, riot, - war and natural events, or from any other events for which it cannot be held responsible (e.g. - strike, lockout, traffic disruptions, orders proclaimed by a supreme authority). - -
  • -
  • - - The IOTA Foundation does not accept any liability for transactions, due to a lack of control over - transaction processes. We are therefore expressly not responsible for any claims, damages or any - other type of liability caused by any third-party service provider. In no event will the IOTA - Foundation be liable to the User for any losses caused by user-error, software or system - malfunctions, errors, interruptions, delays or inability to use the App, including any losses caused - thereof to the User or any third party. - -
  • -
  • - - The App may enable features such as voting, participation in token distributions (airdrops) and - staking. All such features are provided on an "as available" and an "as is" basis. The IOTA - Foundation expressly disclaims any liability for the use of such features and does not warrant or - represent that such features are free from errors or interruptions. The IOTA Foundation shall not be - liable for lost profits and other indirect damages. Any use of such features is at the sole risk of - the User. - -
  • -
  • - - The IOTA Foundation does not accept any liability for the liabilities of users towards other users - or third parties, such as due to non-fulfilment of concluded contracts. - -
  • -
  • - - The IOTA Foundation shall not be liable for any loss or theft of the User's digital assets - including, but not limited to the loss of the User’s private keys, configuration, installation or - transaction errors made by the User, or late execution or late settlement of any transaction. - -
  • -
  • - - The liability restrictions and liability exclusions contained in this contract also apply to - liability for official bodies and/or managerial staff and non-managerial staff as well as for other - agents of the IOTA Foundation. They also apply to the personal liability of the above-mentioned - persons. - -
  • -
  • - - To the fullest extent permissible at law, indirect, special, pure economic or consequential losses - are expressly excluded under the Agreement. - -
  • -
-
- - 10. Compliance by the user - - The user is obligated to use the Firefly App exclusively for legal purposes. The following activities are - specifically prohibited in association with use of the App: - - -
    -
  • - - A violation against these conditions, or any other agreement you have made with the IOTA Foundation; - -
  • -
  • - - A violation against valid law, a contract or a directive (such as, but not limited to, regulations - for financial services, money laundering, economic sanctions, consumer protection, competition law, - protection against discrimination or misleading advertising); - -
  • -
  • - - A violation against copyrights, patents, trademarks, trade secrets and other property rights; - -
  • -
  • - Provision of incorrect, inapplicable or misleading data; -
  • -
  • - - Transfer of tokens for which there is a justified reason to suspect that the money originates from - fraudulent or other prohibited activities; - -
  • -
  • - - Refusal to cooperate in an account review or provide confirmation of your identity or provide other - details which we are required by law to request from you; - -
  • -
  • - - Concealing your identity such as by using a proxy server or by using a post box as an address for - the purpose of carrying out illegal, fraudulent, or other prohibited activities; - -
  • -
  • - - Management of a Firefly Account associated with another E-Wallet involved with prohibited - activities; - -
  • -
  • - - Conducting your business or using the IOTA Foundation's services in such a way that it leads to, or - could lead to complaints, conflicts, return debits, credit card back transfers, fees, contract - penalties, fines or other liability by the IOTA Foundation, a user, a third party or yourself; - -
  • -
  • - - Enabling (including attempting to enable) the penetration of viruses, Trojans, malware, worms or - other program processes that damage, disrupt, misuse, impair, secretly intercept, destroy or disable - (operating) systems, data or information, or granting unauthorised access to systems, data, - information or the IOTA Foundation's services; - -
  • -
  • - - Use of an automatic device (e.g. robot or spider) or a mechanical or manual method for monitoring or - replicating the IOTA Foundation or Firefly App website(s) without our prior written permission. - -
  • -
-
- - 11. Place of jurisdiction - - To the extent permitted by law, the place of jurisdiction regarding all legal disputes is Berlin. This applies - to merchants, legal entities under public law, special funds under public law and persons without a general - court of jurisdiction in the Federal Republic of Germany. - - - 12. Contact - - The IOTA Foundation provides the following email address to users to contact the IOTA Foundation in individual - cases: contact@iota.org - - - 13. Applicable law - - These conditions as well as all disputes or legal issues resulting from operation or use of the Firefly App are - subject to German law. - - - 14. Severability clause - -
    -
  • - - Should individual clauses of this contract be or become ineffective or infeasible, then this shall - not affect the effectiveness and feasibility of the remaining clauses. The ineffective clause shall - be replaced by a clause that comes as close as possible to the original intention of the contract - parties. - -
  • -
-
-
- -
- Firefly Privacy Policy - - General Information - - This Firefly privacy policy (the "Privacy Policy") describes how your data is collected and processed in - connection with the Firefly App (the "App"). - - - This Privacy Policy is dedicated to the users of the App. If you would like to know more about how the IOTA - Foundation (hereinafter "IOTA", "we", "us", "our") processes Personal Data collected and processed in connection - with other services and activities offered by IOTA, please see IOTA's general Privacy Policy available at - openUrlInBrowser('https://www.iota.org/privacy-policy')}> - https://www.iota.org/privacy-policy - - . - - - What is Personal Data - - "Personal Data" - means any information relating to an identified or identifiable natural person (‘data subject'); an identifiable - natural person is one who can be identified, directly or indirectly, in particular by reference to an identifier - such as a name, an identification number, location data, an online identifier or to one or more factors specific - to the physical, physiological, genetic, mental, economic, cultural or social identity of that natural person. - - - How we Collect Personal Data - - IOTA does not collect your Personal Data through the App. However, if you download, install and use the App on - your phone or other device, it may be necessary to process some data about you or your device for the operation - of the App and to improve our services. - - - Further, IOTA may collect and process Personal Data like your name, email address or phone number when: - - -
    -
  • - - you contact IOTA, or request that IOTA contacts you, for any reason; or - -
  • -
  • - you submit your Personal Data to IOTA for any reason. -
  • -
-
- - What Personal Data do we Collect? - - It is crucial to note that the private keys of the users are never transmitted to IOTA and it is not possible - for IOTA to access a user's crypto-assets in any case. - - - We may collect information relating to your general use of the App such as errors, log information concerning - any errors encountered in the App and other related information relevant to IOTA's provision of the services, - for the purpose of administration and diagnostics analysis to help IOTA improve its services. - - - Purpose of Processing of Personal Data - - We may process data about your use of the App in order to enable the operation and use of the App, as well as - for the administration and management of the App and the services offered via it. - - - Lawful Basis for Processing of Data - - In processing your Personal Data in connection with the purposes set out in this Privacy Policy, we may rely on - one or more of the following legal bases, depending on the circumstances: - - -
    -
  • - - we have obtained your explicit prior consent to the processing (this legal basis is only used in - relation to processing that is entirely voluntary – it is not used for processing that is - necessary or obligatory in any way); - -
  • -
  • - - the processing is necessary in connection with any contractual relationship that you may enter into - with us; - -
  • -
  • - the processing is required by the applicable law; -
  • -
  • - - the processing is necessary to protect the vital interests of any individual; or - -
  • -
  • - - we have a legitimate interest in carrying out the processing for the purpose of managing, operating - or promoting our business, and that legitimate interest is not overridden by your interests, - fundamental rights, or freedoms. - -
  • -
-
- - Use of Cookies - - We do not use cookies in the App, but we use the localStorage API to store information about the login data to - keep you logged in through various sessions (we do not store personal information), furthermore the localStorage - data is not accessible by third-parties. - - - How we Protect and Store Personal Data - - We implement appropriate technical and organisational measures to ensure a level of security appropriate to the - risk, including inter alia as appropriate: - - -
    -
  • - pseudonymisation and encryption of Personal Data; -
  • -
  • - - the ability to ensure the ongoing confidentiality, integrity, availability and resilience of - processing systems and services; - -
  • -
  • - - the ability to restore the availability and access to Personal Data in a timely manner in the event - of a physical or technical incident; and - -
  • -
  • - - a process for regular testing, assessing and evaluating the effectiveness of technical and - organisational measures for ensuring the security of the processing. - -
  • -
-
- - In assessing the appropriate level of security, we account for the risks that are presented by processing the - Personal Data, in particular, from accidental or unlawful destruction, loss, alteration, unauthorised disclosure - of, or access to Personal Data transmitted, stored or otherwise processed. - - - How we Share and Disclose Personal Data - - In order to properly operate the App and to be able to provide you with the services offered, we use the - following analytics software during the operation of the App: - - CoinGecko - - We use CoinGeckoAPI of Gecko Labs Pte. Ltd, 101 Upper Cross Street, #05-16 People's Park Centre, Singapore - 058357 to obtain historical price and market data for cryptocurrencies. Further information regarding their - privacy policy can be found under https://www.coingecko.com/en/privacy. - - GitHub - - We use GitHub of GitHub Inc., 88 Colin P. Kelly Street, San Francisco, CA 94107, USA (in the European Union: - GitHub BV Vijzelstraat 68-72, 1017 HL Amsterdam, The Netherlands) to check for app updates in order to provide - the auto-update functionality. Further information regarding their privacy policy can be found under - https://help.github.com/articles/github-privacy-statement/. - - Amazon Web Services - - We use Amazon Web Services to host our website and any updated versions of the App. Further information - regarding their privacy policy can be found under https://aws.amazon.com/privacy/. - - Cloudflare - - We use the load balancing and the Web Application Firewall (WAF) services of Cloudflare, Inc., 101 Townsend St, - San Francisco, CA 94107 to improve the performance and availability of the App. Further information regarding - their privacy policy can be found under https://www.cloudflare.com/privacypolicy/. - - - Providers of Operating Systems and Telecommunication Services - - Any transmission of data from your device depends on the operating system, the telecommunication network - provider as well as other providers of data communication (e.g. Wi-Fi provider) used. Please observe the data - protection notices of these companies. - - - Data Processors - - We may use further data processors during the operation of the App. When we are involving data processors into - the performance of our services and contractual obligations and such involvement requires the sharing of - Personal Data, we have entered into data processing agreements with the data processors, according to Art. 28 of - the European General Data Protection Regulation 2016/679 ("GDPR") and, as far as required, further appropriate - safeguards according to Art. 46-49 GDPR. The list of actual data processors to which we disclose your Personal - Data can be requested by e-mail to: privacy@iota.org. - - - Please note that IOTA may collect your Personal Data directly from the country where you are based and store it - on servers in Europe and the United States of America (USA). For the USA, there does not exist an adequacy - decision by the European Commission, guaranteeing an adequate data privacy level. Therefore IOTA has implemented - appropriate safeguards to protect your Personal Data in the USA. A copy of the safeguards may be obtained by - e-mail to: privacy@iota.org. - - - Processing of your Sensitive Personal Data - - We do not seek to collect or otherwise process your sensitive Personal Data, except where: - - -
    -
  • - - the processing is required or permitted by applicable law; - -
  • -
  • - - the processing is necessary for the establishment, exercise or defence of legal rights; or - -
  • -
  • - - we have, in accordance with applicable law, obtained your explicit consent prior to processing your - sensitive Personal Data (as above, this legal basis is only used in relation to processing that is - entirely voluntary – it is not used for processing that is necessary or obligatory in any - way). - -
  • -
-
- - Consequences of not Collecting your Personal Data - - To enable your use of the App and to provide you with the services offered via the App, it is necessary to - process some data about your usage of the App or your device. Without processing such data, we may not be able - to provide the App and its services to you. - - - Consent and Withdrawal - - Any consent is provided freely. If you have given your consent to process your data, you have the right to - withdraw your consent at any time. The withdrawal of consent does not affect the lawfulness of processing based - on consent before its withdrawal. After your withdrawal we will stop processing your Personal Data, including - storage, unless further data processing is required and legally permitted. This paragraph is only relevant for - processing that is entirely voluntary – it does not apply for processing that is necessary or obligatory - in any way, as is for example the case with regard to any data required for the installation and the operation - of the App. - - - To withdraw your consent, please send us an e-mail to: privacy@iota.org or a letter to IOTA Foundation, - Pappelallee 78/79, 10437 Berlin. - - - Legitimate Interest and Right to Object - - You may object to the processing of your Personal Data based on legitimate interests of IOTA or third parties. - Unless your objection is directed solely against direct marketing by IOTA, you have to explain your special - situation, which makes the processing of your personal data based on legitimate interests unacceptable for you. - - - To object, please send us an e-mail to: privacy@iota.org or a letter to IOTA Foundation, Pappelallee 78/79, - 10437 Berlin. - - - When we Erase Personal Data - - We erase your Personal Data automatically when they are no longer required for the purposes listed above. We - also erase your Personal Data according to your request, as explained below, and if further storage is neither - required nor permitted by the applicable laws. Further storage only occurs as long as and as far as it is - designated by the EU or Member States' legislation in EU Acts, Law, or other regulations, that IOTA is subject - to (e.g. transactional data may be stored for a period of 10 years). - - - Your Rights Related to Data Privacy - - You have the right to request access to and rectification or erasure of your Personal Data, or restriction of - their processing. Furthermore, you have the right to request data portability. If you are in the EU you have the - right to file a complaint to the relevant data protection authority, e.g. the Berlin Data Protection Authority - (Berliner Beauftragte für Datenschutz und Informationsfreiheit). - - - You have the right to obtain from us the information as to whether Personal Data concerning you are being - processed, the purpose of the processing and the categories of Personal Data concerned. - - - To exercise any of these rights, please send us an e-mail to: privacy@iota.org or a letter to IOTA Foundation, - Pappelallee 78/79, 10437 Berlin. - - A copy of the Personal Data undergoing processing can be requested. - - Our Contact Information - For any requests, you can contact us as follows: privacy@iota.org. - IOTA Foundation, Pappelallee 78/79, 10437 Berlin, Germany. - - Changes to the Privacy Policy - - This Privacy Policy may be amended or updated from time to time to reflect changes in our practices with respect - to the processing of Personal Data, or changes in applicable law. We encourage you to read this Privacy Policy - carefully, and to regularly check this page to review any changes we might make in accordance with the terms of - this Privacy Policy. Your continued use of our services or website constitutes your agreement to be bound by - this Privacy Policy, as amended or updated from time to time. - - - Questions - - If you have any questions regarding this Privacy Policy, please contact us at: privacy@iota.org. - -
diff --git a/packages/shared/src/components/molecules/NetworkRecipientSelector.svelte b/packages/shared/src/components/molecules/NetworkRecipientSelector.svelte index 230e2b10b3..d77f6d4761 100644 --- a/packages/shared/src/components/molecules/NetworkRecipientSelector.svelte +++ b/packages/shared/src/components/molecules/NetworkRecipientSelector.svelte @@ -1,11 +1,9 @@ diff --git a/packages/shared/src/components/molecules/TokenList.svelte b/packages/shared/src/components/molecules/TokenList.svelte index 9bcd05dc16..bfd7920b60 100644 --- a/packages/shared/src/components/molecules/TokenList.svelte +++ b/packages/shared/src/components/molecules/TokenList.svelte @@ -5,7 +5,7 @@ import { tokenFilter } from '@core/token/stores' import VirtualList from '@sveltejs/svelte-virtual-list' import { Text, TextType, TokenAmountTile } from '@ui' - import { Filter, TokenListMenuButton } from '../../../../desktop/components' + import { Filter, TokenListMenu } from '../../../../desktop/components' import { PopupId, openPopup } from '../../../../desktop/lib/auxiliary/popup' export let accountTokens: AccountTokens @@ -56,7 +56,7 @@ {localize('tabs.tokens')}
- +
diff --git a/packages/shared/src/components/molecules/activity-info/NftMetadataInformation.svelte b/packages/shared/src/components/molecules/activity-info/NftMetadataInformation.svelte index 82e01aea87..fc92dcc491 100644 --- a/packages/shared/src/components/molecules/activity-info/NftMetadataInformation.svelte +++ b/packages/shared/src/components/molecules/activity-info/NftMetadataInformation.svelte @@ -32,6 +32,10 @@ value: metadata.uri, copyable: true, }, + { + key: localize('general.description'), + value: metadata.description, + }, { key: localize('general.issuerName'), value: metadata.issuerName, diff --git a/packages/shared/src/components/molecules/index.js b/packages/shared/src/components/molecules/index.js index 49c55d9834..0818eb46eb 100644 --- a/packages/shared/src/components/molecules/index.js +++ b/packages/shared/src/components/molecules/index.js @@ -1,5 +1,4 @@ export { default as ActivityInformation } from './ActivityInformation.svelte' -export { default as ConditionsOfUse } from './ConditionsOfUse.svelte' export { default as MarkdownBlock } from './MarkdownBlock.svelte' export { default as MediaPlaceholder } from './MediaPlaceholder.svelte' export { default as NetworkRecipientItem } from './NetworkRecipientItem.svelte' diff --git a/packages/shared/src/components/organisms/index.js b/packages/shared/src/components/organisms/index.js index e67afef711..8830fa8ae8 100644 --- a/packages/shared/src/components/organisms/index.js +++ b/packages/shared/src/components/organisms/index.js @@ -1,2 +1 @@ export { default as NodeConfigurationForm } from './NodeConfigurationForm.svelte' -export { default as NodeListTable } from './NodeListTable.svelte' diff --git a/packages/shared/src/components/pills/Pill.svelte b/packages/shared/src/components/pills/Pill.svelte deleted file mode 100644 index c79811c71d..0000000000 --- a/packages/shared/src/components/pills/Pill.svelte +++ /dev/null @@ -1,30 +0,0 @@ - - - - {#if data} - - {data} - {:else} - - {/if} - diff --git a/packages/shared/src/components/pills/index.js b/packages/shared/src/components/pills/index.js index e91bcc2a42..898f0633e1 100644 --- a/packages/shared/src/components/pills/index.js +++ b/packages/shared/src/components/pills/index.js @@ -2,5 +2,4 @@ export { default as ActivityAsyncStatusPill } from './ActivityAsyncStatusPill.sv export { default as ActivityStatusPills } from './ActivityStatusPills.svelte' export { default as DeveloperIndicatorPill } from './DeveloperIndicatorPill.svelte' export { default as NetworkStatusPill } from './NetworkStatusPill.svelte' -export { default as Pill } from './Pill.svelte' export { default as ProposalStatusPill } from './ProposalStatusPill.svelte' diff --git a/packages/shared/src/lib/core/layer-2/actions/canAccountMakeEvmTransaction.ts b/packages/shared/src/lib/core/layer-2/actions/canAccountMakeEvmTransaction.ts index ac9d4dab5f..8e10a077c7 100644 --- a/packages/shared/src/lib/core/layer-2/actions/canAccountMakeEvmTransaction.ts +++ b/packages/shared/src/lib/core/layer-2/actions/canAccountMakeEvmTransaction.ts @@ -2,17 +2,16 @@ import { NetworkId } from '@core/network/types' import { isEvmChain } from '@core/network/utils' import { SendFlowType } from '@core/wallet/stores' -import { getLayer2AccountBalanceForToken } from '../stores' -import { getGasPriceInWei } from './getGasPriceInWei' +import { getEvmChainGasPrice, getLayer2AccountBalanceForToken } from '../stores' import { FALLBACK_ESTIMATED_GAS, GAS_LIMIT_MULTIPLIER } from '../constants' import { calculateGasFeeInGlow } from '../helpers' -export async function canAccountMakeEvmTransaction( +export function canAccountMakeEvmTransaction( accountIndex: number, networkId: NetworkId, sendFlowType: SendFlowType -): Promise { +): boolean | undefined { if (!isEvmChain(networkId)) { return undefined } @@ -21,7 +20,10 @@ export async function canAccountMakeEvmTransaction( const gasLimit = Math.floor( FALLBACK_ESTIMATED_GAS[sendFlowType ?? SendFlowType.BaseCoinTransfer] * GAS_LIMIT_MULTIPLIER ) - const gasPrice = await getGasPriceInWei(networkId) + const gasPrice = getEvmChainGasPrice(networkId) + if (gasPrice === undefined) { + return undefined + } const minimumGasFee = calculateGasFeeInGlow(gasLimit, gasPrice) - return BigInt(baseTokenAccountBalance) < BigInt(minimumGasFee.toString()) + return BigInt(baseTokenAccountBalance) > BigInt(minimumGasFee.toString()) } diff --git a/packages/shared/src/lib/core/layer-2/actions/getGasFeesForLayer1ToLayer2Transaction.ts b/packages/shared/src/lib/core/layer-2/actions/getGasFeesForLayer1ToLayer2Transaction.ts index ddae720aad..db92552b69 100644 --- a/packages/shared/src/lib/core/layer-2/actions/getGasFeesForLayer1ToLayer2Transaction.ts +++ b/packages/shared/src/lib/core/layer-2/actions/getGasFeesForLayer1ToLayer2Transaction.ts @@ -1,9 +1,9 @@ -import { SendFlowParameters } from '@core/wallet' import { BigIntLike } from '@ethereumjs/util' +import { SendFlowParameters } from '@core/wallet/types' import { GAS_LIMIT_MULTIPLIER } from '../constants' import { calculateGasFeeInGlow } from '../helpers' +import { getEvmChainGasPrice } from '../stores' import { estimateGasForLayer1ToLayer2Transaction } from './estimateGasForLayer1ToLayer2Transaction' -import { getGasPriceInWei } from './getGasPriceInWei' export async function getGasFeesForLayer1ToLayer2Transaction( sendFlowParameters: SendFlowParameters @@ -12,7 +12,7 @@ export async function getGasFeesForLayer1ToLayer2Transaction( if (sendFlowParameters.destinationNetworkId) { const estimatedGas = await estimateGasForLayer1ToLayer2Transaction(sendFlowParameters) const gasLimit = Math.floor(estimatedGas * GAS_LIMIT_MULTIPLIER) - const gasPrice = await getGasPriceInWei(sendFlowParameters.destinationNetworkId) + const gasPrice = getEvmChainGasPrice(sendFlowParameters.destinationNetworkId) const estimatedGasFee = calculateGasFeeInGlow(estimatedGas, gasPrice) const maxGasFee = calculateGasFeeInGlow(gasLimit, gasPrice) return { estimatedGasFee, maxGasFee } diff --git a/packages/shared/src/lib/core/layer-2/actions/getGasPriceInWei.ts b/packages/shared/src/lib/core/layer-2/actions/getGasPriceForNetwork.ts similarity index 80% rename from packages/shared/src/lib/core/layer-2/actions/getGasPriceInWei.ts rename to packages/shared/src/lib/core/layer-2/actions/getGasPriceForNetwork.ts index 2500a5f3ab..652489bb54 100644 --- a/packages/shared/src/lib/core/layer-2/actions/getGasPriceInWei.ts +++ b/packages/shared/src/lib/core/layer-2/actions/getGasPriceForNetwork.ts @@ -2,7 +2,7 @@ import { NetworkId } from '@core/network/types' import { getNetwork } from '@core/network/stores' import { Converter } from '@core/utils' -export async function getGasPriceInWei(networkId: NetworkId): Promise { +export async function getGasPriceForNetwork(networkId: NetworkId): Promise { const chain = getNetwork()?.getChain(networkId) const provider = chain?.getProvider() diff --git a/packages/shared/src/lib/core/layer-2/actions/index.ts b/packages/shared/src/lib/core/layer-2/actions/index.ts index 231a398e07..675d3455ec 100644 --- a/packages/shared/src/lib/core/layer-2/actions/index.ts +++ b/packages/shared/src/lib/core/layer-2/actions/index.ts @@ -5,11 +5,13 @@ export * from './canAccountMakeEvmTransaction' export * from './estimateGasForLayer1ToLayer2Transaction' export * from './fetchSelectedAccountLayer2Balance' export * from './generateAndStoreEvmAddressForAccount' -export * from './getNetworkIdFromAddress' export * from './getGasFeesForLayer1ToLayer2Transaction' -export * from './getGasPriceInWei' +export * from './getGasPriceForNetwork' export * from './getIscpTransferSmartContractData' export * from './getLayer2MetadataForTransfer' export * from './getLayer2NetworkFromAddress' +export * from './getNetworkIdFromAddress' +export * from './pollEvmChainGasPrices' export * from './pollLayer2Tokens' export * from './signEvmTransactionWithStronghold' +export * from './updateEvmChainGasPrice' diff --git a/packages/shared/src/lib/core/layer-2/actions/pollEvmChainGasPrices.ts b/packages/shared/src/lib/core/layer-2/actions/pollEvmChainGasPrices.ts new file mode 100644 index 0000000000..c842153e6a --- /dev/null +++ b/packages/shared/src/lib/core/layer-2/actions/pollEvmChainGasPrices.ts @@ -0,0 +1,38 @@ +import { NetworkId } from '@core/network/types' +import { MILLISECONDS_PER_SECOND } from '@core/utils' +import { updateEvmChainGasPrice } from './updateEvmChainGasPrice' + +const EVM_CHAIN_GAS_PRICE_POLLING_INTERVAL: number = 60 * MILLISECONDS_PER_SECOND + +const pollIntervalMap: { [id in NetworkId]?: number } = {} + +export function pollEvmChainGasPrice(networkId: NetworkId): void { + if (!networkId || isPollingEvmChainGasPrice(networkId)) { + return + } + void updateEvmChainGasPrice(networkId) + pollIntervalMap[networkId] = window.setInterval(() => { + void updateEvmChainGasPrice(networkId) + }, EVM_CHAIN_GAS_PRICE_POLLING_INTERVAL) +} + +export function pollEvmChainGasPrices(networkIds: NetworkId[]): void { + stopPollingEvmChainGasPrices() + for (const networkId of networkIds) { + pollEvmChainGasPrice(networkId) + } +} + +export function stopPollingEvmChainGasPrices(networkIdsToIgnore?: NetworkId[]): void { + for (const networkId of Object.keys(pollIntervalMap) as NetworkId[]) { + if (!networkIdsToIgnore?.includes(networkId)) { + if (isPollingEvmChainGasPrice(networkId)) { + clearInterval(pollIntervalMap[networkId]) + } + } + } +} + +export function isPollingEvmChainGasPrice(networkId: NetworkId): boolean { + return typeof pollIntervalMap[networkId] === 'number' +} diff --git a/packages/shared/src/lib/core/layer-2/actions/updateEvmChainGasPrice.ts b/packages/shared/src/lib/core/layer-2/actions/updateEvmChainGasPrice.ts new file mode 100644 index 0000000000..2f569aa892 --- /dev/null +++ b/packages/shared/src/lib/core/layer-2/actions/updateEvmChainGasPrice.ts @@ -0,0 +1,15 @@ +import { handleError } from '@core/error/handlers' +import { NetworkId } from '@core/network/types' +import { setEvmChainGasPrice } from '../stores' +import { getGasPriceForNetwork } from './getGasPriceForNetwork' + +export async function updateEvmChainGasPrice(chainId: NetworkId): Promise { + try { + const gasPrice = await getGasPriceForNetwork(chainId) + if (gasPrice) { + setEvmChainGasPrice(BigInt(gasPrice), chainId) + } + } catch (err) { + handleError(err) + } +} diff --git a/packages/shared/src/lib/core/layer-2/stores/evm-chain-gas-prices.store.ts b/packages/shared/src/lib/core/layer-2/stores/evm-chain-gas-prices.store.ts new file mode 100644 index 0000000000..395fc7563b --- /dev/null +++ b/packages/shared/src/lib/core/layer-2/stores/evm-chain-gas-prices.store.ts @@ -0,0 +1,23 @@ +import { get, writable } from 'svelte/store' +import { NetworkId } from '@core/network/types' +import { isEvmChain } from '@core/network/utils' +import { EvmChainGasPrices } from '../types' + +export const evmChainGasPrices = writable({}) + +export function getEvmChainGasPrice(networkId: NetworkId): bigint | undefined { + return get(evmChainGasPrices)[networkId] +} + +export function setEvmChainGasPrice(price: bigint, networkId: NetworkId): void { + evmChainGasPrices.update((state) => { + if (typeof price === 'bigint' && isEvmChain(networkId)) { + return { + ...state, + [networkId]: price, + } + } else { + return state + } + }) +} diff --git a/packages/shared/src/lib/core/layer-2/stores/index.ts b/packages/shared/src/lib/core/layer-2/stores/index.ts index 7c15aa4d3f..2c59ed1ce6 100644 --- a/packages/shared/src/lib/core/layer-2/stores/index.ts +++ b/packages/shared/src/lib/core/layer-2/stores/index.ts @@ -1 +1,2 @@ +export * from './evm-chain-gas-prices.store' export * from './layer2-balances.store' diff --git a/packages/shared/src/lib/core/layer-2/types/evm-chain-gas-prices.type.ts b/packages/shared/src/lib/core/layer-2/types/evm-chain-gas-prices.type.ts new file mode 100644 index 0000000000..876a3c8e17 --- /dev/null +++ b/packages/shared/src/lib/core/layer-2/types/evm-chain-gas-prices.type.ts @@ -0,0 +1,5 @@ +import { NetworkId } from '@core/network/types' + +export type EvmChainGasPrices = { + [id in NetworkId]?: bigint +} diff --git a/packages/shared/src/lib/core/layer-2/types/index.ts b/packages/shared/src/lib/core/layer-2/types/index.ts index 57eb6baa5a..4a0f1b1fe7 100644 --- a/packages/shared/src/lib/core/layer-2/types/index.ts +++ b/packages/shared/src/lib/core/layer-2/types/index.ts @@ -1,5 +1,6 @@ export * from './abi.type' export * from './contract.type' +export * from './evm-chain-gas-prices.type' export * from './evm-transaction-options.type' export * from './evm-transaction-data.type' export * from './layer2-account-balance.interface' diff --git a/packages/shared/src/lib/core/wallet/tests/getOutputParameters.test.ts b/packages/shared/src/lib/core/wallet/tests/getOutputParameters.test.ts index 5e9038ec85..e54fde7597 100644 --- a/packages/shared/src/lib/core/wallet/tests/getOutputParameters.test.ts +++ b/packages/shared/src/lib/core/wallet/tests/getOutputParameters.test.ts @@ -90,8 +90,8 @@ jest.mock('../../network/actions/getChainConfiguration', () => ({ getChainConfiguration: jest.fn((_) => destinationNetwork), })) -jest.mock('../../layer-2/actions/getGasPriceInWei', () => ({ - getGasPriceInWei: jest.fn((_) => 1_000_000_000_000n), +jest.mock('../../layer-2/actions/getGasPriceForNetwork', () => ({ + getGasPriceForNetwork: jest.fn((_) => 1_000_000_000_000n), })) jest.mock('../../layer-2/actions/estimateGasForLayer1ToLayer2Transaction', () => ({ @@ -234,7 +234,7 @@ describe('File: getOutputParameters.ts', () => { const output = await getOutputParameters(sendFlowParameters, senderAddress) const expectedOutput = { recipientAddress: destinationNetwork.aliasAddress, - amount: '1000026620', + amount: '1000000000', features: { metadata: '0x00000000025e4b3ca1e3f423fccf01010161200300010000070c000c30680e00000090000f0ea000060009000d300000000000808094ebdc03', @@ -266,7 +266,7 @@ describe('File: getOutputParameters.ts', () => { const expectedOutput = { recipientAddress: destinationNetwork.aliasAddress, - amount: '26785', + amount: '0', assets: { nativeTokens: [ { @@ -297,7 +297,7 @@ describe('File: getOutputParameters.ts', () => { const expectedOutput = { recipientAddress: destinationNetwork.aliasAddress, - amount: '27170', + amount: '0', assets: { nftId, },