Skip to content

Commit

Permalink
[NO CHANGELOG][Add Funds Widget] Add validation for selected deliver …
Browse files Browse the repository at this point in the history
…to and pay with wallets (#2312)
  • Loading branch information
jhesgodi authored Oct 16, 2024
1 parent 5391749 commit 7067a43
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
type ConnectWalletDrawerProps = {
heading: string;
visible: boolean;
onClose: () => void;
onClose: (address?: string) => void;
onConnect?: (
provider: Web3Provider,
providerInfo: EIP6963ProviderInfo
Expand All @@ -45,6 +45,7 @@ type ConnectWalletDrawerProps = {
label: string;
rdns: string;
}[];
getShouldRequestWalletPermissions?: (providerInfo: EIP6963ProviderInfo) => boolean | undefined;
};

export function ConnectWalletDrawer({
Expand All @@ -58,6 +59,7 @@ export function ConnectWalletDrawer({
bottomSlot,
menuItemSize = 'small',
disabledOptions = [],
getShouldRequestWalletPermissions,
}: ConnectWalletDrawerProps) {
const {
providersState: { checkout },
Expand Down Expand Up @@ -110,6 +112,8 @@ export function ConnectWalletDrawer({
},
});
}

return address;
};

const handleOnWalletChangeEvent = async (event: WalletChangeEvent) => {
Expand Down Expand Up @@ -155,17 +159,21 @@ export function ConnectWalletDrawer({
}
}

let address: string | undefined;

// Proceed to connect selected provider
const shouldRequestWalletPermissions = getShouldRequestWalletPermissions?.(info);
try {
const { provider } = await connectEIP6963Provider(
providerDetail,
checkout,
shouldRequestWalletPermissions,
);
// Identify connected wallet
await identifyUser(identify, provider);

// Store selected provider as fromProvider in context
setProviderInContext(provider, providerDetail.info);
address = await setProviderInContext(provider, providerDetail.info);

// Notify successful connection
onConnect?.(provider, providerDetail.info);
Expand All @@ -188,7 +196,7 @@ export function ConnectWalletDrawer({
return;
}

onClose();
onClose(address);
};

const retrySelectedWallet = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import {
ViewActions,
ViewContext,
} from '../../context/view-context/ViewContext';
import { useProvidersContext } from '../../context/providers-context/ProvidersContext';

type DeliverToWalletDrawerProps = {
visible: boolean;
onClose: () => void;
onClose: (toAddress?: string) => void;
walletOptions: EIP6963ProviderDetail[];
onConnect: (
onConnect?: (
providerType: 'from' | 'to',
provider: Web3Provider,
providerInfo: EIP6963ProviderInfo
Expand All @@ -29,10 +30,17 @@ export function DeliverToWalletDrawer({
onConnect,
walletOptions,
}: DeliverToWalletDrawerProps) {
const {
providersState: { fromProviderInfo },
} = useProvidersContext();

const { viewDispatch } = useContext(ViewContext);

const handleOnConnect = (provider: Web3Provider, providerInfo: EIP6963ProviderInfo) => {
onConnect('to', provider, providerInfo);
const handleOnConnect = (
provider: Web3Provider,
providerInfo: EIP6963ProviderInfo,
) => {
onConnect?.('to', provider, providerInfo);
};

const handleOnError = (errorType: ConnectEIP6963ProviderError) => {
Expand All @@ -50,6 +58,13 @@ export function DeliverToWalletDrawer({
}
};

// Becuase wallets extensions don't support multiple wallet connections
// UX decides to have the user use the same wallet type they selected to pay with
// ie: Metamask to Metamsk, will send to same wallet address
const selectedSameFromWalletType = (
providerInfo: EIP6963ProviderInfo,
): boolean | undefined => (fromProviderInfo?.rdns !== providerInfo.rdns ? undefined : false);

return (
<ConnectWalletDrawer
heading="Deliver To"
Expand All @@ -59,6 +74,9 @@ export function DeliverToWalletDrawer({
walletOptions={walletOptions}
onConnect={handleOnConnect}
onError={handleOnError}
getShouldRequestWalletPermissions={
selectedSameFromWalletType
}
/>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { SharedViews, ViewActions, ViewContext } from '../../context/view-contex

type PayWithWalletDrawerProps = {
visible: boolean;
onClose: () => void;
onClose: (fromAddress?: string) => void;
onConnect: (providerType: 'from' | 'to', provider: Web3Provider, providerInfo: EIP6963ProviderInfo) => void;
onPayWithCard: () => void;
onPayWithCard?: () => void;
walletOptions: EIP6963ProviderDetail[];
insufficientBalance?: boolean;
showOnRampOption?: boolean;
Expand Down Expand Up @@ -69,7 +69,7 @@ export function PayWithWalletDrawer({
emphasized
onClick={() => {
onClose();
onPayWithCard();
onPayWithCard?.();
}}
>
<MenuItem.FramedIcon
Expand Down
13 changes: 10 additions & 3 deletions packages/checkout/widgets-lib/src/lib/connectEIP6963Provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ export type ConnectEIP6963ProviderResult = {
export const connectEIP6963Provider = async (
providerDetail: EIP6963ProviderDetail,
checkout: Checkout,
shouldRequestWalletPermissions?: boolean,
): Promise<ConnectEIP6963ProviderResult> => {
const web3Provider = new Web3Provider(providerDetail.provider as any);

try {
const requestWalletPermissions = providerDetail.info.rdns === WalletProviderRdns.METAMASK;
const requestWalletPermissions = shouldRequestWalletPermissions
?? providerDetail.info.rdns === WalletProviderRdns.METAMASK;
const connectResult = await checkout.connect({
provider: web3Provider,
requestWalletPermissions,
Expand All @@ -40,7 +42,10 @@ export const connectEIP6963Provider = async (
);

if (isSanctioned) {
throw new CheckoutError('Sanctioned address', ConnectEIP6963ProviderError.SANCTIONED_ADDRESS);
throw new CheckoutError(
'Sanctioned address',
ConnectEIP6963ProviderError.SANCTIONED_ADDRESS,
);
}

addProviderListenersForWidgetRoot(connectResult.provider);
Expand All @@ -51,7 +56,9 @@ export const connectEIP6963Provider = async (
} catch (error: CheckoutErrorType | ConnectEIP6963ProviderError | any) {
switch (error.type) {
case CheckoutErrorType.USER_REJECTED_REQUEST_ERROR:
throw new Error(ConnectEIP6963ProviderError.USER_REJECTED_REQUEST_ERROR);
throw new Error(
ConnectEIP6963ProviderError.USER_REJECTED_REQUEST_ERROR,
);
case ConnectEIP6963ProviderError.SANCTIONED_ADDRESS:
throw new Error(ConnectEIP6963ProviderError.SANCTIONED_ADDRESS);
default:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
Body, Box, Button, Drawer, Heading,
} from '@biom3/react';
import { WalletWarningHero } from '../../../components/Hero/WalletWarningHero';

export interface AddressMissmatchDrawerProps {
visible: boolean;
onClick: () => void;
}

export function AddressMissmatchDrawer({
visible,
onClick,
}: AddressMissmatchDrawerProps) {
return (
<Drawer size="full" visible={visible} showHeaderBar={false}>
<Drawer.Content>
<WalletWarningHero />
<Box sx={{ px: 'base.spacing.x6' }}>
<Heading
sx={{
marginTop: 'base.spacing.x6',
marginBottom: 'base.spacing.x2',
textAlign: 'center',
}}
>
Oops! It seems your payment wallet has changed
</Heading>
<Body
size="medium"
sx={{
display: 'block',
textAlign: 'center',
color: 'base.color.text.body.secondary',
marginBottom: 'base.spacing.x21',
}}
>
You&apos;ll be ask to re-connect the same wallet you selected to pay with before proceeding.
</Body>
</Box>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
paddingX: 'base.spacing.x6',
width: '100%',
}}
>
<Button
sx={{ width: '100%', marginBottom: 'base.spacing.x10' }}
testId="non-passport-cta-button"
variant="primary"
size="large"
onClick={onClick}
>
Re-select payment wallet
</Button>
</Box>
</Drawer.Content>
</Drawer>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { ethers } from 'ethers';
import { Web3Provider } from '@ethersproject/providers';

export const convertToNetworkChangeableProvider = async (
provider: Web3Provider,
): Promise<Web3Provider> => new ethers.providers.Web3Provider(provider.provider, 'any');
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ export const useExecute = (environment: Environment) => {
showErrorHandover(errorType, { error });
};

const convertToNetworkChangeableProvider = async (
provider: Web3Provider,
): Promise<Web3Provider> => new ethers.providers.Web3Provider(provider.provider, 'any');

// @TODO: Move to util function
const checkProviderChain = async (
provider: Web3Provider,
chainId: string,
Expand Down Expand Up @@ -166,7 +163,6 @@ export const useExecute = (environment: Environment) => {
};

return {
convertToNetworkChangeableProvider,
checkProviderChain,
getAllowance,
approve,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,6 @@ export function AddFunds({
visible={showDeliverToDrawer}
walletOptions={walletOptions}
onClose={() => setShowDeliverToDrawer(false)}
onConnect={handleWalletConnected}
/>
<OnboardingDrawer environment={checkout?.config.environment!} />
</Stack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ import { Environment } from '@imtbl/config';
import { SimpleLayout } from '../../../components/SimpleLayout/SimpleLayout';
import { AddFundsContext } from '../context/AddFundsContext';
import { useRoutes } from '../hooks/useRoutes';
import { AddFundsReviewData } from '../../../context/view-context/AddFundsViewContextTypes';
import {
AddFundsReviewData,
AddFundsWidgetViews,
} from '../../../context/view-context/AddFundsViewContextTypes';
import { RiveStateMachineInput } from '../types';
import { useExecute } from '../hooks/useExecute';
import {
ViewActions,
ViewContext,
} from '../../../context/view-context/ViewContext';
import { SquidIcon } from '../components/SquidIcon';
Expand All @@ -53,12 +57,14 @@ import { useProvidersContext } from '../../../context/providers-context/Provider
import { LoadingView } from '../../../views/loading/LoadingView';
import { getDurationFormatted } from '../functions/getDurationFormatted';
import { RouteFees } from '../components/RouteFees';
import { AddressMissmatchDrawer } from '../components/AddressMissmatchDrawer';
import { getTotalRouteFees } from '../functions/getTotalRouteFees';
import { getRouteChains } from '../functions/getRouteChains';
import {
getFormattedAmounts,
getFormattedNumber,
} from '../functions/getFormattedNumber';
import { convertToNetworkChangeableProvider } from '../functions/convertToNetworkChangeableProvider';

interface ReviewProps {
data: AddFundsReviewData;
Expand Down Expand Up @@ -96,14 +102,13 @@ export function Review({
const [route, setRoute] = useState<RouteResponse | undefined>();
const [proceedDisabled, setProceedDisabled] = useState(true);
const [showFeeBreakdown, setShowFeeBreakdown] = useState(false);

const [showAddressMissmatchDrawer, setShowAddressMissmatchDrawer] = useState(false);
const { getAmountData, getRoute } = useRoutes();
const { addHandover, closeHandover } = useHandover({
id: HandoverTarget.GLOBAL,
});

const {
convertToNetworkChangeableProvider,
checkProviderChain,
getAllowance,
approve,
Expand Down Expand Up @@ -235,6 +240,13 @@ export function Review({
return;
}

const currentFromAddress = await fromProvider.getSigner().getAddress();

if (currentFromAddress !== fromAddress) {
setShowAddressMissmatchDrawer(true);
return;
}

clearInterval(getRouteIntervalIdRef.current);
setProceedDisabled(true);

Expand Down Expand Up @@ -342,7 +354,6 @@ export function Review({
approve,
showHandover,
checkProviderChain,
convertToNetworkChangeableProvider,
getAllowance,
execute,
closeHandover,
Expand Down Expand Up @@ -662,7 +673,7 @@ export function Review({
</>
)}

{!route && <LoadingView loadingText="Securing quote" />}
{!route && !showAddressMissmatchDrawer && <LoadingView loadingText="Securing quote" />}
</Stack>
<RouteFees
routeData={route}
Expand All @@ -671,6 +682,21 @@ export function Review({
totalAmount={totalFees}
totalFiatAmount={totalFeesUsd}
/>
<AddressMissmatchDrawer
visible={showAddressMissmatchDrawer}
onClick={() => {
setShowAddressMissmatchDrawer(false);

viewDispatch({
payload: {
type: ViewActions.UPDATE_VIEW,
view: {
type: AddFundsWidgetViews.ADD_FUNDS,
},
},
});
}}
/>
</SimpleLayout>
);
}

0 comments on commit 7067a43

Please sign in to comment.