Skip to content

Commit

Permalink
chore: dapp improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaisailovic committed Sep 6, 2024
1 parent fa0e71e commit fcfae6d
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 24 deletions.
21 changes: 15 additions & 6 deletions advanced/dapps/chain-abstraction-demo/app/hooks/useSendUsdc.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
"use client";
import { config } from "@/config";
import { erc20Abi } from "viem";
import { getWalletClient } from "wagmi/actions";
import { tokenAddresses } from "@/consts/tokens";
import { erc20Abi, Hex } from "viem";
import { getAccount, getWalletClient } from "wagmi/actions";

export default function useSendUsdc() {
const sendUsdcAsync = async () => {
const sendUsdcAsync = async (address: Hex, amount: number) => {
const client = await getWalletClient(config);

const account = getAccount(config);
const chain = account.chain?.id;
if (!chain) {
throw new Error("Chain undefined");
}
const contract = tokenAddresses[chain];
if (!chain) {
throw new Error("Cant send on specified chain");
}
const tx = await client.writeContract({
abi: erc20Abi,
address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // arbitrum usdc
address: contract, // arbitrum usdc
functionName: "transfer",
args: ["0x81D8C68Be5EcDC5f927eF020Da834AA57cc3Bd24", BigInt(6000000)],
args: [address, BigInt(amount)],
});
return tx;
};
Expand Down
13 changes: 10 additions & 3 deletions advanced/dapps/chain-abstraction-demo/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import AppKitProvider from "@/context";
import { Toaster } from "@/components/ui/toaster";
import { headers } from "next/headers";
import { cn } from "@/lib/utils";
import { ThemeProvider } from "@/components/theme-provider";

const fontSans = FontSans({
subsets: ["latin"],
Expand Down Expand Up @@ -35,9 +36,15 @@ export default function RootLayout({
)}
>
<AppKitProvider initialState={initialState}>
<div className="flex items-center justify-center min-h-screen">
{children}
</div>
<ThemeProvider
attribute="class"
defaultTheme="dark"
disableTransitionOnChange
>
<div className="flex items-center justify-center min-h-screen">
{children}
</div>
</ThemeProvider>
</AppKitProvider>
<Toaster />
</body>
Expand Down
1 change: 0 additions & 1 deletion advanced/dapps/chain-abstraction-demo/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import Transfer from "./transfer";

Expand Down
42 changes: 39 additions & 3 deletions advanced/dapps/chain-abstraction-demo/app/transfer.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,54 @@
"use client";
import { Button } from "@/components/ui/button";
import useSendUsdc from "./hooks/useSendUsdc";
import { useAccount } from "wagmi";
import { useState } from "react";
import { useToast } from "@/hooks/use-toast";
import { Loader2 } from "lucide-react";

const sendToAddress = "0x81D8C68Be5EcDC5f927eF020Da834AA57cc3Bd24";
const sendAmount = 6000000;

export default function Transfer() {
const { sendUsdcAsync } = useSendUsdc();
const { isConnected, chain } = useAccount();
const [isLoading, setIsLoading] = useState(false);
const { toast } = useToast();

const onButtonClick = async () => {
const res = await sendUsdcAsync();
console.log(res);
try {
setIsLoading(true);
const res = await sendUsdcAsync(sendToAddress, sendAmount);
console.log("Transaction completed", res);
toast({
title: "Transaction completed",
description: res,
});
} catch (error) {
console.log(error);
toast({
variant: "destructive",
title: "Uh oh! Something went wrong.",
description: "There was a problem with your request.",
});
} finally {
setIsLoading(false);
}
};

return (
<>
<Button onClick={onButtonClick}>Send USDC</Button>
{isConnected ? (
<Button onClick={onButtonClick} disabled={isLoading}>
{isLoading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" /> Sending...
</>
) : (
<>Perform action with USDC on {chain?.name}</>
)}
</Button>
) : null}
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use client";

import * as React from "react";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ThemeProviderProps } from "next-themes/dist/types";

export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
5 changes: 5 additions & 0 deletions advanced/dapps/chain-abstraction-demo/consts/tokens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Hex } from "viem";

export const tokenAddresses: Record<number, Hex> = {
42161: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831' // Arbitrum
}
3 changes: 2 additions & 1 deletion advanced/dapps/chain-abstraction-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
"@web3modal/wagmi": "^5.1.6",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"lucide-react": "^0.438.0",
"lucide-react": "^0.439.0",
"next": "14.2.7",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18",
"tailwind-merge": "^2.5.2",
Expand Down
13 changes: 9 additions & 4 deletions advanced/dapps/chain-abstraction-demo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3843,10 +3843,10 @@ lru-cache@^10.2.0, lru-cache@^10.4.3:
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==

lucide-react@^0.438.0:
version "0.438.0"
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.438.0.tgz#80cc2602c973416256ad65ded9872531626b4f70"
integrity sha512-uq6yCB+IzVfgIPMK8ibkecXSWTTSOMs9UjUgZigfrDCVqgdwkpIgYg1fSYnf0XXF2AoSyCJZhoZXQwzoai7VGw==
lucide-react@^0.439.0:
version "0.439.0"
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.439.0.tgz#eb9250e7255e56460ed37b68e807717c534395d6"
integrity sha512-PafSWvDTpxdtNEndS2HIHxcNAbd54OaqSYJO90/b63rab2HWYqDbH194j0i82ZFdWOAcf0AHinRykXRRK2PJbw==

merge-stream@^2.0.0:
version "2.0.0"
Expand Down Expand Up @@ -3993,6 +3993,11 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==

next-themes@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.3.0.tgz#b4d2a866137a67d42564b07f3a3e720e2ff3871a"
integrity sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==

[email protected]:
version "14.2.7"
resolved "https://registry.yarnpkg.com/next/-/next-14.2.7.tgz#e02d5d9622ff4b998e5c89adfd660c9bf6435970"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ import { LoaderProps } from '@/components/ModalFooter'
import RequestDataCard from '@/components/RequestDataCard'
import RequesDetailsCard from '@/components/RequestDetalilsCard'
import RequestMethodCard from '@/components/RequestMethodCard'
import { Divider, Text } from '@nextui-org/react'
import { Avatar, Col, Container, Divider, Row, Text } from '@nextui-org/react'
import { web3wallet } from '@/utils/WalletConnectUtil'
import RequestModal from './RequestModal'
import ModalStore from '@/store/ModalStore'
import { useCallback, useState } from 'react'
import {
bridgeFunds,
BridgingRequest,
convertTokenBalance,
getAssetByContractAddress,
supportedAssets
} from '@/utils/MultibridgeUtil'
import { getWallet } from '@/utils/EIP155WalletUtil'

import { styledToast } from '@/utils/HelperUtil'
import { approveEIP155Request } from '@/utils/EIP155RequestHandlerUtil'
import { EIP155_CHAINS, EIP155_MAINNET_CHAINS, TEIP155Chain } from '@/data/EIP155Data'

interface IProps {
onReject: () => void
Expand Down Expand Up @@ -101,6 +103,12 @@ export default function MultibridgeRequestModal({
return <Text>Request not found</Text>
}

const asset = getAssetByContractAddress(bridgingRequest.transfer.contract)
const amount = convertTokenBalance(asset, bridgingRequest.transfer.amount)
const destination = bridgingRequest.transfer.to
const sourceChain = EIP155_CHAINS[`eip155:${bridgingRequest.sourceChain}` as TEIP155Chain]
const targetChain = EIP155_CHAINS[`eip155:${bridgingRequest.targetChain}` as TEIP155Chain]

return (
<RequestModal
intention="Multibridge"
Expand All @@ -109,10 +117,44 @@ export default function MultibridgeRequestModal({
onReject={onReject}
approveLoader={{ active: isLoadingApprove }}
rejectLoader={rejectLoader}
disableThreatDetection={true}
>
<RequestDataCard data={transaction} />
<Row>
<Col>
<Text h5>Transaction details</Text>
<Text
color=""
data-testid="request-details-chain"
css={{ paddingTop: '$6', paddingBottom: '$6' }}
>
Sending {amount} {asset} to:
</Text>
<Text color="$gray400" data-testid="request-details-chain" size="sm">
{destination}
</Text>
</Col>
</Row>
<Divider y={1} />
<RequesDetailsCard chains={[chainId ?? '']} protocol={requestSession?.relay.protocol} />
<Row>
<Col>
<Text h5>Chain details</Text>
<Text color="">Target chain:</Text>
<Row align="center" css={{ marginTop: '$6' }}>
<Col>
<Avatar src={targetChain.logo} />
</Col>
<Col>{targetChain.name}</Col>
</Row>

<Text color="">Sourcing funds from:</Text>
<Row align="center" css={{ marginTop: '$6' }}>
<Col>
<Avatar src={sourceChain.logo} />
</Col>
<Col>{sourceChain.name}</Col>
</Row>
</Col>
</Row>
<Divider y={1} />
<RequestMethodCard methods={[request.method]} />
</RequestModal>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fragment, ReactNode, useMemo, useState } from 'react'
import { Fragment, ReactNode, useEffect, useMemo, useState } from 'react'
import { Divider } from '@nextui-org/react'
import { CoreTypes } from '@walletconnect/types'
import ModalFooter, { LoaderProps } from '@/components/ModalFooter'
Expand All @@ -21,6 +21,7 @@ interface IProps {
rejectLoader?: LoaderProps
disableApprove?: boolean
disableReject?: boolean
disableThreatDetection?: boolean
}
export default function RequestModal({
children,
Expand All @@ -33,7 +34,8 @@ export default function RequestModal({
infoBoxCondition,
infoBoxText,
disableApprove,
disableReject
disableReject,
disableThreatDetection
}: IProps) {
const { currentRequestVerifyContext } = useSnapshot(SettingsStore.state)
const isScam = currentRequestVerifyContext?.verified.isScam
Expand All @@ -57,7 +59,7 @@ export default function RequestModal({
<Divider y={1} />
{children}
<Divider y={1} />
<VerifyInfobox metadata={metadata} />
{disableThreatDetection === undefined ? <VerifyInfobox metadata={metadata} /> : null}
</RequestModalContainer>
<ModalFooter
onApprove={onApprove}
Expand Down
13 changes: 13 additions & 0 deletions advanced/wallets/react-wallet-v2/src/utils/MultibridgeUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export const supportedAssets: Record<string, Record<number, Hex>> = {
}
} as const

const assetDecimals: Record<string, number> = {
'USDC': 6
}

export const supportedChains = [base, optimism, arbitrum] as const

export function getCrossChainTokens(address: Hex): Record<number, Hex> | undefined {
Expand Down Expand Up @@ -45,6 +49,15 @@ export function getAssetByContractAddress(address: Hex): string {
throw new Error('Asset not found for the given contract address')
}

export function convertTokenBalance(asset: string, amount: number): number {
const decimals = assetDecimals[asset]
if (!decimals) {
throw new Error('Asset not supported')
}
const balance = amount / (10**decimals)
return balance
}

export async function getErc20TokenBalance(
tokenAddress: Hex,
chainId: number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
getErc20TokenBalance
} from '@/utils/MultibridgeUtil'
import MultibridgeRequestModal from '@/components/MultibridgeRequestModal'
import SettingsStore from '@/store/SettingsStore'

export default function SessionSendTransactionModal() {
const [isLoadingApprove, setIsLoadingApprove] = useState(false)
Expand All @@ -42,6 +43,10 @@ export default function SessionSendTransactionModal() {
setIsTypeResolved(true)
return
}
if (!SettingsStore.state.chainAbstractionEnabled) {
setIsTypeResolved(true)
return
}
const transfer = decodeErc20Transaction(request.params[0])
if (!transfer) {
setIsTypeResolved(true)
Expand Down

0 comments on commit fcfae6d

Please sign in to comment.