diff --git a/src/components/Sponsor/Web3Donation/components/Input/InputGroup.module.css b/src/components/Sponsor/Web3Donation/components/Input/InputGroup.module.css
index 6fb0c48f..645fc329 100644
--- a/src/components/Sponsor/Web3Donation/components/Input/InputGroup.module.css
+++ b/src/components/Sponsor/Web3Donation/components/Input/InputGroup.module.css
@@ -74,6 +74,10 @@
color: var(--text-color-light);
}
+.disclaimer code {
+ color: var(--text-color);
+}
+
@keyframes fadeIn {
from {
opacity: 0.01;
diff --git a/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx b/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx
index 3fe4f3ab..df706729 100644
--- a/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx
+++ b/src/components/Sponsor/Web3Donation/components/Input/InputGroup.tsx
@@ -4,25 +4,26 @@ import { Conversion } from '../Conversion'
import styles from './InputGroup.module.css'
import { TokenSelect } from '../Tokens'
import config from '@config/blog.config'
+import type { GetToken } from '../../api/getTokens'
export function InputGroup({
amount,
+ token,
isDisabled,
- symbol,
setAmount,
- setToken
+ setTokenSelected
}: {
amount: string
+ token: GetToken | undefined
isDisabled: boolean
- symbol: string
- setAmount(amount: string): void
- setToken(token: string): void
+ setAmount: React.Dispatch
>
+ setTokenSelected: React.Dispatch>
}): ReactElement {
return (
<>
-
+
This form sends tokens to my account {config.author.ether}
diff --git a/src/components/Sponsor/Web3Donation/components/Send/SendErc20.tsx b/src/components/Sponsor/Web3Donation/components/Send/SendErc20.tsx
new file mode 100644
index 00000000..681e0040
--- /dev/null
+++ b/src/components/Sponsor/Web3Donation/components/Send/SendErc20.tsx
@@ -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 <>>
+}
diff --git a/src/components/Sponsor/Web3Donation/components/Send/SendNative.tsx b/src/components/Sponsor/Web3Donation/components/Send/SendNative.tsx
new file mode 100644
index 00000000..c2f5c881
--- /dev/null
+++ b/src/components/Sponsor/Web3Donation/components/Send/SendNative.tsx
@@ -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 <>>
+}
diff --git a/src/components/Sponsor/Web3Donation/components/Send/abi.ts b/src/components/Sponsor/Web3Donation/components/Send/abi.ts
new file mode 100644
index 00000000..60f186d5
--- /dev/null
+++ b/src/components/Sponsor/Web3Donation/components/Send/abi.ts
@@ -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'
+ }
+]
diff --git a/src/components/Sponsor/Web3Donation/components/Send/index.tsx b/src/components/Sponsor/Web3Donation/components/Send/index.tsx
new file mode 100644
index 00000000..a286ddb3
--- /dev/null
+++ b/src/components/Sponsor/Web3Donation/components/Send/index.tsx
@@ -0,0 +1,2 @@
+export * from './SendErc20'
+export * from './SendNative'
diff --git a/src/components/Sponsor/Web3Donation/components/Tokens/Token.tsx b/src/components/Sponsor/Web3Donation/components/Tokens/Token.tsx
index 8987f930..f7607df4 100644
--- a/src/components/Sponsor/Web3Donation/components/Tokens/Token.tsx
+++ b/src/components/Sponsor/Web3Donation/components/Tokens/Token.tsx
@@ -6,13 +6,13 @@ import { Check } from '@images/components/react'
import type { GetToken } from '../../api/getTokens'
interface SelectItemProps extends HTMLAttributes {
- token: GetToken
+ token: GetToken | undefined
}
export const Token = forwardRef(
({ className, token, ...props }, forwardedRef) => {
const balance =
- token.balance && token.symbol
+ token?.balance && token?.symbol
? formatCurrency(token.balance, token.symbol, 'en', false, {
decimalPlaces: 3,
significantFigures: 3
@@ -20,28 +20,30 @@ export const Token = forwardRef(
: 0
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')
return balance && parseInt(balance) !== 0 && valueInUsd >= 1 ? (
- {token.logo ? (
+ {token?.logo ? (
) : (
- token.symbol?.substring(0, 3)
+ token?.symbol?.substring(0, 3)
)}
-
{token.name}
+
{token?.name}
{balance}
{valueInUsdFormatted}
diff --git a/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx b/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx
index 562a301d..aff0c99f 100644
--- a/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx
+++ b/src/components/Sponsor/Web3Donation/components/Tokens/TokenSelect.tsx
@@ -4,11 +4,13 @@ import { Token } from './Token'
import { ChevronDown, ChevronsDown, ChevronsUp } from '@images/components/react'
import { useTokens } from '../../hooks/useTokens'
import { TokenLoading } from './TokenLoading'
+import type { GetToken } from '../../api/getTokens'
+import { useEffect } from 'react'
export function TokenSelect({
- setToken
+ setTokenSelected
}: {
- setToken: (token: string) => void
+ setTokenSelected: React.Dispatch>
}) {
const { data: tokens, isLoading } = useTokens()
@@ -16,10 +18,19 @@ export function TokenSelect({
))
+ 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 ? (
setToken(value)}
+ onValueChange={(value: `0x${string}`) => handleValueChange(value)}
disabled={!tokens || isLoading}
>
()
+ const [tokenSelected, setTokenSelected] = useState({
+ address: '0x0'
+ } as any)
const [message, setMessage] = useState<{ status: string; text: string }>()
- const [transactionHash, setTransactionHash] = useState()
+ const [sendFormData, setSendFormData] = useState<{
+ data: { hash: `0x${string}` }
+ send: () => Promise
+ isLoading: boolean
+ isSuccess: boolean
+ isError: boolean
+ error: Error | null
+ }>()
- // dummy
- if (token) {
- console.log(token)
- }
+ const { data, send, isLoading, isSuccess, isError, error } =
+ sendFormData || {}
- const { config } = usePrepareSendTransaction({
- chainId: chain?.id,
- to: address,
- value: parseEther(debouncedAmount)
- })
- const { sendTransactionAsync, isError, isSuccess } =
- useSendTransaction(config)
+ useEffect(() => {
+ if (!isError || !error) return
+
+ setMessage(
+ error.message.includes('User rejected the request.')
+ ? undefined
+ : {
+ status: 'error',
+ text: error?.message as string
+ }
+ )
+ }, [isError])
+
+ useEffect(() => {
+ if (!isLoading) return
- async function handleSendTransaction() {
setMessage({
status: 'loading',
- text: getTransactionMessage().waitingForUser
+ text: getTransactionMessage().waitingConfirmation
})
+ }, [isLoading])
- try {
- const result = sendTransactionAsync && (await sendTransactionAsync())
+ useEffect(() => {
+ if (!isSuccess) return
- if (isError) {
- throw new Error(undefined)
- }
-
- setTransactionHash(result?.hash)
- setMessage({
- status: 'loading',
- text: getTransactionMessage().waitingConfirmation
- })
-
- if (isSuccess) {
- setMessage({
- status: 'success',
- text: getTransactionMessage().success
- })
- }
- } catch (error) {
- setMessage(undefined)
- }
- }
+ setMessage({
+ status: 'success',
+ text: getTransactionMessage().success
+ })
+ }, [isSuccess])
const isDisabled = !account
return (
)
}
diff --git a/src/pages/thanks.astro b/src/pages/thanks.astro
index 74ee3ce8..8a4d7a22 100644
--- a/src/pages/thanks.astro
+++ b/src/pages/thanks.astro
@@ -37,12 +37,12 @@ const coins = Object.entries(config.author).filter(
-
Send from your browser wallet.
+ Send from your browser wallet
-
Send from any wallet.
+ Send from any wallet
{
coins.map(([key, value]: [key: string, value: string]) => (