Skip to content

Commit

Permalink
fix: asset selection
Browse files Browse the repository at this point in the history
  • Loading branch information
JayJay1024 committed Oct 10, 2024
1 parent 760a1d7 commit b105c8c
Show file tree
Hide file tree
Showing 16 changed files with 202 additions and 206 deletions.
12 changes: 10 additions & 2 deletions src/components/accountButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function AccountButton({ setSwitchWallet }: { setSwitchWallet: (x
setActiveSenderWallet(undefined);
setActiveSenderAccount(undefined);
disconnect();
}, [setSender, setActiveSenderWallet, setActiveSenderAccount]);
}, [setSender, setActiveSenderWallet, setActiveSenderAccount, disconnect]);

useEffect(() => {
if (needSwitchNetwork) {
Expand All @@ -78,7 +78,15 @@ export default function AccountButton({ setSwitchWallet }: { setSwitchWallet: (x
setSwitchWallet(true);
});
}
}, [sourceChain, chain, switchNetworkAsync]);
}, [
sourceChain,
chain,
switchNetworkAsync,
handleDisconnect,
setSwitchWallet,
activeSenderWallet,
needSwitchNetwork,
]);

useEffect(() => {
window.addEventListener("click", () => {
Expand Down
151 changes: 61 additions & 90 deletions src/components/appBox.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
"use client";

import { ChangeEventHandler, useCallback, useEffect, useMemo, useRef, useState } from "react";
import data from "../data/data.json";
import { ChangeEventHandler, useCallback, useMemo, useRef, useState } from "react";
import Image from "next/image";
import ChainSelectInput, { chainType } from "./chainSelectInput";
import ChainSelectInput from "./chainSelectInput";
import SuccessModal from "./successModal";
import PendingModal from "./pendingModal";
import { formatBalance, getAssetIconSrc, isExceedingCrossChainLimit, isValidAddress, parseCross } from "@/utils";
import {
formatBalance,
getAssetIconSrc,
getAvailableSourceAsset,
getAvailableSourceChain,
getAvailableSourceChainOptions,
getAvailableTargetAsset,
getAvailableTargetChain,
getAvailableTargetChainOptions,
isExceedingCrossChainLimit,
isValidAddress,
} from "@/utils";
import { useTransfer } from "@/hooks";
import { BN, BN_ZERO, bnToBn } from "@polkadot/util";
import { formatUnits, parseUnits } from "viem";
import { WalletID } from "@/types";
import { useAccount, useNetwork, useSwitchNetwork } from "wagmi";
import notification from "@/ui/notification";
import { supportedTokenList } from "@/config/tokens";
import { useTrail, animated, useSpring } from "@react-spring/web";
import WalletSelectionModal from "./walletSelectionModal";
import { assetCategories } from "@/config/asset-categories";

export default function AppBox() {
const [connectModal, setConnectModal] = useState(false);

const { defaultSourceChainOptions, defaultSourceAssetOptions } = parseCross();
const [selectedAsset, setSelectedAsset] = useState(supportedTokenList[0]);
const [allowedChain, setAllowedChain] = useState<any>([]);
// const [sourceAssetOptions, setSourceAssetOptions] = useState(defaultSourceAssetOptions);
const [successModal, setSuccessModal] = useState<boolean>(false);
const [receipt, setReceipt] = useState<boolean | null>(false);

Expand Down Expand Up @@ -58,7 +63,10 @@ export default function AppBox() {
activeSenderAccount,
feeBalanceOnSourceChain,
sourceNativeBalance,
assetCategory,
setAssetCategory,
} = useTransfer();

const handleCloseSuccessModal = useCallback(() => {
setSuccessModal(false);
setReceipt(null);
Expand All @@ -69,7 +77,15 @@ export default function AppBox() {
updateSourceNativeBalance();
updateTargetNativeBalance();
updateFeeBalanceOnSourceChain();
}, []);
}, [
setTransferAmount,
updateFeeBalanceOnSourceChain,
updateSourceAssetBalance,
updateSourceNativeBalance,
updateTargetAssetBalance,
updateTargetAssetSupply,
updateTargetNativeBalance,
]);

const sourceChainRef = useRef(sourceChain);
const targetChainRef = useRef(targetChain);
Expand Down Expand Up @@ -158,8 +174,6 @@ export default function AppBox() {
return null;
}, [bridgeInstance, feeBalanceOnSourceChain]);

// console.log("fee alert", feeAlert);

const existentialAlertOnSourceChain = useMemo(() => {
if (
sourceChain.existential &&
Expand Down Expand Up @@ -219,26 +233,12 @@ export default function AppBox() {
!!existentialAlertOnSourceChain ||
!!existentialAlertOnTargetChain;

// console.log(
// "check this now",
// sender?.address,
// sender?.valid,
// recipient?.address,
// recipient?.valid,
// transferAmount.input,
// transferAmount.valid,
// feeAlert,
// existentialAlertOnSourceChain,
// existentialAlertOnTargetChain,
// );

const handleSend = useCallback(async () => {
if (needSwitchNetwork) {
switchNetwork?.(sourceChain.id);
} else if (bridgeInstance && recipient) {
const callback = {
successCb: (receipt: any) => {
console.log("receipt", receipt);
setReceipt(receipt);
setBusy(false);
setSuccessModal(true);
Expand Down Expand Up @@ -266,69 +266,14 @@ export default function AppBox() {
needSwitchNetwork,
recipient,
sender?.address,
setTransferAmount,
sourceChain.id,
switchNetwork,
transfer,
transferAmount.amount,
transferAmount.input,
updateFeeBalanceOnSourceChain,
updateSourceAssetBalance,
updateTargetAssetBalance,
updateTargetAssetSupply,
updateSourceNativeBalance,
updateTargetNativeBalance,
]);

useEffect(() => {
console.log("defaultSourceAssetOptions", sourceChain.assets);
let sourceChainOptions: any = [];
for (const item of selectedAsset.allowedSource) {
for (const chain of defaultSourceChainOptions) {
if (chain.name === item) {
sourceChainOptions.push(chain);
}
}
}
let selectedSourceAsset;
for (const item of sourceChainOptions[0].assets) {
if (selectedAsset.icon === item.icon) {
selectedSourceAsset = item;
}
}
setAllowedChain([...sourceChainOptions]);
setSourceChain(sourceChainOptions[0]);
setSourceAsset(selectedSourceAsset);
setTargetChain(sourceChainOptions[1]);
}, [selectedAsset]);

useEffect(() => {
console.log(allowedChain);
if (allowedChain.length > 0) {
if (sourceChain.name === allowedChain[0].name && targetChain.name === allowedChain[0].name) {
setTargetChain(allowedChain[1]);
} else if (sourceChain.name === allowedChain[1].name && targetChain.name === allowedChain[1].name) {
setTargetChain(allowedChain[0]);
}
}
for (const asset of sourceChain.assets) {
if (selectedAsset.name === asset.name) setSourceAsset(asset);
}
}, [sourceChain]);

useEffect(() => {
if (allowedChain.length > 0) {
if (targetChain.name === allowedChain[0].name && sourceChain.name == allowedChain[0].name) {
setSourceChain(allowedChain[1]);
} else if (targetChain.name === allowedChain[1].name && sourceChain.name === allowedChain[1].name) {
setSourceChain(allowedChain[0]);
}
}
for (const asset of targetChain.assets) {
if (selectedAsset.name === asset.name) setTargetAsset(asset);
}
}, [targetChain]);

const trails = useTrail(5, {
from: { transform: "translateX(-100%)", opacity: 0 },
to: { opacity: 1, transform: "translateX(0)" },
Expand All @@ -339,8 +284,6 @@ export default function AppBox() {
to: { opacity: 1, transform: "translateY(0)" },
});

// console.log("check this.................", sender, needSwitchNetwork, disabledSend);

return (
<>
<animated.section
Expand All @@ -355,16 +298,24 @@ export default function AppBox() {
<p className="text-[12px] leading-[15.22px] text-[#12161980]">Token</p>
</div>
<div className="flex items-center gap-[10px]">
{supportedTokenList.map((item: any) => (
{assetCategories.map((item) => (
<div
className="flex items-center gap-[10px] duration-500"
key={item.name}
style={{
maxWidth: selectedAsset.name === item.name ? "100px" : "30px",
transitionDelay: selectedAsset.name === item.name ? "0.4s" : "0s",
maxWidth: assetCategory === item.category ? "100px" : "30px",
transitionDelay: assetCategory === item.category ? "0.4s" : "0s",
}}
onClick={() => {
setSelectedAsset(item);
setAssetCategory(item.category);
const _sourceChain = getAvailableSourceChain(getAvailableSourceChainOptions(item.category));
const _sourceAsset = getAvailableSourceAsset(_sourceChain, item.category);
const _targetChain = getAvailableTargetChain(getAvailableTargetChainOptions(_sourceAsset));
const _targetAsset = getAvailableTargetAsset(_targetChain, item.category);
setSourceChain(_sourceChain);
setSourceAsset(_sourceAsset);
setTargetChain(_targetChain);
setTargetAsset(_targetAsset);
}}
>
<Image
Expand All @@ -385,7 +336,19 @@ export default function AppBox() {
>
<div className="flex h-[30px] items-center justify-between">
<p className="text-[12px] leading-[15.22px] text-[#12161980]">Sender</p>
<ChainSelectInput options={allowedChain} who="sender" />
<ChainSelectInput
value={sourceChain}
options={getAvailableSourceChainOptions(assetCategory)}
onSelect={(chain) => {
setSourceChain(chain);
const _sourceAsset = getAvailableSourceAsset(chain, assetCategory);
const _targetChain = getAvailableTargetChain(getAvailableTargetChainOptions(_sourceAsset));
const _targetAsset = getAvailableTargetAsset(_targetChain, assetCategory);
setSourceAsset(_sourceAsset);
setTargetChain(_targetChain);
setTargetAsset(_targetAsset);
}}
/>
</div>
{sender ? (
<input
Expand Down Expand Up @@ -413,7 +376,15 @@ export default function AppBox() {
>
<div className="flex h-[30px] items-center justify-between">
<p className="text-[12px] leading-[15.22px] text-[#12161980]">Recipient</p>
<ChainSelectInput options={allowedChain} who="target" />
<ChainSelectInput
value={targetChain}
options={getAvailableTargetChainOptions(sourceAsset)}
onSelect={(chain) => {
setTargetChain(chain);
const _targetAsset = getAvailableTargetAsset(chain, assetCategory);
setTargetAsset(_targetAsset);
}}
/>
</div>
<input
type="text"
Expand Down
96 changes: 18 additions & 78 deletions src/components/chainSelectInput.tsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,31 @@
"use clients";

import Image from "next/image";
import data from "../data/data.json";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTransfer } from "@/hooks";
import { getChainLogoSrc, parseCross } from "@/utils";
import { Asset, ChainConfig } from "@/types";

export interface chainType {
name: string;
logo: string;
}

export default function ChainSelectInput({ who, options }: { who: string; options: [any] }) {
const { sourceChain, setSourceChain, sourceAsset, setTargetChain, setSourceAsset, targetChain } = useTransfer();
const {
defaultSourceChainOptions,
defaultTargetChainOptions,
availableTargetChainOptions,
availableSourceAssetOptions,
defaultSourceAssetOptions,
} = parseCross();
const [sourceChainOptions, _setSourceChainOptions] = useState(defaultSourceChainOptions);
const [sourceAssetOptions, setSourceAssetOptions] = useState(defaultSourceAssetOptions);
const [targetChainOptions, setTargetChainOptions] = useState(defaultTargetChainOptions);

const targetChainRef = useRef(targetChain);
const sourceAssetRef = useRef(sourceAsset);
const sourceChainRef = useRef(sourceChain);

const _setTargetChain = useCallback(
(chain: ChainConfig | undefined) => {
setTargetChain((prev) => chain ?? prev);
targetChainRef.current = chain ?? targetChainRef.current;
},
[setTargetChain],
);

// useEffect(() => {
// const options = availableTargetChainOptions[sourceChain.network]?.[sourceAsset.symbol] || [];
// setTargetChainOptions(options);
// _setTargetChain(options.at(0));
// }, [sourceChain, sourceAsset, _setTargetChain]);

const _setSourceChain = useCallback(
(chain: ChainConfig | undefined) => {
setSourceChain((prev) => chain ?? prev);
sourceChainRef.current = chain ?? sourceChainRef.current;
},
[setSourceChain],
);

// const _setSourceAsset = useCallback(
// (asset: Asset | undefined) => {
// setSourceAsset((prev) => asset ?? prev);
// sourceAssetRef.current = asset ?? sourceAssetRef.current;
// },
// [setSourceAsset],
// );

// useEffect(() => {
// const options = availableSourceAssetOptions[sourceChain.network] || [];
// setSourceAssetOptions(options);
// _setSourceAsset(options.at(0));
// }, [sourceChain, _setSourceAsset]);
import { useState } from "react";
import { getChainLogoSrc } from "@/utils";
import { ChainConfig } from "@/types";

export default function ChainSelectInput({
value,
options,
onSelect,
}: {
value: ChainConfig;
options: ChainConfig[];
onSelect: (chain: ChainConfig) => void;
}) {
const [open, setOpen] = useState<boolean>(false);

const name = "Polkadot AssetHub";
return (
<div
className="relative cursor-pointer"
onClick={() => {
setOpen(!open);
setOpen((prev) => !prev);
}}
>
<div className="flex items-center justify-center gap-[5px]">
<Image
src={getChainLogoSrc(who === "sender" ? sourceChain.logo : targetChain.logo)}
width={20}
height={20}
alt={who === "sender" ? sourceChain.name : targetChain.name}
/>
<p className="text-[12px] leading-[15px]">{who === "sender" ? sourceChain.name : targetChain.name}</p>
<Image src={getChainLogoSrc(value.logo)} width={20} height={20} alt={value.name} />
<p className="text-[12px] leading-[15px]">{value.name}</p>
<span className="block h-[16px] w-[16px] bg-[url('/images/icons/downarrow-icon.svg')] bg-contain bg-center bg-no-repeat" />
</div>
<div
Expand All @@ -90,12 +34,8 @@ export default function ChainSelectInput({ who, options }: { who: string; option
>
<div className="relative flex h-fit w-full flex-col gap-[10px] rounded-[10px] p-[10px]">
{options.map((item) => (
<div
key={item.name}
className="flex w-full items-center gap-[5px]"
onClick={who === "sender" ? () => _setSourceChain(item) : () => _setTargetChain(item)}
>
<Image src={getChainLogoSrc(item.logo)} width={20} height={20} alt={item.name} />
<div key={item.name} className="flex w-full items-center gap-[5px]" onClick={() => onSelect(item)}>
<Image src={getChainLogoSrc(item.logo)} width={16} height={16} alt={item.name} />
<p className="truncate whitespace-nowrap text-[12px] leading-[15px]">{item.name}</p>
</div>
))}
Expand Down
Loading

0 comments on commit b105c8c

Please sign in to comment.