diff --git a/src/app/(mobile-ui)/layout.tsx b/src/app/(mobile-ui)/layout.tsx index 0728a7e91..d8019c399 100644 --- a/src/app/(mobile-ui)/layout.tsx +++ b/src/app/(mobile-ui)/layout.tsx @@ -19,6 +19,7 @@ import { twMerge } from 'tailwind-merge' import '../../styles/globals.css' import SupportDrawer from '@/components/Global/SupportDrawer' import { useSupportModalContext } from '@/context/SupportModalContext' +import { useRouter } from 'next/navigation' // Allow access to some public paths without authentication const publicPathRegex = /^\/(request\/pay|claim|pay\/.+$|support)/ @@ -34,6 +35,7 @@ const Layout = ({ children }: { children: React.ReactNode }) => { const isHistory = pathName === '/history' const isSupport = pathName === '/support' const alignStart = isHome || isHistory || isSupport + const router = useRouter() useEffect(() => { // check for JWT token @@ -77,6 +79,12 @@ const Layout = ({ children }: { children: React.ReactNode }) => { // Allow access to public paths without authentication const isPublicPath = publicPathRegex.test(pathName) + useEffect(() => { + if (!isPublicPath && !isFetchingUser && !user) { + router.push('/setup') + } + }, [user, isFetchingUser]) + if (!isReady || (isFetchingUser && !user && !hasToken && !isPublicPath)) { return (
diff --git a/src/app/actions/claimLinks.ts b/src/app/actions/claimLinks.ts index 06ace8b47..71e48536c 100644 --- a/src/app/actions/claimLinks.ts +++ b/src/app/actions/claimLinks.ts @@ -8,6 +8,7 @@ import { getPublicClient, type ChainId } from '@/app/actions/clients' import { fetchTokenDetails } from '@/app/actions/tokens' import { getLinkFromReceipt, fetchWithSentry, jsonParse } from '@/utils' import { PEANUT_API_URL, PEANUT_WALLET_CHAIN } from '@/constants' +import type { SendLink } from '@/services/services.types' export const getLinkDetails = unstable_cache( async (link: string): Promise => { @@ -82,7 +83,11 @@ export async function getNextDepositIndex(contractVersion: string): Promise { const response = await fetchWithSentry(`${PEANUT_API_URL}/send-links/${pubKey}/claim`, { method: 'POST', headers: { @@ -97,9 +102,9 @@ export async function claimSendLink(pubKey: string, recipient: string, password: if (!response.ok) { const body = await response.json() if (!!body.error || !!body.message) { - throw new Error(body.message ?? body.error) + return { error: body.message ?? body.error } } - throw new Error(`HTTP error! status: ${response.status}`) + return { error: `HTTP error! status: ${response.status}` } } - return jsonParse(await response.text()) + return jsonParse(await response.text()) as SendLink } diff --git a/src/components/AddMoney/components/MantecaDepositShareDetails.tsx b/src/components/AddMoney/components/MantecaDepositShareDetails.tsx index 0a7313fea..794b2a118 100644 --- a/src/components/AddMoney/components/MantecaDepositShareDetails.tsx +++ b/src/components/AddMoney/components/MantecaDepositShareDetails.tsx @@ -130,7 +130,11 @@ const MantecaDepositShareDetails = ({ )} - +
diff --git a/src/components/Kyc/InitiateMantecaKYCModal.tsx b/src/components/Kyc/InitiateMantecaKYCModal.tsx index f589edc05..486383168 100644 --- a/src/components/Kyc/InitiateMantecaKYCModal.tsx +++ b/src/components/Kyc/InitiateMantecaKYCModal.tsx @@ -7,6 +7,7 @@ import { useMantecaKycFlow } from '@/hooks/useMantecaKycFlow' import { CountryData } from '@/components/AddMoney/consts' import { Button } from '../0_Bruddle' import { PeanutDoesntStoreAnyPersonalInformation } from './KycVerificationInProgressModal' +import { useEffect } from 'react' interface Props { isOpen: boolean @@ -38,6 +39,20 @@ const InitiateMantecaKYCModal = ({ country, }) + useEffect(() => { + const handleMessage = (event: MessageEvent) => { + if (event.data.source === 'peanut-kyc-success') { + onKycSuccess?.() + } + } + + window.addEventListener('message', handleMessage) + + return () => { + window.removeEventListener('message', handleMessage) + } + }, []) + return ( <> => { const params = getParamsFromLink(link) const pubKey = generateKeysFromString(params.password).address - return await claimSendLink(pubKey, recipient, params.password) + const response = await claimSendLink(pubKey, recipient, params.password) + if ('error' in response) { + throw new Error(response.error) + } + return response }, /** diff --git a/src/services/services.types.ts b/src/services/services.types.ts index 85e81c969..258ac401b 100644 --- a/src/services/services.types.ts +++ b/src/services/services.types.ts @@ -334,3 +334,58 @@ export interface CreateQrPaymentResponse { qrPayment: QrPaymentResponse charge: TRequestChargeResponse } + +export enum ESendLinkStatus { + creating = 'creating', + completed = 'completed', + CLAIMING = 'CLAIMING', + CLAIMED = 'CLAIMED', + CANCELLED = 'CANCELLED', + FAILED = 'FAILED', +} + +export type SendLinkStatus = `${ESendLinkStatus}` + +export type SendLink = { + pubKey: string + depositIdx: number + chainId: string + contractVersion: string + textContent?: string + fileUrl?: string + status: SendLinkStatus + createdAt: Date + senderAddress: string + amount: bigint + tokenAddress: string + sender: { + userId: string + username: string + fullName: string + bridgeKycStatus: string + accounts: { + identifier: string + type: string + }[] + } + claim?: { + amount: string + txHash: string + tokenAddress: string + recipientAddress?: string + recipient?: { + userId: string + username: string + fullName: string + bridgeKycStatus: string + accounts: { + identifier: string + type: string + }[] + } + } + events: { + timestamp: Date + status: SendLinkStatus + }[] +}