mirror of
https://github.com/kremalicious/blog.git
synced 2025-02-14 21:10:25 +01:00
handle sending
This commit is contained in:
parent
15130e8d92
commit
d8da825649
@ -1,5 +1,4 @@
|
|||||||
import Web3Donation from './Web3Donation'
|
import Web3Donation from './Web3Donation'
|
||||||
import config from '@config/blog.config'
|
|
||||||
import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
|
import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
|
||||||
import { WagmiConfig } from 'wagmi'
|
import { WagmiConfig } from 'wagmi'
|
||||||
import { wagmiConfig, chains, theme } from './Web3Donation/lib/rainbowkit'
|
import { wagmiConfig, chains, theme } from './Web3Donation/lib/rainbowkit'
|
||||||
@ -9,7 +8,7 @@ export default function Web3(): ReactElement {
|
|||||||
return (
|
return (
|
||||||
<WagmiConfig config={wagmiConfig}>
|
<WagmiConfig config={wagmiConfig}>
|
||||||
<RainbowKitProvider chains={chains} theme={theme}>
|
<RainbowKitProvider chains={chains} theme={theme}>
|
||||||
<Web3Donation address={config.author.ether} />
|
<Web3Donation />
|
||||||
</RainbowKitProvider>
|
</RainbowKitProvider>
|
||||||
</WagmiConfig>
|
</WagmiConfig>
|
||||||
)
|
)
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
export async function getFiat({
|
|
||||||
amount,
|
|
||||||
tokenId = 'ethereum'
|
|
||||||
}: {
|
|
||||||
amount: number
|
|
||||||
tokenId?: string
|
|
||||||
}): Promise<{ [key: string]: string }> {
|
|
||||||
const url = `https://api.coingecko.com/api/v3/simple/price?ids=${tokenId}&vs_currencies=eur%2Cusd`
|
|
||||||
const response = await fetch(url)
|
|
||||||
const json = await response.json()
|
|
||||||
|
|
||||||
if (!json) console.error(response.statusText)
|
|
||||||
const { usd, eur } = json[tokenId]
|
|
||||||
const dollar = (amount * usd).toFixed(2)
|
|
||||||
const euro = (amount * eur).toFixed(2)
|
|
||||||
|
|
||||||
return { dollar, euro }
|
|
||||||
}
|
|
@ -16,6 +16,8 @@ export async function getTokens(
|
|||||||
address: `0x${string}`,
|
address: `0x${string}`,
|
||||||
chainId: number
|
chainId: number
|
||||||
): Promise<GetToken[]> {
|
): Promise<GetToken[]> {
|
||||||
|
if (!address || !chainId) return []
|
||||||
|
|
||||||
// const url = `http://localhost:3000/api/balance?address=${address}&chainId=${chainId}`
|
// const url = `http://localhost:3000/api/balance?address=${address}&chainId=${chainId}`
|
||||||
const url = `https://web3-api-kremalicious.vercel.app/api/balance?address=${address}&chainId=${chainId}`
|
const url = `https://web3-api-kremalicious.vercel.app/api/balance?address=${address}&chainId=${chainId}`
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
|
@ -1,36 +1,20 @@
|
|||||||
import { type ReactElement, useEffect, useState } from 'react'
|
import { type ReactElement } from 'react'
|
||||||
import styles from './Conversion.module.css'
|
import styles from './Conversion.module.css'
|
||||||
import { getFiat } from '../../api/getFiat'
|
import type { GetToken } from '../../api/getTokens'
|
||||||
|
|
||||||
export function Conversion({
|
export function Conversion({
|
||||||
amount,
|
amount,
|
||||||
symbol
|
token
|
||||||
}: {
|
}: {
|
||||||
amount: string
|
amount: string
|
||||||
symbol: string
|
token: GetToken | undefined
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const [conversion, setConversion] = useState({
|
const dollar = token?.price?.usd
|
||||||
euro: '0.00',
|
? (Number(amount) * token?.price?.usd).toFixed(2)
|
||||||
dollar: '0.00'
|
: '0.00'
|
||||||
})
|
const euro = token?.price?.eur
|
||||||
const { dollar, euro } = conversion
|
? (Number(amount) * token?.price?.eur).toFixed(2)
|
||||||
|
: '0.00'
|
||||||
useEffect(() => {
|
|
||||||
async function getFiatResponse() {
|
|
||||||
try {
|
|
||||||
const tokenId = symbol === 'MATIC' ? 'matic-network' : 'ethereum'
|
|
||||||
const { dollar, euro } = await getFiat({
|
|
||||||
amount: Number(amount),
|
|
||||||
tokenId
|
|
||||||
})
|
|
||||||
setConversion({ euro, dollar })
|
|
||||||
} catch (error) {
|
|
||||||
console.error((error as Error).message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getFiatResponse()
|
|
||||||
}, [amount, symbol])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.conversion}>
|
<div className={styles.conversion}>
|
||||||
|
@ -74,6 +74,10 @@
|
|||||||
color: var(--text-color-light);
|
color: var(--text-color-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disclaimer code {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes fadeIn {
|
@keyframes fadeIn {
|
||||||
from {
|
from {
|
||||||
opacity: 0.01;
|
opacity: 0.01;
|
||||||
|
@ -4,25 +4,26 @@ import { Conversion } from '../Conversion'
|
|||||||
import styles from './InputGroup.module.css'
|
import styles from './InputGroup.module.css'
|
||||||
import { TokenSelect } from '../Tokens'
|
import { TokenSelect } from '../Tokens'
|
||||||
import config from '@config/blog.config'
|
import config from '@config/blog.config'
|
||||||
|
import type { GetToken } from '../../api/getTokens'
|
||||||
|
|
||||||
export function InputGroup({
|
export function InputGroup({
|
||||||
amount,
|
amount,
|
||||||
|
token,
|
||||||
isDisabled,
|
isDisabled,
|
||||||
symbol,
|
|
||||||
setAmount,
|
setAmount,
|
||||||
setToken
|
setTokenSelected
|
||||||
}: {
|
}: {
|
||||||
amount: string
|
amount: string
|
||||||
|
token: GetToken | undefined
|
||||||
isDisabled: boolean
|
isDisabled: boolean
|
||||||
symbol: string
|
setAmount: React.Dispatch<React.SetStateAction<string>>
|
||||||
setAmount(amount: string): void
|
setTokenSelected: React.Dispatch<React.SetStateAction<GetToken>>
|
||||||
setToken(token: string): void
|
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className={styles.inputGroup}>
|
<div className={styles.inputGroup}>
|
||||||
<div className={styles.token}>
|
<div className={styles.token}>
|
||||||
<TokenSelect setToken={setToken} />
|
<TokenSelect setTokenSelected={setTokenSelected} />
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
@ -41,7 +42,7 @@ export function InputGroup({
|
|||||||
Make it rain
|
Make it rain
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<Conversion amount={amount} symbol={symbol} />
|
<Conversion amount={amount} token={token} />
|
||||||
<div className={styles.disclaimer}>
|
<div className={styles.disclaimer}>
|
||||||
This form sends tokens to my account <code>{config.author.ether}</code>
|
This form sends tokens to my account <code>{config.author.ether}</code>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
import { parseEther } from 'viem'
|
||||||
|
import { useContractWrite, usePrepareContractWrite } from 'wagmi'
|
||||||
|
import siteConfig from '@config/blog.config'
|
||||||
|
import { abi } from './abi'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
|
export function SendErc20({
|
||||||
|
amount,
|
||||||
|
tokenAddress,
|
||||||
|
setSendFormData
|
||||||
|
}: {
|
||||||
|
amount: string
|
||||||
|
tokenAddress: `0x${string}` | undefined
|
||||||
|
setSendFormData: any
|
||||||
|
}) {
|
||||||
|
const { config } = usePrepareContractWrite({
|
||||||
|
address: tokenAddress,
|
||||||
|
abi,
|
||||||
|
functionName: 'transfer',
|
||||||
|
args: [siteConfig.author.ether, parseEther(amount)]
|
||||||
|
})
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
writeAsync: send,
|
||||||
|
isError,
|
||||||
|
isSuccess,
|
||||||
|
isLoading,
|
||||||
|
error
|
||||||
|
} = useContractWrite(config)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSendFormData({
|
||||||
|
data,
|
||||||
|
send,
|
||||||
|
isError,
|
||||||
|
isSuccess,
|
||||||
|
isLoading,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
}, [data, send, isError, isSuccess, isLoading, error])
|
||||||
|
|
||||||
|
return <></>
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import { parseEther } from 'viem'
|
||||||
|
import {
|
||||||
|
useNetwork,
|
||||||
|
usePrepareSendTransaction,
|
||||||
|
useSendTransaction
|
||||||
|
} from 'wagmi'
|
||||||
|
import siteConfig from '@config/blog.config'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
|
export function SendNative({
|
||||||
|
amount,
|
||||||
|
setSendFormData
|
||||||
|
}: {
|
||||||
|
amount: string
|
||||||
|
setSendFormData: any
|
||||||
|
}) {
|
||||||
|
const { chain } = useNetwork()
|
||||||
|
const { config } = usePrepareSendTransaction({
|
||||||
|
chainId: chain?.id,
|
||||||
|
to: siteConfig.author.ether,
|
||||||
|
value: parseEther(amount)
|
||||||
|
})
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
sendTransactionAsync: send,
|
||||||
|
isError,
|
||||||
|
isSuccess,
|
||||||
|
isLoading,
|
||||||
|
error
|
||||||
|
} = useSendTransaction(config)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSendFormData({
|
||||||
|
data,
|
||||||
|
send,
|
||||||
|
isError,
|
||||||
|
isSuccess,
|
||||||
|
isLoading,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
}, [data, send, isError, isSuccess, isLoading, error])
|
||||||
|
|
||||||
|
return <></>
|
||||||
|
}
|
13
src/components/Sponsor/Web3Donation/components/Send/abi.ts
Normal file
13
src/components/Sponsor/Web3Donation/components/Send/abi.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export const abi = [
|
||||||
|
{
|
||||||
|
constant: false,
|
||||||
|
inputs: [
|
||||||
|
{ name: '_to', type: 'address' },
|
||||||
|
{ name: '_value', type: 'uint256' }
|
||||||
|
],
|
||||||
|
name: 'transfer',
|
||||||
|
outputs: [{ name: 'success', type: 'bool' }],
|
||||||
|
stateMutability: 'nonpayable',
|
||||||
|
type: 'function'
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,2 @@
|
|||||||
|
export * from './SendErc20'
|
||||||
|
export * from './SendNative'
|
@ -6,13 +6,13 @@ import { Check } from '@images/components/react'
|
|||||||
import type { GetToken } from '../../api/getTokens'
|
import type { GetToken } from '../../api/getTokens'
|
||||||
|
|
||||||
interface SelectItemProps extends HTMLAttributes<HTMLDivElement> {
|
interface SelectItemProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
token: GetToken
|
token: GetToken | undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Token = forwardRef<HTMLDivElement, SelectItemProps>(
|
export const Token = forwardRef<HTMLDivElement, SelectItemProps>(
|
||||||
({ className, token, ...props }, forwardedRef) => {
|
({ className, token, ...props }, forwardedRef) => {
|
||||||
const balance =
|
const balance =
|
||||||
token.balance && token.symbol
|
token?.balance && token?.symbol
|
||||||
? formatCurrency(token.balance, token.symbol, 'en', false, {
|
? formatCurrency(token.balance, token.symbol, 'en', false, {
|
||||||
decimalPlaces: 3,
|
decimalPlaces: 3,
|
||||||
significantFigures: 3
|
significantFigures: 3
|
||||||
@ -20,28 +20,30 @@ export const Token = forwardRef<HTMLDivElement, SelectItemProps>(
|
|||||||
: 0
|
: 0
|
||||||
|
|
||||||
const valueInUsd =
|
const valueInUsd =
|
||||||
token.balance && token.price?.usd ? token.balance * token.price.usd : 0
|
token?.balance && token?.price?.usd
|
||||||
|
? token?.balance * token?.price.usd
|
||||||
|
: 0
|
||||||
const valueInUsdFormatted = formatCurrency(valueInUsd, 'USD', 'en')
|
const valueInUsdFormatted = formatCurrency(valueInUsd, 'USD', 'en')
|
||||||
|
|
||||||
return balance && parseInt(balance) !== 0 && valueInUsd >= 1 ? (
|
return balance && parseInt(balance) !== 0 && valueInUsd >= 1 ? (
|
||||||
<Select.Item
|
<Select.Item
|
||||||
className={`${className ? className : ''} Token`}
|
className={`${className ? className : ''} Token`}
|
||||||
{...props}
|
{...props}
|
||||||
value={token.address}
|
value={token?.address || ''}
|
||||||
title={token.address}
|
title={token?.address}
|
||||||
ref={forwardedRef}
|
ref={forwardedRef}
|
||||||
>
|
>
|
||||||
<Select.ItemText>
|
<Select.ItemText>
|
||||||
<span className="TokenLogo">
|
<span className="TokenLogo">
|
||||||
{token.logo ? (
|
{token?.logo ? (
|
||||||
<img src={token.logo} width="32" height="32" />
|
<img src={token.logo} width="32" height="32" />
|
||||||
) : (
|
) : (
|
||||||
token.symbol?.substring(0, 3)
|
token?.symbol?.substring(0, 3)
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</Select.ItemText>
|
</Select.ItemText>
|
||||||
<div>
|
<div>
|
||||||
<h3 className="TokenName">{token.name}</h3>
|
<h3 className="TokenName">{token?.name}</h3>
|
||||||
<p className="TokenBalance">{balance}</p>
|
<p className="TokenBalance">{balance}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="TokenValue">{valueInUsdFormatted}</div>
|
<div className="TokenValue">{valueInUsdFormatted}</div>
|
||||||
|
@ -4,11 +4,13 @@ import { Token } from './Token'
|
|||||||
import { ChevronDown, ChevronsDown, ChevronsUp } from '@images/components/react'
|
import { ChevronDown, ChevronsDown, ChevronsUp } from '@images/components/react'
|
||||||
import { useTokens } from '../../hooks/useTokens'
|
import { useTokens } from '../../hooks/useTokens'
|
||||||
import { TokenLoading } from './TokenLoading'
|
import { TokenLoading } from './TokenLoading'
|
||||||
|
import type { GetToken } from '../../api/getTokens'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
export function TokenSelect({
|
export function TokenSelect({
|
||||||
setToken
|
setTokenSelected
|
||||||
}: {
|
}: {
|
||||||
setToken: (token: string) => void
|
setTokenSelected: React.Dispatch<React.SetStateAction<GetToken>>
|
||||||
}) {
|
}) {
|
||||||
const { data: tokens, isLoading } = useTokens()
|
const { data: tokens, isLoading } = useTokens()
|
||||||
|
|
||||||
@ -16,10 +18,19 @@ export function TokenSelect({
|
|||||||
<Token key={token.address} token={token} />
|
<Token key={token.address} token={token} />
|
||||||
))
|
))
|
||||||
|
|
||||||
|
function handleValueChange(value: `0x${string}`) {
|
||||||
|
const token = tokens?.find((token) => token.address === value)
|
||||||
|
if (!token) return
|
||||||
|
setTokenSelected(token)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set default token data
|
||||||
|
useEffect(() => handleValueChange('0x0'), [])
|
||||||
|
|
||||||
return tokens ? (
|
return tokens ? (
|
||||||
<Select.Root
|
<Select.Root
|
||||||
defaultValue={tokens?.[0].address}
|
defaultValue={tokens?.[0].address}
|
||||||
onValueChange={(value) => setToken(value)}
|
onValueChange={(value: `0x${string}`) => handleValueChange(value)}
|
||||||
disabled={!tokens || isLoading}
|
disabled={!tokens || isLoading}
|
||||||
>
|
>
|
||||||
<Select.Trigger
|
<Select.Trigger
|
||||||
|
@ -1,98 +1,102 @@
|
|||||||
import { type ReactElement, useState } from 'react'
|
import { type ReactElement, useState, useEffect } from 'react'
|
||||||
import { useDebounce } from 'use-debounce'
|
import { useDebounce } from 'use-debounce'
|
||||||
import { parseEther } from 'viem'
|
import { useAccount } from 'wagmi'
|
||||||
import {
|
|
||||||
useAccount,
|
|
||||||
useNetwork,
|
|
||||||
usePrepareSendTransaction,
|
|
||||||
useSendTransaction
|
|
||||||
} from 'wagmi'
|
|
||||||
import { ConnectButton } from '@rainbow-me/rainbowkit'
|
import { ConnectButton } from '@rainbow-me/rainbowkit'
|
||||||
|
|
||||||
import Alert, { getTransactionMessage } from './components/Alert/Alert'
|
import Alert, { getTransactionMessage } from './components/Alert/Alert'
|
||||||
import { InputGroup } from './components/Input'
|
import { InputGroup } from './components/Input'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
|
import { SendNative, SendErc20 } from './components/Send'
|
||||||
|
import type { GetToken } from './api/getTokens'
|
||||||
|
|
||||||
export default function Web3Donation({
|
export default function Web3Donation(): ReactElement {
|
||||||
address
|
|
||||||
}: {
|
|
||||||
address: string
|
|
||||||
}): ReactElement {
|
|
||||||
const { address: account } = useAccount()
|
const { address: account } = useAccount()
|
||||||
const { chain } = useNetwork()
|
|
||||||
|
|
||||||
const [amount, setAmount] = useState('')
|
const [amount, setAmount] = useState('')
|
||||||
const [debouncedAmount] = useDebounce(amount, 500)
|
const [debouncedAmount] = useDebounce(amount, 500)
|
||||||
const [token, setToken] = useState<string>()
|
const [tokenSelected, setTokenSelected] = useState<GetToken>({
|
||||||
|
address: '0x0'
|
||||||
|
} as any)
|
||||||
const [message, setMessage] = useState<{ status: string; text: string }>()
|
const [message, setMessage] = useState<{ status: string; text: string }>()
|
||||||
const [transactionHash, setTransactionHash] = useState<string>()
|
const [sendFormData, setSendFormData] = useState<{
|
||||||
|
data: { hash: `0x${string}` }
|
||||||
|
send: () => Promise<void>
|
||||||
|
isLoading: boolean
|
||||||
|
isSuccess: boolean
|
||||||
|
isError: boolean
|
||||||
|
error: Error | null
|
||||||
|
}>()
|
||||||
|
|
||||||
// dummy
|
const { data, send, isLoading, isSuccess, isError, error } =
|
||||||
if (token) {
|
sendFormData || {}
|
||||||
console.log(token)
|
|
||||||
}
|
|
||||||
|
|
||||||
const { config } = usePrepareSendTransaction({
|
useEffect(() => {
|
||||||
chainId: chain?.id,
|
if (!isError || !error) return
|
||||||
to: address,
|
|
||||||
value: parseEther(debouncedAmount)
|
setMessage(
|
||||||
})
|
error.message.includes('User rejected the request.')
|
||||||
const { sendTransactionAsync, isError, isSuccess } =
|
? undefined
|
||||||
useSendTransaction(config)
|
: {
|
||||||
|
status: 'error',
|
||||||
|
text: error?.message as string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}, [isError])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isLoading) return
|
||||||
|
|
||||||
async function handleSendTransaction() {
|
|
||||||
setMessage({
|
setMessage({
|
||||||
status: 'loading',
|
status: 'loading',
|
||||||
text: getTransactionMessage().waitingForUser
|
text: getTransactionMessage().waitingConfirmation
|
||||||
})
|
})
|
||||||
|
}, [isLoading])
|
||||||
|
|
||||||
try {
|
useEffect(() => {
|
||||||
const result = sendTransactionAsync && (await sendTransactionAsync())
|
if (!isSuccess) return
|
||||||
|
|
||||||
if (isError) {
|
setMessage({
|
||||||
throw new Error(undefined)
|
status: 'success',
|
||||||
}
|
text: getTransactionMessage().success
|
||||||
|
})
|
||||||
setTransactionHash(result?.hash)
|
}, [isSuccess])
|
||||||
setMessage({
|
|
||||||
status: 'loading',
|
|
||||||
text: getTransactionMessage().waitingConfirmation
|
|
||||||
})
|
|
||||||
|
|
||||||
if (isSuccess) {
|
|
||||||
setMessage({
|
|
||||||
status: 'success',
|
|
||||||
text: getTransactionMessage().success
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setMessage(undefined)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const isDisabled = !account
|
const isDisabled = !account
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={styles.web3}
|
className={styles.web3}
|
||||||
onSubmit={(e) => {
|
onSubmit={async (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
handleSendTransaction()
|
if (!send || amount === '' || amount === '0') return
|
||||||
|
await send()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ConnectButton chainStatus="icon" showBalance={false} />
|
<ConnectButton chainStatus="icon" showBalance={false} />
|
||||||
|
|
||||||
{message ? (
|
{message ? (
|
||||||
<Alert message={message} transactionHash={transactionHash} />
|
<Alert message={message} transactionHash={data?.hash} />
|
||||||
) : (
|
) : (
|
||||||
<InputGroup
|
<InputGroup
|
||||||
amount={amount}
|
amount={amount}
|
||||||
symbol={chain?.nativeCurrency?.symbol || 'ETH'}
|
token={tokenSelected}
|
||||||
setAmount={setAmount}
|
setAmount={setAmount}
|
||||||
setToken={setToken}
|
setTokenSelected={setTokenSelected}
|
||||||
isDisabled={isDisabled}
|
isDisabled={isDisabled}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{tokenSelected?.address === '0x0' ? (
|
||||||
|
<SendNative
|
||||||
|
amount={debouncedAmount}
|
||||||
|
setSendFormData={setSendFormData}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<SendErc20
|
||||||
|
amount={debouncedAmount}
|
||||||
|
tokenAddress={tokenSelected?.address}
|
||||||
|
setSendFormData={setSendFormData}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,12 @@ const coins = Object.entries(config.author).filter(
|
|||||||
<BackButton />
|
<BackButton />
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3 class="subTitle">Send from your browser wallet.</h3>
|
<h3 class="subTitle">Send from your browser wallet</h3>
|
||||||
<Web3 client:only="react" />
|
<Web3 client:only="react" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3 class="subTitle">Send from any wallet.</h3>
|
<h3 class="subTitle">Send from any wallet</h3>
|
||||||
|
|
||||||
{
|
{
|
||||||
coins.map(([key, value]: [key: string, value: string]) => (
|
coins.map(([key, value]: [key: string, value: string]) => (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user