From c909f43310b6433f0b358c6fff8b743b3d957bfb Mon Sep 17 00:00:00 2001 From: Ladd Hoffman Date: Thu, 7 Mar 2024 10:58:55 -0600 Subject: [PATCH] first cut at eth wallet integration --- client/src/App.jsx | 68 +++++++++++++++++++++--------- client/src/Connect.jsx | 50 ---------------------- client/src/QueryMessage.jsx | 18 -------- client/src/QueryRepBalance.jsx | 22 ---------- client/src/UpdateMessage.jsx | 76 ---------------------------------- client/src/casper-wallet.js | 16 ------- 6 files changed, 49 insertions(+), 201 deletions(-) delete mode 100644 client/src/Connect.jsx delete mode 100644 client/src/QueryMessage.jsx delete mode 100644 client/src/QueryRepBalance.jsx delete mode 100644 client/src/UpdateMessage.jsx delete mode 100644 client/src/casper-wallet.js diff --git a/client/src/App.jsx b/client/src/App.jsx index 58a8a6d..3bfbbea 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -1,29 +1,59 @@ import { useState } from 'react'; -import Connect from './Connect'; -import UpdateMessage from './UpdateMessage'; -import QueryMessage from './QueryMessage'; -import QueryRepBalance from './QueryRepBalance'; +import { Web3 } from 'web3'; import './App.css'; function App() { - const [publicKey, setPublicKey] = useState(null); + // react state to store and show the connected account + const [connectedAccounts, setConnectedAccounts] = useState([]); + + async function connectMetamask() { + // instantiate Web3 with the injected provider + const web3 = new Web3(window.ethereum); + + // request user to connect accounts (Metamask will prompt) + await window.ethereum.request({ method: 'eth_requestAccounts' }); + + // get the connected accounts + const accounts = await web3.eth.getAccounts(); + + // show the first connected account in the react page + setConnectedAccounts(accounts); + } + + async function disconnectMetamask() { + await window.ethereum.request({ + method: 'wallet_revokePermissions', + params: [ + { + eth_accounts: {}, + }, + ], + }); + + setConnectedAccounts([]); + } + return ( <> - -
- {publicKey !== null && ( - <> - Wallet connected: - {' '} - {publicKey} -
- - -
- - + {!window.ethereum && ( + <> + Please download Metamask + + )} + {window.ethereum && ( + <> + {/* Button to trigger Metamask connection */} + + + {/* Button to disconnect Metamask */} + + + {/* Display the connected account */} + {connectedAccounts.map( + (connectedAccount) =>

{connectedAccount}

, )} -
+ + )} ); } diff --git a/client/src/Connect.jsx b/client/src/Connect.jsx deleted file mode 100644 index 6e9e88b..0000000 --- a/client/src/Connect.jsx +++ /dev/null @@ -1,50 +0,0 @@ -import getProvider from './casper-wallet'; - -const provider = getProvider(); - -const connectToWallet = (props) => { - provider - .requestConnection() - .then((connected) => { - if (!connected) { - alert("Couldn't connect to wallet"); - } else { - provider - .getActivePublicKey() - .then((publicKey) => { - props.setPublicKey(publicKey); - }) - .catch((error) => { - alert(error.message); - }); - } - }) - .catch((error) => { - alert(error.message); - }); -}; - -const disconnect = (props) => { - provider - .disconnectFromSite() - .then((disconnected) => { - if (disconnected) { - props.setPublicKey(null); - alert('Disconnected'); - } - }) - .catch((error) => { - alert(error.message); - }); -}; - -function Connect(props) { - return ( - <> - - - - ); -} - -export default Connect; diff --git a/client/src/QueryMessage.jsx b/client/src/QueryMessage.jsx deleted file mode 100644 index 2dc2d3e..0000000 --- a/client/src/QueryMessage.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import axios from 'axios'; - -const queryMessage = () => { - axios - .get('/api/queryMessage') - .then((response) => { - alert(response.data); - }) - .catch((error) => { - console.error(error.message); - }); -}; - -function QueryMessage(props) { - return ; -} - -export default QueryMessage; diff --git a/client/src/QueryRepBalance.jsx b/client/src/QueryRepBalance.jsx deleted file mode 100644 index 9e8dc16..0000000 --- a/client/src/QueryRepBalance.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import axios from 'axios'; -import { CLPublicKey, CLValueParsers, encodeBase64 } from 'casper-js-sdk'; - -const queryRepBalance = (props) => { - const accountKeyBytes = CLValueParsers.toBytes(CLPublicKey.fromHex(props.publicKey)).unwrap(); - console.log('accountKeyBytes', accountKeyBytes); - const b64accountKey = encodeBase64(accountKeyBytes); - axios - .get(`/api/repBalance?account=${b64accountKey}`) - .then((response) => { - alert(response.data); - }) - .catch((error) => { - console.error(error.message); - }); -}; - -function QueryRepBalance(props) { - return ; -} - -export default QueryRepBalance; diff --git a/client/src/UpdateMessage.jsx b/client/src/UpdateMessage.jsx deleted file mode 100644 index 6e08c02..0000000 --- a/client/src/UpdateMessage.jsx +++ /dev/null @@ -1,76 +0,0 @@ -import { useState } from 'react'; -import { - Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil, -} from 'casper-js-sdk'; -import axios from 'axios'; -import { contracts, networkName } from 'backend/src/config'; -import getProvider from './casper-wallet'; - -const provider = getProvider(); - -const updateMessage = (props, message) => { - const contract = new Contracts.Contract(); - contract.setContractHash(contracts.availability); - const runtimeArguments = RuntimeArgs.fromMap({ - message: CLValueBuilder.string(message), - }); - const deploy = contract.callEntrypoint( - 'list_append', - runtimeArguments, - CLPublicKey.fromHex(props.publicKey), - networkName, - '1000000000', // 1 CSPR (10^9 Motes) - ); - const deployJSON = DeployUtil.deployToJson(deploy); - // Initiates sign request - provider - .sign(JSON.stringify(deployJSON), props.publicKey) - .then((res) => { - if (res.cancelled) { - alert('Signing cancelled'); - } else { - const signedDeploy = DeployUtil.setSignature( - deploy, - res.signature, - CLPublicKey.fromHex(props.publicKey), - ); - console.log('signedDeploy:', signedDeploy); - console.log('signedDeploy json:', DeployUtil.deployToJson(signedDeploy)); - - axios - .post('/api/sendDeploy', DeployUtil.deployToJson(signedDeploy), { - headers: { - 'Content-Type': 'application/json', - }, - }) - .then((response) => { - alert(response.data); - }) - .catch((error) => { - console.error(error.message); - }); - } - }) - .catch((error) => { - console.error(error.message); - }); -}; - -function UpdateMessage(props) { - const [message, setMessage] = useState(''); - - return ( - <> - { - setMessage(e.target.value); - }} - /> - - - ); -} -export default UpdateMessage; diff --git a/client/src/casper-wallet.js b/client/src/casper-wallet.js deleted file mode 100644 index c4a4f15..0000000 --- a/client/src/casper-wallet.js +++ /dev/null @@ -1,16 +0,0 @@ -// Timeout (in ms) for requests to the extension [DEFAULT: 30 min] -const REQUESTS_TIMEOUT_MS = 30 * 60 * 1000; - -const getProvider = () => { - const providerConstructor = window.CasperWalletProvider; - if (providerConstructor === undefined) { - alert('Casper Wallet extension is not installed!'); - return null; - } - const provider = providerConstructor({ - timeout: REQUESTS_TIMEOUT_MS, - }); - return provider; -}; - -export default getProvider;