import React, { useEffect, useState } from "react"; import { api0x } from "../../utils/0x"; import { BigNumber } from "@0x/utils"; import { ERC20TokenContract } from "@0x/contract-wrappers"; import history from "../Utils/history"; import AlertModal from "../Utils/AlertModal"; import SuccessModal from "../Utils/SuccessModal"; import { precision } from "../../utils/precision"; import zeroxLogo from "../../assets/0x.png"; import { Row, Col, Form, Button, Dropdown, DropdownButton, Card, Image, } from "react-bootstrap"; export default function SwapToken({ buyToken, fixedBuyToken, availableBalance, balanaceNeeded }) { const [processing, setProcessing] = useState(false); const [allTokens, setAllTokens] = useState([]); const [state, setState] = useState({ buyToken: buyToken, sellToken: "USDC", buyAmount: "1", }); const [errorModal, setErrorModal] = useState({ msg: "", open: false }); const [successModal, setSuccessModal] = useState({ msg: "", open: false }); const handleSwapToken = async () => { try { const quote = await api0x.fetchTokenQuote({ buyToken: state.buyToken, sellToken: state.sellToken, buyAmount: await precision.add( state.buyAmount, 18, ), }); if (state.sellToken !== "ETH") { let tokenAddress; allTokens.forEach((element) => { if (state.sellToken === element.symbol) tokenAddress = element.address }); const contract = new ERC20TokenContract( tokenAddress, window.web3.eth.currentProvider ); const maxApproval = new BigNumber(2) .pow(256).minus(1); const approvalTxData = await contract .approve(quote.allowanceTarget, maxApproval) .getABIEncodedTransactionData(); await window.web3.eth.sendTransaction ({ to: tokenAddress, data: approvalTxData, from: window.userAddress }) .on("transactionHash", () => { setProcessing(true); }); } await window.web3.eth.sendTransaction(quote) .on("transactionHash", () => { setProcessing(true); }) .on("receipt", () => { setProcessing(false); setSuccessModal({ open: true, msg: "Congratulations 🎉 !!" }); }); } catch (error) { setProcessing(false); setErrorModal({ open: true, msg: error.message, }); } }; const fetchAllTokens = async () => { const tokens = await api0x.fetchAllTokens(); setAllTokens([{ symbol: "ETH" }].concat(tokens.records)); }; const handleReload = () => { history.go(0); } useEffect(() => { if (allTokens.length === 0) { fetchAllTokens(); } }); return ( <div> <Card className="mx-auto form-card text-center" style={{ backgroundColor: "rgb(253, 255, 255)" }} > <Card.Header> Swap Your Asset </Card.Header> <Card.Body> {fixedBuyToken ? <div> <div style={{ marginBottom: "20px", color: "orange" }}> You don't have enough collateral amount available in your wallet. Please use another wallet or Get Token by swapping another asset directly from 0x protocol using below method: </div> <Row className="text-center" style={{ paddingBottom: "20px" }}> <Col> <u>Available Balance</u> <span> : </span> <span>{availableBalance} {buyToken}</span> </Col> </Row> <Row className="text-center" style={{ paddingBottom: "30px" }}> <Col> <u>Balance Needed</u> <span> : </span> <span>{balanaceNeeded} {buyToken}</span> </Col> </Row> </div> : <div className="auction-message" style={{ fontSize: "medium" }} > * Swap Using 0x Protocol </div> } <Row> <Col className="text-header"> Buy Token: </Col> {fixedBuyToken ? <Col style={{ paddingLeft: "0px" }}> <Form.Control className="mb-4" type="text" style={{ width: "60%" }} value={state.buyToken} readOnly={!buyToken ? false : true} /> </Col> : <Col className="text-left float-left" style={{ marginBottom: "20px", paddingLeft: "0px" }} > <DropdownButton title={state.buyToken} variant="outline-info" onSelect={(event) => setState({ ...state, buyToken: event })} > {allTokens.map((element, key) => ( <Dropdown.Item key={key} eventKey={element.symbol} > {element.symbol} </Dropdown.Item> ))} </DropdownButton> </Col> } </Row> <Row style={{ marginBottom: "30px" }}> <Col className="text-header"> Sell Token: </Col> <Col style={{ paddingLeft: "0px" }}> <DropdownButton style={{ position: "absolute", }} title={state.sellToken} variant="outline-info" onSelect={(event) => setState({ ...state, sellToken: event })} > {allTokens.map((element, key) => ( <Dropdown.Item key={key} eventKey={element.symbol} > {element.symbol} </Dropdown.Item> ))} </DropdownButton> </Col> </Row> <Row> <Col className="text-header"> Buy Amount: </Col> <Col style={{ paddingLeft: "0px" }}> <Form.Control className="mb-4" type="number" min="0" placeholder="0" onChange={async (e) => setState({ ...state, buyAmount: e.target.value, })} style={{ width: "60%" }} value={state.buyAmount} /> </Col> </Row> <Row className="text-center"> <Col> <Button onClick={handleSwapToken} variant="outline-success" > {processing ? <div className="d-flex align-items-center"> Processing <span className="loading ml-2"></span> </div> : <div> <Image src={zeroxLogo} width="25px"></Image> <span> Submit</span> </div> } </Button> </Col> </Row> </Card.Body> </Card> <AlertModal open={errorModal.open} toggle={() => setErrorModal({ ...errorModal, open: false })} > {errorModal.msg} </AlertModal> <SuccessModal open={successModal.open} toggle={() => setSuccessModal({ ...successModal, open: false })} onConfirm={handleReload} > {successModal.msg} </SuccessModal> </div> ); }