diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..600c998
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(awk 'NR>=10 && NR<=46 {printf \"%d:%s$\\\\n\", NR, $0}' cloudbuild.yaml)",
+ "Bash(node *)"
+ ]
+ }
+}
diff --git a/Dockerfile b/Dockerfile
index 5a1d71c..be00195 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -34,16 +34,17 @@ ARG NEXT_PUBLIC_ALLOWED_ORIGINS
ARG NEXT_PUBLIC_EXPLORER_L1_URL
ARG NEXT_PUBLIC_EXPLORER_L2_URL
ARG NEXT_PUBLIC_EXPLORER_NFT_URL
+ARG NEXT_PUBLIC_LAYERSWAP_BASE_URL
ARG RECAPTCHA_API_KEY
ARG NEXT_PUBLIC_RECAPTCHA_SITE_KEY
ARG NEXT_PUBLIC_NFT_IMAGE_REPOSITORY
ARG NEXT_PUBLIC_NFT_MARKETPLACE_URL
ARG NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER
-ARG NEXT_PUBLIC_GA_MEASUREMENT_ID
-ARG NEXT_PUBLIC_MS_CLARITY_ID
-ARG NEXT_PUBLIC_NETWORK
-ARG NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT
-ARG NEXT_PUBLIC_SECURITY_PIN_LENGTH
+ARG NEXT_PUBLIC_GA_MEASUREMENT_ID
+ARG NEXT_PUBLIC_MS_CLARITY_ID
+ARG NEXT_PUBLIC_NETWORK
+ARG NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT
+ARG NEXT_PUBLIC_SECURITY_PIN_LENGTH
# environment variables
ENV NODE_ENV production
@@ -70,16 +71,17 @@ ENV NEXT_PUBLIC_ALLOWED_ORIGINS $NEXT_PUBLIC_ALLOWED_ORIGINS
ENV NEXT_PUBLIC_EXPLORER_L1_URL $NEXT_PUBLIC_EXPLORER_L1_URL
ENV NEXT_PUBLIC_EXPLORER_L2_URL $NEXT_PUBLIC_EXPLORER_L2_URL
ENV NEXT_PUBLIC_EXPLORER_NFT_URL $NEXT_PUBLIC_EXPLORER_NFT_URL
+ENV NEXT_PUBLIC_LAYERSWAP_BASE_URL $NEXT_PUBLIC_LAYERSWAP_BASE_URL
ENV RECAPTCHA_API_KEY $RECAPTCHA_API_KEY
ENV NEXT_PUBLIC_RECAPTCHA_SITE_KEY $NEXT_PUBLIC_RECAPTCHA_SITE_KEY
ENV NEXT_PUBLIC_NFT_IMAGE_REPOSITORY $NEXT_PUBLIC_NFT_IMAGE_REPOSITORY
ENV NEXT_PUBLIC_NFT_MARKETPLACE_URL $NEXT_PUBLIC_NFT_MARKETPLACE_URL
ENV NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER $NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER
-ENV NEXT_PUBLIC_GA_MEASUREMENT_ID $NEXT_PUBLIC_GA_MEASUREMENT_ID
-ENV NEXT_PUBLIC_MS_CLARITY_ID $NEXT_PUBLIC_MS_CLARITY_ID
-ENV NEXT_PUBLIC_NETWORK $NEXT_PUBLIC_NETWORK
-ENV NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT $NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT
-ENV NEXT_PUBLIC_SECURITY_PIN_LENGTH $NEXT_PUBLIC_SECURITY_PIN_LENGTH
+ENV NEXT_PUBLIC_GA_MEASUREMENT_ID $NEXT_PUBLIC_GA_MEASUREMENT_ID
+ENV NEXT_PUBLIC_MS_CLARITY_ID $NEXT_PUBLIC_MS_CLARITY_ID
+ENV NEXT_PUBLIC_NETWORK $NEXT_PUBLIC_NETWORK
+ENV NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT $NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT
+ENV NEXT_PUBLIC_SECURITY_PIN_LENGTH $NEXT_PUBLIC_SECURITY_PIN_LENGTH
# copy dependencies and source
COPY --from=deps /app/node_modules ./node_modules
diff --git a/cloudbuild.yaml b/cloudbuild.yaml
index b99aa2d..32b8c63 100644
--- a/cloudbuild.yaml
+++ b/cloudbuild.yaml
@@ -34,12 +34,13 @@ steps:
- NEXT_PUBLIC_EXPLORER_L1_URL=${_NEXT_PUBLIC_EXPLORER_L1_URL}
- NEXT_PUBLIC_EXPLORER_L2_URL=${_NEXT_PUBLIC_EXPLORER_L2_URL}
- NEXT_PUBLIC_EXPLORER_NFT_URL=${_NEXT_PUBLIC_EXPLORER_NFT_URL}
- - NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER=${_NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER}
- - NEXT_PUBLIC_GA_MEASUREMENT_ID=${_NEXT_PUBLIC_GA_MEASUREMENT_ID}
- - NEXT_PUBLIC_MS_CLARITY_ID=${_NEXT_PUBLIC_MS_CLARITY_ID}
- - NEXT_PUBLIC_NETWORK=${_NEXT_PUBLIC_NETWORK}
- - NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT=${_NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT}
- - NEXT_PUBLIC_SECURITY_PIN_LENGTH=${_NEXT_PUBLIC_SECURITY_PIN_LENGTH}
+ - NEXT_PUBLIC_LAYERSWAP_BASE_URL=${_NEXT_PUBLIC_LAYERSWAP_BASE_URL}
+ - NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER=${_NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER}
+ - NEXT_PUBLIC_GA_MEASUREMENT_ID=${_NEXT_PUBLIC_GA_MEASUREMENT_ID}
+ - NEXT_PUBLIC_MS_CLARITY_ID=${_NEXT_PUBLIC_MS_CLARITY_ID}
+ - NEXT_PUBLIC_NETWORK=${_NEXT_PUBLIC_NETWORK}
+ - NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT=${_NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT}
+ - NEXT_PUBLIC_SECURITY_PIN_LENGTH=${_NEXT_PUBLIC_SECURITY_PIN_LENGTH}
secretEnv: [
'BACKEND_API_TOKEN_SECRET'
]
@@ -82,13 +83,14 @@ steps:
'--build-arg', 'NEXT_PUBLIC_EXPLORER_L1_URL=${_NEXT_PUBLIC_EXPLORER_L1_URL}',
'--build-arg', 'NEXT_PUBLIC_EXPLORER_L2_URL=${_NEXT_PUBLIC_EXPLORER_L2_URL}',
'--build-arg', 'NEXT_PUBLIC_EXPLORER_NFT_URL=${_NEXT_PUBLIC_EXPLORER_NFT_URL}',
- '--build-arg', 'NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER=${_NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER}',
- '--build-arg', 'NEXT_PUBLIC_GA_MEASUREMENT_ID=${_NEXT_PUBLIC_GA_MEASUREMENT_ID}',
- '--build-arg', 'NEXT_PUBLIC_MS_CLARITY_ID=${_NEXT_PUBLIC_MS_CLARITY_ID}',
- '--build-arg', 'NEXT_PUBLIC_NETWORK=${_NEXT_PUBLIC_NETWORK}',
- '--build-arg', 'NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT=${_NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT}',
- '--build-arg', 'NEXT_PUBLIC_SECURITY_PIN_LENGTH=${_NEXT_PUBLIC_SECURITY_PIN_LENGTH}',
- '.'
+ '--build-arg', 'NEXT_PUBLIC_LAYERSWAP_BASE_URL=${_NEXT_PUBLIC_LAYERSWAP_BASE_URL}',
+ '--build-arg', 'NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER=${_NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER}',
+ '--build-arg', 'NEXT_PUBLIC_GA_MEASUREMENT_ID=${_NEXT_PUBLIC_GA_MEASUREMENT_ID}',
+ '--build-arg', 'NEXT_PUBLIC_MS_CLARITY_ID=${_NEXT_PUBLIC_MS_CLARITY_ID}',
+ '--build-arg', 'NEXT_PUBLIC_NETWORK=${_NEXT_PUBLIC_NETWORK}',
+ '--build-arg', 'NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT=${_NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT}',
+ '--build-arg', 'NEXT_PUBLIC_SECURITY_PIN_LENGTH=${_NEXT_PUBLIC_SECURITY_PIN_LENGTH}',
+ '.'
]
secretEnv: [
'BACKEND_API_TOKEN_SECRET'
diff --git a/example_env b/example_env
index ef6be6c..e68417d 100644
--- a/example_env
+++ b/example_env
@@ -33,11 +33,12 @@ NEXT_PUBLIC_NFT_MARKETPLACE_URL='https://testnets.opensea.io/assets/arbitrum_sep
NEXT_PUBLIC_EXPLORER_L1_URL='https://sepolia.etherscan.io'
NEXT_PUBLIC_EXPLORER_L2_URL='https://sepolia.arbiscan.io/'
NEXT_PUBLIC_EXPLORER_NFT_URL='https://sepolia.arbiscan.io'
-NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER={chatizalo phone number}
-NEXT_PUBLIC_NETWORK='scroll sepolia'
-NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT=3
-NEXT_PUBLIC_SECURITY_PIN_LENGTH=6
+NEXT_PUBLIC_LAYERSWAP_BASE_URL='https://testnet.layerswap.io/app'
+NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER={chatizalo phone number}
+NEXT_PUBLIC_NETWORK='scroll sepolia'
+NEXT_PUBLIC_SECURITY_RECOVERY_QUESTIONS_COUNT=3
+NEXT_PUBLIC_SECURITY_PIN_LENGTH=6
# analytics
NEXT_PUBLIC_GA_MEASUREMENT_ID={google analytics measurement id}
-NEXT_PUBLIC_MS_CLARITY_ID={microsoft clarity id}
+NEXT_PUBLIC_MS_CLARITY_ID={microsoft clarity id}
diff --git a/next.config.js b/next.config.js
index e93be99..10b8b2d 100644
--- a/next.config.js
+++ b/next.config.js
@@ -14,6 +14,7 @@ module.exports = {
}
},
output: 'standalone',
+
images: {
domains: [
'storage.googleapis.com',
@@ -88,6 +89,8 @@ module.exports = {
use: ['@svgr/webpack']
}
)
+ config.resolve.fallback = { ...config.resolve.fallback, fs: false, net: false, tls: false }
+ config.externals.push('pino-pretty', 'lokijs', 'encoding')
return config
},
// https://nextjs.org/docs/api-reference/next.config.js/headers
@@ -130,7 +133,7 @@ module.exports = {
img-src 'self' data: https:;
style-src 'self' 'unsafe-inline';
- frame-src 'self' https://www.google.com https://www.youtube.com;
+ frame-src 'self' https://www.google.com https://www.youtube.com https://layerswap.io https://*.layerswap.io;
frame-ancestors 'self';
`
.replace(/\s+/g, ' ')
diff --git a/package.json b/package.json
index 4e3089a..eb23470 100644
--- a/package.json
+++ b/package.json
@@ -81,7 +81,7 @@
"yup": "^1.3.2"
},
"devDependencies": {
- "@biomejs/biome": "^2.3.8",
+ "@biomejs/biome": "2.3.11",
"@commitlint/cli": "20.0.0",
"@commitlint/config-conventional": "20.0.0",
"@svgr/webpack": "^8.1.0",
diff --git a/scripts/docker-build.sh b/scripts/docker-build.sh
index 7b88fb7..1b77d9a 100644
--- a/scripts/docker-build.sh
+++ b/scripts/docker-build.sh
@@ -36,6 +36,7 @@ docker build \
--build-arg NEXT_PUBLIC_EXPLORER_L1_URL="$NEXT_PUBLIC_EXPLORER_L1_URL" \
--build-arg NEXT_PUBLIC_EXPLORER_L2_URL="$NEXT_PUBLIC_EXPLORER_L2_URL" \
--build-arg NEXT_PUBLIC_EXPLORER_NFT_URL="$NEXT_PUBLIC_EXPLORER_NFT_URL" \
+ --build-arg NEXT_PUBLIC_LAYERSWAP_BASE_URL="$NEXT_PUBLIC_LAYERSWAP_BASE_URL" \
--build-arg NEXT_PUBLIC_ALLOWED_ORIGINS="$NEXT_PUBLIC_ALLOWED_ORIGINS" \
--build-arg NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER="$NEXT_PUBLIC_CHATIZALO_PHONE_NUMBER" \
--build-arg NEXT_PUBLIC_GA_MEASUREMENT_ID="$NEXT_PUBLIC_GA_MEASUREMENT_ID" \
diff --git a/src/app/deposit/header.tsx b/src/app/deposit/header.tsx
new file mode 100644
index 0000000..4bf6261
--- /dev/null
+++ b/src/app/deposit/header.tsx
@@ -0,0 +1,40 @@
+'use client'
+
+import Box from '@mui/material/Box'
+import Stack from '@mui/material/Stack'
+import AppBar from '@mui/material/AppBar'
+import Toolbar from '@mui/material/Toolbar'
+
+import { LogoWithName } from 'src/components/logo'
+
+import { HEADER } from 'src/layouts/config-layout'
+import LanguagePopover from 'src/layouts/common/language-popover'
+import SettingsModeButton from 'src/layouts/common/settings-mode-button'
+
+// ----------------------------------------------------------------------
+
+export default function DepositHeader() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/deposit/layout.tsx b/src/app/deposit/layout.tsx
new file mode 100644
index 0000000..80e1cd7
--- /dev/null
+++ b/src/app/deposit/layout.tsx
@@ -0,0 +1,29 @@
+import type { ReactNode } from 'react'
+
+import Box from '@mui/material/Box'
+
+import BaseLayout from 'src/layouts/baseLayout'
+
+import DepositHeader from './header'
+
+// ----------------------------------------------------------------------
+
+export default function DepositLayout({ children }: { children: ReactNode }) {
+ return (
+
+
+
+
+
+ {children}
+
+
+
+ )
+}
diff --git a/src/app/deposit/page.tsx b/src/app/deposit/page.tsx
new file mode 100644
index 0000000..7da9010
--- /dev/null
+++ b/src/app/deposit/page.tsx
@@ -0,0 +1,17 @@
+import { Suspense } from 'react'
+
+import { DepositView } from 'src/sections/deposit/view'
+
+// ----------------------------------------------------------------------
+
+export const metadata = {
+ title: 'ChatterPay: Deposit'
+}
+
+export default function DepositPage() {
+ return (
+
+
+
+ )
+}
diff --git a/src/config-global.ts b/src/config-global.ts
index 09eba2a..3ee0fca 100644
--- a/src/config-global.ts
+++ b/src/config-global.ts
@@ -86,6 +86,9 @@ export const NFT_SHARE = 'https://api.whatsapp.com/send/?text=MESSAGE'
export const STORAGE_KEY_TOKEN = `chatterpay_${APP_ENV}_jwtToken`
export const STORAGE_KEY_SETTINGS = `chatterpay_${APP_ENV}_settings`
export const CONTACT_EMAIL = 'contacto@chatterpay.com.ar'
+export const LAYERSWAP_BG = '#0c1526'
+export const LAYERSWAP_BASE_URL =
+ process.env.NEXT_PUBLIC_LAYERSWAP_BASE_URL || 'https://testnet.layerswap.io/app'
export const GET_BALANCES_FROM_BACKEND = true
export const NOTIFICATIONS_PAGE_SIZE: number = Number.isNaN(
parseInt(process.env.NEXT_PUBLIC_NOTIFICATIONS_PAGE_SIZE ?? '', 10)
diff --git a/src/layouts/common/notifications-modal.tsx b/src/layouts/common/notifications-modal.tsx
index 15467d9..2b6dec9 100644
--- a/src/layouts/common/notifications-modal.tsx
+++ b/src/layouts/common/notifications-modal.tsx
@@ -257,7 +257,7 @@ export default function NotificationsModal({ open, onClose }: Props) {
-
+
-
+
{renderMessage(notification.message)}
diff --git a/src/locales/langs/br.json b/src/locales/langs/br.json
index a480c92..39c0616 100644
--- a/src/locales/langs/br.json
+++ b/src/locales/langs/br.json
@@ -357,7 +357,9 @@
"network": "Rede",
"network-warning": "Qualquer ativo enviado em outra rede será perdido",
"wallet-address": "Endereço da carteira",
- "copy-address": "Copiar endereço"
+ "copy-address": "Copiar endereço",
+ "show-address": "Ver meu endereço na Scroll",
+ "back-to-deposit": "Voltar ao depósito"
},
"balances": {
"title": "Seu dinheiro",
@@ -661,5 +663,18 @@
"description": "Acesse o ChatterPay diretamente pelo Telegram. Consulte sua carteira e saldo sem sair do chat — rápido, seguro e privado."
}
}
+ },
+ "layerswapDeposit": {
+ "title": "Depositar no ChatterPay",
+ "description": "Transfira seus ativos para Scroll e deposite diretamente na sua carteira ChatterPay.",
+ "returnButton": "Voltar ao ChatterPay",
+ "whatsappReturnText": "Quero ver meu saldo",
+ "actionButton": "Depositar no ChatterPay",
+ "badge": "Powered by Layerswap",
+ "errors": {
+ "title": "Solicitação inválida",
+ "missingAddress": "Um endereço de carteira é necessário. Forneça seu endereço na URL (?address=0x...).",
+ "invalidAddress": "O endereço de carteira fornecido não é um endereço Ethereum válido."
+ }
}
}
diff --git a/src/locales/langs/en.json b/src/locales/langs/en.json
index 604facc..1583de1 100644
--- a/src/locales/langs/en.json
+++ b/src/locales/langs/en.json
@@ -368,7 +368,9 @@
"network": "Network",
"network-warning": "Any asset sent in other network will be lost",
"wallet-address": "Wallet Address",
- "copy-address": "Copy Address"
+ "copy-address": "Copy Address",
+ "show-address": "See my address on Scroll",
+ "back-to-deposit": "Back to deposit"
},
"balances": {
"title": "Your money",
@@ -670,5 +672,18 @@
"description": "Access ChatterPay directly from Telegram. Check your wallet and balance without leaving the chat — fast, secure, and private."
}
}
+ },
+ "layerswapDeposit": {
+ "title": "Deposit to ChatterPay",
+ "description": "Bridge your assets to Scroll and deposit directly into your ChatterPay wallet.",
+ "returnButton": "Return to ChatterPay",
+ "whatsappReturnText": "I want to see my balance",
+ "actionButton": "Deposit to ChatterPay",
+ "badge": "Powered by Layerswap",
+ "errors": {
+ "title": "Invalid Request",
+ "missingAddress": "A wallet address is required. Please provide your address in the URL (?address=0x...).",
+ "invalidAddress": "The wallet address provided is not a valid Ethereum address."
+ }
}
}
diff --git a/src/locales/langs/es.json b/src/locales/langs/es.json
index 9f400c6..d516f05 100644
--- a/src/locales/langs/es.json
+++ b/src/locales/langs/es.json
@@ -356,7 +356,9 @@
"network": "Red",
"network-warning": "Cualquier activo enviado en otra red se perderá",
"wallet-address": "Dirección de billetera",
- "copy-address": "Copiar dirección"
+ "copy-address": "Copiar dirección",
+ "show-address": "Ver mi dirección en Scroll",
+ "back-to-deposit": "Volver a depositar"
},
"balances": {
"title": "Tu dinero",
@@ -660,5 +662,18 @@
"description": "Accedé a ChatterPay directamente desde Telegram. Consultá tu billetera y saldo sin salir del chat: rápido, seguro y privado."
}
}
+ },
+ "layerswapDeposit": {
+ "title": "Depositar en ChatterPay",
+ "description": "Transfiere tus activos a Scroll y deposita directamente en tu billetera ChatterPay.",
+ "returnButton": "Volver a ChatterPay",
+ "whatsappReturnText": "Quiero ver mi balance",
+ "actionButton": "Depositar en ChatterPay",
+ "badge": "Impulsado por Layerswap",
+ "errors": {
+ "title": "Solicitud inválida",
+ "missingAddress": "Se requiere una dirección de billetera. Proporciónala en la URL (?address=0x...).",
+ "invalidAddress": "La dirección de billetera proporcionada no es una dirección Ethereum válida."
+ }
}
}
diff --git a/src/routes/paths.ts b/src/routes/paths.ts
index 1126b71..e40fa3f 100644
--- a/src/routes/paths.ts
+++ b/src/routes/paths.ts
@@ -12,6 +12,7 @@ export const paths = {
terms: '/terms',
policy: '/policy',
aboutUs: '/about-us',
+ deposit: '/deposit',
products: {
root: '/products',
diff --git a/src/sections/banking/banking-balances.tsx b/src/sections/banking/banking-balances.tsx
index fc1df20..5da7e32 100644
--- a/src/sections/banking/banking-balances.tsx
+++ b/src/sections/banking/banking-balances.tsx
@@ -1,4 +1,4 @@
-import { useState, useEffect } from 'react'
+import { useState } from 'react'
import { enqueueSnackbar } from 'notistack'
import QRCode from 'react-qr-code'
@@ -18,9 +18,6 @@ import {
DialogContent,
type SelectChangeEvent
} from '@mui/material'
-import { alpha, useTheme } from '@mui/material/styles'
-
-import { useRouter } from 'src/routes/hooks'
import { useBoolean } from 'src/hooks/use-boolean'
import { useResponsive } from 'src/hooks/use-responsive'
@@ -32,6 +29,8 @@ import { BOT_WAPP_URL, EXPLORER_L2_URL } from 'src/config-global'
import Iconify from 'src/components/iconify'
+import LayerswapWidget from 'src/sections/deposit/view/layerswap-widget'
+
import type { IBalances, CurrencyKey } from 'src/types/wallet'
// ----------------------------------------------------------------------
@@ -59,11 +58,15 @@ export default function BankingBalances({
const walletLinkL2 = `${EXPLORER_L2_URL}/address/${tableData?.wallet || ''}`
const { t } = useTranslate()
- const theme = useTheme()
const mdUp = useResponsive('up', 'md')
const depositModal = useBoolean()
- const router = useRouter()
+ const [showAddress, setShowAddress] = useState(false)
+
+ const handleCloseDeposit = () => {
+ depositModal.onFalse()
+ setShowAddress(false)
+ }
const sendReciveUrl = BOT_WAPP_URL.replaceAll('MESSAGE', t('balances.wapp-msg'))
@@ -181,82 +184,120 @@ export default function BankingBalances({
)
+ // Deposit modal — uses theme palette so it respects dark/light mode
+
const renderDepositModal = (
-