From 6c9a08efa4e16c17d0cd2be975df4df4fb65410a Mon Sep 17 00:00:00 2001 From: Daria Mikhailova Date: Tue, 5 Mar 2024 19:06:44 +1300 Subject: [PATCH] adjusted types --- .example.env | 2 +- scripts/client.build.ts | 3 + .../components/auth/PolkadotProvider.tsx | 163 ++++++++++-------- src/client/components/auth/config.ts | 16 +- src/client/components/auth/helper.tsx | 22 ++- src/client/config.ts | 3 + .../auth/providers/polkadot/manifest.json | 2 +- 7 files changed, 131 insertions(+), 80 deletions(-) diff --git a/.example.env b/.example.env index bfb0f6d6..c552f9ca 100644 --- a/.example.env +++ b/.example.env @@ -14,7 +14,7 @@ OAUTH2_GOOGLE_CLIENT_SECRET="" # Polkadot AUTH_MESSAGE_TO_SIGN="027bbda234f3e86273683eab96a4a2a1d3a0" - +WALLET_CONNECT_PROJECT_ID="projectIdOnWalletConnectCloud" # INTEGRATIONS diff --git a/scripts/client.build.ts b/scripts/client.build.ts index 5f9d266f..3eeadf23 100644 --- a/scripts/client.build.ts +++ b/scripts/client.build.ts @@ -65,6 +65,9 @@ function getBuildConfig(): BuildOptions { 'process.env.AUTH_MESSAGE_TO_SIGN': JSON.stringify( config.authMessageToSign ), + 'process.env.WALLET_CONNECT_PROJECT_ID': JSON.stringify( + config.walletConnectProjectId + ), 'process.env.ROLE_GROUPS': JSON.stringify( appConfig.config.permissions.roleGroups.map((x) => ({ ...x, diff --git a/src/client/components/auth/PolkadotProvider.tsx b/src/client/components/auth/PolkadotProvider.tsx index ef5364f5..bc53d57a 100644 --- a/src/client/components/auth/PolkadotProvider.tsx +++ b/src/client/components/auth/PolkadotProvider.tsx @@ -12,9 +12,17 @@ import { import config from '#client/config' import { CopyToClipboard } from '#client/components/ui' import { api } from '#client/utils/api' -import { WalletAggregator, WalletType } from '@polkadot-onboard/core' +import { + WalletAggregator, + WalletType, + BaseWallet, + Account, +} from '@polkadot-onboard/core' import { InjectedWalletProvider } from '@polkadot-onboard/injected-wallets' -import { WalletConnectProvider } from '@polkadot-onboard/wallet-connect/packages/wallet-connect/src' +import { + WalletConnectProvider, + WalletConnectConfiguration, +} from '@polkadot-onboard/wallet-connect/packages/wallet-connect/src' const DAPP_NAME = config.appName @@ -27,9 +35,11 @@ import { WhiteWindow, providerUrls, WalletTab, + ExtendedMetadata, + ExtensionAccount, } from './helper' import { sign, verify } from '#client/utils/polkadot' -import { extensionConfig, walletConnectConfig } from './config' +import { extensionConfig, themeConfig, walletConnectConfig } from './config' import { cn } from '#client/utils' type ModalProps = { @@ -78,21 +88,21 @@ const LoaderWithText = ({ text = 'Connecting' }: { text?: string }) => ( export const PolkadotProvider: React.FC = () => { const [wallets, setWallets] = useState([]) const [chosenWallet, setChosenWallet] = useState() - const [accounts, setAccounts] = useState< - Array<{ address: string; name: string; source: string }> - >([]) + const [accounts, setAccounts] = useState>([]) const [selectedAddress, setSelectedAddress] = useState('') const [isValidSignature, setIsValidSignature] = useState(false) const [userSignature, setUserSignature] = useState(null) - const [error, setError] = useState() - const [loading, setLoading] = useState(false) const [step, setStep] = useState(AuthSteps.Connecting) + const [userDetails, setUserDetails] = useState({ fullName: '', email: '' }) - const [walletConnect, setWalletConnect] = useState(null) + const [showModal, setShowModal] = useState(false) const [showTryAgain, setShowTryAgain] = useState(false) - const [loaderText, setLoaderText] = useState('Connecting') const [modalShown, setModalShown] = useState(false) + const [loading, setLoading] = useState(false) + + const [loaderText, setLoaderText] = useState('Connecting') + const [error, setError] = useState() const isWalletConnect = (w) => w.type === WalletType.WALLET_CONNECT const selectedAccount = useMemo( @@ -142,29 +152,38 @@ export const PolkadotProvider: React.FC = () => { ) - const onConnected = { - [WalletType.WALLET_CONNECT]: async (walletInfo) => { + type AddressAccount = { address: string } + + const onConnected: Record< + WalletType.WALLET_CONNECT | WalletType.INJECTED, + (walletInfo: BaseWallet) => void + > = { + [WalletType.WALLET_CONNECT]: async (walletInfo: BaseWallet) => { try { setLoading(true) setChosenWallet(walletInfo) let accounts = await walletInfo.getAccounts() - accounts = Array.from( + // sometimes there are duplicate accounts returned + // issue in polkadot-onboard @fix-me + const uniqueAccounts: string[] = Array.from( new Set( accounts - .filter((a) => a.address.startsWith('1')) - .map((a) => a.address) + .filter((a: AddressAccount) => a.address.startsWith('1')) + .map((a: AddressAccount) => a.address) ) ) - accounts = accounts.map((addr) => { - return { - name: '...' + addr.slice(addr.length - 12, addr.length), - address: addr, - source: walletInfo.session.peer.metadata.name, - wallet: walletInfo, - } - }) - setAccounts(accounts) + setAccounts( + uniqueAccounts.map((addr: string) => { + return { + name: '...' + addr.slice(addr.length - 12, addr.length), + address: addr, + // @ts-ignore // @fixme - define a type in wallet-connect.ts package in polkadot-onboard + source: walletInfo.session.peer.metadata.name, + wallet: walletInfo, + } + }) + ) setStep(AuthSteps.ChooseAccount) setLoading(false) } catch (e) { @@ -172,23 +191,27 @@ export const PolkadotProvider: React.FC = () => { console.log(e) } }, - [WalletType.INJECTED]: async (walletInfo) => { + [WalletType.INJECTED]: async (walletInfo: BaseWallet) => { try { setLoading(true) setChosenWallet(walletInfo) - let accounts = await walletInfo.getAccounts() + let accounts: Account[] = await walletInfo.getAccounts() if (!accounts.length) { setLoading(false) - setError(ErrorComponent[Errors.NoAccountsError](walletInfo.metadata)) + setError( + ErrorComponent[Errors.NoAccountsError]( + walletInfo.metadata as ExtendedMetadata + ) + ) setStep(AuthSteps.Error) return } - accounts = accounts.map((account) => ({ + accounts = accounts.map((account: Account) => ({ ...account, source: walletInfo.metadata.id, wallet: walletInfo, })) - setAccounts(accounts) + setAccounts(accounts as ExtensionAccount[]) setStep(AuthSteps.ChooseAccount) setLoading(false) } catch (e) { @@ -206,44 +229,39 @@ export const PolkadotProvider: React.FC = () => { if (step === AuthSteps.Connecting) { let walletAggregator = new WalletAggregator([ new InjectedWalletProvider(extensionConfig, DAPP_NAME), - new WalletConnectProvider(walletConnectConfig, DAPP_NAME), + new WalletConnectProvider( + walletConnectConfig as WalletConnectConfiguration, + DAPP_NAME + ), ]) + // the timeout here is to wait for polkadot-js to load after initializing setTimeout(async () => { - walletAggregator - .getWallets() - .then((wallets) => { - setWallets(wallets) - let confWallets = wallets.map((wallet) => { - if (isWalletConnect(wallet)) { - if (!walletConnect) { - setWalletConnect(wallet) - } - wallet.walletConnectModal.setTheme({ - themeMode: 'dark', - themeVariables: { - '--wcm-font-family': 'Unbounded, sans-serif', - '--wcm-accent-color': '#E6007A', - }, - }) - } - return wallet - }) - setWallets(confWallets) - setStep(AuthSteps.ChooseWallet) - setLoading(false) - }) - .catch((e) => { - console.error(e) - switch (e.message) { - case Errors.NoAccountsError: - setError(ErrorComponent[Errors.NoAccountsError]) - break - default: - console.error(e) - setError(GENERIC_ERROR) - break + try { + const wallets = await walletAggregator.getWallets() + let confWallets = wallets.map((wallet) => { + if (isWalletConnect(wallet)) { + // @ts-ignore @fixme export WalletConnectWallet from polkadot-onboard + wallet.walletConnectModal.setTheme(themeConfig) } + return wallet }) + setWallets(confWallets) + setStep(AuthSteps.ChooseWallet) + setLoading(false) + } catch (e: any) { + console.error(e) + switch (e?.message) { + case Errors.NoAccountsError: + setError( + ErrorComponent[Errors.NoAccountsError](chosenWallet.metadata) + ) + break + default: + console.error(e) + setError(GENERIC_ERROR) + break + } + } }, 1000) } }, [step]) @@ -273,9 +291,6 @@ export const PolkadotProvider: React.FC = () => { setStep(AuthSteps.Warning) return } - - console.log(selectedAccount) - console.log(account) try { await api.post(`${polkadotUrl('login')}`, { selectedAccount: account, @@ -408,7 +423,7 @@ export const PolkadotProvider: React.FC = () => { } >
- {wallets.map((ext) => { + {wallets.map((ext: BaseWallet) => { return ( { onClickConnect={() => { setShowModal(true) setModalShown(true) - onConnected[ext.type](ext) + onConnected[ + ext.type as + | WalletType.INJECTED + | WalletType.WALLET_CONNECT + ](ext) }} /> ) @@ -482,15 +501,15 @@ export const PolkadotProvider: React.FC = () => { {isWalletConnect(chosenWallet) && ( { if (!modalShown) { setShowModal(true) } - onConnected[WalletType.WALLET_CONNECT](walletConnect) + onConnected[WalletType.WALLET_CONNECT](chosenWallet) }} disconnect={true} /> diff --git a/src/client/components/auth/config.ts b/src/client/components/auth/config.ts index 77cae217..27ef9192 100644 --- a/src/client/components/auth/config.ts +++ b/src/client/components/auth/config.ts @@ -1,3 +1,13 @@ +import config from '#client/config' + +export const themeConfig = { + themeMode: 'dark', + themeVariables: { + '--wcm-font-family': 'Unbounded, sans-serif', + '--wcm-accent-color': '#E6007A', + }, +} + export const extensionConfig = { disallowed: [], supported: [ @@ -39,14 +49,18 @@ export const extensionConfig = { export const walletConnectConfig = { // @todo add to vars - projectId: 'a7af023707d162a2fbe91a2a66ad9e2e', + projectId: config.walletConnectProjectId, relayUrl: 'wss://relay.walletconnect.com', chainIds: [ + // polkadot 'polkadot:e143f23803ac50e8f6f8e62695d1ce9e', + // polkadot 'polkadot:91b171bb158e2d3848fa23a9f1c25182', ], optionalChainIds: [ + // westend 'polkadot:67f9723393ef76214df0118c34bbbd3d', + // rococo 'polkadot:7c34d42fc815d392057c78b49f2755c7', ], metadata: { diff --git a/src/client/components/auth/helper.tsx b/src/client/components/auth/helper.tsx index 98833718..15391da6 100644 --- a/src/client/components/auth/helper.tsx +++ b/src/client/components/auth/helper.tsx @@ -2,6 +2,7 @@ import config from '#client/config' import { cn } from '#client/utils' import { useEffect, useState } from 'react' import { Background, H1, Icons, Link, P } from '../ui' +import { BaseWallet } from '@polkadot-onboard/core' export const LoginIcons: Record = { google: , @@ -19,12 +20,23 @@ export const Errors = { } // @todo export metadata from the library +export type ExtendedMetadata = { + id: string + title: string + urls?: { main?: string; browsers?: Record } & { + reference: string + } +} + +export type ExtensionAccount = { + address: string + name: string + source: string + wallet: BaseWallet +} + export const ErrorComponent = { - [Errors.NoAccountsError]: (metadata: { - id: string - title: string - urls: { main: string; reference: string } - }) => ( + [Errors.NoAccountsError]: (metadata: ExtendedMetadata) => (

No accounts found.

diff --git a/src/client/config.ts b/src/client/config.ts index 3b3f3abe..aff773fc 100644 --- a/src/client/config.ts +++ b/src/client/config.ts @@ -49,6 +49,7 @@ type ClientAppConfig = { roleGroups: ClientUserRoleGroup[] auth: ClientAuthConfig authMessageToSign: string + walletConnectProjectId: string } type ClientAuthConfig = { providers: string[] } @@ -64,6 +65,8 @@ const config: ClientAppConfig = { roleGroups: process.env.ROLE_GROUPS as unknown as ClientUserRoleGroup[], auth: process.env.AUTH as unknown as ClientAuthConfig, authMessageToSign: process.env.AUTH_MESSAGE_TO_SIGN as unknown as string, + walletConnectProjectId: process.env + .WALLET_CONNECT_PROJECT_ID as unknown as string, } export default config diff --git a/src/server/auth/providers/polkadot/manifest.json b/src/server/auth/providers/polkadot/manifest.json index 2b878799..fe776a87 100644 --- a/src/server/auth/providers/polkadot/manifest.json +++ b/src/server/auth/providers/polkadot/manifest.json @@ -1,4 +1,4 @@ { "id": "polkadot", - "requiredCredentials": [] + "requiredCredentials": ["ALLOWED_EXTENSIONS", "AUTH_MESSAGE_TO_SIGN"] }