I get the following below
How can switch chain in trust wallet with boilerplate please help me.
Watch for github comments only. Do not update the whole project.
Thank you! But that line does not exist in my MenuItems.jsx file…?
Hello,
After adding a custom token the Dex is giving a popup error 400 when trying to swap to the custom token. And when trying to swap any other token it gives a “Swap Complete” popup but doesn’t actually complete the swap. Any help appreciated.
You can test at: https://monkeyninja.io/1inch
Thanks!
Hey @jtran1047
Try to change your package.json
to:
"start": "react-scripts --openssl-legacy-provider start"
You cannot make this. TrustWallet doesn’t have active chain like Metamask.
You can edit the ethereum-boilerplate/src/components/Contract/
More responsive design is now in progress. Fo sure you can, the code is absolutely open, you can edit it any way you want
No
Hey @pkgujjar
The is a table component. But yeah, now I can see it may be confusing. In the coming versions, we will make separate ERC20Balance
for one token and ERC20Balances
for all
For now you can filter a result from useERC20Balances()
No worries. Add this line overflowedIndicator="Your Title Goes Here"
after this line mode="horizontal"
in your MenuItems.jsx.
I think you are misunderstanding. The indicator or icon is there. I just want to know how to change it to a different icon.
You can see here: https://monkeyninja.io
No, just add this overflowedIndicator="Your Title Goes Here"
and it will replace it for whatever you want.
Can you post your code? so I can review it.
import { useState, useEffect, useMemo } from "react";
import { useMoralis } from "react-moralis";
import InchModal from "./components/InchModal";
import useInchDex from "hooks/useInchDex";
import { Button, Card, Image, Input, InputNumber, Modal } from "antd";
import Text from "antd/lib/typography/Text";
import { ArrowDownOutlined } from "@ant-design/icons";
import { useTokenPrice } from "react-moralis";
import { tokenValue } from "helpers/formatters";
import { getWrappedNative } from "helpers/networks";
// import { useOneInchQuote } from "react-moralis";
const styles = {
card: {
maxWidth: "430px",
minWidth: "360px",
boxShadow: "0 0.5rem 1.2rem rgb(189 197 209 / 20%)",
border: "0",
borderRadius: "1rem",
fontSize: "16px",
fontWeight: "500",
color: "#f4db73",
margin: "20px auto 40px",
background: "#222",
},
input: {
padding: "0",
fontWeight: "500",
fontSize: "23px",
display: "block",
width: "100%",
color: "#fff",
},
priceSwap: {
display: "flex",
justifyContent: "space-between",
fontSize: "15px",
color: "#fff",
marginTop: "8px",
padding: "0 10px",
},
priceEst: {
color: "#fff",
},
};
const nativeAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
const chainIds = {
"0x1": "eth",
"0x38": "bsc",
"0x89": "polygon",
};
const getChainIdByName = (chainName) => {
for (let chainId in chainIds) {
if (chainIds[chainId] === chainName) return chainId;
}
};
const IsNative = (address) => address === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
function DEX({ chain, customTokens = {
"0xe7541aa266fa18edc1b4cfd766b814ec25d9c937": {
address: "0xe7541aa266fa18edc1b4cfd766b814ec25d9c937",
decimals: 18,
logoURI: "https://monkeyninja.io/static/media/token-01.png",
name: "Okane",
symbol: "Okane",
},
}}) {
const { trySwap, tokenList, getQuote } = useInchDex(chain = 'polygon');
const { Moralis, isInitialized, chainId } = useMoralis();
const [isFromModalActive, setFromModalActive] = useState(false);
const [isToModalActive, setToModalActive] = useState(false);
const [fromToken, setFromToken] = useState();
const [toToken, setToToken] = useState();
const [fromAmount, setFromAmount] = useState();
const [quote, setQuote] = useState();
const [currentTrade, setCurrentTrade] = useState();
const { fetchTokenPrice } = useTokenPrice();
const [tokenPricesUSD, setTokenPricesUSD] = useState({});
const tokens = useMemo(() => {
return { ...customTokens, ...tokenList };
}, [customTokens, tokenList]);
const fromTokenPriceUsd = useMemo(
() => (tokenPricesUSD?.[fromToken?.["address"]] ? tokenPricesUSD[fromToken?.["address"]] : null),
[tokenPricesUSD, fromToken]
);
const toTokenPriceUsd = useMemo(
() => (tokenPricesUSD?.[toToken?.["address"]] ? tokenPricesUSD[toToken?.["address"]] : null),
[tokenPricesUSD, toToken]
);
const fromTokenAmountUsd = useMemo(() => {
if (!fromTokenPriceUsd || !fromAmount) return null;
return `~$ ${(fromAmount * fromTokenPriceUsd).toFixed(4)}`;
}, [fromTokenPriceUsd, fromAmount]);
const toTokenAmountUsd = useMemo(() => {
if (!toTokenPriceUsd || !quote) return null;
return `~$ ${(Moralis.Units.FromWei(quote?.toTokenAmount, quote?.toToken?.decimals) * toTokenPriceUsd).toFixed(4)}`;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [toTokenPriceUsd, quote]);
// tokenPrices
useEffect(() => {
if (!isInitialized || !fromToken || !chain) return null;
const validatedChain = chain ? getChainIdByName(chain) : chainId;
const tokenAddress = IsNative(fromToken["address"]) ? getWrappedNative(validatedChain) : fromToken["address"];
fetchTokenPrice({
params: { chain: validatedChain, address: tokenAddress },
onSuccess: (price) =>
setTokenPricesUSD({
...tokenPricesUSD,
[fromToken["address"]]: price["usdPrice"],
}),
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [chain, isInitialized, fromToken]);
useEffect(() => {
if (!isInitialized || !toToken || !chain) return null;
const validatedChain = chain ? getChainIdByName(chain) : chainId;
const tokenAddress = IsNative(toToken["address"]) ? getWrappedNative(validatedChain) : toToken["address"];
fetchTokenPrice({
params: { chain: validatedChain, address: tokenAddress },
onSuccess: (price) =>
setTokenPricesUSD({
...tokenPricesUSD,
[toToken["address"]]: price["usdPrice"],
}),
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [chain, isInitialized, toToken]);
useEffect(() => {
if (!tokens || fromToken) return null;
setFromToken(tokens[nativeAddress]);
}, [tokens, fromToken]);
const ButtonState = useMemo(() => {
// if (chainIds?.[chainId] !== chain) return { isActive: false, text: `Switch to ${chain}` };
if (chainIds?.[chainId] !== 'polygon') return { isActive: false, text: `Switch to Polygon` };
if (!fromAmount) return { isActive: false, text: "Enter an Amount" };
if (fromAmount && currentTrade) return { isActive: true, text: "Swap" };
return { isActive: false, text: "Select Tokens" };
}, [fromAmount, currentTrade, chainId/*, chain*/]);
useEffect(() => {
if (fromToken && toToken && fromAmount) setCurrentTrade({ fromToken, toToken, fromAmount, chain });
}, [toToken, fromToken, fromAmount, chain]);
useEffect(() => {
if (currentTrade) getQuote(currentTrade).then((quote) => setQuote(quote));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentTrade]);
const PriceSwap = () => {
const Quote = quote;
if (!Quote || !tokenPricesUSD?.[toToken?.["address"]]) return null;
if (Quote?.statusCode === 400) return <>{Quote.message}</>;
console.log(Quote);
const { fromTokenAmount, toTokenAmount } = Quote;
const { symbol: fromSymbol } = fromToken;
const { symbol: toSymbol } = toToken;
const pricePerToken = parseFloat(
tokenValue(fromTokenAmount, fromToken["decimals"]) / tokenValue(toTokenAmount, toToken["decimals"])
).toFixed(6);
return (
<Text style={styles.priceSwap}>
Price:{" "}
<Text style={styles.priceEst}>{`1 ${toSymbol} = ${pricePerToken} ${fromSymbol} ($${tokenPricesUSD[[toToken["address"]]].toFixed(6)})`}</Text>
</Text>
);
};
return (
<>
<h1 style={{ textAlign: "center", paddingTop: "7rem" }}>Ninja Swap</h1>
{/*<h4 style={{ textAlign: "center" }}>Please make sure your wallet is connected to the Polygon Mainnet.</h4>*/}
<Card style={styles.card} bodyStyle={{ padding: "8px" }}>
<Card style={{ borderRadius: "0.5rem", background: "#333" }} bodyStyle={{ padding: "0.8rem" }}>
<div style={{ marginBottom: "5px", fontSize: "14px", color: "#fff" }}>From</div>
<div
style={{
display: "flex",
flexFlow: "row nowrap",
}}
>
<div>
<InputNumber
bordered={false}
placeholder="0.00"
style={{ ...styles.input, marginLeft: "-10px" }}
onChange={setFromAmount}
value={fromAmount}
/>
<Text style={{ fontWeight: "600", color: "rgb(69, 184, 0)" }}>{fromTokenAmountUsd}</Text>
</div>
<Button
style={{
height: "fit-content",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
borderRadius: "4px",
padding: "5px 10px",
fontWeight: "500",
fontSize: "18px",
gap: "7px",
border: "none",
}}
onClick={() => setFromModalActive(true)}
>
{fromToken ? (
<Image
src={fromToken?.logoURI || "https://etherscan.io/images/main/empty-token.png"}
alt="nologo"
width="30px"
preview={false}
style={{ borderRadius: "15px" }}
/>
) : (
<span>Select a Token</span>
)}
<span>{fromToken?.symbol}</span>
<Arrow />
</Button>
</div>
</Card>
<div style={{ display: "flex", justifyContent: "center", margin: "-15px 0 3px" }}>
<ArrowDownOutlined style={{ zIndex: "1", }} />
</div>
<Card style={{ borderRadius: "0.5rem", background: "#333" }} bodyStyle={{ padding: "0.8rem" }}>
<div style={{ marginBottom: "5px", fontSize: "14px", color: "#fff" }}>To</div>
<div
style={{
display: "flex",
flexFlow: "row nowrap",
}}
>
<div>
<Input
className="dexInput"
bordered={false}
placeholder="0.00"
style={styles.input}
readOnly
value={quote ? Moralis.Units.FromWei(quote?.toTokenAmount, quote?.toToken?.decimals).toFixed(6) : ""}
/>
<Text style={{ fontWeight: "600", color: "rgb(69, 184, 0)" }}>{toTokenAmountUsd}</Text>
</div>
<Button
style={{
height: "fit-content",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
borderRadius: "4px",
padding: "5px 10px",
fontWeight: "500",
fontSize: "18px",
gap: "7px",
border: "none",
}}
onClick={() => setToModalActive(true)}
type={toToken ? "default" : "primary"}
>
{toToken ? (
<Image
src={toToken?.logoURI || "https://etherscan.io/images/main/empty-token.png"}
alt="nologo"
width="30px"
preview={false}
style={{ borderRadius: "15px" }}
/>
) : (
<span>Select A Token</span>
)}
<span>{toToken?.symbol}</span>
<Arrow />
</Button>
</div>
</Card>
{quote && (
<div>
<Text
style={{
display: "flex",
justifyContent: "space-between",
fontSize: "15px",
color: "#fff",
marginTop: "8px",
padding: "0 10px",
borderTop: "4px dotted #fff",
paddingTop: "8px",
}}
>
Estimated Gas: <Text style={{ color: "#fff" }}>{quote?.estimatedGas}</Text>
</Text>
<PriceSwap />
</div>
)}
<Button
type="primary"
size="large"
style={{
width: "100%",
marginTop: "15px",
borderRadius: "4px",
border: "0",
height: "50px",
background: "#ffb148",
color: "#fff",
textTransform: "uppercase",
fontWeight: "bold",
}}
onClick={() => trySwap(currentTrade)}
disabled={!ButtonState.isActive}
>
{ButtonState.text}
</Button>
</Card>
<Modal
title="Select a Token"
visible={isFromModalActive}
onCancel={() => setFromModalActive(false)}
bodyStyle={{ padding: 0 }}
maxWidth="450px"
minWidth="360px"
footer={null}
>
<InchModal
open={isFromModalActive}
onClose={() => setFromModalActive(false)}
setToken={setFromToken}
tokenList={tokens}
/>
</Modal>
<Modal
title="Select a Token"
visible={isToModalActive}
onCancel={() => setToModalActive(false)}
bodyStyle={{ padding: 0 }}
maxWidth="450px"
minWidth="360px"
footer={null}
>
<InchModal
open={isToModalActive}
onClose={() => setToModalActive(false)}
setToken={setToToken}
tokenList={tokens} />
</Modal>
</>
);
}
export default DEX;
const Arrow = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<polyline points="6 9 12 15 18 9" />
</svg>
);
Oooooh excellent! Can I give it an image file path or what type of attribute does it need?
I think you can use this :
url(“img.png”)’,`
That doesn’t seem to work…
Hi Mejmerlin, Have u successfully created DEX? I am working on creating dex as well