Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Commit

Permalink
Wire up withdraw USDC saga to modal state (#4045)
Browse files Browse the repository at this point in the history
  • Loading branch information
dharit-tan authored Sep 7, 2023
1 parent 72d8eaa commit 91c49fa
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 25 deletions.
9 changes: 8 additions & 1 deletion packages/common/src/store/ui/withdraw-usdc/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ const slice = createSlice({
setAmountFailed: (state, action: PayloadAction<{ error: Error }>) => {
state.amountError = action.payload.error
},
beginWithdrawUSDC: (state) => {
beginWithdrawUSDC: (
state,
_action: PayloadAction<{
amount: number
destinationAddress: string
onSuccess: (transaction: string) => void
}>
) => {
state.withdrawStatus = Status.LOADING
},
withdrawUSDCSucceeded: (state) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { useCallback } from 'react'

import {
SolanaWalletAddress,
useUSDCBalance,
useWithdrawUSDCModal,
WithdrawUSDCModalPages
WithdrawUSDCModalPages,
withdrawUSDCActions
} from '@audius/common'
import { Modal, ModalContent, ModalHeader } from '@audius/stems'
import { Formik } from 'formik'
import { useDispatch } from 'react-redux'
import { z } from 'zod'
import { toFormikValidationSchema } from 'zod-formik-adapter'

Expand All @@ -20,6 +24,8 @@ import { EnterTransferDetails } from './components/EnterTransferDetails'
import { TransferInProgress } from './components/TransferInProgress'
import { TransferSuccessful } from './components/TransferSuccessful'

const { beginWithdrawUSDC } = withdrawUSDCActions

const messages = {
title: 'Withdraw Funds',
errors: {
Expand Down Expand Up @@ -49,10 +55,34 @@ const WithdrawUSDCFormSchema = (userBalance: number) => {
}

export const WithdrawUSDCModal = () => {
const { isOpen, onClose, onClosed, data } = useWithdrawUSDCModal()
const dispatch = useDispatch()
const { isOpen, onClose, onClosed, data, setData } = useWithdrawUSDCModal()
const { page } = data
const { data: balance } = useUSDCBalance()

const onSuccess = useCallback(
(signature: string) => {
setData({
page: WithdrawUSDCModalPages.TRANSFER_SUCCESSFUL,
signature
})
},
[setData]
)

const handleSubmit = useCallback(
({ amount, address }: { amount: number; address: string }) => {
dispatch(
beginWithdrawUSDC({
amount,
destinationAddress: address,
onSuccess
})
)
},
[dispatch, onSuccess]
)

let formPage
switch (page) {
case WithdrawUSDCModalPages.ENTER_TRANSFER_DETAILS:
Expand Down Expand Up @@ -90,15 +120,15 @@ export const WithdrawUSDCModal = () => {
</ModalHeader>
<ModalContent>
<Formik
initialValues={{ [AMOUNT]: balance, [ADDRESS]: '', [CONFIRM]: false }}
initialValues={{
[AMOUNT]: balance?.toNumber() ?? 0,
[ADDRESS]: '',
[CONFIRM]: false
}}
validationSchema={toFormikValidationSchema(
WithdrawUSDCFormSchema(balance?.toNumber() ?? 0)
)}
// TODO -- call sagas to withdraw
// Saga in turn should update modal state to advance page
onSubmit={(values) => {
console.info(values)
}}
onSubmit={handleSubmit}
>
{formPage}
</Formik>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
AMOUNT,
CONFIRM
} from 'components/withdraw-usdc-modal/WithdrawUSDCModal'
import { toHumanReadable } from 'utils/tokenInput'

import styles from './ConfirmTransferDetails.module.css'
import { Hint } from './Hint'
Expand Down Expand Up @@ -56,7 +57,10 @@ export const ConfirmTransferDetails = () => {
return (
<div className={styles.root}>
<div className={styles.amount}>
<TextRow left={messages.amountToWithdraw} right={`-$${amountValue}`} />
<TextRow
left={messages.amountToWithdraw}
right={`-$${toHumanReadable(amountValue)}`}
/>
</div>
<Divider style={{ margin: 0 }} />
<div className={styles.destination}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ADDRESS,
AMOUNT
} from 'components/withdraw-usdc-modal/WithdrawUSDCModal'
import { toHumanReadable } from 'utils/tokenInput'

import { TextRow } from './TextRow'
import styles from './TransferInProgress.module.css'
Expand All @@ -40,7 +41,10 @@ export const TransferInProgress = () => {
left={messages.currentBalance}
right={`$${balanceFormatted}`}
/>
<TextRow left={messages.amountToWithdraw} right={`-$${amountValue}`} />
<TextRow
left={messages.amountToWithdraw}
right={`-$${toHumanReadable(amountValue)}`}
/>
</div>
<Divider style={{ margin: 0 }} />
<div className={styles.destination}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ADDRESS,
AMOUNT
} from 'components/withdraw-usdc-modal/WithdrawUSDCModal'
import { toHumanReadable } from 'utils/tokenInput'

import { TextRow } from './TextRow'
import styles from './TransferSuccessful.module.css'
Expand Down Expand Up @@ -56,7 +57,10 @@ export const TransferSuccessful = () => {
return (
<div className={styles.root}>
<Divider style={{ margin: 0 }} />
<TextRow left={messages.amountWithdrawn} right={`-$${amountValue}`} />
<TextRow
left={messages.amountWithdrawn}
right={`-$${toHumanReadable(amountValue)}`}
/>
<Divider style={{ margin: 0 }} />
<div className={styles.newBalance}>
<TextRow left={messages.newBalance} right={`$${balanceFormatted}`} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { TextField, TextFieldProps } from 'components/form-fields'
import layoutStyles from 'components/layout/layout.module.css'
import { Text } from 'components/typography'
import {
PRECISION,
onTokenInputBlur,
onTokenInputChange
onTokenInputChange,
toHumanReadable
} from 'utils/tokenInput'

import { PREVIEW, PRICE } from '../AccessAndSaleField'
Expand Down Expand Up @@ -94,7 +94,7 @@ const PriceField = (props: TrackAvailabilityFieldsProps) => {
const { disabled } = props
const [{ value }, , { setValue: setPrice }] = useField<number>(PRICE)
const [humanizedValue, setHumanizedValue] = useState(
value ? (value / 100).toFixed(PRECISION) : null
value ? toHumanReadable(value) : null
)

const handlePriceChange: ChangeEventHandler<HTMLInputElement> = useCallback(
Expand Down
24 changes: 14 additions & 10 deletions packages/web/src/store/application/ui/withdraw-usdc/sagas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
withdrawUSDCActions,
withdrawUSDCSelectors,
solanaSelectors,
ErrorLevel,
SolanaWalletAddress,
Expand Down Expand Up @@ -47,10 +46,9 @@ const {
setDestinationAddress,
setDestinationAddressFailed,
setDestinationAddressSucceeded,
withdrawUSDCFailed
withdrawUSDCFailed,
withdrawUSDCSucceeded
} = withdrawUSDCActions
const { getWithdrawDestinationAddress, getWithdrawAmount } =
withdrawUSDCSelectors
const { getFeePayer } = solanaSelectors

function* doSetAmount({ payload: { amount } }: ReturnType<typeof setAmount>) {
Expand Down Expand Up @@ -109,15 +107,18 @@ function* doSetDestinationAddress({
}
}

function* doWithdrawUSDC({ payload }: ReturnType<typeof beginWithdrawUSDC>) {
/**
* Handles all logic for withdrawing USDC to a given destination. Expects amount in dollars.
*/
function* doWithdrawUSDC({
payload: { amount, destinationAddress, onSuccess }
}: ReturnType<typeof beginWithdrawUSDC>) {
try {
const libs = yield* call(getLibs)
if (!libs.solanaWeb3Manager) {
throw new Error('Failed to get solana web3 manager')
}
// Assume destinationAddress and amount have already been validated
const destinationAddress = yield* select(getWithdrawDestinationAddress)
const amount = yield* select(getWithdrawAmount)
if (!destinationAddress || !amount) {
throw new Error('Please enter a valid destination address and amount')
}
Expand Down Expand Up @@ -256,9 +257,10 @@ function* doWithdrawUSDC({ payload }: ReturnType<typeof beginWithdrawUSDC>) {
)
destinationTokenAccount = destinationTokenAccountPubkey.toString()
}
const amountWei = new BN(amount).mul(
new BN(TOKEN_LISTING_MAP.USDC.decimals)
)
// Multiply by 10^6 to account for USDC decimals, but also convert from cents to dollars
const amountWei = new BN(amount)
.mul(new BN(10 ** TOKEN_LISTING_MAP.USDC.decimals))
.div(new BN(100))
const usdcUserBank = yield* call(getUSDCUserBank)
const transferInstructions = yield* call(
[
Expand Down Expand Up @@ -288,6 +290,8 @@ function* doWithdrawUSDC({ payload }: ReturnType<typeof beginWithdrawUSDC>) {
'Withdraw USDC - successfully transferred USDC - tx hash',
transferSignature
)
yield* call(onSuccess, transferSignature)
yield* put(withdrawUSDCSucceeded())
} catch (e: unknown) {
console.error('Withdraw USDC failed', e)
const reportToSentry = yield* getContext('reportToSentry')
Expand Down
4 changes: 4 additions & 0 deletions packages/web/src/utils/tokenInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@ export const onTokenInputBlur = (e: FocusEvent<HTMLInputElement>) => {
.padEnd(PRECISION, '0')
return `${whole.length > 0 ? whole : '0'}.${paddedDecimal}`
}

export const toHumanReadable = (value: number) => {
return (value / 100).toFixed(PRECISION)
}

0 comments on commit 91c49fa

Please sign in to comment.