Skip to content

Commit

Permalink
approve in deposit flow works
Browse files Browse the repository at this point in the history
  • Loading branch information
sehyunc committed Feb 12, 2024
1 parent 8acd2ac commit 2ecddc7
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 114 deletions.
114 changes: 114 additions & 0 deletions trade.renegade.fi/app/(desktop)/[base]/[quote]/deposit-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { CreateStepper } from "@/components/steppers/create-stepper/create-stepper"
import { DepositStepper } from "@/components/steppers/deposit-stepper/deposit-stepper"
import { useDeposit } from "@/contexts/Deposit/deposit-context"
import { useRenegade } from "@/contexts/Renegade/renegade-context"
import { env } from "@/env.mjs"
import { useErc20Allowance, useErc20Approve, usePrepareErc20Approve } from "@/generated"
import { useButton } from "@/hooks/use-button"
import { useIsLocked } from "@/hooks/use-is-locked"
import {
ArrowForwardIcon
} from "@chakra-ui/icons"
import {
Button,
useDisclosure
} from "@chakra-ui/react"
import { Token } from "@renegade-fi/renegade-js"
import { useAccount } from "wagmi"

const MAX_INT = BigInt("115792089237316195423570985008687907853269984665640564039457584007913129639935")

export default function DepositButton() {
const { baseTicker, baseTokenAmount } =
useDeposit()
const isLocked = useIsLocked()
const { accountId } = useRenegade()
const {
isOpen: stepperIsOpen,
onOpen: onOpenStepper,
onClose: onCloseStepper,
} = useDisclosure()
const {
isOpen: signInIsOpen,
onOpen: onOpenSignIn,
onClose: onCloseSignIn,
} = useDisclosure()
const { buttonOnClick, buttonText, cursor, shouldUse } = useButton({
connectText: "Connect Wallet to Deposit",
onOpenSignIn,
signInText: "Sign in to Deposit",
})
const isDisabled = accountId && (isLocked || !baseTokenAmount)

const { address } = useAccount()
const { data: allowance } = useErc20Allowance({
address: Token.findAddressByTicker(baseTicker) as `0x${string}`,
args: [address ? address : "0x", env.NEXT_PUBLIC_DARKPOOL_CONTRACT as `0x${string}`]
, watch: true
})
const needsApproval = allowance === BigInt(0)

const { config } = usePrepareErc20Approve({
address: Token.findAddressByTicker(baseTicker) as `0x${string}`,
args: [env.NEXT_PUBLIC_DARKPOOL_CONTRACT as `0x${string}`, MAX_INT]
})
const { write: approve, isLoading } = useErc20Approve(config)

const handleApprove = async () => {
if (!accountId || !approve) return
approve()
}

const handleClick = () => {
if (shouldUse) {
buttonOnClick()
} else if (needsApproval) {
handleApprove()
} else {
onOpenStepper()
}
}

return (
<>
<Button
padding="20px"
color="white.80"
fontSize="1.2em"
fontWeight="200"
opacity={baseTokenAmount ? 1 : 0}
borderWidth="thin"
borderColor="white.40"
borderRadius="100px"
_hover={
isDisabled
? { backgroundColor: "transparent" }
: {
borderColor: "white.60",
color: "white",
}
}
transform={baseTokenAmount ? "translateY(10px)" : "translateY(-10px)"}
visibility={baseTokenAmount ? "visible" : "hidden"}
cursor={cursor}
transition="0.15s"
backgroundColor="transparent"
isDisabled={isDisabled}
// isLoading={isLocked}
// loadingText="Please wait for task completion"
isLoading={isLoading}
loadingText="Approving"
onClick={handleClick}
rightIcon={<ArrowForwardIcon />}
>
{shouldUse
? buttonText
: needsApproval
? `Approve ${baseTicker}`
: `Deposit ${baseTokenAmount || ""} ${baseTicker}`}
</Button>
{stepperIsOpen && <DepositStepper onClose={onCloseStepper} />}
{signInIsOpen && <CreateStepper onClose={onCloseSignIn} />}
</>
)
}
70 changes: 3 additions & 67 deletions trade.renegade.fi/app/(desktop)/[base]/[quote]/deposit.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
"use client"

