From 06a3f2530783837ec1ac21e1732cd2952ebbd146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Thu, 2 Oct 2025 14:28:32 -0300 Subject: [PATCH 1/4] fix: communicate with iframe to close it on success --- src/app/(mobile-ui)/layout.tsx | 8 ++++++++ src/components/Kyc/InitiateMantecaKYCModal.tsx | 9 +++++++++ 2 files changed, 17 insertions(+) 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/components/Kyc/InitiateMantecaKYCModal.tsx b/src/components/Kyc/InitiateMantecaKYCModal.tsx index f589edc05..2b1e6269e 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,14 @@ const InitiateMantecaKYCModal = ({ country, }) + useEffect(() => { + window.addEventListener('message', (event) => { + if (event.data.source === 'peanut-kyc-success') { + onKycSuccess?.() + } + }) + }, []) + return ( <> Date: Thu, 2 Oct 2025 14:37:27 -0300 Subject: [PATCH 2/4] chore: add more info to network fees --- .../AddMoney/components/MantecaDepositShareDetails.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/AddMoney/components/MantecaDepositShareDetails.tsx b/src/components/AddMoney/components/MantecaDepositShareDetails.tsx index 0a7313fea..203ed6372 100644 --- a/src/components/AddMoney/components/MantecaDepositShareDetails.tsx +++ b/src/components/AddMoney/components/MantecaDepositShareDetails.tsx @@ -130,7 +130,11 @@ const MantecaDepositShareDetails = ({ )} - +
From 8924ca1bb9d2b887f12d6a565559d1526c8630b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Thu, 2 Oct 2025 14:54:34 -0300 Subject: [PATCH 3/4] fix: remove element listener from manteca kyc modal --- src/components/Kyc/InitiateMantecaKYCModal.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/Kyc/InitiateMantecaKYCModal.tsx b/src/components/Kyc/InitiateMantecaKYCModal.tsx index 2b1e6269e..486383168 100644 --- a/src/components/Kyc/InitiateMantecaKYCModal.tsx +++ b/src/components/Kyc/InitiateMantecaKYCModal.tsx @@ -40,11 +40,17 @@ const InitiateMantecaKYCModal = ({ }) useEffect(() => { - window.addEventListener('message', (event) => { + const handleMessage = (event: MessageEvent) => { if (event.data.source === 'peanut-kyc-success') { onKycSuccess?.() } - }) + } + + window.addEventListener('message', handleMessage) + + return () => { + window.removeEventListener('message', handleMessage) + } }, []) return ( From d050a30139ed7e29ccd09268cae611b2c3156821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Ram=C3=ADrez?= Date: Thu, 2 Oct 2025 15:10:34 -0300 Subject: [PATCH 4/4] fix: sendlink error reporting --- src/app/actions/claimLinks.ts | 13 ++-- .../components/MantecaDepositShareDetails.tsx | 2 +- src/services/sendLinks.ts | 63 +++---------------- src/services/services.types.ts | 55 ++++++++++++++++ 4 files changed, 73 insertions(+), 60 deletions(-) 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 203ed6372..794b2a118 100644 --- a/src/components/AddMoney/components/MantecaDepositShareDetails.tsx +++ b/src/components/AddMoney/components/MantecaDepositShareDetails.tsx @@ -131,7 +131,7 @@ const MantecaDepositShareDetails = ({ )} diff --git a/src/services/sendLinks.ts b/src/services/sendLinks.ts index 97c4f9aed..5226cd26d 100644 --- a/src/services/sendLinks.ts +++ b/src/services/sendLinks.ts @@ -3,61 +3,10 @@ import { PEANUT_API_URL } from '@/constants' import { fetchWithSentry, jsonParse, jsonStringify } from '@/utils' import { generateKeysFromString, getParamsFromLink } from '@squirrel-labs/peanut-sdk' import Cookies from 'js-cookie' +import type { SendLink } from '@/services/services.types' -export enum ESendLinkStatus { - creating = 'creating', - completed = 'completed', - CLAIMING = 'CLAIMING', - CLAIMED = 'CLAIMED', - CANCELLED = 'CANCELLED', - FAILED = 'FAILED', -} - -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 - }[] -} +export { ESendLinkStatus } from '@/services/services.types' +export type { SendLinkStatus, SendLink } from '@/services/services.types' export type ClaimLinkData = SendLink & { link: string; password: string; tokenSymbol: string; tokenDecimals: number } @@ -203,7 +152,11 @@ export const sendLinksApi = { claim: async (recipient: string, link: string): Promise => { 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 + }[] +}