Skip to content

Commit

Permalink
Merge pull request #25 from base-org/lukas/types-refactor
Browse files Browse the repository at this point in the history
types / write refactor & finalize hooks
  • Loading branch information
lukasrosario authored Nov 22, 2023
2 parents 63927bf + bb03c93 commit eeeeba0
Show file tree
Hide file tree
Showing 43 changed files with 1,565 additions and 614 deletions.
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

0 comments on commit eeeeba0

Please sign in to comment.