Ethereum Boilerplate Questions

Post full code of the component

This is my DEX.jsx

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: {
width: “430px”,
boxShadow: “0 0.5rem 1.2rem rgb(189 197 209 / 20%)”,
border: “1px solid #e7eaf3”,
borderRadius: “1rem”,
fontSize: “16px”,
fontWeight: “500”,
},
input: {
padding: “0”,
fontWeight: “500”,
fontSize: “23px”,
display: “block”,
width: “100%”,
},
priceSwap: {
display: “flex”,
justifyContent: “space-between”,
fontSize: “15px”,
color: “#434343”,
marginTop: “8px”,
padding: “0 10px”,
},
};

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 = {} }) {
const { trySwap, tokenList, getQuote } = useInchDex(chain);

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 (!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 (

Price:{" "}
{1 ${toSymbol} = ${pricePerToken} ${fromSymbol} ($${tokenPricesUSD[[toToken["address"]]].toFixed(6)})}

);
};

return (
<>
<Card style={styles.card} bodyStyle={{ padding: “18px” }}>
<Card style={{ borderRadius: “1rem” }} bodyStyle={{ padding: “0.8rem” }}>
<div style={{ marginBottom: “5px”, fontSize: “14px”, color: “#434343” }}>From
<div
style={{
display: “flex”,
flexFlow: “row nowrap”,
}}
>


<InputNumber
bordered={false}
placeholder=“0.00”
style={{ …styles.input, marginLeft: “-10px” }}
onChange={setFromAmount}
value={fromAmount}
/>
<Text style={{ fontWeight: “600”, color: “#434343” }}>{fromTokenAmountUsd}

<Button
style={{
height: “fit-content”,
display: “flex”,
justifyContent: “space-between”,
alignItems: “center”,
borderRadius: “0.6rem”,
padding: “5px 10px”,
fontWeight: “500”,
fontSize: “17px”,
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” }}
/>
) : (
Select a token
)}
{fromToken?.symbol}




<div style={{ display: “flex”, justifyContent: “center”, padding: “10px” }}>


<Card style={{ borderRadius: “1rem” }} bodyStyle={{ padding: “0.8rem” }}>
<div style={{ marginBottom: “5px”, fontSize: “14px”, color: “#434343” }}>To
<div
style={{
display: “flex”,
flexFlow: “row nowrap”,
}}
>

<Input
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: “#434343” }}>{toTokenAmountUsd}

<Button
style={{
height: “fit-content”,
display: “flex”,
justifyContent: “space-between”,
alignItems: “center”,
borderRadius: “0.6rem”,
padding: “5px 10px”,
fontWeight: “500”,
fontSize: “17px”,
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” }}
/>
) : (
Select a token
)}
{toToken?.symbol}




{quote && (

<Text
style={{
display: “flex”,
justifyContent: “space-between”,
fontSize: “15px”,
color: “#434343”,
marginTop: “8px”,
padding: “0 10px”,
}}
>
Estimated Gas: {quote?.estimatedGas}



)}
<Button
type=“primary”
size=“large”
style={{
width: “100%”,
marginTop: “15px”,
borderRadius: “0.6rem”,
height: “50px”,
}}
onClick={() => trySwap(currentTrade)}
disabled={!ButtonState.isActive}
>
{ButtonState.text}


<Modal
title=“Select a token”
visible={isFromModalActive}
onCancel={() => setFromModalActive(false)}
bodyStyle={{ padding: 0 }}
width=“450px”
footer={null}
>
<InchModal
open={isFromModalActive}
onClose={() => setFromModalActive(false)}
setToken={setFromToken}
tokenList={tokens}
/>

<Modal
title=“Select a token”
visible={isToModalActive}
onCancel={() => setToModalActive(false)}
bodyStyle={{ padding: 0 }}
width=“450px”
footer={null}
>
<InchModal open={isToModalActive} onClose={() => setToModalActive(false)} setToken={setToToken} tokenList={tokens} />

</>
);
}

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" />
);

Can you please tell me where the code is in the boilerplate to create NFT? I learn how to sell, buy NFT from youtube. But user should be able to create NFT collection and upload NFT. Is that in the boilerplate? where?

Thank you.

Hi everyone,

I am new to this amazing community. A few weeks ago I was testing the Ethereum-boilerplate and It was working fine for me. Yesterday, and after the new update, I start have issuing deploying the new git on Vercel.com.

I have too many warnings and errors completing the deployment.

Here is my log!
Treating warnings as errors because process.env.CI = true.
Failed to compile.
Module not found: Can’t resolve ‘contracts/contractInfo.json’ in ‘/vercel/path0/src/components/Contract’
Error: Command “react-scripts build” exited with 1

I am not really sure, how I can generate another contracts/contractInfo.json

I was not able to fix this issue. Any luck from your end?

Hi @jphoto

Basic ethereum-boilerplate doesn’t have this functionality, it’s in the NFT marketplace boilerplate. Take a look at https://www.youtube.com/watch?v=WZWCzsB1xUE&list=PLFPZ8ai7J-iR4F882O2mBjqydynG9iDZS

Hi @Cedro

For now, you need to enable deploy functionality even with warning messages(normal practice). There is a detailed guide: https://github.com/vercel/vercel/discussions/5566#discussioncomment-566413

The previous version had no warnings, but this one has them. We will disable them in the coming version

i faced this error each time i use yarn start

C:\Users\USER\Desktop\NFTDevelopment\NFT> yarn start
yarn run v1.22.17
warning package.json: No license field
error Command "start" not found.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Hi @Cyberhot

Looks like you are running it from the not correct folder. Write cd .. and try again

Hi Yomoo,

I was able to fix this by uploading my contract [contractInfo.json] to the repo before deploying. Now it’s working just fine. Was that right?

it’s also a possible solution. Because the component checks if contractInfo.json exists

Hmm, I guess it’s better to add a blank contractInfo.json to the boilerplate. Thank you @Cedro for the idea.

@Yomoo

  1. blank contractInfo.json didn’t work for me. I had to deploy a new contract and upload the new contractInfo.json to this directory */ethereum-boilerplate/src/contracts/contractInfo.json.

  2. Add [ CI=false npm run build] in the build command.

  3. Yarn install.

Now its working just fine.

1 Like

it works now but i saw this warning message in my terminal

./src/components/Contract/ContractResolver.jsx
Module not found: Can't resolve 'contracts/contractInfo.json' in 'C:\Users\USER\Desktop\NFTDevelopment\NFT\ethereum-boilerplate\src\components\Contract'

src\components\Account\Account.jsx
  Line 47:70:  'web3' is assigned a value but never used  no-unused-vars

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

also when i run yarn start i can see the NFT section is blank

So you guys are great! I have this working fine on my local machine.
Now I’m trying to run it on a linux server. Is there anything obvious I need to change?
Thank you!

This was fixed on the new version

Hey @m360ai

Nice to hear this! This is a frontend, why do you want to run it on a linux server? Sorry, I’m not sure if I got your question correctly. Could you please provide some more info :raised_hands:

How would I change the number of columns on the NFTBalance display to 3 across rather than 4?

Hi @unlabeled

Since our boilerplate was built using Ant design you can find all settings there https://ant.design/components/table/

Check the pagination and size