diff --git a/src/Accounts.js b/src/Accounts.js new file mode 100644 index 00000000..c280def7 --- /dev/null +++ b/src/Accounts.js @@ -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 ( +
+ + +

+ {showBalance ? ( + `This wallet has a balance of ${balance} ETH` + ) : ( +
+ )} +
+ ); +}; + +export default Accounts; \ No newline at end of file diff --git a/src/App.css b/src/App.css index 74b5e053..94c9b67c 100644 --- a/src/App.css +++ b/src/App.css @@ -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; +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 4c073522..1107057a 100644 --- a/src/App.js +++ b/src/App.js @@ -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 @@ -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. // @@ -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 ( +
+
+

Ethereum BlockExplorer

+
+
+
+ Block Number: {blockInfo === undefined ? "Pending..." : blockNumber} +
+

+
+ Block Timestamp:{" "} + {blockInfo === undefined + ? "Pending..." + : getTime(blockInfo.timestamp)} +
+

+
+ Amount of Transactions:{" "} + {blockInfo === undefined + ? "Pending..." + : blockInfo.transactions.length} +
+

- return
Block Number: {blockNumber}
; +
+ Gas Used:{" "} + {blockInfo === undefined + ? "Pending..." + : parseInt(blockInfo.gasUsed._hex)} +
+

+ + + +
+ {showAccount ? :
} + {showTransactions ? ( + + ) : ( +
+ )} +
+ ); } -export default App; +export default App; \ No newline at end of file diff --git a/src/MoreInfoTx.js b/src/MoreInfoTx.js new file mode 100644 index 00000000..b3f78ebc --- /dev/null +++ b/src/MoreInfoTx.js @@ -0,0 +1,11 @@ +export const MoreInfoTx = (props) => { + return ( +
+
From: {props.from}
+
To: {props.to}
+
Amount: {props.amount} ETH
+
+ ); +}; + +export default MoreInfoTx; \ No newline at end of file diff --git a/src/Transactions.js b/src/Transactions.js new file mode 100644 index 00000000..cc5feaf8 --- /dev/null +++ b/src/Transactions.js @@ -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 ( +
+

Transactions:

+ {props.txs.map((el, i) => { + return ( + + ); + })} +
+ ) +} + +export default Transactions; \ No newline at end of file