Skip to content

Commit 836fabf

Browse files
feat: improve preferredSymbol options
1 parent f761532 commit 836fabf

File tree

17 files changed

+242
-443
lines changed

17 files changed

+242
-443
lines changed

examples/nextjs-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"@headlessui/react": "^2.2.0",
1515
"@rainbow-me/rainbowkit": "^2.2.8",
1616
"@rozoai/intent-common": "0.1.7-beta.2",
17-
"@rozoai/intent-pay": "0.1.7-beta.3",
17+
"@rozoai/intent-pay": "0.1.7-beta.6",
1818
"@tanstack/react-query": "^5.51.11",
1919
"@types/react-syntax-highlighter": "^15.5.13",
2020
"@wagmi/core": "^2.22.0",

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

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Config = {
3030
chainId: number; // Destination chain ID
3131
tokenAddress: string;
3232
amount: string;
33+
preferredSymbol: TokenSymbol[];
3334
};
3435

3536
/**
@@ -118,6 +119,9 @@ export default function YourComponent() {
118119
toToken={${tokenCode}}
119120
toAddress={${addressCode}}
120121
toUnits="${config.amount}"
122+
preferredSymbol={[${config.preferredSymbol
123+
.map((s: TokenSymbol) => `TokenSymbol.${s}`)
124+
.join(", ")}]}
121125
onPaymentStarted={(event) => {
122126
console.log("Payment started:", event);
123127
}}
@@ -179,11 +183,20 @@ export default function DemoBasic() {
179183
} as Config);
180184
const [parsedConfig, setParsedConfig] = useState<Config | null>(null);
181185
const { resetPayment } = useRozoPayUI();
186+
const [preferredSymbol, setPreferredSymbol] = useState<TokenSymbol[]>([
187+
TokenSymbol.USDC,
188+
TokenSymbol.USDT,
189+
]);
182190

183191
const handleSetConfig = useCallback(
184-
(newConfig: Config) => {
185-
setConfig(newConfig);
186-
setParsedConfig(newConfig);
192+
(newConfig: Config, symbols?: TokenSymbol[]) => {
193+
const symbolsToUse = symbols ?? preferredSymbol;
194+
const configWithSymbols = {
195+
...newConfig,
196+
preferredSymbol: symbolsToUse,
197+
};
198+
setConfig(configWithSymbols);
199+
setParsedConfig(configWithSymbols);
187200

188201
// NOTE: This is used to reset the payment state when the config changes
189202
const isEvm = isEvmChain(newConfig.chainId);
@@ -198,16 +211,16 @@ export default function DemoBasic() {
198211
} else {
199212
payParams.toAddress = newConfig.recipientAddress;
200213
payParams.toToken = newConfig.tokenAddress;
201-
// if (isStellarChain(newConfig.chainId)) {
202-
// payParams.toStellarAddress = newConfig.recipientAddress;
203-
// } else if (isSolanaChain(newConfig.chainId)) {
204-
// payParams.toSolanaAddress = newConfig.recipientAddress;
205-
// }
206214
}
207215

208-
resetPayment(payParams);
216+
const params = {
217+
...payParams,
218+
preferredSymbol: symbolsToUse,
219+
};
220+
console.log("params", params);
221+
resetPayment(params);
209222
},
210-
[setConfig, resetPayment]
223+
[setConfig, resetPayment, preferredSymbol]
211224
);
212225

213226
useEffect(() => {
@@ -234,6 +247,10 @@ export default function DemoBasic() {
234247
chainId: getConfig.chainId || 0,
235248
tokenAddress: getConfig.tokenAddress || "",
236249
amount: getConfig.amount || "",
250+
preferredSymbol: getConfig.preferredSymbol || [
251+
TokenSymbol.USDC,
252+
TokenSymbol.USDT,
253+
],
237254
};
238255

239256
// Validate and clean up config
@@ -246,6 +263,9 @@ export default function DemoBasic() {
246263
) {
247264
setConfig(parsedConfig);
248265
setParsedConfig(parsedConfig);
266+
if (parsedConfig.preferredSymbol) {
267+
setPreferredSymbol(parsedConfig.preferredSymbol);
268+
}
249269
}
250270
}
251271
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -272,6 +292,17 @@ export default function DemoBasic() {
272292
[]
273293
);
274294

295+
// Toggle between [USDC, USDT] and [EURC]
296+
const handleChangeCurrency = useCallback(() => {
297+
const nextSymbols =
298+
preferredSymbol.length === 1 && preferredSymbol[0] === TokenSymbol.EURC
299+
? [TokenSymbol.USDC, TokenSymbol.USDT]
300+
: [TokenSymbol.EURC];
301+
302+
setPreferredSymbol(nextSymbols);
303+
handleSetConfig(config, nextSymbols);
304+
}, [config, preferredSymbol, handleSetConfig]);
305+
275306
return (
276307
<Container className="max-w-4xl mx-auto p-6">
277308
{/* Header Section */}
@@ -286,6 +317,8 @@ export default function DemoBasic() {
286317
</Text>
287318
</div>
288319

320+
<button onClick={handleChangeCurrency}>Change currency</button>
321+
289322
{/* Main Content */}
290323
<div className="flex flex-col items-center gap-6">
291324
{/* Payment Button Section */}
@@ -312,8 +345,8 @@ export default function DemoBasic() {
312345
console.log("✓ Payout completed:", e);
313346
}}
314347
feeType={FeeType.ExactOut}
348+
preferredSymbol={preferredSymbol}
315349
metadata={metadata}
316-
preferredSymbol={[TokenSymbol.EURC]}
317350
resetOnSuccess
318351
showProcessingPayout
319352
>
@@ -485,7 +518,7 @@ export default function DemoBasic() {
485518
configType="payment"
486519
isOpen={isConfigOpen}
487520
onClose={() => setIsConfigOpen(false)}
488-
onConfirm={handleSetConfig}
521+
onConfirm={(config) => handleSetConfig(config as Config)}
489522
defaultRecipientAddress={config.recipientAddress}
490523
/>
491524
</div>

examples/nextjs-app/src/app/shared.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { RozoPayEvent, getChainExplorerByChainId } from "@rozoai/intent-common";
2-
import { useEffect, useState } from "react";
2+
import { useCallback, useEffect, useState } from "react";
33
import { isAddress } from "viem";
44

55
export const APP_ID = "rozoDemo"; // Your public app ID. Use pay-demo for prototyping only.
@@ -55,14 +55,17 @@ export function usePersistedConfig<T>(
5555
}
5656
}, [key]);
5757

