Skip to content

Commit ef50189

Browse files
feat: improve eurc warning on demo
1 parent 58f95fc commit ef50189

File tree

1 file changed

+132
-1
lines changed
  • examples/nextjs-app/src/app/basic

1 file changed

+132
-1
lines changed

examples/nextjs-app/src/app/basic/page.tsx

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
import * as Tokens from "@rozoai/intent-common";
44
import {
5+
baseEURC,
56
FeeType,
67
getChainName,
78
getChainNativeToken,
9+
getKnownToken,
810
knownTokens,
911
rozoSolana,
1012
rozoStellar,
13+
rozoStellarEURC,
1114
TokenSymbol,
1215
} from "@rozoai/intent-common";
1316
import {
@@ -187,10 +190,32 @@ export default function DemoBasic() {
187190
TokenSymbol.USDC,
188191
TokenSymbol.USDT,
189192
]);
193+
const [eurcValidationError, setEurcValidationError] = useState<string>("");
190194

191195
const handleSetConfig = useCallback(
192196
(newConfig: Config, symbols?: TokenSymbol[]) => {
193197
const symbolsToUse = symbols ?? preferredSymbol;
198+
199+
// Validate EURC: EURC can only be sent to EURC
200+
const hasEURC = symbolsToUse.includes(TokenSymbol.EURC);
201+
if (hasEURC && newConfig.tokenAddress) {
202+
const destinationToken = getKnownToken(
203+
newConfig.chainId,
204+
newConfig.tokenAddress
205+
);
206+
const isDestinationEURC = destinationToken?.symbol === TokenSymbol.EURC;
207+
208+
if (!isDestinationEURC) {
209+
setEurcValidationError(
210+
`EURC can only be sent to another EURC. Please select an EURC token as the destination token.`
211+
);
212+
return; // Don't update config if validation fails
213+
}
214+
}
215+
216+
// Clear error if validation passes
217+
setEurcValidationError("");
218+
194219
const configWithSymbols = {
195220
...newConfig,
196221
preferredSymbol: symbolsToUse,
@@ -261,6 +286,27 @@ export default function DemoBasic() {
261286
"chainId" in parsedConfig &&
262287
"tokenAddress" in parsedConfig
263288
) {
289+
// Validate EURC: EURC can only be sent to EURC
290+
const hasEURC = parsedConfig.preferredSymbol?.includes(
291+
TokenSymbol.EURC
292+
);
293+
if (hasEURC && parsedConfig.tokenAddress && parsedConfig.chainId) {
294+
const destinationToken = getKnownToken(
295+
parsedConfig.chainId,
296+
parsedConfig.tokenAddress
297+
);
298+
const isDestinationEURC =
299+
destinationToken?.symbol === TokenSymbol.EURC;
300+
301+
if (!isDestinationEURC) {
302+
// Reset preferredSymbol to default if EURC validation fails
303+
parsedConfig.preferredSymbol = [TokenSymbol.USDC, TokenSymbol.USDT];
304+
setEurcValidationError(
305+
`EURC can only be sent to another EURC. Configuration has been reset to default.`
306+
);
307+
}
308+
}
309+
264310
setConfig(parsedConfig);
265311
setParsedConfig(parsedConfig);
266312
if (parsedConfig.preferredSymbol) {
@@ -279,6 +325,41 @@ export default function DemoBasic() {
279325
parsedConfig.tokenAddress &&
280326
parsedConfig.amount;
281327

328+
// Check if destination token is Base EURC or Stellar EURC
329+
const isDestinationEURC = useMemo(() => {
330+
if (!parsedConfig || !parsedConfig.tokenAddress || !parsedConfig.chainId) {
331+
return false;
332+
}
333+
334+
const destinationToken = getKnownToken(
335+
parsedConfig.chainId,
336+
parsedConfig.tokenAddress
337+
);
338+
339+
if (!destinationToken) return false;
340+
341+
// Check if it's Base EURC
342+
if (
343+
parsedConfig.chainId === baseEURC.chainId &&
344+
isEvmChain(parsedConfig.chainId)
345+
) {
346+
try {
347+
return (
348+
getAddress(destinationToken.token) === getAddress(baseEURC.token)
349+
);
350+
} catch {
351+
return destinationToken.token === baseEURC.token;
352+
}
353+
}
354+
355+
// Check if it's Stellar EURC
356+
if (parsedConfig.chainId === rozoStellarEURC.chainId) {
357+
return destinationToken.token === rozoStellarEURC.token;
358+
}
359+
360+
return false;
361+
}, [parsedConfig]);
362+
282363
// Generate code snippet when config changes
283364
const codeSnippet = useMemo(() => {
284365
if (!hasValidConfig || !parsedConfig) return "";
@@ -299,6 +380,30 @@ export default function DemoBasic() {
299380
? [TokenSymbol.USDC, TokenSymbol.USDT]
300381
: [TokenSymbol.EURC];
301382

383+
// If switching to EURC, find and set an EURC token for the current chain
384+
if (nextSymbols.includes(TokenSymbol.EURC) && config.chainId) {
385+
const eurcToken = knownTokens.find(
386+
(t: any) =>
387+
t.chainId === config.chainId && t.symbol === TokenSymbol.EURC
388+
);
389+
390+
if (eurcToken) {
391+
const updatedConfig: Config = {
392+
...config,
393+
tokenAddress: eurcToken.token,
394+
preferredSymbol: nextSymbols,
395+
};
396+
setPreferredSymbol(nextSymbols);
397+
handleSetConfig(updatedConfig, nextSymbols);
398+
return;
399+
} else {
400+
setEurcValidationError(
401+
`EURC is not available on the selected chain. Please select a chain that supports EURC (Base, Ethereum, or Stellar).`
402+
);
403+
return;
404+
}
405+
}
406+
302407
setPreferredSymbol(nextSymbols);
303408
handleSetConfig(config, nextSymbols);
304409
}, [config, preferredSymbol, handleSetConfig]);
@@ -317,7 +422,19 @@ export default function DemoBasic() {
317422
</Text>
318423
</div>
319424

320-
<button onClick={handleChangeCurrency}>Change currency</button>
425+
<div className="mb-4 flex items-center gap-4">
426+
<button
427+
onClick={handleChangeCurrency}
428+
className="px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded-lg transition-colors font-medium mx-auto"
429+
>
430+
Change currency
431+
</button>
432+
{eurcValidationError && (
433+
<div className="flex-1 bg-red-50 border border-red-200 rounded-lg p-3">
434+
<p className="text-sm text-red-800">{eurcValidationError}</p>
435+
</div>
436+
)}
437+
</div>
321438

322439
{/* Main Content */}
323440
<div className="flex flex-col items-center gap-6">
@@ -328,6 +445,14 @@ export default function DemoBasic() {
328445
<h2 className="text-xl font-semibold text-gray-800 mb-4">
329446
Try the Payment
330447
</h2>
448+
{isDestinationEURC && (
449+
<div className="mb-4 bg-yellow-50 border border-yellow-200 rounded-lg p-3">
450+
<p className="text-sm text-yellow-800">
451+
<strong>⚠️ EURC Restriction:</strong> EURC can only be sent
452+
to another EURC token. The destination token must be EURC.
453+
</p>
454+
</div>
455+
)}
331456
<div className="flex flex-col gap-3">
332457
<RozoPayButton.Custom
333458
appId={APP_ID}
@@ -512,6 +637,12 @@ export default function DemoBasic() {
512637
</code>
513638
. Automatically finds matching tokens across all supported
514639
chains.
640+
<br />
641+
<strong className="text-red-600">
642+
⚠️ Important: EURC can only be sent to another EURC token.
643+
If EURC is in preferredSymbol, the destination token must
644+
also be EURC.
645+
</strong>
515646
</dd>
516647
</div>
517648
<div>

0 commit comments

Comments
 (0)