Skip to content

Commit

Permalink
fix: useWallets rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaccoSordo committed Jan 31, 2025
1 parent a7fa7c8 commit ba20fda
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ import { StorageKey } from '@airgap/beacon-types'
import QR from 'src/components/qr'
import useWallets from '../../hooks/useWallets'
import { ConfigurableAlertProps } from '../../../common'
import useIsMobile from '../../hooks/useIsMobile'

const PairingAlert: React.FC<ConfigurableAlertProps> = (props) => {
const {
walletConnectSyncCode: wcPayload,
p2pSyncCode: p2pPayload,
postmessageSyncCode: postPayload
} = props.pairingPayload!
const isMobile = useIsMobile()
const wallets = useWallets(props.pairingPayload?.networkType, props.featuredWallets)
const [
wallet,
isMobile,
isLoading,
qrCode,
state,
Expand All @@ -38,7 +39,7 @@ const PairingAlert: React.FC<ConfigurableAlertProps> = (props) => {
handleUpdateState,
handleUpdateQRCode,
handleShowMoreContent
] = useConnect(wcPayload, p2pPayload, postPayload, wallets, props.onClose)
] = useConnect(isMobile, wcPayload, p2pPayload, postPayload, wallets, props.onClose)
const isOnline = navigator.onLine
const walletList = Array.from(wallets.values())
const areMetricsEnabled = localStorage
Expand Down
4 changes: 1 addition & 3 deletions packages/beacon-ui/src/ui/alert/hooks/useConnect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { MergedWallet, OSLink } from 'src/utils/wallets'
import getDefaultLogo from '../getDefautlLogo'
import { parseUri } from '@walletconnect/utils'
import { AlertConfig } from '../../common'
import useIsMobile from './useIsMobile'

const logger = new Logger('useConnect')

const useConnect = (
isMobile: boolean,
wcPayload: string,
p2pPayload: string,
postPayload: string,
Expand All @@ -27,7 +27,6 @@ const useConnect = (
const [displayQRExtra, setDisplayQRExtra] = useState(false)
const [showMoreContent, setShowMoreContent] = useState(false)
const [isWCWorking, setIsWCWorking] = useState(true)
const isMobile = isMobileOS(window) || useIsMobile()

const setInstallState = (wallet?: MergedWallet) => {
if (
Expand Down Expand Up @@ -317,7 +316,6 @@ const useConnect = (

return [
wallet,
isMobile,
isLoading,
qrCode,
state,
Expand Down
3 changes: 2 additions & 1 deletion packages/beacon-ui/src/ui/alert/hooks/useIsMobile.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState, useEffect } from 'react'
import { isMobileOS } from 'src/utils/platform'

const useIsMobile = (breakpoint = 768) => {
const [isMobile, setIsMobile] = useState(window.innerWidth <= breakpoint)
Expand All @@ -16,7 +17,7 @@ const useIsMobile = (breakpoint = 768) => {
}
}, [breakpoint])

return isMobile
return isMobileOS(window) || isMobile
}

export default useIsMobile
183 changes: 83 additions & 100 deletions packages/beacon-ui/src/ui/alert/hooks/useWallets.tsx
Original file line number Diff line number Diff line change
@@ -1,125 +1,108 @@
import { useCallback, useEffect, useState } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { PostMessageTransport } from '@airgap/beacon-transport-postmessage'
import {
arrangeTopWallets,
MergedWallet,
mergeWallets,
parseWallets,
Wallet
} from 'src/utils/wallets'
import { arrangeTopWallets, mergeWallets, parseWallets } from 'src/utils/wallets'
import { Extension, NetworkType } from '@airgap/beacon-types'
import { desktopList, extensionList, iOSList, webList } from '../wallet-lists'
import { windowRef } from '@airgap/beacon-core'

const useWallets = (networkType?: NetworkType, featuredWallets?: string[]) => {
const [wallets, setWallets] = useState<MergedWallet[]>([])
const [availableExtensions, setAvailableExtensions] = useState<Extension[]>([])

// Fetch and listen for extension updates
useEffect(() => {
PostMessageTransport.getAvailableExtensions().then((extensions) =>
setWallets(createWallets(extensions))
)
const handler = async (event: any): Promise<void> => {
PostMessageTransport.getAvailableExtensions().then(setAvailableExtensions)

const handler = async (event: any) => {
if (event.data === 'extensionsUpdated') {
setWallets(createWallets(await PostMessageTransport.getAvailableExtensions()))
const extensions = await PostMessageTransport.getAvailableExtensions()
setAvailableExtensions(extensions)
}
}

windowRef.addEventListener('message', handler)
return () => {
windowRef.removeEventListener('message', handler)
}
return () => windowRef.removeEventListener('message', handler)
}, [])

const createWallets = useCallback((availableExtensions: Extension[]) => {
const wallets: Wallet[] = [
// Memoize wallet list creation
const wallets = useMemo(() => {
const merged = [
// Desktop wallets filtered by available extensions
...desktopList
// This is used for a special case where desktop wallets have inApp browsers.
// In this case, the wallet will act like an extension. This means we have to remove
// the desktop app from the list to make the user experience better. One example of this
// is Infinity Wallet.
.filter(
(wallet) => !availableExtensions.some((extWallet) => wallet.name === extWallet.name)
)
.map((wallet) => {
return {
id: wallet.key,
key: wallet.key,
name: wallet.shortName,
image: wallet.logo,
description: 'Desktop App',
supportedInteractionStandards: wallet.supportedInteractionStandards,
type: 'desktop',
link: wallet.downloadLink,
deepLink: wallet.deepLink
}
}),
...extensionList.map((wallet) => {
return {
id: wallet.id,
key: wallet.key,
name: wallet.shortName,
image: wallet.logo,
description: 'Browser Extension',
supportedInteractionStandards: wallet.supportedInteractionStandards,
type: 'extension',
link: wallet.link
}
}),
...iOSList.map((wallet) => {
return {
id: wallet.key,
key: wallet.key,
name: wallet.shortName,
image: wallet.logo,
description: 'Mobile App',
supportedInteractionStandards: wallet.supportedInteractionStandards,
type: 'ios',
link: wallet.universalLink,
deepLink: wallet.deepLink
}
}),
...webList.map((wallet) => {
const link = wallet.links[networkType ?? NetworkType.MAINNET]
.filter((w) => !availableExtensions.some((e) => w.name === e.name))
.map((w) => ({
id: w.key,
key: w.key,
name: w.shortName,
image: w.logo,
description: 'Desktop App',
supportedInteractionStandards: w.supportedInteractionStandards,
type: 'desktop' as const,
link: w.downloadLink,
deepLink: w.deepLink
})),

// Browser extensions
...extensionList.map((w) => ({
id: w.id,
key: w.key,
name: w.shortName,
image: w.logo,
description: 'Browser Extension',
supportedInteractionStandards: w.supportedInteractionStandards,
type: 'extension' as const,
link: w.link
})),

// iOS wallets
...iOSList.map((w) => ({
id: w.key,
key: w.key,
name: w.shortName,
image: w.logo,
description: 'Mobile App',
supportedInteractionStandards: w.supportedInteractionStandards,
type: 'ios' as const,
link: w.universalLink,
deepLink: w.deepLink
})),

// Web wallets (networkType sensitive)
...webList.map((w) => {
const link = w.links[networkType ?? NetworkType.MAINNET]
return {
id: wallet.key,
key: wallet.key,
name: wallet.shortName,
image: wallet.logo,
id: w.key,
key: w.key,
name: w.shortName,
image: w.logo,
description: 'Web App',
supportedInteractionStandards: wallet.supportedInteractionStandards,
type: 'web',
link: link ?? wallet.links.mainnet
supportedInteractionStandards: w.supportedInteractionStandards,
type: 'web' as const,
link: link ?? w.links.mainnet
}
}),

// Additional detected extensions
...availableExtensions
.filter((newExt) => !extensionList.some((ext) => ext.id === newExt.id))
.map((wallet) => {
return {
id: wallet.id,
key: wallet.id,
name: wallet.shortName ?? wallet.name ?? '',
image: wallet.iconUrl ?? '',
description: 'Browser Extension',
type: 'extension',
link: (wallet as any).link ?? ''
}
})
.filter((e) => !extensionList.some((w) => w.id === e.id))
.map((e) => ({
id: e.id,
key: e.id,
name: e.shortName ?? e.name ?? '',
image: e.iconUrl ?? '',
description: 'Browser Extension',
type: 'extension' as const,
link: (e as any).link ?? ''
}))
]

// Parse wallet names
const parsedWallets = parseWallets(wallets)

// Merge wallets by name
const mergedWallets = mergeWallets(parsedWallets)

// Default selection of featured wallets
const defaultWalletList = ['kukai', 'temple', 'plenty', 'umami']

// Sort wallets by top 4
const arrangedWallets = arrangeTopWallets(mergedWallets, featuredWallets ?? defaultWalletList)

return arrangedWallets
}, [])
return arrangeTopWallets(
mergeWallets(parseWallets(merged)),
featuredWallets ?? ['kukai', 'temple', 'plenty', 'umami']
)
}, [availableExtensions, networkType, featuredWallets])

return new Map(wallets.map((wallet) => [wallet.id, wallet]))
// Memoize the final Map structure
return useMemo(() => new Map(wallets.map((wallet) => [wallet.id, wallet])), [wallets])
}

export default useWallets
2 changes: 1 addition & 1 deletion packages/beacon-ui/src/ui/toast/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const ToastRoot = (props: ToastConfig) => {
// because otherwise the "fade-out" animation
// won't have enough time to play
if (config && config.timer) {
setTimeout(() => setMount(false), 300)
setTimeout(() => setMount(false), config.timer)
}

// no else that acts like a "default"
Expand Down

0 comments on commit ba20fda

Please sign in to comment.