Skip to content

Commit

Permalink
feat: web3js demo
Browse files Browse the repository at this point in the history
  • Loading branch information
sanyu1225 committed Sep 6, 2023
1 parent c7d004d commit c680478
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 216 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { FC, ReactNode } from 'react';
import { isEmpty } from '../utils';
interface ButtonWithResultProps {
action: () => void;
result?: any;
label: string;
resultIsJson?: boolean;
children?: ReactNode;
}

const ButtonWithResult: FC<ButtonWithResultProps> = ({
action,
result = '',
label,
resultIsJson = false,
children,
}) => {
function replacer(key: string, value: any) {
if (typeof value === 'bigint') {
return {
type: 'bigint',
value: value.toString(),
};
} else {
return value;
}
}
const resultString = (result: any) => JSON.stringify(result, replacer);

return (
<>
<div>
<button onClick={action}>
<span>{label}</span>
</button>
{children}
</div>
{!isEmpty(result) && (
<code>
{label}: {resultIsJson ? resultString(result) : result}
</code>
)}
</>
);
};

export default ButtonWithResult;
215 changes: 145 additions & 70 deletions examples/with-web3js-playground/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,65 @@
import Head from "next/head";
import { useState } from "react";
import { web3, bloctoSDK } from "../services/ethereum";

/* eslint-disable @typescript-eslint/ban-ts-comment */
import Head from 'next/head';
import { useState } from 'react';
import { web3, bloctoSDK } from '../services/ethereum';
import ButtonWithResult from '../components/ButtonWithResult';
const userOp = {
sender: "0x9fd042a18e90ce326073fa70f111dc9d798d9a52",
nonce: "123",
init_code: "0x68656c6c6f",
call_data: "0x776F726C64",
call_gas_limit: "1000",
verification_gas_limit: "2300",
pre_verification_gas: "3100",
max_fee_per_gas: "8500",
max_priority_fee_per_gas: "1",
paymaster_and_data: "0x626c6f63746f",
signature: "0x636c656d656e74",
sender: '0x9fd042a18e90ce326073fa70f111dc9d798d9a52',
nonce: '123',
initCode: '0x68656c6c6f',
callData: '0x776F726C64',
callGasLimit: '1000',
verificationGasLimit: '2300',
preVerificationGas: '3100',
maxFeePerGas: '8500',
maxPriorityFeePerGas: '1',
paymasterAndData: '0x626c6f63746f',
signature: '0x636c656d656e74',
};

const callData =
'b61d27f600000000000000000000000000005ea00ac477b1030ce78506496e8c2de24bf5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000084161ac21f000000000000000000000000fd8ec18d48ac1f46b600e231da07d1da8209ceef0000000000000000000000000000a26b00c1f0df003000390027140000faa7190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000';

export default function Home() {
const [address, setAddress] = useState<undefined | string>(undefined);
const [userOpHash, setUserOpHash] = useState<string>("");
const [estimateUserOpHash, setEstimateUserOpHash] = useState<string>("");
const [userOpByHash, setUserOpByHash] = useState<string>("");
const [userOpHash, setUserOpHash] = useState<string>('');
const [estimateUserOpHash, setEstimateUserOpHash] = useState<string>('');
const [userOpByHash, setUserOpByHash] = useState<string>('');
const [entryPoint, setEntryPoint] = useState<string[]>([]);
const [userOpReceipt, setUserOpReceipt] = useState<string>("");
const [chainId, setChainId] = useState();
const [userOpReceipt, setUserOpReceipt] = useState<string>('');
const [generateUserOpHash, setGenerateUserOpHash] = useState<string>('');
const [userOpHashInput, setUserOpHashInput] = useState<string>('');
const [userOperationReceiptInput, setUserOperationReceiptInput] =
useState<string>('');

const connectHandler = async () => {
const accounts = await bloctoSDK?.ethereum?.enable();
const [addr] = accounts || [];
setAddress(addr);
};

const disconnectHandler = async () => {
await bloctoSDK?.ethereum?.request({ method: "wallet_disconnect" });
await bloctoSDK?.ethereum?.request({ method: 'wallet_disconnect' });
setAddress(undefined);
setUserOpHash("");
setUserOpHash('');
};

const getChainId = async () => {
try {
const result = await web3.eth.getChainId();
setChainId(result.toString());
} catch (error) {
console.error('error: ', error);
}
};

const getEntryPoint = async () => {
try {
const result = await web3.eth.supportedEntryPoints();
setEntryPoint(result);
} catch (error) {
console.error("error: ", error);
console.error('error: ', error);
}
};

Expand All @@ -49,18 +68,27 @@ export default function Home() {
if (entryPoint.length === 0) {
await getEntryPoint();
}
const result = await web3.eth.sendUserOperation(userOp, entryPoint[0]);
const result = await web3.eth.sendUserOperation(
// @ts-ignore
{
callData,
},
entryPoint[0]
);
setUserOpHash(result);
} catch (error) {
console.error("sendUserOp error", error);
console.error('sendUserOp error', error);
}
};