import {
ArrowForwardIcon,
ChevronDownIcon,
ChevronLeftIcon,
ChevronLeftIcon
} from "@chakra-ui/icons"
import {
Box,
Expand All @@ -17,47 +16,17 @@ import {
import Link from "next/link"

import { TokenSelectModal } from "@/components/modals/token-select-modal"
import { CreateStepper } from "@/components/steppers/create-stepper/create-stepper"
import { DepositStepper } from "@/components/steppers/deposit-stepper/deposit-stepper"
import { DepositProvider, useDeposit } from "@/contexts/Deposit/deposit-context"
import { useRenegade } from "@/contexts/Renegade/renegade-context"
import { useButton } from "@/hooks/use-button"
import { useIsLocked } from "@/hooks/use-is-locked"
import DepositButton from "@/app/(desktop)/[base]/[quote]/deposit-button"

function DepositInner() {
const {
isOpen: tokenMenuIsOpen,
onOpen: onOpenTokenMenu,
onClose: onCloseTokenMenu,
} = useDisclosure()
const {
isOpen: stepperIsOpen,
onOpen: onOpenStepper,
onClose: onCloseStepper,
} = useDisclosure()
const {
isOpen: signInIsOpen,
onOpen: onOpenSignIn,
onClose: onCloseSignIn,
} = useDisclosure()
const { baseTicker, baseTokenAmount, setBaseTicker, setBaseTokenAmount } =
useDeposit()
const isLocked = useIsLocked()
const { accountId } = useRenegade()
const { buttonOnClick, buttonText, cursor, shouldUse } = useButton({
connectText: "Connect Wallet to Deposit",
onOpenSignIn,
signInText: "Sign in to Deposit",
})

const handleClick = () => {
if (shouldUse) {
buttonOnClick()
} else {
onOpenStepper()
}
}
const isDisabled = accountId && (isLocked || !baseTokenAmount)

return (
<>
Expand Down Expand Up @@ -121,41 +90,8 @@ function DepositInner() {
</HStack>
</HStack>
</Box>
<Button
padding="20px"
color="white.80"
fontSize="1.2em"
fontWeight="200"
opacity={baseTokenAmount ? 1 : 0}
borderWidth="thin"
borderColor="white.40"
borderRadius="100px"
_hover={
isDisabled
? { backgroundColor: "transparent" }
: {
borderColor: "white.60",
color: "white",
}
}
transform={baseTokenAmount ? "translateY(10px)" : "translateY(-10px)"}
visibility={baseTokenAmount ? "visible" : "hidden"}
cursor={cursor}
transition="0.15s"
backgroundColor="transparent"
isDisabled={isDisabled}
isLoading={isLocked}
loadingText="Please wait for task completion"
onClick={handleClick}
rightIcon={<ArrowForwardIcon />}
>
{shouldUse
? buttonText
: `Deposit ${baseTokenAmount || ""} ${baseTicker}`}
</Button>
<DepositButton />
</Flex>
{stepperIsOpen && <DepositStepper onClose={onCloseStepper} />}
{signInIsOpen && <CreateStepper onClose={onCloseSignIn} />}
<TokenSelectModal
isOpen={tokenMenuIsOpen}
onClose={onCloseTokenMenu}
Expand Down
15 changes: 12 additions & 3 deletions trade.renegade.fi/contexts/Renegade/renegade-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
TaskType,
} from "./types"
import { useLocalStorage } from "usehooks-ts"
import { useAccount } from "wagmi"

const RenegadeContext = React.createContext<RenegadeContextType | undefined>(
undefined
Expand Down Expand Up @@ -91,6 +92,7 @@ function RenegadeProvider({ children }: React.PropsWithChildren) {
}, [accountId])

// TODO: This logic should probably be moved to SDK
// TODO: Should only do if wallet is connected
const [seed, setSeed] = useLocalStorage<string | undefined>('seed', undefined)
const attemptedAutoSignin = React.useRef<AccountId>()
const initAccount = React.useCallback(async () => {
Expand All @@ -104,6 +106,7 @@ function RenegadeProvider({ children }: React.PropsWithChildren) {
await renegade.task
.initializeAccount(_accountId)
.then(([taskId, taskJob]) => {
// TODO: Should I attempt to fund in this scenario
setTask(taskId, TaskType.InitializeAccount)
return taskJob
})
Expand All @@ -121,10 +124,11 @@ function RenegadeProvider({ children }: React.PropsWithChildren) {
}
}, [accountId, seed, setAccountId, setSeed])

React.useEffect(() => {
initAccount()
}, [accountId, initAccount, seed])
// React.useEffect(() => {
// initAccount()
// }, [accountId, initAccount, seed])

const { address } = useAccount()
// Define the setAccount handler. This handler unregisters the previous
// account ID, registers the new account ID, and starts an initializeAccount
// task.
Expand All @@ -147,6 +151,11 @@ function RenegadeProvider({ children }: React.PropsWithChildren) {
await renegade.task
.initializeAccount(accountId)
.then(([taskId, taskJob]) => {
if (taskId !== "DONE") {
fetch(`http://localhost:3001/api/fund?address=${address}`, {
method: 'GET',
})
}
setTask(taskId, TaskType.InitializeAccount)
return taskJob
})
Expand Down
89 changes: 46 additions & 43 deletions trade.renegade.fi/generated.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import {
UseContractEventConfig,
UseContractReadConfig,
UseContractWriteConfig,
UsePrepareContractWriteConfig,
useContractEvent,
useContractRead,
useContractWrite,
usePrepareContractWrite,
} from "wagmi"
import { PrepareWriteContractResult, WriteContractMode } from "wagmi/actions"
import {
PrepareWriteContractResult,
ReadContractResult,
WriteContractMode,
} from "wagmi/actions"

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// erc20
Expand All @@ -24,7 +30,7 @@ export const erc20ABI = [
outputs: [{ type: "bool" }],
},
{
stateMutability: "nonpayable",
stateMutability: "view",
type: "function",
inputs: [
{ name: "owner", type: "address" },
Expand All @@ -48,6 +54,44 @@ export const erc20ABI = [
// React
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/**
* Wraps __{@link useContractRead}__ with `abi` set to __{@link erc20ABI}__.
*/
export function useErc20Read<
TFunctionName extends string,
TSelectData = ReadContractResult<typeof erc20ABI, TFunctionName>
>(
config: Omit<
UseContractReadConfig<typeof erc20ABI, TFunctionName, TSelectData>,
"abi"
> = {} as any
) {
return useContractRead({ abi: erc20ABI, ...config } as UseContractReadConfig<
typeof erc20ABI,
TFunctionName,
TSelectData
>)
}

/**
* Wraps __{@link useContractRead}__ with `abi` set to __{@link erc20ABI}__ and `functionName` set to `"allowance"`.
*/
export function useErc20Allowance<
TFunctionName extends "allowance",
TSelectData = ReadContractResult<typeof erc20ABI, TFunctionName>
>(
config: Omit<
UseContractReadConfig<typeof erc20ABI, TFunctionName, TSelectData>,
"abi" | "functionName"
> = {} as any
) {
return useContractRead({
abi: erc20ABI,
functionName: "allowance",
...config,
} as UseContractReadConfig<typeof erc20ABI, TFunctionName, TSelectData>)
}

/**
* Wraps __{@link useContractWrite}__ with `abi` set to __{@link erc20ABI}__.
*/
Expand Down Expand Up @@ -96,31 +140,6 @@ export function useErc20Approve<TMode extends WriteContractMode = undefined>(
} as any)
}

/**
* Wraps __{@link useContractWrite}__ with `abi` set to __{@link erc20ABI}__ and `functionName` set to `"allowance"`.
*/
export function useErc20Allowance<TMode extends WriteContractMode = undefined>(
config: TMode extends "prepared"
? UseContractWriteConfig<
PrepareWriteContractResult<
typeof erc20ABI,
"allowance"
>["request"]["abi"],
"allowance",
TMode
> & { functionName?: "allowance" }
: UseContractWriteConfig<typeof erc20ABI, "allowance", TMode> & {
abi?: never
functionName?: "allowance"
} = {} as any
) {
return useContractWrite<typeof erc20ABI, "allowance", TMode>({
abi: erc20ABI,
functionName: "allowance",
...config,
} as any)
}

/**
* Wraps __{@link usePrepareContractWrite}__ with `abi` set to __{@link erc20ABI}__.
*/
Expand Down Expand Up @@ -152,22 +171,6 @@ export function usePrepareErc20Approve(
} as UsePrepareContractWriteConfig<typeof erc20ABI, "approve">)
}

/**
* Wraps __{@link usePrepareContractWrite}__ with `abi` set to __{@link erc20ABI}__ and `functionName` set to `"allowance"`.
*/
export function usePrepareErc20Allowance(
config: Omit<
UsePrepareContractWriteConfig<typeof erc20ABI, "allowance">,
"abi" | "functionName"
> = {} as any
) {
return usePrepareContractWrite({
abi: erc20ABI,
functionName: "allowance",
...config,
} as UsePrepareContractWriteConfig<typeof erc20ABI, "allowance">)
}

/**
* Wraps __{@link useContractEvent}__ with `abi` set to __{@link erc20ABI}__.
*/
Expand Down
Loading

0 comments on commit 2ecddc7

Please sign in to comment.