Ethereum Boilerplate Questions

Hi @mejmerlin

You can install typescript, but you also should allow js, jsx in the typescript config. So your tsconfig.json will be like this:

{
  "compilerOptions": {
    "allowJs": true,
    "jsx": "react-jsx",
     // other settings
  },
}

Hi @John

You should ask questions about nft-marketplace here: https://forum.moralis.io/t/cloning-opensea-nft-boilerplate-questions

Please follow the quickstart steps. You need to add your contract ABI and contract address like this:

const [contractABI, setContractABI] = useState([abi: "abi"]);
const [marketAddress, setMarketAddress] = useState("0x12...ssdgf");

Hi!
is it possible to upload this to my own hosting and domain?
Thx!

Hi @Baldal

Yes, you can upload it to your own hosting. It’s better to find instructions how to upload app on your hosting site

localhost works perfectly. So isn’t it all I have to do to put the files in storage? will it work that way?

Hello @Baldal yes it is, but keep in mind you need to host the production version of your app by running npm run build or yarn build and run the build version instead of the dev version you use in npm run start or yarn start.

Hi guys,
The setup Moralis/Ganache/Boilerplate works in the background (I can do contracts through terminal) but I have issues with the Boilerplate. see attached
Metamask is connected.
When I use the local chain ‘Token Balances’ doesn’t have a table and with the Ethereum network it does show a table but without any tokens.
Any help is appreciated.

Seems a chain reference is missing on the local network. Any idea what the chain reference must be and where to set in the VS code project?
Screenshot 3

Has the instructions been created? It would be great if this was a YouTube training like your others!

I would also like to know the answer to this. Please help :slight_smile:

What is the status of this? Thank you!

Hi @cstanleyhns @BooneBergsma

Please update your boilerplate version and follow instructions https://github.com/ethereum-boilerplate/ethereum-boilerplate/blob/main/README.md#dex-

For example you can create an object customTokens in App.jsx with custom tokens and provide them as props to <DEX customTokens={customTokens} /> component

1 Like

I believe today/tomorrow this feature will be finally released :raised_hands:

1 Like

Great questions! I am learning JS and Solidity now and coming from a WordPress background. I am trying think about how to reverse engineer the boilerplate for WP. The Moralis DAO should really be thinking about how they can make it easy for one of the largest pool of developers to take part in Web3 by making a WordPress plugin or template. And would also love to see it work well with Elementor. You would see massive growth in your platform if you empower the WP community to build on web3.0

I created my own using this boilerplate and start testing.

I found two bugs.

  1. In DEX, I can’t change ETH to something else, but ok on the 2nd option selecting other token. Same issue when I choose BNC or Polygon, can’t choose other token.
    2… I logged successfully using Metamask. When I tried to logout to use other eth account, I have no way of changing it.

Let me know how to fix it.
Thank you.

Hi @Hacker

This bug was fixed on the latest version. Pull the latest version or you can fix it yourself: ethereum-boilerplate\src\components\DEX\DEX.jsx. Change the code in the useEffect hook on 125th line to:

 useEffect(() => {
    if (!tokens || fromToken) return null;
    setFromToken(tokens[nativeAddress]);
  }, [tokens, fromToken]);

Hello @Yomoo
I have the new install.

I will try your recommendation and let you know.

@Yomoo This code is what I have in my build. Nothing to change.

useEffect(() => {
if (!tokens || fromToken) return null;
setFromToken(tokens[nativeAddress]);
}, [tokens, fromToken]);

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.