-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a7fa7c8
commit ba20fda
Showing
5 changed files
with
90 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters