Skip to content

Commit

Permalink
[PAY-1629] Purchase flow cleanup (#3873)
Browse files Browse the repository at this point in the history
  • Loading branch information
schottra committed Aug 14, 2023
1 parent a15d125 commit dd729b2
Show file tree
Hide file tree
Showing 20 changed files with 135 additions and 98 deletions.
22 changes: 11 additions & 11 deletions apps/audius-client/packages/common/src/store/buy-usdc/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import { initializeStripeModal } from 'store/ui/stripe-modal/slice'
import {
buyUSDCFlowFailed,
buyUSDCFlowSucceeded,
onRampCanceled,
onRampOpened,
onPurchaseStarted,
onRampSucceeded
onrampCanceled,
onrampOpened,
purchaseStarted,
onrampSucceeded
} from './slice'
import { USDCOnRampProvider } from './types'
import { getUSDCUserBank } from './utils'
Expand Down Expand Up @@ -69,12 +69,12 @@ function* purchaseStep({
)
const initialBalance = initialAccountInfo.amount

yield* put(onPurchaseStarted())
yield* put(purchaseStarted())

// Wait for on ramp finish
const result = yield* race({
success: take(onRampSucceeded),
canceled: take(onRampCanceled)
success: take(onrampSucceeded),
canceled: take(onrampCanceled)
})

// If the user didn't complete the on ramp flow, return early
Expand Down Expand Up @@ -119,7 +119,7 @@ function* doBuyUSDC({
provider,
purchaseInfo: { desiredAmount }
}
}: ReturnType<typeof onRampOpened>) {
}: ReturnType<typeof onrampOpened>) {
const reportToSentry = yield* getContext('reportToSentry')
const { track, make } = yield* getContext('analytics')

Expand All @@ -136,8 +136,8 @@ function* doBuyUSDC({
amount: (desiredAmount / 100).toString(),
destinationCurrency: 'usdc',
destinationWallet: userBank.toString(),
onRampCanceled,
onRampSucceeded
onrampCanceled,
onrampSucceeded
})
)

