Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

types / write refactor & finalize hooks #25

Merged
merged 5 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions example/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@
'use client'

import { BridgeToggle } from '@/components/BridgeToggle'
import { ConnectButton } from '@/components/ConnectButton'
import { DepositERC20 } from '@/components/DepositERC20'
import { DepositETH } from '@/components/DepositETH'
import { WithdrawETH } from '@/components/WithdrawETH'
import { WithdrawERC20 } from '@/components/WriteWithdrawERC20'
import { DepositContainer } from '@/components/DepositContainer'
import { FinalizeContainer } from '@/components/FinalizeContainer'
import { ProveContainer } from '@/components/ProveContainer'
import { WithdrawContainer } from '@/components/WithdrawContainer'
import { useEffect, useState } from 'react'

export default function Home() {
const [isClient, setIsClient] = useState(false)
const [action, setAction] = useState<'deposit' | 'withdraw' | 'prove' | 'finalize'>('deposit')

useEffect(() => {
setIsClient(true)
}, [])

return (isClient && (
<main className='flex min-h-screen flex-col items-center justify-center p-24 space-y-16'>
<span className='text-4xl font-bold text-white'>op-wagmi</span>
<span className='text-4xl font-bold text-white'>🔴🔵 Superchain Bridge 🔵🔴</span>
<ConnectButton />
<div className='flex flex-col space-y-6 items-center'>
<DepositETH />
<DepositERC20 />
<WithdrawETH />
<WithdrawERC20 />
<div className='flex flex-col justify-start items-center space-y-8 w-full shadow-lg shadow-white rounded-lg py-16 pt-8 px-4'>
<BridgeToggle action={action} setAction={setAction} />
{action === 'deposit' && <DepositContainer />}
{action === 'withdraw' && <WithdrawContainer />}
{action === 'prove' && <ProveContainer />}
{action === 'finalize' && <FinalizeContainer />}
</div>
</main>
))
Expand Down
6 changes: 3 additions & 3 deletions example/components/ActionToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ type ActionToggleProps = {

export function ActionToggle({ action, setAction }: ActionToggleProps) {
return (
<div className='flex flex-row justify-center items-center self-center w-64 rounded-full divide-x bg-white'>
<div className='flex flex-row justify-center items-center self-center w-48 rounded-full divide-x bg-white'>
<button
className={`w-32 flex items-center justify-center h-12 rounded-l-full ${
className={`w-32 flex items-center justify-center h-8 rounded-l-full ${
action === 'simulate' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
onClick={() => setAction('simulate')}
>
Simulate
</button>
<button
className={`w-32 flex items-center justify-center h-12 rounded-r-full ${
className={`w-32 flex items-center justify-center h-8 rounded-r-full ${
action === 'write' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
onClick={() => setAction('write')}
Expand Down
29 changes: 29 additions & 0 deletions example/components/AssetTypeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
type AssetTypeToggleProps = {
selectedAssetType: 'eth' | 'erc20'
setSelectedAssetType: (assetType: 'eth' | 'erc20') => void
}

export function AssetTypeToggle({ selectedAssetType, setSelectedAssetType }: AssetTypeToggleProps) {
return (
<div className='flex flex-row justify-center items-center self-center w-48 rounded-full divide-x bg-white'>
<button
className={`w-24 flex items-center justify-center h-8 rounded-l-full ${
selectedAssetType === 'eth' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
onClick={() => setSelectedAssetType('eth')}
>
ETH
</button>
<button
className={`w-24 flex items-center justify-center h-8 rounded-r-full ${
selectedAssetType === 'erc20'
? 'bg-blue-500 text-white shadow-inner shadow-stone-900'
: 'bg-white text-black'
}`}
onClick={() => setSelectedAssetType('erc20')}
>
ERC-20
</button>
</div>
)
}
45 changes: 45 additions & 0 deletions example/components/BridgeToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
type BridgeToggleProps = {
action: 'deposit' | 'withdraw' | 'prove' | 'finalize'
setAction: (action: 'deposit' | 'withdraw' | 'prove' | 'finalize') => void
}

export function BridgeToggle({ action, setAction }: BridgeToggleProps) {
return (
<div className='flex flex-row justify-center items-center self-center w-72 rounded-full divide-x bg-white'>
<div className='flex flex-row divide-x'>
<button
onClick={() => setAction('deposit')}
className={`w-36 flex items-center justify-center h-12 rounded-l-full ${
action === 'deposit' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
>
Deposit
</button>
<button
onClick={() => setAction('withdraw')}
className={`w-36 flex items-center justify-center h-12 ${
action === 'withdraw' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
>
Withdraw
</button>
<button
onClick={() => setAction('prove')}
className={`w-36 flex items-center justify-center h-12 ${
action === 'prove' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
>
Prove
</button>
<button
onClick={() => setAction('finalize')}
className={`w-36 flex items-center justify-center h-12 rounded-r-full ${
action === 'finalize' ? 'bg-blue-500 text-white shadow-inner shadow-stone-900' : 'bg-white text-black'
}`}
>
Finalize
</button>
</div>
</div>
)
}
24 changes: 24 additions & 0 deletions example/components/DepositContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useState } from 'react'
import { AssetTypeToggle } from './AssetTypeToggle'
import { DepositERC20 } from './DepositERC20'
import { DepositETH } from './DepositETH'
import { NetworkSelector } from './NetworkSelector'

const networkToChainId: Record<'optimism' | 'base', number> = {
base: 84531,
optimism: 420,
}

export function DepositContainer() {
const [selectedAssetType, setSelectedAssetType] = useState<'eth' | 'erc20'>('eth')
const [selectedNetwork, setSelectedNetwork] = useState<'optimism' | 'base'>('base')
return (
<div className='w-full flex flex-col items-center space-y-4'>
<AssetTypeToggle selectedAssetType={selectedAssetType} setSelectedAssetType={setSelectedAssetType} />
<span className='text-white'>To</span>
<NetworkSelector selectedNetwork={selectedNetwork} setSelectedNetwork={setSelectedNetwork} />
{selectedAssetType === 'eth' && <DepositETH selectedChainId={networkToChainId[selectedNetwork]} />}
{selectedAssetType === 'erc20' && <DepositERC20 selectedChainId={networkToChainId[selectedNetwork]} />}
</div>
)
}
153 changes: 62 additions & 91 deletions example/components/DepositERC20.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import { useDisclosure } from '@/hooks/useDisclosure'
import { useSimulateDepositERC20, useWriteDepositERC20 } from 'op-wagmi'
import { useState } from 'react'
import { Address, erc20Abi, isAddress, parseUnits } from 'viem'
import { useReadContract } from 'wagmi'
import { Action, ActionToggle } from './ActionToggle'
import { Button } from './Button'
import { InputGroup } from './InputGroup'
import { Modal } from './Modal'

const l1StandardBridge = '0xfA6D8Ee5BE770F84FC001D098C4bD604Fe01284a'
const cbETHL1 = '0xD0bb78d0B337aA6D3A0530DD2e58560bf00851f1'
const cbETHL2 = '0x7c6b91D9Be155A6Db01f749217d76fF02A7227F2'

type DepositERC20ModalProps = {
isOpen: boolean
onClose: () => void
type DepositERC20Props = {
selectedChainId: number
}

function DepositERC20Modal({ isOpen, onClose }: DepositERC20ModalProps) {
export function DepositERC20({ selectedChainId }: DepositERC20Props) {
const [l1Token, setL1Token] = useState(cbETHL1)
const [l2Token, setL2Token] = useState(cbETHL2)
const [to, setTo] = useState('')
Expand All @@ -30,113 +26,88 @@ function DepositERC20Modal({ isOpen, onClose }: DepositERC20ModalProps) {
chainId: 5,
query: { enabled: isAddress(l1Token) },
})

const { status: simulateStatus, refetch: simulateDepositERC20 } = useSimulateDepositERC20({
args: {
l1Token: l1Token as Address,
l2Token: l2Token as Address,
to: to as Address,
amount: parseUnits(amount, tokenDecimals ?? 18),
minGasLimit: 100000,
},
l1StandardBridge,
chainId: 5,
query: { enabled: false },
l2ChainId: selectedChainId,
query: { enabled: false, retry: false },
})
const { data, status: writeStatus, writeDepositERC20Async } = useWriteDepositERC20()
const { data: l1TxHash, status: writeStatus, writeDepositERC20Async } = useWriteDepositERC20()

const handleClick = async () => {
if (action === 'simulate') {
simulateDepositERC20()
} else {
try {
await writeDepositERC20Async({
args: {
l1Token: l1Token as Address,
l2Token: l2Token as Address,
to: to as Address,
amount: BigInt(1),
minGasLimit: 100000,
},
l1StandardBridge,
chainId: 5,
})
} catch (e) {
console.error(e)
}
await writeDepositERC20Async({
args: {
l1Token: l1Token as Address,
l2Token: l2Token as Address,
to: to as Address,
amount: parseUnits(amount, tokenDecimals ?? 18),
},
l2ChainId: selectedChainId,
})
}
}

return (
<Modal isOpen={isOpen} onClose={onClose}>
<div className='flex flex-col space-y-8 pb-8'>
<span className='text-2xl font-bold text-white'>Deposit ERC20</span>
<div className='flex flex-col space-y-4 pb-8'>
<div className='flex flex-col w-full px-16 space-y-4'>
<InputGroup
label='L1 Token:'
placeholder='0x...'
value={l1Token}
setValue={setL1Token}
/>
<InputGroup
label='L2 Token:'
placeholder='0x...'
value={l2Token}
setValue={setL2Token}
/>
<InputGroup label='To' placeholder='0x...' value={to} setValue={setTo} />
<InputGroup label='Amount' value={amount} setValue={setAmount} />
<ActionToggle action={action} setAction={setAction} />
<div className='self-center'>
<Button onClick={handleClick}>
{`🚀 ${action === 'simulate' ? 'Simulate' : 'Write'} Deposit ERC20 🚀`}
</Button>
</div>
</div>
{action === 'simulate' && simulateStatus && (
<div className='flex flex-col w-full px-16 space-y-4'>
<InputGroup
label='L1 Token:'
placeholder='0x...'
value={l1Token}
setValue={setL1Token}
/>
<InputGroup
label='L2 Token:'
placeholder='0x...'
value={l2Token}
setValue={setL2Token}
/>
<InputGroup label='To' placeholder='0x...' value={to} setValue={setTo} />
<InputGroup label='Amount' value={amount} setValue={setAmount} />
<ActionToggle action={action} setAction={setAction} />
<div className='self-center'>
<Button onClick={handleClick}>
{`🚀 ${action === 'simulate' ? 'Simulate' : 'Write'} Deposit ERC20 🚀`}
</Button>
<div className='flex flex-row justify-center space-x-8 items-center w-full'>
<span className='text-white'>Status:</span>
<span className='text-white'>{simulateStatus}</span>
</div>
</div>
{action === 'simulate' && simulateStatus && (
<div className='flex flex-col w-full px-16 space-y-4'>
<div className='flex flex-row justify-center space-x-8 items-center w-full'>
<span className='text-white'>Status:</span>
<span className='text-white'>{simulateStatus}</span>
</div>
)}
{action === 'write' && writeStatus && (
<div className='flex flex-col w-full px-16 space-y-4'>
<div className='flex flex-row justify-center space-x-8 items-center w-full'>
<span className='text-white'>Status:</span>
<span className='text-white'>{writeStatus}</span>
</div>
)}
{action === 'write' && writeStatus && (
<div className='flex flex-col w-full px-16 space-y-4'>
{l1TxHash && (
<div className='flex flex-row justify-center space-x-8 items-center w-full'>
<span className='text-white'>Status:</span>
<span className='text-white'>{writeStatus}</span>
<span className='text-white'>L1 Tx:</span>
<a
className='text-blue-500 underline'
target='_blank'
rel='noreferrer'
href={`https://goerli.etherscan.io/tx/${l1TxHash}`}
>
{`${l1TxHash?.slice(0, 8)}...`}
</a>
</div>
{data && (
<div className='flex flex-row justify-center space-x-8 items-center w-full'>
<span className='text-white'>Transaction:</span>
<a
className='text-blue-500 underline'
target='_blank'
rel='noreferrer'
href={`https://goerli.etherscan.io/tx/${data}`}
>
{`${data?.slice(0, 8)}...`}
</a>
</div>
)}
</div>
)}
</div>
</Modal>
)
}

export function DepositERC20() {
const { isOpen, onClose, onOpen } = useDisclosure()

return (
<div>
{isOpen && <DepositERC20Modal isOpen={isOpen} onClose={onClose} />}
<Button
onClick={onOpen}
>
Deposit ERC20
</Button>
)}
</div>
)}
</div>
)
}
Loading
Loading