58-
const setConfig = (newConfig: T) => {
59-
setConfigState(newConfig);
60-
try {
61-
localStorage.setItem(key, JSON.stringify(newConfig));
62-
} catch {
63-
// Handle localStorage errors silently
64-
}
65-
};
58+
const setConfig = useCallback(
59+
(newConfig: T) => {
60+
setConfigState(newConfig);
61+
try {
62+
localStorage.setItem(key, JSON.stringify(newConfig));
63+
} catch {
64+
// Handle localStorage errors silently
65+
}
66+
},
67+
[key]
68+
);
6669

6770
return [config, setConfig];
6871
}

packages/connectkit/bundle-analysis.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

packages/connectkit/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@rozoai/intent-pay",
33
"private": false,
4-
"version": "0.1.7-beta.3",
4+
"version": "0.1.7-beta.6",
55
"author": "RozoAI",
66
"homepage": "https://github.com/RozoAI/intent-pay",
77
"license": "BSD-2-Clause",

packages/connectkit/src/components/Common/ConnectorList/index.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const ConnectorList = ({
6565
if (paymentState === "error") {
6666
context.setRoute(ROUTES.ERROR);
6767
}
68+
// eslint-disable-next-line react-hooks/exhaustive-deps
6869
}, [paymentState]);
6970

7071
return (
@@ -144,11 +145,9 @@ const ConnectorItem = ({
144145
return;
145146
}
146147
} else {
147-
// EVM-only wallet: clear selectedChainId to show all available tokens
148-
context.paymentState.setSelectedChainId(undefined);
148+
// EVM-only wallet: navigate to connect page
149149
context.setPendingConnectorId(wallet.id);
150-
// Explicitly set chainId to null to indicate we want all chains, not just the current one
151-
context.setRoute(ROUTES.CONNECT, { ...meta, chainId: null });
150+
context.setRoute(ROUTES.CONNECT, meta);
152151
return;
153152
}
154153
}

