Skip to content

Commit

Permalink
Add daemon data (#4)
Browse files Browse the repository at this point in the history
* add menu

* smaller main

* fix layout

* add deamon data

* add margin

* add effect
  • Loading branch information
julienbrg authored Nov 22, 2024
1 parent f73d904 commit 4d94652
Show file tree
Hide file tree
Showing 8 changed files with 1,148 additions and 71 deletions.
13 changes: 8 additions & 5 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export function Header(props: Props) {
mb={8}
alignItems="center">
<LinkComponent href="/" invisible>
<Heading as="h1" size="md">
<Heading as="h1" size="md" mr={4}>
{SITE_NAME}
</Heading>
</LinkComponent>
Expand All @@ -48,11 +48,14 @@ export function Header(props: Props) {
<Menu>
<MenuButton as={IconButton} aria-label="Options" icon={<HamburgerIcon />} size={'sm'} mr={4} />
<MenuList>
<LinkComponent href="/" invisible>
<MenuItem fontSize="md">Home</MenuItem>
<LinkComponent href="/eth-op" invisible>
<MenuItem fontSize="md">Sepolia to OP Sepolia</MenuItem>
</LinkComponent>
<LinkComponent href="/new" invisible>
<MenuItem fontSize="md">New</MenuItem>
<LinkComponent href="/eth-arb" invisible>
<MenuItem fontSize="md">Sepolia to Arbitrum Sepolia</MenuItem>
</LinkComponent>
<LinkComponent href="/eth-base" invisible>
<MenuItem fontSize="md">Sepolia to Base Sepolia</MenuItem>
</LinkComponent>
</MenuList>
</Menu>
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function RootLayout({ children }: Props) {
<Web3Modal>
<Box margin="0 auto" minH="100vh">
<Header />
<Container maxW="container.lg">{children}</Container>
<Container maxW="container.sm">{children}</Container>
</Box>
</Web3Modal>
)
Expand Down
322 changes: 322 additions & 0 deletions src/pages/eth-arb/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,322 @@
import * as React from 'react'
import {
Text,
Button,
useToast,
Box,
NumberInput,
NumberInputField,
NumberInputStepper,
NumberIncrementStepper,
NumberDecrementStepper,
Flex,
Select,
} from '@chakra-ui/react'
import { useState, useEffect } from 'react'
import { BrowserProvider, Contract, Eip1193Provider, parseEther } from 'ethers'
import { useAppKitAccount, useAppKitProvider } from '@reown/appkit/react'
import { ERC20_CONTRACT_ADDRESS, ERC20_CONTRACT_ABI } from '../../utils/erc20'
import { LinkComponent } from '../../components/LinkComponent'
import { ethers } from 'ethers'
import { Head } from '../../components/Head'
import { SITE_NAME, SITE_DESCRIPTION } from '../../utils/config'
import { NextSeo } from 'next-seo'
import { SITE_URL } from '../../utils/config'

export default function EthArb() {
const seoTitle = 'Lambula - Bridge your assets in seconds'
const seoDescription =
'An on-chain asset bridge for converting ERC-20 tokens between EVM-compatible blockchains without smart contracts or interfaces.'

const [isLoading, setIsLoading] = useState<boolean>(false)
const [txLink, setTxLink] = useState<string>()
const [txHash, setTxHash] = useState<string>()
const [balance, setBalance] = useState<string>('0')
const [network, setNetwork] = useState<string>('Unknown')
const [swapAmount, setSwapAmount] = useState<string>('8')
const [availableBalance, setAvailableBalance] = useState<number | null>(null)

const { address, isConnected, caipAddress } = useAppKitAccount()
const { walletProvider } = useAppKitProvider('eip155')
// const { walletInfo } = useWalletInfo()
const toast = useToast()

useEffect(() => {
if (isConnected) {
setTxHash(undefined)
getNetwork()
// updateLoginType()
getBal()
console.log('user address:', address)
console.log('erc20 contract address:', ERC20_CONTRACT_ADDRESS)
// console.log('walletInfo:', walletInfo)
}
}, [isConnected, address, caipAddress])

const getBal = async () => {
if (isConnected && walletProvider) {
const ethersProvider = new BrowserProvider(walletProvider as any)
const balance = await ethersProvider.getBalance(address as any)

const ethBalance = ethers.formatEther(balance)
console.log('bal:', Number(parseFloat(ethBalance).toFixed(5)))
setBalance(parseFloat(ethBalance).toFixed(5))
if (ethBalance !== '0') {
return Number(ethBalance)
} else {
return 0
}
} else {
return 0
}
}

const getNetwork = async () => {
if (walletProvider) {
const ethersProvider = new BrowserProvider(walletProvider as any)
const network = await ethersProvider.getNetwork()
const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1)
setNetwork(capitalize(network.name))
}
}

// const updateLoginType = async () => {
// try {
// if (walletInfo != undefined) {
// setLoginType(walletInfo.name ? walletInfo.name : 'Unknown')
// }
// } catch (error) {
// console.error('Error getting login type:', error)
// setLoginType('Unknown')
// }
// }

const openEtherscan = () => {
if (address) {
const baseUrl =
caipAddress === 'eip155:11155111:' ? 'https://sepolia.etherscan.io/address/' : 'https://etherscan.io/address/'
window.open(baseUrl + address, '_blank')
}
}

const faucetTx = async () => {
try {
const response = await fetch('/api/faucet', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ address }),
})
const data = await response.json()
if (!response.ok) {
throw new Error(data.message || 'Faucet request failed')
}
return data.txHash
} catch (error) {
console.error('Faucet error:', error)
throw error
}
}

