From c95212a575f3112c58703a86565c58a984c44909 Mon Sep 17 00:00:00 2001 From: Viktor Vasas Date: Mon, 7 Oct 2024 14:04:04 +0200 Subject: [PATCH] feat: add ew method to get extensions --- .../providers/MultiWalletProviderProxy.ts | 26 ++- .../providers/initializeInpageProvider.ts | 41 +++- src/background/providers/models.ts | 5 + .../providers/utils/getWalletExtensionType.ts | 10 + .../web3/handlers/avalanche_selectWallet.ts | 2 + src/background/services/web3/models.ts | 3 + src/pages/ApproveAction/SelectWallet.tsx | 33 +++- .../components/WalletExtensionButton.tsx | 178 +++++++++++++----- 8 files changed, 231 insertions(+), 67 deletions(-) diff --git a/src/background/providers/MultiWalletProviderProxy.ts b/src/background/providers/MultiWalletProviderProxy.ts index 7eb1ce3da..a9d86c9b3 100644 --- a/src/background/providers/MultiWalletProviderProxy.ts +++ b/src/background/providers/MultiWalletProviderProxy.ts @@ -8,6 +8,7 @@ import { getWalletExtensionType } from './utils/getWalletExtensionType'; import { Maybe } from '@avalabs/core-utils-sdk'; import EventEmitter from 'events'; import { EVMProvider } from '@avalabs/evm-module/dist/provider'; +import { EIP6963ProviderDetail } from '@avalabs/vm-module-types'; export class MultiWalletProviderProxy extends EventEmitter { #_providers: unknown[] = []; @@ -64,8 +65,10 @@ export class MultiWalletProviderProxy extends EventEmitter { }); } - public addProvider(provider) { + public addProvider(providerDetail) { + console.log('providerDetail: ', providerDetail); // the COINBASE collects here the wallets + /* if (provider.providerMap) { for (const providerProxy of provider.providerMap.values()) { if ( @@ -77,14 +80,22 @@ export class MultiWalletProviderProxy extends EventEmitter { } return; } + */ // the coinbase would add another proxy which is useless for us - if (provider.coinbaseWalletInstalls) { - return; - } - - if (!this.#_providers.includes(provider)) { - this.#_providers.push(provider); + // if (providerDetail.coinbaseWalletInstalls) { + // return; + // } + + const isProviderAdded = this.#_providers.find( + (provider) => provider.info.uuid === providerDetail.info.uuid + ); + console.log('isProviderAdded: ', isProviderAdded); + if (!isProviderAdded) { + console.log('providerDetail: ', providerDetail); + console.log('ADD -++++--_'); + this.#_providers.push(providerDetail); + console.log('this.#_providers: ', this.#_providers); } } @@ -105,6 +116,7 @@ export class MultiWalletProviderProxy extends EventEmitter { return { index: i, type, + info: p.info, }; }), ], diff --git a/src/background/providers/initializeInpageProvider.ts b/src/background/providers/initializeInpageProvider.ts index 7cc6c8355..dd4e11918 100644 --- a/src/background/providers/initializeInpageProvider.ts +++ b/src/background/providers/initializeInpageProvider.ts @@ -17,6 +17,7 @@ export function initializeProvider( maxListeners = 100, globalObject = window ): EVMProvider { + console.log('initializeProvider globalObject: ', globalObject); const chainAgnosticProvider = new Proxy( new ChainAgnosticProvider(connection), { @@ -44,10 +45,27 @@ export function initializeProvider( deleteProperty: () => true, } ); + const multiWalletProxy = createMultiWalletProxy(evmProvider); + + globalObject.addEventListener('eip6963:announceProvider', (event: any) => { + // console.log('event: ', event.detail); + multiWalletProxy.addProvider( + new Proxy( + { + info: { ...event.detail.info }, + ...event.detail.provider, + }, + { + deleteProperty: () => true, + set: () => true, + } + ) + ); + }); - setGlobalProvider(evmProvider, globalObject); + setGlobalProvider(evmProvider, globalObject, multiWalletProxy); setAvalancheGlobalProvider(evmProvider, globalObject); - setEvmproviders(evmProvider, globalObject); + // setEvmproviders(evmProvider, globalObject); announceWalletProvider(evmProvider, globalObject); announceChainAgnosticProvider(chainAgnosticProvider, globalObject); @@ -62,23 +80,28 @@ export function initializeProvider( */ function setGlobalProvider( providerInstance: EVMProvider, - globalObject = window + globalObject = window, + multiWalletProxy ): void { + // console.log('globalObject: ', globalObject); + // console.log('globalObject.ethereum: ', globalObject.ethereum); + // console.log('globalObject.phatnom: ', globalObject.phantom); try { - const multiWalletProxy = createMultiWalletProxy(providerInstance); + // const multiWalletProxy = createMultiWalletProxy(providerInstance); // if we already have a wallet lets add it - if (globalObject.ethereum) { - multiWalletProxy.addProvider(globalObject.ethereum); - } + // if (globalObject.ethereum) { + // console.log('addProvider globalObject.ethereum: ', globalObject.ethereum); + // multiWalletProxy.addProvider(globalObject.ethereum); + // } Object.defineProperty(globalObject, 'ethereum', { get: () => { return multiWalletProxy; }, // in case a wallet tries to overwrite us lets add them to the list - set: (value) => { - multiWalletProxy.addProvider(value); + set: () => { + return multiWalletProxy; }, }); diff --git a/src/background/providers/models.ts b/src/background/providers/models.ts index f338116ac..f16f8a4b6 100644 --- a/src/background/providers/models.ts +++ b/src/background/providers/models.ts @@ -24,6 +24,11 @@ export interface EIP6963ProviderDetail { provider: Eip1193Provider; } +export interface EIP6963AnnounceProviderEvent extends CustomEvent { + type: 'eip6963:announceProvider'; + detail: EIP6963ProviderDetail; +} + export enum EventNames { CORE_WALLET_ANNOUNCE_PROVIDER = 'core-wallet:announceProvider', CORE_WALLET_REQUEST_PROVIDER = 'core-wallet:requestProvider', diff --git a/src/background/providers/utils/getWalletExtensionType.ts b/src/background/providers/utils/getWalletExtensionType.ts index ee7926598..f81b26dd2 100644 --- a/src/background/providers/utils/getWalletExtensionType.ts +++ b/src/background/providers/utils/getWalletExtensionType.ts @@ -2,9 +2,19 @@ import { WalletExtensionType } from '../../services/web3/models'; // using any since we don't really know what properties other wallets define export function getWalletExtensionType(provider: any): WalletExtensionType { + console.log('provider: ', provider); if (provider.isAvalanche) { return WalletExtensionType.CORE; } + if (provider.isPhantom) { + return WalletExtensionType.PHANTOM; + } + if (provider.isKeplr) { + return WalletExtensionType.KEPLR; + } + if (provider.isZerion) { + return WalletExtensionType.ZERION; + } if (provider.isRabby) { return WalletExtensionType.RABBY; } diff --git a/src/background/services/web3/handlers/avalanche_selectWallet.ts b/src/background/services/web3/handlers/avalanche_selectWallet.ts index 891fb8188..f8f422b78 100644 --- a/src/background/services/web3/handlers/avalanche_selectWallet.ts +++ b/src/background/services/web3/handlers/avalanche_selectWallet.ts @@ -13,6 +13,7 @@ export class AvalancheSelectWalletHandler extends DAppRequestHandler { handleUnauthenticated = async (rpcCall) => { const { request } = rpcCall; const [availableExtensions] = request.params; + console.log('availableExtensions: ', availableExtensions); if (!availableExtensions || availableExtensions.length === 0) { return { @@ -26,6 +27,7 @@ export class AvalancheSelectWalletHandler extends DAppRequestHandler { ...request, displayData: { options: availableExtensions.map((o) => o.type), + info: availableExtensions.map((extension) => extension.info), }, }, `approve/select-wallet` diff --git a/src/background/services/web3/models.ts b/src/background/services/web3/models.ts index 97a308c65..e0425f5e2 100644 --- a/src/background/services/web3/models.ts +++ b/src/background/services/web3/models.ts @@ -4,4 +4,7 @@ export enum WalletExtensionType { UNKNOWN = 'UNKNOWN', RABBY = 'RABBY', COINBASE = 'COINBASE', + PHANTOM = 'PHANTOM', + ZERION = 'ZERION', + KEPLR = 'KEPLR', } diff --git a/src/pages/ApproveAction/SelectWallet.tsx b/src/pages/ApproveAction/SelectWallet.tsx index 7555b755d..f074661dd 100644 --- a/src/pages/ApproveAction/SelectWallet.tsx +++ b/src/pages/ApproveAction/SelectWallet.tsx @@ -4,13 +4,17 @@ import { useApproveAction } from '@src/hooks/useApproveAction'; import { useGetRequestId } from '@src/hooks/useGetRequestId'; import { useCallback } from 'react'; import { LoadingOverlay } from '../../components/common/LoadingOverlay'; -import { WalletExtensionButton } from '../Wallet/components/WalletExtensionButton'; +import { + NewButton, + WalletExtensionButton, +} from '../Wallet/components/WalletExtensionButton'; import { Trans } from 'react-i18next'; import { Stack, Typography, WalletIcon } from '@avalabs/core-k2-components'; export function SelectWallet() { const requestId = useGetRequestId(); const { action: request, updateAction } = useApproveAction(requestId); + console.log('request: ', request); const selectWallet = useCallback( async (index: number | string) => @@ -46,15 +50,30 @@ export function SelectWallet() { - {request.displayData.options.map((option, i) => ( - { + if (info.rdns === 'app.core.extension') { + return ( + { + selectWallet(i); + }} + info={info} + /> + ); + } + return; + })} + {request.displayData.info.length > 1 && ( + { - selectWallet(i); + // selectWallet(i); + console.log('selectWAlelt'); }} - type={option} + // info={info} + wallets={request.displayData.info} /> - ))} + )} ); diff --git a/src/pages/Wallet/components/WalletExtensionButton.tsx b/src/pages/Wallet/components/WalletExtensionButton.tsx index 475f08b22..2a68fba3f 100644 --- a/src/pages/Wallet/components/WalletExtensionButton.tsx +++ b/src/pages/Wallet/components/WalletExtensionButton.tsx @@ -1,74 +1,164 @@ import { useTranslation } from 'react-i18next'; import { Button, + ButtonGroup, + ChevronDownIcon, + ClickAwayListener, CoinbaseWalletIcon, CoreIcon, + Grow, + KeyIcon, + MenuItem, + MenuList, MetaMaskIcon, + Popper, + Stack, + styled, + Typography, WalletIcon, } from '@avalabs/core-k2-components'; import { WalletExtensionType } from '@src/background/services/web3/models'; +import { EIP6963ProviderInfo } from '@avalabs/vm-module-types'; +import { useRef, useState } from 'react'; interface WalletExtensionButtonProps { - type: WalletExtensionType; + type?: WalletExtensionType; + info?: EIP6963ProviderInfo; onClick: () => void; + wallets?: EIP6963ProviderInfo[]; } +const StyledMenuItem = styled(MenuItem)` + color: ${({ theme }) => theme.palette.text.secondary}; + &:hover { + color: ${({ theme }) => theme.palette.text.primary}; + } +`; + +const StyledButtonGroup = styled(ButtonGroup)` + border-radius: 999px; +`; + export function WalletExtensionButton({ - type, + info, onClick, }: WalletExtensionButtonProps) { + console.log('info: ', info); const { t } = useTranslation(); - const getWalletDisplayName = (walletType: WalletExtensionType) => { - switch (walletType) { - case WalletExtensionType.METAMASK: - return 'Metamask'; - case WalletExtensionType.COINBASE: - return 'Coinbase'; - case WalletExtensionType.UNKNOWN: - default: - return t('Unknown wallet'); - } - }; - - const getWalletLogo = (walletType: WalletExtensionType) => { - switch (walletType) { - case WalletExtensionType.METAMASK: - return ; - case WalletExtensionType.COINBASE: - return ; - case WalletExtensionType.UNKNOWN: - default: - return ; - } - }; - - if (type === WalletExtensionType.CORE) { - return ( - - ); - } - return ( ); } + +export function NewButton({ + info, + onClick, + wallets, +}: WalletExtensionButtonProps) { + console.log('wallets: ', wallets); + const { t } = useTranslation(); + const toggleButtonRef = useRef(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + return ( + + setIsMenuOpen(false)}> + + + + + + + + ); +}