first cut at eth wallet integration
Gitea Actions Demo / Explore-Gitea-Actions (push) Failing after 32s Details

This commit is contained in:
Ladd Hoffman 2024-03-07 10:58:55 -06:00
parent 0367428fa9
commit c909f43310
6 changed files with 49 additions and 201 deletions

View File

@ -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 (
<>
<Connect setPublicKey={setPublicKey} />
<div>
{publicKey !== null && (
<>
Wallet connected:
{' '}
{publicKey}
<br />
<UpdateMessage publicKey={publicKey} />
<QueryMessage />
<br />
<QueryRepBalance publicKey={publicKey} />
</>
{!window.ethereum && (
<>
Please download Metamask
</>
)}
{window.ethereum && (
<>
{/* Button to trigger Metamask connection */}
<button type="button" onClick={() => connectMetamask()}>Connect to Metamask</button>
{/* Button to disconnect Metamask */}
<button type="button" onClick={() => disconnectMetamask()}>Disconnect from Metamask</button>
{/* Display the connected account */}
{connectedAccounts.map(
(connectedAccount) => <h2 key={connectedAccount}>{connectedAccount}</h2>,
)}
</div>
</>
)}
</>
);
}

View File

@ -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 (
<>
<button type="button" onClick={() => connectToWallet(props)}>Connect Wallet</button>
<button type="button" onClick={() => disconnect(props)}>Disconnect</button>
</>
);
}
export default Connect;

View File

@ -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 <button type="button" onClick={() => queryMessage(props)}>Query Message</button>;
}
export default QueryMessage;

View File

@ -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 <button type="button" onClick={() => queryRepBalance(props)}>Query REP Balance</button>;
}
export default QueryRepBalance;

View File

@ -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 (
<>
<input
id="message"
type="text"
value={message}
onChange={(e) => {
setMessage(e.target.value);
}}
/>
<button type="button" onClick={() => updateMessage(props, message)}>Update Message</button>
</>
);
}
export default UpdateMessage;

View File

@ -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;