import React, { useCallback, useEffect, useRef, useState } from "react";
import { Onramper } from "./Onramper";
import { useEthers, useEtherBalance, useTokenBalance } from "@usedapp/core";
import { WebViewMessageEvent } from "react-native-webview";
import { AsyncStorage, useBuyGd } from "@gooddollar/web3sdk-v2";
import { noop } from "lodash";
import { useModal } from "../../hooks/useModal";
import { View, Text } from "native-base";
import { WalletAndChainGuard } from "../../core";
import { useSignWalletModal } from "../../hooks/useSignWalletModal";
const ErrorModal = () => (
Something went wrong.
);
interface IGdOnramperProps {
isTesting?: boolean;
onEvents: (action: string, data?: any, error?: string) => void;
selfSwap?: boolean;
withSwap?: boolean;
donateOrExecTo?: string;
callData?: string;
apiKey?: string;
}
export const GdOnramperWidget = ({
isTesting = false,
onEvents = noop,
selfSwap = false,
withSwap = true,
donateOrExecTo = undefined,
callData = "0x",
apiKey = undefined
}: IGdOnramperProps) => {
const cusd = "0x765de816845861e75a25fca122bb6898b8b1282a";
const { account, library } = useEthers();
const swapLock = useRef(false);
const { createAndSwap, swap, swapState, createState, gdHelperAddress, triggerSwapTx } = useBuyGd({
donateOrExecTo,
callData,
withSwap
});
const { SignWalletModal } = useSignWalletModal();
const celoBalance = useEtherBalance(gdHelperAddress, { refresh: 1 });
// const accountCeloBalance = useEtherBalance(account, { refresh: 1 }) || ethers.constants.Zero;
const cusdBalance = useTokenBalance(cusd, gdHelperAddress, { refresh: 1 });
const { showModal, Modal } = useModal();
const [step, setStep] = useState(0);
// console.log({ selfSwap, account, gdHelperAddress, accountCeloBalance, cusdBalance, celoBalance });
/**
* callback to get event from onramper iframe
*/
const callback = useCallback(async (event: WebViewMessageEvent) => {
if ((event.nativeEvent.data as any).title === "success") {
await AsyncStorage.setItem("gdOnrampSuccess", "true");
//start the stepper
setStep(2);
}
}, []);
const triggerSwap = async () => {
if (swapLock.current) return; //prevent from useEffect retriggering this
swapLock.current = true;
try {
setStep(3);
//user sends swap tx
if (selfSwap && gdHelperAddress && library && account) {
const minAmount = 0; // we let contract use oracle for minamount, we might calculate it for more precision in the future
const code = await library.getCode(gdHelperAddress);
let swapTx;
if (code.length <= 2) {
console.log("deploying helper...");
swapTx = createAndSwap(minAmount);
} else {
swapTx = swap(minAmount);
}
setStep(4);
// after tx sent progress the stepper
const res = await swapTx;
console.log("swap tx res:", res);
if (res?.status !== 1) throw Error("reverted");
} else {
if (account) {
//or backends sends swap tx
setStep(4);
const tx = await triggerSwapTx();
if (!tx?.ok) throw Error("reverted");
}
}
// when done set stepper at final step
setStep(5);
swapLock.current = false;
onEvents("buy_success");
} catch (e: any) {
console.log("swap error:", e.message, e);
showModal();
onEvents("buygd_swap_failed", e.message);
setStep(0);
}
};
// when the helper contract has some balance we trigger the swap
useEffect(() => {
if (cusdBalance?.gt(0) || celoBalance?.gt(0)) {
void AsyncStorage.removeItem("gdOnrampSuccess");
console.log("starting swap:", cusdBalance?.toString(), celoBalance?.toString());
triggerSwap().catch(e => {
showModal();
onEvents("buygd_swap_failed", e.message);
});
}
}, [celoBalance, cusdBalance]);
return (
<>
} _modalContainer={{ paddingBottom: 18, paddingLeft: 18, paddingRight: 18 }} />
>
);
};