diff --git a/app.vue b/app.vue index d8376e93..21644ac0 100644 --- a/app.vue +++ b/app.vue @@ -109,17 +109,8 @@ const setupViewedProfile = async () => { } } -const setupNetwork = async () => { - const chainId = (await INJECTED_PROVIDER?.request({ - method: 'eth_chainId', - })) as string - - selectedChainId.value = chainId -} - onMounted(async () => { setupTranslations() - await setupNetwork() await setupWeb3Instances() checkConnectionExpiry() await routerBackProfileLoad() diff --git a/components/AppFooter.vue b/components/AppFooter.vue index 91704654..e7c23b00 100644 --- a/components/AppFooter.vue +++ b/components/AppFooter.vue @@ -1,16 +1,21 @@ - + - + + +import { SelectStringOption } from '@lukso/web-components' + +const networks = ref() +const selectedNetwork = ref() +const { currentNetwork, selectedChainId } = storeToRefs(useAppStore()) +const { disconnect } = useBrowserExtension() +const { isMobileOrTablet } = useDevice() +const isOpen = ref(false) + +onMounted(() => { + networks.value = NETWORKS.map(network => { + return { + id: network.chainId, + value: network.name, + } + }) +}) + +watchEffect(() => { + selectedNetwork.value = { + id: currentNetwork.value.chainId, + value: currentNetwork.value.name, + } +}) + +const handleNetworkChange = (event: CustomEvent) => { + const selectedNetwork = event.detail.value as SelectStringOption + selectedNetwork.id && (selectedChainId.value = selectedNetwork.id) + disconnect() + navigateTo(homeRoute()) +} + + + + + diff --git a/components/ModalTemplateSwitchNetwork.vue b/components/ModalTemplateSwitchNetwork.vue new file mode 100644 index 00000000..be0b9787 --- /dev/null +++ b/components/ModalTemplateSwitchNetwork.vue @@ -0,0 +1,57 @@ + + + + + + + {{ $formatMessage('modal_switch_network_title') }} + + + + + + + {{ $formatMessage('modal_switch_network_cancel') }} + + + {{ $formatMessage('modal_switch_network_confirm') }} + + + + diff --git a/composables/useBrowserExtension.ts b/composables/useBrowserExtension.ts index c5be4550..f96e644a 100644 --- a/composables/useBrowserExtension.ts +++ b/composables/useBrowserExtension.ts @@ -53,9 +53,11 @@ const connect = async () => { console.error(error) disconnect() + await checkNetwork() + showModal({ title: formatMessage('web3_connect_error_title'), - message: getConnectionErrorMessage(error), + message: getErrorMessage(error), }) } finally { isConnecting.value = false @@ -102,14 +104,6 @@ const handleAccountsChanged = async (accounts: string[]) => { } } -const handleChainChanged = (network: { chainId: string }) => { - const { selectedChainId } = storeToRefs(useAppStore()) - - selectedChainId.value = network.chainId - disconnect() - navigateTo(homeRoute()) -} - const handleDisconnect = () => { location.reload() } @@ -117,13 +111,11 @@ const handleDisconnect = () => { const addProviderEvents = async (provider: ProviderAPI) => { provider?.on?.('accountsChanged', handleAccountsChanged) provider?.on?.('disconnect', handleDisconnect) - provider?.on?.('chainChanged', handleChainChanged) } const removeProviderEvents = async (provider: ProviderAPI) => { provider?.off?.('accountsChanged', handleAccountsChanged) provider?.off?.('disconnect', handleDisconnect) - provider?.off?.('chainChanged', handleChainChanged) } const isUniversalProfileExtension = () => { diff --git a/package.json b/package.json index daf2a15f..fd56842b 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@formatjs/intl": "^2.9.5", "@lukso/lsp-smart-contracts": "0.12.0", - "@lukso/web-components": "1.47.1", + "@lukso/web-components": "1.49.0", "@nuxt/devtools": "^0.7.6", "@nuxtjs/algolia": "^1.9.0", "@nuxtjs/device": "^3.1.1", diff --git a/pages/[profileAddress]/send.vue b/pages/[profileAddress]/send.vue index 8b09f1fe..07a4666b 100644 --- a/pages/[profileAddress]/send.vue +++ b/pages/[profileAddress]/send.vue @@ -152,9 +152,11 @@ const handleSend = async () => { console.error(error) setStatus('draft') + await checkNetwork() + showModal({ title: formatMessage('web3_connect_error_title'), - message: getSendErrorMessage(error), + message: getErrorMessage(error), }) } } diff --git a/public/images/switch-network.png b/public/images/switch-network.png new file mode 100644 index 00000000..3d4bb767 Binary files /dev/null and b/public/images/switch-network.png differ diff --git a/tests/e2e/404.spec.ts-snapshots/404-chrome.png b/tests/e2e/404.spec.ts-snapshots/404-chrome.png index b87429fe..23ea33d8 100644 Binary files a/tests/e2e/404.spec.ts-snapshots/404-chrome.png and b/tests/e2e/404.spec.ts-snapshots/404-chrome.png differ diff --git a/tests/e2e/index.spec.ts-snapshots/landing-no-extension-chrome.png b/tests/e2e/index.spec.ts-snapshots/landing-no-extension-chrome.png index 7f7fa991..8f42d5a5 100644 Binary files a/tests/e2e/index.spec.ts-snapshots/landing-no-extension-chrome.png and b/tests/e2e/index.spec.ts-snapshots/landing-no-extension-chrome.png differ diff --git a/translations/en_US.json b/translations/en_US.json index 97a28f1f..73ab5967 100644 --- a/translations/en_US.json +++ b/translations/en_US.json @@ -1,35 +1,37 @@ { - "web3_eoa_error_message": "Please use Universal Profile Extension. ", + "error_pending_request": "You have pending request. Check your browser extension.", "connect_or_install_button_connect": "Connect with Universal Profile", "button_send": "Send", + "error_rejected_request": "You rejected the request", + "modal_switch_network_title": "Switch network", "asset_standard_info_LSP8_title": "LSP8 Token Standard", "header_title": "UNIVERSAL\nPROFILES", "token_details_contract_address": "Contract Address", "landing_hero_description_no_extension": "Looks like you don’t have the Universal Profile browser extension installed. You’ll need it before you can log in to our wallet service.", + "error_no_accounts": "Account not found.", "send_pending_title": "Sending {amount} {symbol}", "assets_empty_state_title": "No created assets", "web3_connect_no_extension": "You don't have the Universal Profile browser extension installed.", "header_install_extension": "Install Extension", + "error_same_address": "You cannot send {lyxSymbol} to yourself", "asset_standard_info_legacy_details": "Info about the standard goes here....", "asset_standard_info_LSP7_details": "Info about the standard goes here....", "web3_connect_error_title": "Can't connect", + "modal_switch_network_confirm": "Switch network", "send_error_title": "Something went wrong...", "not_found_title": "Oops!", "landing_hero_supported_browsers": "Supported Browsers", "not_found_get_help_url": "https://lukso.network/faq", "send_input_placeholder": "Enter address of recipient", - "web3_connect_error_pending_request": "You have pending request. Check your browser extension.", - "send_error_rejected_request": "User rejected the request.", "token_details_send": "Send {token}", "token_details_token_id": "Token ID", "send_button": "Send {amount} {symbol}", "asset_supply_title": "Total Token Supply", - "send_error_same_address": "You cannot send {lyxSymbol} to yourself", "header_discovery": "Discovery", "not_found_text": "We can’t seem to find the page you’re looking for!", "asset_filter_owned_assets": "Owned assets", "asset_standard_info_LSP8_details": "Info about the standard goes here....", - "web3_connect_error_rejected_request": "You rejected the request", + "error_eoa": "Please use Universal Profile Extension. ", "modal_default_title": "Something went wrong...", "modal_select_assets_title": "Select a token to send", "footer_need_help_text": "NEED HELP?", @@ -39,20 +41,22 @@ "lyx_details_description": "This is the native token of the LUKSO blockchain.", "asset_standard_info_LSP7_title": "LSP7 Token Standard", "asset_filter_created_assets": "Created assets", - "landing_hero_title": "Universal Profiles Wallet", + "landing_hero_title": "Universal Profile Wallet", "header_send": "Send", "asset_standard_info_legacy_title": "Legacy Token Standard", "connect_or_install_button_install": "Install browser extension", "token_details_description": "Token Description", "header_my_profile": "My profile", "send_success_button": "Send another token", + "modal_switch_network_description": "You will need to switch to {name} in the extension to continue using this application", "send_success_title": "Sending complete!", "profile_default_name": "anonymous-profile", + "error_no_profiles": "You don't have any profiles.", "footer_terms_text": "Terms & Conditions", "assets_empty_state_description": "To find out how to create own assets such as Tokens and NFT’s on LUKSO head over to our documentation. ", "connect_or_install_button_coming_soon": "Coming soon...", "profile_balance_of": "of {balance} {symbol}", - "send_error_message": "Looks like there was some kind of issue with your transaction. Please try again.", + "modal_switch_network_cancel": "Cancel", "footer_docs_text": "DOCS", "not_found_get_help": "Get some help", "header_disconnect": "Disconnect", @@ -67,9 +71,9 @@ "web3_interface_error_message": "You tried to connect with a legacy profile that is no longer supported.", "errors_invalid_address": "This is an invalid address", "header_connect": "Connect", + "error_wrong_network": "Your browser extension is using different network. In order to continue please switch to {name}.", "web3_connect_error": "There was an error while connecting to the browser extension.", "footer_privacy_policy_text": "Privacy Policy", - "web3_connect_error_no_profiles": "You don't have any profiles.", "token_details_images": "Token Images", "profile_search_no_results": "No profile found" } \ No newline at end of file diff --git a/utils/checkNetwork.ts b/utils/checkNetwork.ts new file mode 100644 index 00000000..4fa6b8d3 --- /dev/null +++ b/utils/checkNetwork.ts @@ -0,0 +1,15 @@ +export const checkNetwork = async () => { + const { currentNetwork } = useAppStore() + const { showModal } = useModal() + const chainId = (await INJECTED_PROVIDER?.request({ + method: 'eth_chainId', + })) as string + + if (currentNetwork.chainId !== chainId) { + showModal({ + template: 'SwitchNetwork', + }) + + throw new Error('Wrong network') + } +} diff --git a/utils/getErrorMessage.ts b/utils/getErrorMessage.ts index 2a1a4014..ed20bbc7 100644 --- a/utils/getErrorMessage.ts +++ b/utils/getErrorMessage.ts @@ -1,45 +1,31 @@ -export const getConnectionErrorMessage = (error: unknown) => { +export const getErrorMessage = (error: unknown) => { const { formatMessage } = useIntl() + const { currentNetwork } = useAppStore() // known error types if (error instanceof EoAError) { - return formatMessage('web3_eoa_error_message') + return formatMessage('error_eoa') } if (error instanceof InterfaceError) { - return formatMessage('web3_interface_error_message') + return formatMessage('error_invalid_profile_interface') } // errors that have a code or message if (error && typeof error === 'object' && 'code' in error) { switch (error.code) { case 4001: - return formatMessage('web3_connect_error_rejected_request') + return formatMessage('error_rejected_request') case -32005: - return formatMessage('web3_connect_error_pending_request') + return formatMessage('error_pending_request') case -32001: - return formatMessage('web3_connect_error_no_profiles') - default: - break - } - } - - // generic message for unknowns errors - return formatMessage('web3_connect_error') -} - -export const getSendErrorMessage = (error: unknown): string => { - const { formatMessage } = useIntl() - const appStore = useAppStore() - - // errors that have a code or message - if (error && typeof error === 'object' && 'code' in error) { - switch (error.code) { - case 4001: - return formatMessage('send_error_rejected_request') + return formatMessage('error_no_profiles') + case -32600: + return formatMessage('error_no_accounts') + case -32601: case -32602: - return formatMessage('send_error_same_address', { - lyxSymbol: appStore.currentNetwork.token.symbol, + return formatMessage('error_same_address', { + lyxSymbol: currentNetwork.token.symbol, }) default: break @@ -47,5 +33,5 @@ export const getSendErrorMessage = (error: unknown): string => { } // generic message for unknowns errors - return formatMessage('send_error_message') + return formatMessage('web3_connect_error') } diff --git a/yarn.lock b/yarn.lock index e1c35930..44571ac8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1913,12 +1913,12 @@ __metadata: languageName: node linkType: hard -"@lukso/web-components@npm:1.47.1": - version: 1.47.1 - resolution: "@lukso/web-components@npm:1.47.1" +"@lukso/web-components@npm:1.49.0": + version: 1.49.0 + resolution: "@lukso/web-components@npm:1.49.0" dependencies: ethereum-blockies-base64: ^1.0.2 - checksum: a23aaa4c9848c28b5dff7d2e20c13ebd21772616e3c52742151c2d0e07a18698f50d20bfb6d271173e419cc7be9d7fc6adbb502a13d01ba1ace4fbfaaf33fff5 + checksum: 6ad7d2a491d121a9a5a26c1495ed704a635ee181320d994c559c2b60553cedc59be4cd5c33ce31343866530a126f242339f5498c00f04168c85f7f5f4c2afcb2 languageName: node linkType: hard @@ -16379,7 +16379,7 @@ __metadata: "@esbuild-plugins/node-globals-polyfill": 0.2.3 "@formatjs/intl": ^2.9.5 "@lukso/lsp-smart-contracts": 0.12.0 - "@lukso/web-components": 1.47.1 + "@lukso/web-components": 1.49.0 "@nuxt/devtools": ^0.7.6 "@nuxtjs/algolia": ^1.9.0 "@nuxtjs/device": ^3.1.1