Merge branch 'main' of github.com:web3well/eth-global-lisbon-hackathon

This commit is contained in:
jacque006
2023-05-14 01:48:14 +01:00
9 changed files with 173 additions and 86 deletions

View File

@@ -3,6 +3,8 @@ import SideBar from './components/Sidebar';
import Propose from './routes/Propose';
import Create from './routes/Create';
import Sign from './routes/Sign';
import Wallet from './routes/Wallet';
import Debug from './routes/Debug';
export default function App() {
return (
@@ -12,6 +14,8 @@ export default function App() {
<Route index element={<Create />} />
<Route path="propose" element={<Propose />} />
<Route path="sign" element={<Sign />} />
<Route path="wallet" element={<Wallet />} />
<Route path="debug" element={<Debug />} />
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>

View File

@@ -1,4 +1,4 @@
import { BigNumber, BigNumberish } from 'ethers';
import { BigNumber, BigNumberish, ethers } from 'ethers';
import {
SafeProxy,
SafeProxy__factory,
@@ -16,6 +16,7 @@ import { Signer } from '@ethersproject/abstract-signer';
import { BaseAccountAPI } from '@account-abstraction/sdk';
import { BaseApiParams } from '@account-abstraction/sdk/src/BaseAccountAPI';
import { TransactionDetailsForUserOp } from '@account-abstraction/sdk/src/TransactionDetailsForUserOp';
import { solG1 } from '@thehubbleproject/bls/dist/mcl';
/**
* constructor params, added no top of base params:
@@ -71,8 +72,11 @@ export class AccountAPI extends BaseAccountAPI {
);
}
setNextAggBlsSignature(sig: string) {
this.nextAggBlsSignature = sig;
setNextAggBlsSignature(sig: solG1) {
this.nextAggBlsSignature = ethers.utils.defaultAbiCoder.encode(
['uint256[2]'],
[sig],
);
}
async _getAccountContract(): Promise<SafeProxy> {

View File

@@ -1,6 +1,7 @@
import { BigNumber, ethers } from 'ethers';
import { FormEvent } from 'react';
import { BLSGroupVerifier__factory } from 'account-abstraction';
import AppContext from '../AppContext';
import createWallet from '../createWallet';
import { solG2 } from '@thehubbleproject/bls/dist/mcl';
interface CreateWalletFieldProps {
label: string;
@@ -10,28 +11,52 @@ interface CreateWalletFieldProps {
const SetupWalletField = ({ label, name }: CreateWalletFieldProps) => (
<div className="mt-6 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<div className="sm:col-span-4">
<label
htmlFor={name}
className="block text-sm font-medium leading-6 text-white"
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyItems: 'center',
justifyContent: 'center',
gap: '1rem',
}}
>
{label}
</label>
<div className="mt-2">
<input
id={name}
name={name}
type={name}
autoComplete={name}
className="block w-full rounded-md border-0 bg-white/5 py-1.5 text-white shadow-sm ring-1 ring-inset ring-white/10 focus:ring-2 focus:ring-inset focus:ring-indigo-500 sm:text-sm sm:leading-6"
/>
<div
style={{
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
}}
>
<label
htmlFor={name}
className="block text-sm font-medium leading-6 text-white"
style={{ textAlign: 'center', justifyContent: 'center' }}
>
{label}
</label>
</div>
<div
style={{
flexGrow: 1,
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
}}
>
<input
id={name}
name={name}
type={name}
autoComplete={name}
className="block w-full rounded-md border-0 bg-white/5 py-1.5 text-white shadow-sm ring-1 ring-inset ring-white/10 focus:ring-2 focus:ring-inset focus:ring-indigo-500 sm:text-sm sm:leading-6"
/>
</div>
</div>
</div>
</div>
);
export default function Page() {
const appContext = AppContext.use();
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
@@ -51,7 +76,7 @@ export default function Page() {
'public-key-5',
) as HTMLInputElement;
const pubKeys = [
const pubKeyStrings = [
pubKey1.value,
pubKey2.value,
pubKey3.value,
@@ -65,8 +90,18 @@ export default function Page() {
).deploy();
await blsGroupVerifier.deployed();
const setupGroup = await blsGroupVerifier.setupGroup([]);
await setupGroup.wait();
const pubKeys = pubKeyStrings
.filter((str) => str !== '')
.map(
(str) =>
ethers.utils.defaultAbiCoder
.decode(['uint256', 'uint256', 'uint256', 'uint256'], str)
.map((x: BigNumber) => x.toHexString()) as solG2,
);
const walletAddress = await createWallet(pubKeys);
location.href = `/wallet?address=${walletAddress}`;
};
return (
@@ -74,26 +109,26 @@ export default function Page() {
<div className="space-y-12">
<div className="border-b border-white/10 pb-12">
<h2 className="text-base font-semibold leading-7 text-white">
Setup Multi-sig
Create a Wallet
</h2>
<p className="mt-1 text-sm leading-6 text-gray-400">
Setup a Multi-sig wallet with a list of addresses and a threshold
Enter the BLS public keys that should have access to this wallet.
</p>
<SetupWalletField name="public-key-1" label="Signer public key 1" />
<SetupWalletField name="public-key-2" label="Signer public key 2" />
<SetupWalletField name="public-key-3" label="Signer public key 3" />
<SetupWalletField name="public-key-4" label="Signer public key 4" />
<SetupWalletField name="public-key-5" label="Signer public key 5" />
<SetupWalletField name="public-key-1" label="Key 1" />
<SetupWalletField name="public-key-2" label="Key 2" />
<SetupWalletField name="public-key-3" label="Key 3" />
<SetupWalletField name="public-key-4" label="Key 4" />
<SetupWalletField name="public-key-5" label="Key 5" />
</div>
</div>
<div className="mt-6 flex items-center justify-end gap-x-6">
<div className="mt-6 flex items-center gap-x-6">
<button
type="submit"
className="rounded-xl bg-green-500 px-4 py-2 text-lg font-semibold text-white shadow-sm hover:bg-green-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
>
Setup Wallet
Create
</button>
</div>
</form>

View File

@@ -6,23 +6,29 @@ import {
XMarkIcon,
WalletIcon,
PencilIcon,
BugAntIcon,
} from '@heroicons/react/24/outline';
import PublicKey from './PublicKey';
import { usePathname } from 'next/navigation';
import { Link, Outlet } from 'react-router-dom';
const navigation = [
{ name: 'Create Multi-sig', href: '/', icon: WalletIcon },
{ name: 'Create', href: '/', icon: WalletIcon },
{
name: 'Propose Transaction',
name: 'Propose',
href: '/propose',
icon: UsersIcon,
},
{
name: 'Sign Transaction',
name: 'Sign',
href: '/sign',
icon: PencilIcon,
},
{
name: 'Debug',
href: '/debug',
icon: BugAntIcon,
},
];
function classNames(...classes: string[]) {

View File

@@ -0,0 +1,5 @@
import { solG2 } from '@thehubbleproject/bls/dist/mcl';
export default async function createWallet(_publicKeys: solG2[]) {
return '0x0000006789000000000000000000001234001234';
}

View File

@@ -6,60 +6,9 @@ import AppContext from '../AppContext';
import { ethers } from 'ethers';
export default function Create() {
const appContext = AppContext.use();
return (
<div className="home">
<CreateWalletForm />
<div className="flex flex-col mt-10">
<h1 className="text-xl">OLD UI TO TEST BUNDLE</h1>
<p>Press the fund wallet button and then the new transaction button</p>
<p className="mt-8">Hardhat wallet: {appContext?.hhSigner.address}</p>
<p>
Hardhat balance:
{(() => {
const hhBalance = appContext?.hhBalance;
if (hhBalance === undefined) {
return '...';
}
return ethers.utils.formatEther(hhBalance);
})()}
</p>
<button
onClick={() => appContext?.fundWallet()}
className="p-2 rounded-lg bg-green-500"
>
Fund AA wallet
</button>
</div>
<div className="flex flex-col mt-8">
<div>
Smart Account Balance:{' '}
{(() => {
const balance = appContext?.balance;
if (balance === undefined) {
return '...';
}
return ethers.utils.formatEther(balance);
})()}
</div>
<div>Address: {appContext?.address}</div>
<div>
<NewTransactionButton provider={appContext?.aaProvider} />
</div>
</div>
<div>
<h2>Accounts</h2>
<div>0x1234</div>
<div>0x1234</div>
<div>0x1234</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,62 @@
import NewTransactionButton from '../components/NewTransactionButton';
import AppContext from '../AppContext';
import { ethers } from 'ethers';
export default function Page() {
const appContext = AppContext.use();
return (
<div>
<div className="flex flex-col mt-10">
<h1 className="text-xl">OLD UI TO TEST BUNDLE</h1>
<p>Press the fund wallet button and then the new transaction button</p>
<p className="mt-8">Hardhat wallet: {appContext?.hhSigner.address}</p>
<p>
Hardhat balance:
{(() => {
const hhBalance = appContext?.hhBalance;
if (hhBalance === undefined) {
return '...';
}
return ethers.utils.formatEther(hhBalance);
})()}
</p>
<button
onClick={() => appContext?.fundWallet()}
className="p-2 rounded-lg bg-green-500"
>
Fund AA wallet
</button>
</div>
<div className="flex flex-col mt-8">
<div>
Smart Account Balance:{' '}
{(() => {
const balance = appContext?.balance;
if (balance === undefined) {
return '...';
}
return ethers.utils.formatEther(balance);
})()}
</div>
<div>Address: {appContext?.address}</div>
<div>
<NewTransactionButton provider={appContext?.aaProvider} />
</div>
</div>
<div>
<h2>Accounts</h2>
<div>0x1234</div>
<div>0x1234</div>
<div>0x1234</div>
</div>
</div>
);
}

View File

@@ -4,6 +4,8 @@ import PaymentChannel, { Payment } from '../PaymentChannel';
import Transaction from '../components/Transaction';
import AppContext from '../AppContext';
import calculateSignaturesNeeded from '../utils/calculateSignaturesNeeded';
import { IERC20__factory } from '../ERC20/IERC20__factory';
import { AccountAPI } from '../account/AccountAPI';
export default function Page() {
const appContext = AppContext.use();
@@ -37,6 +39,23 @@ export default function Page() {
const addSignatureAndSend = async () => {
await addSignature();
const provider = appContext?.aaProvider;
const signer = provider?.getSigner();
if (!id) return;
const channel = new PaymentChannel(id);
const signedTx = await channel.getSignedPayment();
const accountApi = provider?.smartAccountAPI as AccountAPI;
accountApi.setNextAggBlsSignature(signedTx.signature);
if (!payment || !signer) return;
const ERC20 = IERC20__factory.connect(payment.token, signer);
const transferTx = await ERC20.transfer(payment.to, payment.amount);
const reciept = await transferTx.wait();
console.log('reciept', reciept);
};
if (!payment)

View File

@@ -0,0 +1,3 @@
export default function Page() {
return <>Wallet page</>;
}