Skip to content

Commit b105c8c

Browse files
committed
fix: asset selection
1 parent 760a1d7 commit b105c8c

16 files changed

+202
-206
lines changed

src/components/accountButton.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export default function AccountButton({ setSwitchWallet }: { setSwitchWallet: (x
6464
setActiveSenderWallet(undefined);
6565
setActiveSenderAccount(undefined);
6666
disconnect();
67-
}, [setSender, setActiveSenderWallet, setActiveSenderAccount]);
67+
}, [setSender, setActiveSenderWallet, setActiveSenderAccount, disconnect]);
6868

6969
useEffect(() => {
7070
if (needSwitchNetwork) {
@@ -78,7 +78,15 @@ export default function AccountButton({ setSwitchWallet }: { setSwitchWallet: (x
7878
setSwitchWallet(true);
7979
});
8080
}
81-
}, [sourceChain, chain, switchNetworkAsync]);
81+
}, [
82+
sourceChain,
83+
chain,
84+
switchNetworkAsync,
85+
handleDisconnect,
86+
setSwitchWallet,
87+
activeSenderWallet,
88+
needSwitchNetwork,
89+
]);
8290

8391
useEffect(() => {
8492
window.addEventListener("click", () => {

src/components/appBox.tsx

+61-90
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
11
"use client";
22

3-
import { ChangeEventHandler, useCallback, useEffect, useMemo, useRef, useState } from "react";
4-
import data from "../data/data.json";
3+
import { ChangeEventHandler, useCallback, useMemo, useRef, useState } from "react";
54
import Image from "next/image";
6-
import ChainSelectInput, { chainType } from "./chainSelectInput";
5+
import ChainSelectInput from "./chainSelectInput";
76
import SuccessModal from "./successModal";
87
import PendingModal from "./pendingModal";
9-
import { formatBalance, getAssetIconSrc, isExceedingCrossChainLimit, isValidAddress, parseCross } from "@/utils";
8+
import {
9+
formatBalance,
10+
getAssetIconSrc,
11+
getAvailableSourceAsset,
12+
getAvailableSourceChain,
13+
getAvailableSourceChainOptions,
14+
getAvailableTargetAsset,
15+
getAvailableTargetChain,
16+
getAvailableTargetChainOptions,
17+
isExceedingCrossChainLimit,
18+
isValidAddress,
19+
} from "@/utils";
1020
import { useTransfer } from "@/hooks";
1121
import { BN, BN_ZERO, bnToBn } from "@polkadot/util";
1222
import { formatUnits, parseUnits } from "viem";
1323
import { WalletID } from "@/types";
1424
import { useAccount, useNetwork, useSwitchNetwork } from "wagmi";
1525
import notification from "@/ui/notification";
16-
import { supportedTokenList } from "@/config/tokens";
1726
import { useTrail, animated, useSpring } from "@react-spring/web";
1827
import WalletSelectionModal from "./walletSelectionModal";
28+
import { assetCategories } from "@/config/asset-categories";
1929

2030
export default function AppBox() {
2131
const [connectModal, setConnectModal] = useState(false);
22-
23-
const { defaultSourceChainOptions, defaultSourceAssetOptions } = parseCross();
24-
const [selectedAsset, setSelectedAsset] = useState(supportedTokenList[0]);
25-
const [allowedChain, setAllowedChain] = useState<any>([]);
26-
// const [sourceAssetOptions, setSourceAssetOptions] = useState(defaultSourceAssetOptions);
2732
const [successModal, setSuccessModal] = useState<boolean>(false);
2833
const [receipt, setReceipt] = useState<boolean | null>(false);
2934

@@ -58,7 +63,10 @@ export default function AppBox() {
5863
activeSenderAccount,
5964
feeBalanceOnSourceChain,
6065
sourceNativeBalance,
66+
assetCategory,
67+
setAssetCategory,
6168
} = useTransfer();
69+
6270
const handleCloseSuccessModal = useCallback(() => {
6371
setSuccessModal(false);
6472
setReceipt(null);
@@ -69,7 +77,15 @@ export default function AppBox() {
6977
updateSourceNativeBalance();
7078
updateTargetNativeBalance();
7179
updateFeeBalanceOnSourceChain();
72-
}, []);
80+
}, [
81+
setTransferAmount,
82+
updateFeeBalanceOnSourceChain,
83+
updateSourceAssetBalance,
84+
updateSourceNativeBalance,
85+
updateTargetAssetBalance,
86+
updateTargetAssetSupply,
87+
updateTargetNativeBalance,
88+
]);
7389

7490
const sourceChainRef = useRef(sourceChain);
7591
const targetChainRef = useRef(targetChain);
@@ -158,8 +174,6 @@ export default function AppBox() {
158174
return null;
159175
}, [bridgeInstance, feeBalanceOnSourceChain]);
160176

161-
// console.log("fee alert", feeAlert);
162-
163177
const existentialAlertOnSourceChain = useMemo(() => {
164178
if (
165179
sourceChain.existential &&
@@ -219,26 +233,12 @@ export default function AppBox() {
219233
!!existentialAlertOnSourceChain ||
220234
!!existentialAlertOnTargetChain;
221235

222-
// console.log(
223-
// "check this now",
224-
// sender?.address,
225-
// sender?.valid,
226-
// recipient?.address,
227-
// recipient?.valid,
228-
// transferAmount.input,
229-
// transferAmount.valid,
230-
// feeAlert,
231-
// existentialAlertOnSourceChain,
232-
// existentialAlertOnTargetChain,
233-
// );
234-
235236
const handleSend = useCallback(async () => {
236237
if (needSwitchNetwork) {
237238
switchNetwork?.(sourceChain.id);
238239
} else if (bridgeInstance && recipient) {
239240
const callback = {
240241
successCb: (receipt: any) => {
241-
console.log("receipt", receipt);
242242
setReceipt(receipt);
243243
setBusy(false);
244244
setSuccessModal(true);
@@ -266,69 +266,14 @@ export default function AppBox() {
266266
needSwitchNetwork,
267267
recipient,
268268
sender?.address,
269-
setTransferAmount,
270269
sourceChain.id,
271270
switchNetwork,
272271
transfer,
273272
transferAmount.amount,
274273
transferAmount.input,
275-
updateFeeBalanceOnSourceChain,
276-
updateSourceAssetBalance,
277-
updateTargetAssetBalance,
278274
updateTargetAssetSupply,
279-
updateSourceNativeBalance,
280-
updateTargetNativeBalance,
281275
]);
282276

283-
useEffect(() => {
284-
console.log("defaultSourceAssetOptions", sourceChain.assets);
285-
let sourceChainOptions: any = [];
286-
for (const item of selectedAsset.allowedSource) {
287-
for (const chain of defaultSourceChainOptions) {
288-
if (chain.name === item) {
289-
sourceChainOptions.push(chain);
290-
}
291-
}
292-
}
293-
let selectedSourceAsset;
294-
for (const item of sourceChainOptions[0].assets) {
295-
if (selectedAsset.icon === item.icon) {
296-
selectedSourceAsset = item;
297-
}
298-
}
299-
setAllowedChain([...sourceChainOptions]);
300-
setSourceChain(sourceChainOptions[0]);
301-
setSourceAsset(selectedSourceAsset);
302-
setTargetChain(sourceChainOptions[1]);
303-
}, [selectedAsset]);
304-
305-
useEffect(() => {
306-
console.log(allowedChain);
307-
if (allowedChain.length > 0) {
308-
if (sourceChain.name === allowedChain[0].name && targetChain.name === allowedChain[0].name) {
309-
setTargetChain(allowedChain[1]);
310-
} else if (sourceChain.name === allowedChain[1].name && targetChain.name === allowedChain[1].name) {
311-
setTargetChain(allowedChain[0]);
312-
}
313-
}
314-
for (const asset of sourceChain.assets) {
315-
if (selectedAsset.name === asset.name) setSourceAsset(asset);
316-
}
317-
}, [sourceChain]);
318-
319-
useEffect(() => {
320-
if (allowedChain.length > 0) {
321-
if (targetChain.name === allowedChain[0].name && sourceChain.name == allowedChain[0].name) {
322-
setSourceChain(allowedChain[1]);
323-
} else if (targetChain.name === allowedChain[1].name && sourceChain.name === allowedChain[1].name) {
324-
setSourceChain(allowedChain[0]);
325-
}
326-
}
327-
for (const asset of targetChain.assets) {
328-
if (selectedAsset.name === asset.name) setTargetAsset(asset);
329-
}
330-
}, [targetChain]);
331-
332277
const trails = useTrail(5, {
333278
from: { transform: "translateX(-100%)", opacity: 0 },
334279
to: { opacity: 1, transform: "translateX(0)" },
@@ -339,8 +284,6 @@ export default function AppBox() {
339284
to: { opacity: 1, transform: "translateY(0)" },
340285
});
341286

342-
// console.log("check this.................", sender, needSwitchNetwork, disabledSend);
343-
344287
return (
345288
<>
346289
<animated.section
@@ -355,16 +298,24 @@ export default function AppBox() {
355298
<p className="text-[12px] leading-[15.22px] text-[#12161980]">Token</p>
356299
</div>
357300
<div className="flex items-center gap-[10px]">
358-
{supportedTokenList.map((item: any) => (
301+
{assetCategories.map((item) => (
359302
<div
360303
className="flex items-center gap-[10px] duration-500"
361304
key={item.name}
362305
style={{
363-
maxWidth: selectedAsset.name === item.name ? "100px" : "30px",
364-
transitionDelay: selectedAsset.name === item.name ? "0.4s" : "0s",
306+
maxWidth: assetCategory === item.category ? "100px" : "30px",
307+
transitionDelay: assetCategory === item.category ? "0.4s" : "0s",
365308
}}
366309
onClick={() => {
367-
setSelectedAsset(item);
310+
setAssetCategory(item.category);
311+
const _sourceChain = getAvailableSourceChain(getAvailableSourceChainOptions(item.category));
312+
const _sourceAsset = getAvailableSourceAsset(_sourceChain, item.category);
313+
const _targetChain = getAvailableTargetChain(getAvailableTargetChainOptions(_sourceAsset));
314+
const _targetAsset = getAvailableTargetAsset(_targetChain, item.category);
315+
setSourceChain(_sourceChain);
316+
setSourceAsset(_sourceAsset);
317+
setTargetChain(_targetChain);
318+
setTargetAsset(_targetAsset);
368319
}}
369320
>
370321
<Image
@@ -385,7 +336,19 @@ export default function AppBox() {
385336
>
386337
<div className="flex h-[30px] items-center justify-between">
387338
<p className="text-[12px] leading-[15.22px] text-[#12161980]">Sender</p>
388-
<ChainSelectInput options={allowedChain} who="sender" />
339+
<ChainSelectInput
340+
value={sourceChain}
341+
options={getAvailableSourceChainOptions(assetCategory)}
342+
onSelect={(chain) => {
343+
setSourceChain(chain);
344+
const _sourceAsset = getAvailableSourceAsset(chain, assetCategory);
345+
const _targetChain = getAvailableTargetChain(getAvailableTargetChainOptions(_sourceAsset));
346+
const _targetAsset = getAvailableTargetAsset(_targetChain, assetCategory);
347+
setSourceAsset(_sourceAsset);
348+
setTargetChain(_targetChain);
349+
setTargetAsset(_targetAsset);
350+
}}
351+
/>
389352
</div>
390353
{sender ? (
391354
<input
@@ -413,7 +376,15 @@ export default function AppBox() {
413376
>
414377
<div className="flex h-[30px] items-center justify-between">
415378
<p className="text-[12px] leading-[15.22px] text-[#12161980]">Recipient</p>
416-
<ChainSelectInput options={allowedChain} who="target" />
379+
<ChainSelectInput
380+
value={targetChain}
381+
options={getAvailableTargetChainOptions(sourceAsset)}
382+
onSelect={(chain) => {
383+
setTargetChain(chain);
384+
const _targetAsset = getAvailableTargetAsset(chain, assetCategory);
385+
setTargetAsset(_targetAsset);
386+
}}
387+
/>
417388
</div>
418389
<input
419390
type="text"

src/components/chainSelectInput.tsx

+18-78
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,31 @@
11
"use clients";
22

33
import Image from "next/image";
4-
import data from "../data/data.json";
5-
import { useCallback, useEffect, useRef, useState } from "react";
6-
import { useTransfer } from "@/hooks";
7-
import { getChainLogoSrc, parseCross } from "@/utils";
8-
import { Asset, ChainConfig } from "@/types";
9-
10-
export interface chainType {
11-
name: string;
12-
logo: string;
13-
}
14-
15-
export default function ChainSelectInput({ who, options }: { who: string; options: [any] }) {
16-
const { sourceChain, setSourceChain, sourceAsset, setTargetChain, setSourceAsset, targetChain } = useTransfer();
17-
const {
18-
defaultSourceChainOptions,
19-
defaultTargetChainOptions,
20-
availableTargetChainOptions,
21-
availableSourceAssetOptions,
22-
defaultSourceAssetOptions,
23-
} = parseCross();
24-
const [sourceChainOptions, _setSourceChainOptions] = useState(defaultSourceChainOptions);
25-
const [sourceAssetOptions, setSourceAssetOptions] = useState(defaultSourceAssetOptions);
26-
const [targetChainOptions, setTargetChainOptions] = useState(defaultTargetChainOptions);
27-
28-
const targetChainRef = useRef(targetChain);
29-
const sourceAssetRef = useRef(sourceAsset);
30-
const sourceChainRef = useRef(sourceChain);
31-
32-
const _setTargetChain = useCallback(
33-
(chain: ChainConfig | undefined) => {
34-
setTargetChain((prev) => chain ?? prev);
35-
targetChainRef.current = chain ?? targetChainRef.current;
36-
},
37-
[setTargetChain],
38-
);
39-
40-
// useEffect(() => {
41-
// const options = availableTargetChainOptions[sourceChain.network]?.[sourceAsset.symbol] || [];
42-
// setTargetChainOptions(options);
43-
// _setTargetChain(options.at(0));
44-
// }, [sourceChain, sourceAsset, _setTargetChain]);
45-
46-
const _setSourceChain = useCallback(
47-
(chain: ChainConfig | undefined) => {
48-
setSourceChain((prev) => chain ?? prev);
49-
sourceChainRef.current = chain ?? sourceChainRef.current;
50-
},
51-
[setSourceChain],
52-
);
53-
54-
// const _setSourceAsset = useCallback(
55-
// (asset: Asset | undefined) => {
56-
// setSourceAsset((prev) => asset ?? prev);
57-
// sourceAssetRef.current = asset ?? sourceAssetRef.current;
58-
// },
59-
// [setSourceAsset],
60-
// );
61-
62-
// useEffect(() => {
63-
// const options = availableSourceAssetOptions[sourceChain.network] || [];
64-
// setSourceAssetOptions(options);
65-
// _setSourceAsset(options.at(0));
66-
// }, [sourceChain, _setSourceAsset]);
4+
import { useState } from "react";
5+
import { getChainLogoSrc } from "@/utils";
6+
import { ChainConfig } from "@/types";
7+
8+
export default function ChainSelectInput({
9+
value,
10+
options,
11+
onSelect,
12+
}: {
13+
value: ChainConfig;
14+
options: ChainConfig[];
15+
onSelect: (chain: ChainConfig) => void;
16+
}) {
6717
const [open, setOpen] = useState<boolean>(false);
6818

69-
const name = "Polkadot AssetHub";
7019
return (
7120
<div
7221
className="relative cursor-pointer"
7322
onClick={() => {
74-
setOpen(!open);
23+
setOpen((prev) => !prev);
7524
}}
7625
>
7726
<div className="flex items-center justify-center gap-[5px]">
78-
<Image
79-
src={getChainLogoSrc(who === "sender" ? sourceChain.logo : targetChain.logo)}
80-
width={20}
81-
height={20}
82-
alt={who === "sender" ? sourceChain.name : targetChain.name}
83-
/>
84-
<p className="text-[12px] leading-[15px]">{who === "sender" ? sourceChain.name : targetChain.name}</p>
27+
<Image src={getChainLogoSrc(value.logo)} width={20} height={20} alt={value.name} />
28+
<p className="text-[12px] leading-[15px]">{value.name}</p>
8529
<span className="block h-[16px] w-[16px] bg-[url('/images/icons/downarrow-icon.svg')] bg-contain bg-center bg-no-repeat" />
8630
</div>
8731
<div
@@ -90,12 +34,8 @@ export default function ChainSelectInput({ who, options }: { who: string; option
9034
>
9135
<div className="relative flex h-fit w-full flex-col gap-[10px] rounded-[10px] p-[10px]">
9236
{options.map((item) => (
93-
<div
94-
key={item.name}
95-
className="flex w-full items-center gap-[5px]"
96-
onClick={who === "sender" ? () => _setSourceChain(item) : () => _setTargetChain(item)}
97-
>
98-
<Image src={getChainLogoSrc(item.logo)} width={20} height={20} alt={item.name} />
37+
<div key={item.name} className="flex w-full items-center gap-[5px]" onClick={() => onSelect(item)}>
38+
<Image src={getChainLogoSrc(item.logo)} width={16} height={16} alt={item.name} />
9939
<p className="truncate whitespace-nowrap text-[12px] leading-[15px]">{item.name}</p>
10040
</div>
10141
))}

0 commit comments

Comments
 (0)