Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
feat: network switch (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
dzbo authored Nov 8, 2023
1 parent 5fe3c93 commit 49830ce
Show file tree
Hide file tree
Showing 14 changed files with 163 additions and 66 deletions.
9 changes: 0 additions & 9 deletions app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 9 additions & 4 deletions components/AppFooter.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
<script setup lang="ts">
import { ProviderName } from '@lukso/web-components/dist/components/lukso-share'
const providers: ProviderName[] = ['twitter', 'discord', 'github']
const providers = ref<ProviderName[]>()
onMounted(() => {
providers.value = ['twitter', 'discord', 'github']
})
</script>

<template>
<lukso-footer :providers="providers">
<lukso-footer v-if="providers" :providers="providers">
<div
slot="links"
class="grid gap-4 items-center grid-cols-1 grid-rows-2 xl:grid-cols-[repeat(3,max-content)] xl:gap-10 xl:grid-rows-1"
class="grid gap-4 items-center grid-cols-1 grid-rows-3 xl:grid-cols-[repeat(4,max-content)] xl:gap-10 xl:grid-rows-1"
>
<div class="flex gap-10">
<AppFooterNetworkSelect />
<div class="flex gap-10 items-center">
<a
href="https://docs.lukso.tech/"
class="nav-apax-12-medium-uppercase text-purple-41 hover:underline hover:text-purple-31"
Expand Down
45 changes: 45 additions & 0 deletions components/AppFooterNetworkSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script setup lang="ts">
import { SelectStringOption } from '@lukso/web-components'
const networks = ref<SelectStringOption[]>()
const selectedNetwork = ref<SelectStringOption>()
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())
}
</script>

<template>
<lukso-select
:value="JSON.stringify(selectedNetwork)"
:options="JSON.stringify(networks)"
:open-top="!isMobileOrTablet ? true : undefined"
:is-open="isOpen ? true : undefined"
:is-full-width="isMobileOrTablet ? true : undefined"
class="sm:w-40"
@on-select="handleNetworkChange"
></lukso-select>
</template>
57 changes: 57 additions & 0 deletions components/ModalTemplateSwitchNetwork.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script setup lang="ts">
const { currentNetwork } = useAppStore()
type Props = {
closeModal: () => void
}
const props = defineProps<Props>()
const handleChangeNetwork = async () => {
try {
await INJECTED_PROVIDER?.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: currentNetwork.chainId }],
})
} catch (error: unknown) {
console.error(error)
} finally {
props.closeModal()
}
}
</script>

<template>
<div class="bg-neutral-98 text-center p-6 rounded-12 flex flex-col">
<img
src="/images/switch-network.png"
class="mx-auto w-[150px] mb-6"
alt=""
/>
<div class="heading-inter-21-semi-bold pb-4">
{{ $formatMessage('modal_switch_network_title') }}
</div>
<div class="paragraph-inter-16-regular">
<lukso-sanitize
:html-content="
$formatMessage('modal_switch_network_description', {
name: `<strong>${currentNetwork.name}</strong>`,
})
"
></lukso-sanitize>
</div>
<div class="grid grid-cols-[max-content,auto]">
<lukso-button variant="text" @click="closeModal" class="mt-6">
{{ $formatMessage('modal_switch_network_cancel') }}
</lukso-button>
<lukso-button
variant="landing"
is-full-width
@click="handleChangeNetwork"
class="mt-6"
>
{{ $formatMessage('modal_switch_network_confirm') }}
</lukso-button>
</div>
</div>
</template>
14 changes: 3 additions & 11 deletions composables/useBrowserExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -102,28 +104,18 @@ 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()
}

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 = () => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 3 additions & 1 deletion pages/[profileAddress]/send.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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),
})
}
}
Expand Down
Binary file added public/images/switch-network.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/e2e/404.spec.ts-snapshots/404-chrome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 12 additions & 8 deletions translations/en_US.json
Original file line number Diff line number Diff line change
@@ -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 <span class=\"paragraph-inter-16-semi-bold\">Universal Profile browser extension</span> 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?",
Expand All @@ -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 <strong>LUKSO</strong> head over to our <a href=\"https://docs.lukso.tech/guides/digital-assets/create-lsp7-digital-asset/\" target=\"_blank\" class=\"text-purple-51 hover:text-purple-41 underline\"><strong>documentation</strong></a>. ",
"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",
Expand All @@ -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"
}
15 changes: 15 additions & 0 deletions utils/checkNetwork.ts
Original file line number Diff line number Diff line change
@@ -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')
}
}
40 changes: 13 additions & 27 deletions utils/getErrorMessage.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,37 @@
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
}
}

// generic message for unknowns errors
return formatMessage('send_error_message')
return formatMessage('web3_connect_error')
}
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 49830ce

Please sign in to comment.