Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

creating an ethereum block-explorer #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/Accounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

import { Alchemy, Network } from "alchemy-sdk";
import { useState } from "react";
import { Utils } from "alchemy-sdk";

export const Accounts = () => {
const settings = {
apiKey: process.env.REACT_APP_ALCHEMY_API_KEY,
network: Network.ETH_MAINNET,
};

const alchemy = new Alchemy(settings);

let [balance, setBalance] = useState(null);
let [userAddress, setUserAddress] = useState("");
let [showBalance, setShowBalance] = useState(false);
let [showNFTs, setShowNFTs] = useState(false);
let [ownedNFTs, setOwnedNFTs] = useState(null);

async function getBalance(address) {
try {
let response = await alchemy.core.getBalance(address, "latest");
setBalance(Utils.formatEther(parseInt(response._hex).toString()));
if (showBalance === true) return;
else setShowBalance(!showBalance);
} catch {
alert("Error. This wallet probably doesn't exist.");
setShowBalance(false);
setShowNFTs(false);
}
}

async function getNFTs(address) {
try {
let response = await alchemy.nft.getNftsForOwner(address);
console.log(response);
setOwnedNFTs(response.totalCount);
if (showNFTs === true) return;
else setShowNFTs(!showNFTs);
} catch {
alert("Error. This wallet probably doesn't exist.");
setShowBalance(false);
setShowNFTs(false);
}
}

return (
<div className="accounts">
<label>
ETH Address:
<br></br>
<input
type="text"
placeholder="0x..."
onChange={(e) => {
setUserAddress(e.target.value);
}}
/>
</label>
<button
onClick={() => {
getBalance(userAddress);
}}
>
Get Balance
</button>
<br></br>
{showBalance ? (
`This wallet has a balance of ${balance} ETH`
) : (
<div></div>
)}
</div>
);
};

export default Accounts;
58 changes: 31 additions & 27 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
.App {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}

.App-logo {
height: 40vmin;
pointer-events: none;
.intro {
border-style: solid;
padding: 50px;
background-color: blanchedalmond;
margin-bottom: 40px;
display: flex;
flex-direction: column;
}

@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
button {
max-width: 200px;
margin-bottom: 10px;
margin-left: 20px;
padding: 10px;
}

.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}

.App-link {
color: #61dafb;
.accounts {
border-color: black;
border-style: solid;
padding: 20px;
margin-bottom: 30px;
background-color: gold;
}

@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
.transactions {
border-color: black;
padding: 10px;
background-color: blanchedalmond;
border-style: solid;
}

input {
width: 330px;
}
111 changes: 102 additions & 9 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Alchemy, Network } from 'alchemy-sdk';
import { useEffect, useState } from 'react';
import { Alchemy, Network } from "alchemy-sdk";
import { useEffect, useState } from "react";
import Transactions from "./Transactions";
import Accounts from "./Accounts";

import './App.css';
import "./App.css";

// Refer to the README doc for more information about using API
// keys in client-side code. You should never do this in production
Expand All @@ -11,7 +13,6 @@ const settings = {
network: Network.ETH_MAINNET,
};


// In this week's lessons we used ethers.js. Here we are using the
// Alchemy SDK is an umbrella library with several different packages.
//
Expand All @@ -20,17 +21,109 @@ const settings = {
const alchemy = new Alchemy(settings);

function App() {
const [blockNumber, setBlockNumber] = useState();
const [blockNumber, setBlockNumber] = useState("");
const [blockInfo, setBlockInfo] = useState();
const [showTransactions, setShowTransactions] = useState(false);
const [showAccount, setShowAccount] = useState(false);

useEffect(() => {
async function getBlockNumber() {
setBlockNumber(await alchemy.core.getBlockNumber());
try {
setBlockNumber(await alchemy.core.getBlockNumber());
} catch {
console.log("Could not get most recent block");
}
}

async function getBlockInfo() {
try {
setBlockInfo(await alchemy.core.getBlock(blockNumber));
} catch {
console.log("Could not get block information");
}
}
getBlockNumber();
});
getBlockInfo();
}, [blockNumber]);

function getTime(timestamp) {
let unix_timestamp = timestamp;
// Create a new JavaScript Date object based on the timestamp
// multiplied by 1000 so that the argument is in milliseconds, not seconds.
var date = new Date(unix_timestamp * 1000);
// Hours part from the timestamp
var hours = date.getHours();
// Minutes part from the timestamp
var minutes = "0" + date.getMinutes();
// Seconds part from the timestamp
var seconds = "0" + date.getSeconds();
// Will display time in 10:30:23 format
var formattedTime = hours + ":" + minutes + ":" + seconds.slice(1, 3);
return formattedTime;
}

return (
<div className="App">
<div>
<h1> Ethereum BlockExplorer</h1>
</div>
<div className="intro">
<div>
Block Number: {blockInfo === undefined ? "Pending..." : blockNumber}
</div>
<br></br>
<div>
Block Timestamp:{" "}
{blockInfo === undefined
? "Pending..."
: getTime(blockInfo.timestamp)}
</div>
<br></br>
<div>
Amount of Transactions:{" "}
{blockInfo === undefined
? "Pending..."
: blockInfo.transactions.length}
</div>
<br></br>

return <div className="App">Block Number: {blockNumber}</div>;
<div>
Gas Used:{" "}
{blockInfo === undefined
? "Pending..."
: parseInt(blockInfo.gasUsed._hex)}
</div>
<br></br>
<button
onClick={() => {
setBlockNumber("Pending...");
}}
>
Get Latest Block
</button>
<button
onClick={() => {
setShowTransactions(!showTransactions);
}}
>
Show Transactions
</button>
<button
onClick={() => {
setShowAccount(!showAccount);
}}
>
Account Information
</button>
</div>
{showAccount ? <Accounts /> : <div></div>}
{showTransactions ? (
<Transactions txs={blockInfo.transactions} />
) : (
<div></div>
)}
</div>
);
}

export default App;
export default App;
11 changes: 11 additions & 0 deletions src/MoreInfoTx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const MoreInfoTx = (props) => {
return (
<div>
<div>From: {props.from}</div>
<div>To: {props.to}</div>
<div>Amount: {props.amount} ETH</div>
</div>
);
};

export default MoreInfoTx;
57 changes: 57 additions & 0 deletions src/Transactions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Alchemy, Network } from "alchemy-sdk";
import { Utils } from "alchemy-sdk";
import { useState } from "react";
import MoreInfoTx from "./MoreInfoTx";

export const Transactions = (props) => {
let i = 0;

const settings = {
apiKey: process.env.REACT_APP_ALCHEMY_API_KEY,
network: Network.ETH_MAINNET,
};

const alchemy = new Alchemy(settings);

const [from, setFrom] = useState("");
const [to, setTo] = useState("");
const [amount, setAmount] = useState(0);
const [selectedIndex, setSelected] = useState(null)

async function getMoreInfo(hash) {
try {
const response = await alchemy.core.getTransaction(hash)
setFrom(response.from);
setTo(response.to);
setAmount(Utils.formatEther(parseInt(response.value._hex).toString()));
setSelected(hash);
} catch {
alert("something went wrong")
}
}

return (
<div className="transactions">
<h1>Transactions:</h1>
{props.txs.map((el, i) => {
return (
<ul key={i}>
{el}{" "}
<button
onClick={() => {
getMoreInfo(el);
}}
>
More Info
</button>
{selectedIndex === el && (
<MoreInfoTx from={from} to={to} amount={amount} />
)}
</ul>
);
})}
</div>
)
}

export default Transactions;