feat: query blockchain for ens text records
This commit is contained in:
185
src/App.js
185
src/App.js
@@ -2,20 +2,24 @@ import "./App.css";
|
||||
import "animate.css";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
//import namehash from "eth-ens-namehash"; // DO NOT REMOVE COMMENT
|
||||
import namehash from "eth-ens-namehash";
|
||||
import { Keccak } from "sha3";
|
||||
//import axiosClient from "axios"; // DO NOT REMOVE COMMENT
|
||||
|
||||
import Card from "@mui/material/Card";
|
||||
import CardActions from "@mui/material/CardActions";
|
||||
import ButtonBase from "@mui/material/ButtonBase";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
|
||||
import OpenSeaIcon from "./asset/image/opensea-icon.svg";
|
||||
import EnsIcon from "./asset/image/ens-icon.jpeg";
|
||||
import GithubIcon from "./asset/image/github-icon.svg";
|
||||
import TwitterIcon from "./asset/image/twitter-icon.svg";
|
||||
import WebsiteIcon from "./asset/image/website-icon.png";
|
||||
|
||||
import { hexToDec } from "./utility";
|
||||
import { EnsContract, hexToDec, textRecordToUrl } from "./utility";
|
||||
|
||||
//var ensContract = new EnsContract();
|
||||
var ensContract = new EnsContract();
|
||||
|
||||
/* vanilla js to adapt height to actual viewport vs therotical */
|
||||
let vh = window.innerHeight * 0.01;
|
||||
@@ -30,6 +34,12 @@ window.addEventListener("resize", () => {
|
||||
function App() {
|
||||
const [seconds, setSeconds] = useState("00");
|
||||
const [currentEnsImage, setCurrentEnsImage] = useState("");
|
||||
const [currentEnsMetadata, setCurrentEnsMetadata] = useState({
|
||||
url: "",
|
||||
twitter: "",
|
||||
github: "",
|
||||
});
|
||||
|
||||
const ensImages = {};
|
||||
const donationLink =
|
||||
"https://heliowallet.com/ethereum-donation?address=0x2652CBE035CF346A4E085D4C2Fb30F2B5Abf3d3d&amount=0.01&accessWallet=1&qrCode=1ðBalance=1";
|
||||
@@ -37,11 +47,14 @@ function App() {
|
||||
useEffect(() => {
|
||||
setSeconds(getSeconds());
|
||||
setInterval(() => {
|
||||
if (getSeconds() === "59") {
|
||||
getEnsMetadata(getEnsName(1));
|
||||
}
|
||||
setSeconds(getSeconds());
|
||||
setCurrentEnsImage(ensImages[getEnsName()]);
|
||||
}, 1000);
|
||||
|
||||
preloadImages();
|
||||
getEnsMetadata(getEnsName());
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
@@ -82,6 +95,31 @@ function App() {
|
||||
await new Promise((r) => setTimeout(r, timeDelay));
|
||||
};
|
||||
|
||||
const getEnsMetadata = async (ensName) => {
|
||||
const urlPromise = ensContract.getTextRecord("url", getNameHash(ensName));
|
||||
const twitterPromise = ensContract.getTextRecord(
|
||||
"com.twitter",
|
||||
getNameHash(ensName)
|
||||
);
|
||||
const githubPromise = ensContract.getTextRecord(
|
||||
"com.github",
|
||||
getNameHash(ensName)
|
||||
);
|
||||
|
||||
const results = await Promise.all([
|
||||
urlPromise,
|
||||
twitterPromise,
|
||||
githubPromise,
|
||||
]);
|
||||
|
||||
const ensMetadata = {
|
||||
url: results[0] ? textRecordToUrl(results[0], "uri") : "",
|
||||
twitter: results[1] ? textRecordToUrl(results[1], "twitter") : "",
|
||||
github: results[2] ? textRecordToUrl(results[2], "github") : "",
|
||||
};
|
||||
setCurrentEnsMetadata(ensMetadata);
|
||||
};
|
||||
|
||||
const getEnsImageUri = (ensName) => {
|
||||
return `https://metadata.ens.domains/mainnet/0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85/${getLabelHash(
|
||||
ensName
|
||||
@@ -93,21 +131,21 @@ function App() {
|
||||
};
|
||||
|
||||
const getOpenSeaUri = (ensName) => {
|
||||
const tokenId = hexToDec(getLabelHash(ensName).replace("0x", ""));
|
||||
const tokenId = hexToDec(getLabelHash(ensName, true));
|
||||
return `https://opensea.io/assets/0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85/${tokenId}`;
|
||||
};
|
||||
|
||||
// const getNameHash = (ensName) => { // DO NOT REMOVE COMMENT
|
||||
// return namehash.hash(ensName);
|
||||
// };
|
||||
const getNameHash = (ensName) => {
|
||||
return namehash.hash(ensName);
|
||||
};
|
||||
|
||||
const getLabelHash = (ensName) => {
|
||||
const getLabelHash = (ensName, omitPrefix) => {
|
||||
const label = ensName.replace(".eth", "");
|
||||
|
||||
const hasher = new Keccak(256);
|
||||
hasher.update(label);
|
||||
|
||||
return "0x" + hasher.digest("hex");
|
||||
return (!omitPrefix ? "0x" : "") + hasher.digest("hex");
|
||||
};
|
||||
|
||||
const getEnsName = (minutesToAdd) => {
|
||||
@@ -167,11 +205,102 @@ function App() {
|
||||
);
|
||||
};
|
||||
|
||||
const renderIcon = (icon, uri, tooltip, style) => {
|
||||
return (
|
||||
<Tooltip title={tooltip} placement="bottom">
|
||||
<ButtonBase
|
||||
sx={{
|
||||
marginRight: 1,
|
||||
marginLeft: 1,
|
||||
}}
|
||||
>
|
||||
<a href={uri} target="_blank" rel="noreferrer">
|
||||
<img
|
||||
src={icon}
|
||||
className="icon-size"
|
||||
alt={tooltip + " icon"}
|
||||
style={!style ? {} : style}
|
||||
/>
|
||||
</a>
|
||||
</ButtonBase>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const websiteIconStyle = {
|
||||
backgroundColor: "white",
|
||||
borderRadius: "50%",
|
||||
};
|
||||
const ensIconStyle = {
|
||||
borderRadius: "50%",
|
||||
};
|
||||
|
||||
const hasEnsMetadata = () => {
|
||||
return (
|
||||
currentEnsMetadata.url ||
|
||||
currentEnsMetadata.twitter ||
|
||||
currentEnsMetadata.github
|
||||
);
|
||||
};
|
||||
|
||||
const renderIcons = () => {
|
||||
return (
|
||||
<>
|
||||
{currentEnsMetadata.url ? (
|
||||
renderIcon(
|
||||
WebsiteIcon,
|
||||
currentEnsMetadata.url,
|
||||
"Website",
|
||||
websiteIconStyle
|
||||
)
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{currentEnsMetadata.twitter ? (
|
||||
renderIcon(TwitterIcon, currentEnsMetadata.twitter, "Twitter")
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{currentEnsMetadata.github ? (
|
||||
renderIcon(GithubIcon, currentEnsMetadata.github, "Github")
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{!hasEnsMetadata() ? (
|
||||
renderIcon(OpenSeaIcon, getOpenSeaUri(getEnsName()), "OpenSea")
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{!hasEnsMetadata() ? (
|
||||
renderIcon(
|
||||
EnsIcon,
|
||||
getEnsDetailsUri(getEnsName()),
|
||||
"ENS",
|
||||
ensIconStyle
|
||||
)
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<div className="App-header container">
|
||||
<div className="col">
|
||||
<div className="col" style={{ display: "none" }}>
|
||||
<div className="row"></div>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
href="https://icons8.com/icon/63807/website"
|
||||
>
|
||||
Website
|
||||
</a>
|
||||
icon by
|
||||
<a target="_blank" rel="noreferrer" href="https://icons8.com">
|
||||
Icons8
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="App-body container align-self-center">
|
||||
@@ -182,39 +311,7 @@ function App() {
|
||||
? renderLoadingRipple()
|
||||
: renderCardContent()}
|
||||
<CardActions sx={{ marginBottom: 1, marginTop: 1 }}>
|
||||
<div style={{ margin: "auto" }}>
|
||||
<ButtonBase
|
||||
sx={{
|
||||
marginRight: 2,
|
||||
}}
|
||||
>
|
||||
<a
|
||||
href={getOpenSeaUri(getEnsName())}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
src={OpenSeaIcon}
|
||||
className="icon-size"
|
||||
alt="opensea logo"
|
||||
/>
|
||||
</a>
|
||||
</ButtonBase>
|
||||
<ButtonBase>
|
||||
<a
|
||||
href={getEnsDetailsUri(getEnsName())}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
src={EnsIcon}
|
||||
className="icon-size"
|
||||
style={{ borderRadius: "50%" }}
|
||||
alt="ens logo"
|
||||
/>
|
||||
</a>
|
||||
</ButtonBase>
|
||||
</div>
|
||||
<div style={{ margin: "auto" }}>{renderIcons()}</div>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user