const getUserOperationReceipt = async () => {
try {
const result = await web3.eth.getUserOperationReceipt(userOpHash);
const result = await web3.eth.getUserOperationReceipt(
userOperationReceiptInput
);
setUserOpReceipt(result);
} catch (error) {
console.error("error: ", error);
console.error('error: ', error);
}
};

Expand All @@ -70,22 +98,47 @@ export default function Home() {
await getEntryPoint();
}
const result = await web3.eth.estimateUserOperationGas(
userOp,
{ ...userOp, sender: address, callData },
entryPoint[0]
);
console.log('result: ', result);
setEstimateUserOpHash(result);
} catch (error) {
console.error("estimateUserOpGas error: ", error);
console.error('estimateUserOpGas error: ', error);
}
};

const getUserOpByHash = async () => {
if (!userOpHashInput) {
return console.error('userOpHashInput is not defined');
}
try {
const result = await web3.eth.getUserOperationByHash(userOpHashInput);
if (result) {
console.log('result: ', result);
setUserOpByHash(result);
}
} catch (error) {
console.error('getUserOpByHash error: ', error);
}
};

const generateUserOpHashHandler = async () => {
try {
const result = await web3.eth.getUserOperationByHash(userOpHash);
setUserOpByHash(result);
console.log("result: ", result);
if (!chainId) {
throw new Error('chainId is not defined');
}
if (!entryPoint[0]) {
throw new Error('entryPoint is not defined');
}
const result = await web3.eth.generateUserOpHash(
userOp,
entryPoint[0],
chainId
);
setGenerateUserOpHash(result);
} catch (error) {
console.error("getUserOpByHash error: ", error);
console.error('generateUserOpHashHandler error: ', error);
}
};

Expand All @@ -99,45 +152,67 @@ export default function Home() {
</Head>
<main>
{address ? (
<>
<button onClick={disconnectHandler}>
<span>disconnect</span>
</button>
<button onClick={getEntryPoint}>
<span>getEntryPoint</span>
</button>
{entryPoint.length > 0 && (
<code>entryPoint: {JSON.stringify(entryPoint)}</code>
)}
<button onClick={sendUserOp}>
<span>sendUserOp</span>
</button>
{userOpHash && (
<code>userOpHash: {JSON.stringify(userOpHash)}</code>
)}
<button onClick={estimateUserOpGas}>
<span>estimateUserOpGas</span>
</button>
{estimateUserOpHash && (
<code>userOpHash: {JSON.stringify(estimateUserOpHash)}</code>
)}
<button onClick={getUserOpByHash}>
<span>getUserOpByHash</span>
</button>
{userOpByHash && (
<code>getUserOpByHash: {JSON.stringify(userOpByHash)}</code>
)}
<button onClick={getUserOperationReceipt}>
<span>getUserOpReceipt</span>
</button>
{userOpReceipt && (
<code>UserOpReceipt: {JSON.stringify(userOpReceipt)}</code>
)}
</>
<div>
<div className="connect_btn">
<ButtonWithResult action={disconnectHandler} label="Disconnect" />
</div>
<div className="grid">
<ButtonWithResult
action={getChainId}
result={chainId}
label="getChainId"
/>
<ButtonWithResult
action={getEntryPoint}
result={entryPoint}
label="getEntryPoint"
/>
<ButtonWithResult
action={sendUserOp}
result={userOpHash}
label="sendUserOp"
/>
<ButtonWithResult
action={estimateUserOpGas}
result={estimateUserOpHash}
label="estimateUserOpGas"
resultIsJson
/>
<ButtonWithResult
action={getUserOpByHash}
result={userOpByHash}
label="getUserOpByHash"
resultIsJson
>
<input
value={userOpHashInput}
placeholder="please input userOpHash"
onChange={(e) => setUserOpHashInput(e.target.value)}
/>
</ButtonWithResult>
<ButtonWithResult
action={getUserOperationReceipt}
result={userOpReceipt}
label="getUserOpReceipt"
resultIsJson
>
<input
value={userOperationReceiptInput}
placeholder="hash a userOpHash value returned by eth_sendUserOperation"
onChange={(e) => setUserOperationReceiptInput(e.target.value)}
/>
</ButtonWithResult>
<ButtonWithResult
action={generateUserOpHashHandler}
result={generateUserOpHash}
label="genUserOpHash"
/>
</div>
</div>
) : (
<button onClick={connectHandler}>
<span>connect</span>
</button>
<div className="connect_btn">
<ButtonWithResult action={connectHandler} label="Connect" />
</div>
)}
</main>
</>
Expand Down
22 changes: 22 additions & 0 deletions examples/with-web3js-playground/src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,25 @@ button span:hover:before {
button span:hover:after {
width: 100%;
}

.connect_btn {
position: fixed;
top: 20px;
right: 20px;
}

code {
padding: 0 20px;
}

input {
width: 400px;
height: 25px;
}

.grid {
display: grid;
grid-auto-flow: row;
grid-gap: 1rem;
margin-top: 1rem;
}
Loading

0 comments on commit c680478

Please sign in to comment.