'use client' import React, { useEffect, useState } from 'react' import { autorun } from 'mobx' import { observer } from 'mobx-react-lite' import { ethers } from 'ethers' import { Button, Input, Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, toast } from '@hanzo/ui/primitives' import Eth from '../crypto-icons/eth' import { useCommerce } from '../../../../service/context' import type { PaymentMethodComponentProps } from '../../../../types' import { sendFBEvent, sendGAEvent } from '../../../../util/analytics' import ContactForm from '../contact-form' declare global { interface Window{ ethereum?: any } } const PayWithCrypto: React.FC = observer(({ onDone, transactionStatus, setTransactionStatus, storePaymentInfo, contactForm }) => { const cmmc = useCommerce() const [loadingPrice, setLoadingPrice] = useState(false) //const [selectedToken, setSelectedToken] = useState('eth') const [amount, setAmount] = useState() const [provider, setProvider] = useState() //const selectedToken = 'eth' useEffect(() => { setTransactionStatus('unpaid') // responding to changes in user.walletAddress return autorun(() => { const newProvider = new ethers.BrowserProvider(window.ethereum) setProvider(newProvider) }) }, []) // Get latest USD -> ETH exchange rate useEffect(() => { const fetchPrice = () => { setLoadingPrice(true) fetch(process.env.NEXT_PUBLIC_ETH_EXCHANGE_RATE_API ?? '') .then(res => res.json()) .then((exchangeRate) => { const oneUsdInWei = (10**18) / exchangeRate.data.amount const usdAmountInWei = oneUsdInWei * cmmc.promoAppliedCartTotal setAmount(usdAmountInWei) setLoadingPrice(false) }) } // Call immediately on load fetchPrice() // Then set interval to call every 30 seconds const interval = setInterval(fetchPrice, 30000) return () => clearInterval(interval) }, [cmmc.promoAppliedCartTotal]) const sendPayment = async (ether: number) => { contactForm.handleSubmit(async () => { // Check that we are on ethereum network try { await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: "0x1"}], }) const newProvider = new ethers.BrowserProvider(window.ethereum) setProvider(newProvider) } catch (err) { toast('Please switch your wallet to the Ethereum network.') return } try { if (!provider) { // :aa TODO string table throw new Error('No crypto wallet found. Please install it.') } await window.ethereum.send('eth_requestAccounts') const signer = await provider.getSigner() ethers.getAddress(process.env.NEXT_PUBLIC_ETH_PAYMENT_ADDRESS ?? '') const price = ethers.parseEther(ether.toString()) const tx = await signer.sendTransaction({ to: process.env.NEXT_PUBLIC_ETH_PAYMENT_ADDRESS, value: price }) console.log({ ether, addr: process.env.NEXT_PUBLIC_ETH_PAYMENT_ADDRESS }) console.log('tx', tx) setTransactionStatus('paid') await storePaymentInfo({ ether, transactionHash: tx.hash, to: process.env.NEXT_PUBLIC_ETH_PAYMENT_ADDRESS, paymentMethod: 'crypto' }) provider.waitForTransaction(tx.hash) .then(async (receipt) => { console.log(receipt) await storePaymentInfo({ ether, addr: process.env.NEXT_PUBLIC_ETH_PAYMENT_ADDRESS, receipt, paymentMethod: 'crypto' }) sendGAEvent('purchase', { transaction_id: tx.hash, value: price, currency: 'ETH', items: cmmc.cartItems.map((item) => ({ item_id: item.sku, item_name: item.title, item_category: item.familyId, price: item.price, quantity: item.quantity })), }) sendFBEvent('Purchase', { content_ids: cmmc.cartItems.map((item) => item.sku), contents: cmmc.cartItems.map(item => ({ id: item.sku, quantity: item.quantity })), num_items: cmmc.cartItems.length, value: price, currency: 'ETH', }) setTransactionStatus('confirmed') }) .catch((error) => { console.error(error) setTransactionStatus('error') }) } catch (err) { console.log(err) // :aa TODO string table toast('Not enough funds in your wallet') } })() } const nextStep = async () => { await storePaymentInfo({ paymentMethod: 'crypto' }) onDone() } return (
ETH
{transactionStatus === 'error' ? (

There was an error while confirming the transaction.

) : transactionStatus === 'paid' ? (

Waiting for transaction to be confirmed on chain.

) : transactionStatus === 'confirmed' ? (

Transaction confirmed!

) : null} {transactionStatus === 'unpaid' ? ( ) : ( )}
) }) export default PayWithCrypto