packages/connectkit/src/components/Common/OrderHeader/index.tsx

Lines changed: 11 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { useAccount } from "wagmi";
66
import {
77
Base,
88
BinanceSmartChain,
9-
chainToLogo,
109
Ethereum,
1110
Polygon,
1211
Solana,
@@ -18,7 +17,6 @@ import { useRozoPay } from "../../../hooks/useDaimoPay";
1817
import { usePayContext } from "../../../hooks/usePayContext";
1918
import { useStellar } from "../../../provider/StellarContextProvider";
2019
import styled from "../../../styles/styled";
21-
import { EVM_CHAIN_IDS, NON_EVM_CHAIN_IDS } from "../../../types/chainAddress";
2220
import { formatUsd } from "../../../utils/format";
2321

2422
/** Shows payment amount. */
@@ -56,31 +54,6 @@ export const OrderHeader = ({
5654
);
5755
const orderUsd = order?.destFinalCallTokenAmount.usd;
5856
const appId = paymentState.payParams?.appId;
59-
const selectedChainId = paymentState.selectedChainId;
60-
61-
// Get chain logo component based on chainId
62-
const getChainLogo = (
63-
chainId: number | undefined
64-
): React.ReactNode | null => {
65-
if (!chainId) return null;
66-
67-
switch (chainId) {
68-
case EVM_CHAIN_IDS.BASE:
69-
return <Base />;
70-
case EVM_CHAIN_IDS.ETHEREUM:
71-
return <Ethereum />;
72-
case EVM_CHAIN_IDS.POLYGON:
73-
return <Polygon />;
74-
case 56: // BSC
75-
return <BinanceSmartChain />;
76-
case NON_EVM_CHAIN_IDS.SOLANA:
77-
return <Solana />;
78-
case NON_EVM_CHAIN_IDS.STELLAR:
79-
return <Stellar />;
80-
default:
81-
return null;
82-
}
83-
};
8457

8558
const titleAmountContent = (() => {
8659
if (paymentState.isDepositFlow) {
@@ -106,27 +79,18 @@ export const OrderHeader = ({
10679
return null;
10780
}
10881

109-
const chainLogo = selectedChainId ? chainToLogo[selectedChainId] : null;
110-
11182
return (
112-
<WalletIconWrapper>
113-
<LogoContainer
114-
$size={size}
115-
$zIndex={1}
116-
style={{ borderRadius: "22.5%" }}
117-
>
118-
{typeof icon === "string" ? (
119-
<img
120-
src={icon}
121-
alt={name || "wallet"}
122-
style={{ maxWidth: "100%", maxHeight: "100%" }}
123-
/>
124-
) : (
125-
icon
126-
)}
127-
</LogoContainer>
128-
{chainLogo && <ChainLogoBadge>{chainLogo}</ChainLogoBadge>}
129-
</WalletIconWrapper>
83+
<LogoContainer $size={size} $zIndex={1} style={{ borderRadius: "22.5%" }}>
84+
{typeof icon === "string" ? (
85+
<img
86+
src={icon}
87+
alt={name || "wallet"}
88+
style={{ maxWidth: "100%", maxHeight: "100%" }}
89+
/>
90+
) : (
91+
icon
92+
)}
93+
</LogoContainer>
13094
);
13195
};
13296

@@ -345,30 +309,3 @@ const SubtitleContainer = styled.div`
345309
justify-content: flex-end;
346310
gap: 8px;
347311
`;
348-
349-
const WalletIconWrapper = styled.div`
350-
position: relative;
351-
display: inline-block;
352-
`;
353-
354-
const ChainLogoBadge = styled(motion.div)`
355-
position: absolute;
356-
bottom: -5px;
357-
right: 0px;
358-
display: flex;
359-
align-items: center;
360-
justify-content: center;
361-
width: 15px;
362-
height: 15px;
363-
overflow: hidden;
364-
z-index: 10;
365-
svg,
366-
img {
367-
display: block;
368-
position: relative;
369-
pointer-events: none;
370-
overflow: hidden;
371-
width: 100%;
372-
height: 100%;
373-
}
374-
`;

0 commit comments

Comments
 (0)