Expand Down Expand Up @@ -201,7 +201,7 @@ function* doBuyUSDC({
}

function* watchOnRampOpened() {
yield takeLatest(onRampOpened, doBuyUSDC)
yield takeLatest(onrampOpened, doBuyUSDC)
}

export default function sagas() {
Expand Down
17 changes: 8 additions & 9 deletions apps/audius-client/packages/common/src/store/buy-usdc/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const slice = createSlice({
name: 'buy-usdc',
initialState,
reducers: {
onRampOpened: (
onrampOpened: (
state,
action: PayloadAction<{
purchaseInfo: PurchaseInfo
Expand All @@ -44,19 +44,18 @@ const slice = createSlice({
state.provider = action.payload.provider
state.onSuccess = action.payload.onSuccess
},
onPurchaseStarted: (state) => {
purchaseStarted: (state) => {
state.stage = BuyUSDCStage.PURCHASING
},
onRampCanceled: (state) => {
onrampCanceled: (state) => {
if (state.stage === BuyUSDCStage.PURCHASING) {
state.stage = BuyUSDCStage.CANCELED
}
},
onRampSucceeded: (state) => {
onrampSucceeded: (state) => {
state.stage = BuyUSDCStage.CONFIRMING_PURCHASE
},
buyUSDCFlowFailed: (state) => {
// TODO: Probably want to pass error in action payload
state.error = new Error('USDC purchase failed')
},
buyUSDCFlowSucceeded: (state) => {
Expand All @@ -74,10 +73,10 @@ const slice = createSlice({
export const {
buyUSDCFlowFailed,
buyUSDCFlowSucceeded,
onRampOpened,
onPurchaseStarted,
onRampSucceeded,
onRampCanceled,
onrampOpened,
purchaseStarted,
onrampSucceeded,
onrampCanceled,
stripeSessionStatusChanged
} = slice.actions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export {
export * as purchaseContentSelectors from './selectors'
export { default as purchaseContentSagas } from './sagas'
export * from './types'
export * from './utils'
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { accountSelectors } from 'store/account'
import {
buyUSDCFlowFailed,
buyUSDCFlowSucceeded,
onRampOpened,
onRampCanceled
onrampOpened,
onrampCanceled
} from 'store/buy-usdc/slice'
import { USDCOnRampProvider } from 'store/buy-usdc/types'
import { getUSDCUserBank } from 'store/buy-usdc/utils'
Expand All @@ -29,10 +29,11 @@ import { pollPremiumTrack } from '../premium-content/sagas'
import { updatePremiumTrackStatus } from '../premium-content/slice'

import {
onBuyUSDC,
onPurchaseConfirmed,
onPurchaseSucceeded,
onUSDCBalanceSufficient,
buyUSDC,
purchaseCanceled,
purchaseConfirmed,
purchaseSucceeded,
usdcBalanceSufficient,
purchaseContentFlowFailed,
startPurchaseContentFlow
} from './slice'
Expand Down Expand Up @@ -159,9 +160,9 @@ function* doStartPurchaseContentFlow({

// buy USDC if necessary
if (initialBalance.lt(new BN(price).mul(BN_USDC_CENT_WEI))) {
yield* put(onBuyUSDC())
yield* put(buyUSDC())
yield* put(
onRampOpened({
onrampOpened({
provider: USDCOnRampProvider.STRIPE,
purchaseInfo: {
desiredAmount: price
Expand All @@ -171,17 +172,22 @@ function* doStartPurchaseContentFlow({

const result = yield* race({
success: take(buyUSDCFlowSucceeded),
canceled: take(onRampCanceled),
canceled: take(onrampCanceled),
failed: take(buyUSDCFlowFailed)
})

if (result.canceled || result.failed) {
// Return early for failure or cancellation
// Return early for failure or cancellation
if (result.canceled) {
yield* put(purchaseCanceled())
return
}
if (result.failed) {
yield* put(purchaseContentFlowFailed())
return
}
}

yield* put(onUSDCBalanceSufficient())
yield* put(usdcBalanceSufficient())

const { blocknumber, splits } = yield* getPurchaseConfig({
contentId,
Expand All @@ -195,13 +201,13 @@ function* doStartPurchaseContentFlow({
splits,
type: 'track'
})
yield* put(onPurchaseSucceeded())
yield* put(purchaseSucceeded())

// confirm purchase
yield* pollForPurchaseConfirmation({ contentId, contentType })

// finish
yield* put(onPurchaseConfirmed())
yield* put(purchaseConfirmed())

yield* put(
setVisibility({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,35 @@ const slice = createSlice({
state.contentType = action.payload.contentType || ContentType.TRACK
state.onSuccess = action.payload.onSuccess
},
onBuyUSDC: (state) => {
buyUSDC: (state) => {
state.stage = PurchaseContentStage.BUY_USDC
},
onUSDCBalanceSufficient: (state) => {
usdcBalanceSufficient: (state) => {
state.stage = PurchaseContentStage.PURCHASING
},
onPurchaseCanceled: (state) => {
state.error = new Error('Content purchase canceled')
purchaseCanceled: (state) => {
state.stage = PurchaseContentStage.CANCELED
},
onPurchaseSucceeded: (state) => {
purchaseSucceeded: (state) => {
state.stage = PurchaseContentStage.CONFIRMING_PURCHASE
},
onPurchaseConfirmed: (state) => {
purchaseConfirmed: (state) => {
state.stage = PurchaseContentStage.FINISH
},

purchaseContentFlowFailed: (state) => {
// TODO: Probably want to pass error in action payload
state.error = new Error('Content purchase failed')
}
},
cleanup: () => initialState
}
})

export const {
startPurchaseContentFlow,
onBuyUSDC,
onUSDCBalanceSufficient,
onPurchaseSucceeded,
onPurchaseConfirmed,
onPurchaseCanceled,
buyUSDC,
usdcBalanceSufficient,
purchaseSucceeded,
purchaseConfirmed,
purchaseCanceled,
purchaseContentFlowFailed
} = slice.actions

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { PurchaseContentStage } from './types'

export const isContentPurchaseInProgress = (stage: PurchaseContentStage) => {
return [
PurchaseContentStage.BUY_USDC,
PurchaseContentStage.PURCHASING,
PurchaseContentStage.CONFIRMING_PURCHASE
].includes(stage)
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ const slice = createSlice({
state.provider = action.payload.provider
state.onSuccess = action.payload.onSuccess
},
onRampOpened: (state, _action: PayloadAction<PurchaseInfo>) => {
onrampOpened: (state, _action: PayloadAction<PurchaseInfo>) => {
state.stage = BuyAudioStage.PURCHASING
},
onRampCanceled: (state) => {
onrampCanceled: (state) => {
if (state.stage === BuyAudioStage.PURCHASING) {
state.error = true
}
},
onRampSucceeded: (state) => {
onrampSucceeded: (state) => {
state.stage = BuyAudioStage.CONFIRMING_PURCHASE
},
swapStarted: (state) => {
Expand Down Expand Up @@ -175,9 +175,9 @@ export const {
cacheTransactionFees,
clearFeesCache,
startBuyAudioFlow,
onRampOpened,
onRampSucceeded,
onRampCanceled,
onrampOpened,
onrampSucceeded,
onrampCanceled,
swapStarted,
swapCompleted,
transferStarted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,20 @@ function* handleStripeSessionChanged({
payload: { status }
}: ReturnType<typeof stripeSessionStatusChanged>) {
if (status === 'fulfillment_complete') {
const { onRampSucceeded } = yield* select(getStripeModalState)
if (onRampSucceeded) {
yield* put(onRampSucceeded)
const { onrampSucceeded } = yield* select(getStripeModalState)
if (onrampSucceeded) {
yield* put(onrampSucceeded)
}
yield* put(setVisibility({ modal: 'StripeOnRamp', visible: false }))
}
}

function* handleCancelStripeOnramp() {
const { onRampCanceled } = yield* select(getStripeModalState)
const { onrampCanceled } = yield* select(getStripeModalState)
yield* put(setVisibility({ modal: 'StripeOnRamp', visible: false }))

if (onRampCanceled) {
yield* put(onRampCanceled)
if (onrampCanceled) {
yield* put(onrampCanceled)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ type InitializeStripeModalPayload = {
amount: string
destinationCurrency: StripeDestinationCurrencyType
destinationWallet: string
onRampSucceeded: Action
onRampCanceled: Action
onrampSucceeded: Action
onrampCanceled: Action
}

const initialState: StripeModalState = {}
Expand All @@ -25,8 +25,8 @@ const slice = createSlice({
action: PayloadAction<InitializeStripeModalPayload>
) => {
state.stripeSessionStatus = 'initialized'
state.onRampSucceeded = action.payload.onRampSucceeded
state.onRampCanceled = action.payload.onRampCanceled
state.onrampSucceeded = action.payload.onrampSucceeded
state.onrampCanceled = action.payload.onrampCanceled
},
stripeSessionCreated: (
state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ export type StripeSessionStatus =
export type StripeDestinationCurrencyType = 'sol' | 'usdc'

export type StripeModalState = {
onRampSucceeded?: Action
onRampCanceled?: Action
onrampSucceeded?: Action
onrampCanceled?: Action
stripeSessionStatus?: StripeSessionStatus
stripeClientSecret?: string
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import { getRootSolanaAccount } from 'services/audius-backend/BuyAudio'
import styles from './CoinbaseBuyAudioButton.module.css'

const {
onRampOpened,
onRampCanceled,
onRampSucceeded,
onrampOpened,
onrampCanceled,
onrampSucceeded,
calculateAudioPurchaseInfo
} = buyAudioActions
const { getAudioPurchaseInfo, getAudioPurchaseInfoStatus } = buyAudioSelectors
Expand All @@ -43,10 +43,10 @@ export const CoinbaseBuyAudioButton = () => {
const isDisabled = purchaseInfoStatus === Status.LOADING || belowSolThreshold

const handleExit = useCallback(() => {
dispatch(onRampCanceled())
dispatch(onrampCanceled())
}, [dispatch])
const handleSuccess = useCallback(() => {
dispatch(onRampSucceeded())
dispatch(onrampSucceeded())
}, [dispatch])

const handleClick = useCallback(() => {
Expand All @@ -60,7 +60,7 @@ export const CoinbaseBuyAudioButton = () => {
onSuccess: handleSuccess,
onExit: handleExit
})
dispatch(onRampOpened(purchaseInfo))
dispatch(onrampOpened(purchaseInfo))
coinbasePay.open()
} else if (purchaseInfoStatus === Status.IDLE) {
// Generally only possible if `amount` is still undefined,
Expand Down
Loading

0 comments on commit dd729b2

Please sign in to comment.