-
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
219 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,19 @@ | ||
import './index.css'; | ||
import './index.css' | ||
// imd | ||
import { Navbar, Welcome, Footer, Services, Transactions } from './components'; | ||
import { Navbar, Welcome, Footer, Services, Transactions } from './components' | ||
|
||
const App = () => { | ||
return ( | ||
<div className='min-h-screen'> | ||
<div className='gradient-bg-welcome'> | ||
<Navbar /> | ||
<Welcome /> | ||
</div> | ||
<Services /> | ||
<Transactions /> | ||
<Footer /> | ||
</div> | ||
); | ||
}; | ||
return ( | ||
<div className="min-h-screen"> | ||
<div className="gradient-bg-welcome"> | ||
<Navbar /> | ||
<Welcome /> | ||
</div> | ||
<Services /> | ||
<Transactions /> | ||
<Footer /> | ||
</div> | ||
) | ||
} | ||
|
||
export default App; | ||
export default App |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React from 'react' | ||
import { render, fireEvent, waitFor, screen } from '@testing-library/react' | ||
import Welcome from '../components/Welcome' | ||
|
||
describe('Welcome', () => { | ||
test('renders', () => { | ||
render(<Welcome />) | ||
screen.debug() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 175 additions & 23 deletions
198
blockchain-app/client/src/context/TransactionContext.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,183 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { ethers } from 'ethers'; | ||
import { contractABI, contractAddress } from '../utils/constants'; | ||
/* eslint-disable no-undef */ | ||
import React, { useEffect, useState } from 'react' | ||
import { ethers } from 'ethers' | ||
import { contractABI, contractAddress } from '../utils/constants' | ||
|
||
// create a context for transactions with no default value | ||
export const TransactionContext = React.createContext(); | ||
export const TransactionContext = React.createContext() | ||
|
||
// window.ethereum is enabled thanks to our Metamask extension | ||
const { ethereum } = window; | ||
const { ethereum } = window | ||
|
||
const getEthereumContract = () => { | ||
const provider = new ethers.providers.Web3Provider(ethereum); | ||
const signer = provider.getSigner(); | ||
const transactionContract = new ethers.Contract( | ||
contractAddress, | ||
contractABI, | ||
signer | ||
); | ||
const createEthereumContract = () => { | ||
const provider = new ethers.providers.Web3Provider(ethereum) | ||
const signer = provider.getSigner() | ||
const transactionContract = new ethers.Contract(contractAddress, contractABI, signer) | ||
|
||
console.log({ provider, signer, transactionContract }); | ||
}; | ||
return transactionContract | ||
} | ||
|
||
export const TransactionProvider = ({ children }) => { | ||
return ( | ||
// using TransactionContext defined above, .Provider allows us to set | ||
// a value to pass down to all of the children | ||
<TransactionContext.Provider value='test'> | ||
{children} | ||
</TransactionContext.Provider> | ||
); | ||
}; | ||
const [formData, setFormData] = useState({ | ||
addressTo: '', | ||
amount: '', | ||
keyword: '', | ||
message: '', | ||
}) | ||
const [currentAccount, setCurrentAccount] = useState('') | ||
const [isLoading, setIsLoading] = useState(false) | ||
const [transactionCount, setTransactionCount] = useState( | ||
localStorage.getItem('transactionCount') | ||
) | ||
const [transactions, setTransactions] = useState([]) | ||
|
||
const handleChange = (e, name) => { | ||
setformData((prevState) => ({ ...prevState, [name]: e.target.value })) | ||
} | ||
|
||
const getAllTransactions = async () => { | ||
try { | ||
if (ethereum) { | ||
const transactionsContract = createEthereumContract() | ||
|
||
const availableTransactions = await transactionsContract.getAllTransactions() | ||
|
||
const structuredTransactions = availableTransactions.map((transaction) => ({ | ||
addressTo: transaction.receiver, | ||
addressFrom: transaction.sender, | ||
timestamp: new Date(transaction.timestamp.toNumber() * 1000).toLocaleString(), | ||
message: transaction.message, | ||
keyword: transaction.keyword, | ||
amount: parseInt(transaction.amount._hex) / 10 ** 18, | ||
})) | ||
|
||
console.log(structuredTransactions) | ||
|
||
setTransactions(structuredTransactions) | ||
} else { | ||
console.log('Ethereum is not present') | ||
} | ||
} catch (error) { | ||
console.log(error) | ||
} | ||
} | ||
|
||
const isWalletConnected = async () => { | ||
try { | ||
if (!ethereum) return alert('Please install MetaMask.') | ||
|
||
const accounts = await ethereum.request({ method: 'eth_accounts' }) | ||
|
||
if (accounts.length) { | ||
setCurrentAccount(accounts[0]) | ||
|
||
getAllTransactions() | ||
} else { | ||
console.log('No accounts found') | ||
} | ||
} catch (error) { | ||
console.log(error) | ||
} | ||
} | ||
|
||
const connectWallet = async () => { | ||
try { | ||
if (!ethereum) return alert('Please install MetaMask.') | ||
|
||
const accounts = await ethereum.request({ method: 'eth_requestAccounts' }) | ||
|
||
setCurrentAccount(accounts[0]) | ||
window.location.reload() | ||
} catch (error) { | ||
console.log(error) | ||
|
||
throw new Error('No ethereum object') | ||
} | ||
} | ||
|
||
const doesTransactionExist = async () => { | ||
try { | ||
if (ethereum) { | ||
const transactionsContract = createEthereumContract() | ||
const currentTransactionCount = await transactionsContract.getTransactionCount() | ||
|
||
window.localStorage.setItem('transactionCount', currentTransactionCount) | ||
} | ||
} catch (error) { | ||
console.log(error) | ||
|
||
throw new Error('No ethereum object') | ||
} | ||
} | ||
|
||
const sendTransaction = async () => { | ||
try { | ||
if (ethereum) { | ||
const { addressTo, amount, keyword, message } = formData | ||
const transactionsContract = createEthereumContract() | ||
const parsedAmount = ethers.utils.parseEther(amount) | ||
|
||
await ethereum.request({ | ||
method: 'eth_sendTransaction', | ||
params: [ | ||
{ | ||
from: currentAccount, | ||
to: addressTo, | ||
gas: '0x5208', | ||
value: parsedAmount._hex, | ||
}, | ||
], | ||
}) | ||
|
||
const transactionHash = await transactionsContract.addToBlockchain( | ||
addressTo, | ||
parsedAmount, | ||
message, | ||
keyword | ||
) | ||
|
||
setIsLoading(true) | ||
console.log(`Loading - ${transactionHash.hash}`) | ||
await transactionHash.wait() | ||
console.log(`Success - ${transactionHash.hash}`) | ||
setIsLoading(false) | ||
|
||
const transactionsCount = await transactionsContract.getTransactionCount() | ||
|
||
setTransactionCount(transactionsCount.toNumber()) | ||
window.location.reload() | ||
} else { | ||
console.log('No ethereum object') | ||
} | ||
} catch (error) { | ||
console.log(error) | ||
|
||
throw new Error('No ethereum object') | ||
} | ||
} | ||
|
||
// runs after the component is rendered | ||
useEffect(() => { | ||
isWalletConnected() | ||
doesTransactionExist() | ||
}, [transactionCount]) | ||
|
||
return ( | ||
// using TransactionContext defined above, .Provider allows us to set | ||
// a value to pass down to all of the children | ||
<TransactionContext.Provider | ||
value={{ | ||
transactionCount, | ||
connectWallet, | ||
transactions, | ||
currentAccount, | ||
isLoading, | ||
sendTransaction, | ||
handleChange, | ||
formData, | ||
}} | ||
> | ||
{children} | ||
</TransactionContext.Provider> | ||
) | ||
} |