const doSomething = async () => {
setTxHash(undefined)
try {
if (!isConnected) {
toast({
title: 'Not connected yet',
description: 'Please connect your wallet, my friend.',
status: 'error',
position: 'bottom',
variant: 'subtle',
duration: 9000,
isClosable: true,
})
return
}
if (walletProvider) {
setIsLoading(true)
setTxHash('')
setTxLink('')
const ethersProvider = new BrowserProvider(walletProvider as Eip1193Provider)
const signer = await ethersProvider.getSigner()

const erc20 = new Contract(ERC20_CONTRACT_ADDRESS, ERC20_CONTRACT_ABI, signer)

///// Send ETH if needed /////
const bal = await getBal()
console.log('bal:', bal)
if (bal < 0.025) {
const faucetTxHash = await faucetTx()
console.log('faucet tx:', faucetTxHash)
const bal = await getBal()
console.log('bal:', bal)
}
///// Call /////
const call = await erc20.mint(parseEther('10000')) // 0.000804454399826656 ETH // https://sepolia.etherscan.io/tx/0x687e32332965aa451abe45f89c9fefc4b5afe6e99c95948a300565f16a212d7b

let receipt: ethers.ContractTransactionReceipt | null = null
try {
receipt = await call.wait()
} catch (error) {
console.error('Error waiting for transaction:', error)
throw new Error('Transaction failed or was reverted')
}

if (receipt === null) {
throw new Error('Transaction receipt is null')
}

console.log('tx:', receipt)
setTxHash(receipt.hash)
setTxLink('https://sepolia.etherscan.io/tx/' + receipt.hash)
setIsLoading(false)
toast({
title: 'Successful tx',
description: 'Well done! 🎉',
status: 'success',
position: 'bottom',
variant: 'subtle',
duration: 20000,
isClosable: true,
})
await getBal()
}
} catch (e) {
setIsLoading(false)
console.error('Error in doSomething:', e)
toast({
title: 'Woops',
description: e instanceof Error ? e.message : 'Something went wrong...',
status: 'error',
position: 'bottom',
variant: 'subtle',
duration: 9000,
isClosable: true,
})
}
}

const handleSwapAmountChange = (valueString: string) => {
setSwapAmount(valueString)
}

const isAmountExceedingBalance = () => {
if (availableBalance === null) return false
const amount = parseFloat(swapAmount)
return amount > availableBalance
}

return (
<>
<NextSeo
title={seoTitle}
titleTemplate="%s"
description={seoDescription}
canonical={SITE_URL}
openGraph={{
type: 'website',
url: SITE_URL,
title: seoTitle,
description: seoDescription,
site_name: 'Lambula',
images: [
{
url: `${SITE_URL}/huangshan.png`,
width: 1200,
height: 630,
alt: 'Lambula - Bridge your assets in seconds',
},
],
}}
twitter={{
cardType: 'summary_large_image',
site: '@w3hc8',
}}
additionalMetaTags={[
{
name: 'keywords',
content: 'web3, ethereum, blockchain, dapp, onchain, bridge, swap, erc20 ',
},
{
name: 'author',
content: 'W3HC',
},
]}
/>
<Head title={SITE_NAME} description={SITE_DESCRIPTION} />
<main>
{!isConnected ? (
<>
<Text>Please connect your wallet.</Text>
<br />
</>
) : (
<>
<Flex gap={4} align="center" mt={20}>
<NumberInput value={swapAmount} onChange={handleSwapAmountChange} min={1} max={10000} step={1} flex={1}>
<NumberInputField />
<NumberInputStepper>
<NumberIncrementStepper />
<NumberDecrementStepper />
</NumberInputStepper>
</NumberInput>

<Select width="200px">
<option value="LINK">LINK</option>
<option value="BASIC">BASIC</option>
<option value="ETH">ETH</option>
</Select>
</Flex>
<br />
<Box
p={4}
borderWidth={1}
borderColor="#8c1c84"
borderRadius="lg"
my={2}
mb={3}
onClick={openEtherscan}
cursor="pointer"
_hover={{ borderColor: '#45a2f8', boxShadow: 'md' }}>
{/* <Text>
Network: <strong>{network}</strong>
</Text>
{/* <Text>
Login type: <strong>{loginType}</strong>
</Text>
<Text>
Balance: <strong>{balance} ETH</strong>
</Text>
<Text>
Address: <strong>{address || 'Not connected'}</strong>
</Text> */}
<Text>
Bridge <strong>{!swapAmount ? 'your' : swapAmount} LINK</strong> from <strong>Sepolia</strong> to{' '}
<strong>OP Sepolia</strong>.
</Text>
</Box>
<Text fontSize="sm" color="gray.500">
You will pay <strong>0.10</strong> EUR and it will take <strong>3</strong> seconds.
</Text>
</>
)}
{/* <Button
colorScheme="blue"
variant="outline"
type="submit"
onClick={doSomething}
isLoading={isLoading}
loadingText="Minting..."
spinnerPlacement="end">
Bridge
</Button> */}
{txHash && isConnected && (
<Text py={4} fontSize="14px" color="#45a2f8">
<LinkComponent href={txLink ? txLink : ''}>{txHash}</LinkComponent>
</Text>
)}{' '}
</main>
</>
)
}
Loading

0 comments on commit 4d94652

Please sign in to comment.