Skip to content

Commit

Permalink
add additional coinflow purchase metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
schottra committed Dec 18, 2023
1 parent a9a0001 commit 1f24049
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 13 deletions.
119 changes: 107 additions & 12 deletions packages/common/src/store/purchase-content/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { FavoriteSource, Name } from 'models/Analytics'
import { ErrorLevel } from 'models/ErrorReporting'
import { ID } from 'models/Identifiers'
import { PurchaseMethod, PurchaseVendor } from 'models/PurchaseContent'
import { isPremiumContentUSDCPurchaseGated } from 'models/Track'
import { Track, isPremiumContentUSDCPurchaseGated } from 'models/Track'
import { User } from 'models/User'
import { BNUSDC } from 'models/Wallet'
import {
getRecentBlockhash,
Expand Down Expand Up @@ -45,7 +46,10 @@ import {
transactionFailed,
transactionSucceeded
} from 'store/ui/coinflow-modal/slice'
import { coinflowOnrampModalActions } from 'store/ui/modals/coinflow-onramp-modal'
import {
CoinflowPurchaseMetadata,
coinflowOnrampModalActions
} from 'store/ui/modals/coinflow-onramp-modal'
import { BN_USDC_CENT_WEI } from 'utils/wallet'

import { pollPremiumTrack } from '../premium-content/sagas'
Expand All @@ -63,7 +67,7 @@ import {
import { ContentType, PurchaseContentError, PurchaseErrorCode } from './types'
import { getBalanceNeeded } from './utils'

const { getUserId } = accountSelectors
const { getUserId, getAccountUser } = accountSelectors

type RaceStatusResult = {
succeeded?:
Expand Down Expand Up @@ -106,7 +110,93 @@ function* getContentInfo({ contentId, contentType }: GetPurchaseConfigArgs) {
title
} = trackInfo

return { price, title, artistInfo }
return { price, title, artistInfo, trackInfo }
}

const getUserPurchaseMetadata = ({
handle,
name,
wallet,
spl_wallet,
created_at,
updated_at,
user_id,
is_deactivated,
is_verified,
location
}: User) => ({
handle,
name,
wallet,
spl_wallet,
created_at,
updated_at,
user_id,
is_deactivated,
is_verified,
location
})

const getTrackPurchaseMetadata = ({
created_at,
description,
duration,
genre,
is_delete,
isrc,
iswc,
license,
owner_id,
permalink,
release_date,
tags,
title,
track_id,
updated_at
}: Track) => ({
created_at,
description,
duration,
genre,
is_delete,
isrc,
iswc,
license,
owner_id,
permalink,
release_date,
tags,
title,
track_id,
updated_at
})

function* getCoinflowPurchaseMetadata({
contentId,
contentType,
extraAmount,
splits
}: PurchaseWithCoinflowArgs) {
const { trackInfo, artistInfo, title, price } = yield* call(getContentInfo, {
contentId,
contentType
})
const currentUser = yield* select(getAccountUser)

const data: CoinflowPurchaseMetadata = {
productName: `${artistInfo.name}:${title}`,
productType: 'digitalArt',
quantity: 1,
rawProductData: {
priceUSD: price / 100,
extraAmountUSD: extraAmount ? extraAmount / 100 : 0,
usdcRecipientSplits: splits,
artistInfo: getUserPurchaseMetadata(artistInfo),
purchaserInfo: currentUser ? getUserPurchaseMetadata(currentUser) : null,
contentInfo: getTrackPurchaseMetadata(trackInfo)
}
}
return data
}

function* getPurchaseConfig({ contentId, contentType }: GetPurchaseConfigArgs) {
Expand Down Expand Up @@ -177,24 +267,27 @@ type PurchaseWithCoinflowArgs = {
extraAmount?: number
splits: Record<number, number>
contentId: ID
contentType: ContentType
purchaserUserId: ID
/** USDC in dollars */
price: number
}

function* purchaseWithCoinflow({
blocknumber,
extraAmount,
splits,
contentId,
purchaserUserId,
price
}: PurchaseWithCoinflowArgs) {
function* purchaseWithCoinflow(args: PurchaseWithCoinflowArgs) {
const {
blocknumber,
extraAmount,
splits,
contentId,
purchaserUserId,
price
} = args
const audiusBackendInstance = yield* getContext('audiusBackendInstance')
const feePayerAddress = yield* select(getFeePayer)
if (!feePayerAddress) {
throw new Error('Missing feePayer unexpectedly')
}
const purchaseMetadata = yield* call(getCoinflowPurchaseMetadata, args)
const recentBlockhash = yield* call(getRecentBlockhash, audiusBackendInstance)
const rootAccount = yield* call(getRootSolanaAccount, audiusBackendInstance)

Expand All @@ -220,6 +313,7 @@ function* purchaseWithCoinflow({
coinflowOnrampModalActions.open({
amount: price,
serializedTransaction,
purchaseMetadata,
contentId
})
)
Expand Down Expand Up @@ -408,6 +502,7 @@ function* doStartPurchaseContentFlow({
extraAmount,
splits,
contentId,
contentType,
purchaserUserId,
price: purchaseAmount
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ import { ID } from 'models/Identifiers'

import { createModal } from '../createModal'

export type CoinflowPurchaseMetadata = {
productName: string
productType: 'digitalArt'
quantity: number
rawProductData: Record<string, any>
}

export type CoinflowOnrampModalState = {
amount: number
contentId?: ID
purchaseMetadata?: CoinflowPurchaseMetadata
serializedTransaction: string
onrampSucceeded?: Action
onrampCanceled?: Action
Expand Down
8 changes: 8 additions & 0 deletions packages/web/src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { Suspense, lazy } from 'react'

import { FeatureFlags, useFeatureFlag } from '@audius/common'
import { CoinflowPurchaseProtection } from '@coinflowlabs/react'
import { Redirect, Route, Switch } from 'react-router-dom'

import { CoinbasePayButtonProvider } from 'components/coinbase-pay-button'
Expand All @@ -20,6 +21,9 @@ const SignOn = lazy(() => import('pages/sign-on/SignOn'))
const OAuthLoginPage = lazy(() => import('pages/oauth-login-page'))
const DemoTrpcPage = lazy(() => import('pages/demo-trpc/DemoTrpcPage'))

const MERCHANT_ID = process.env.VITE_COINFLOW_MERCHANT_ID
const IS_PRODUCTION = process.env.VITE_ENVIRONMENT === 'production'

export const AppInner = () => {
const { isEnabled: isSignInRedesignEnabled, isLoaded } = useFeatureFlag(
FeatureFlags.SIGN_UP_REDESIGN
Expand All @@ -29,6 +33,10 @@ export const AppInner = () => {
<>
<SomethingWrong />
<Suspense fallback={null}>
<CoinflowPurchaseProtection
merchantId={MERCHANT_ID || ''}
coinflowEnv={IS_PRODUCTION ? 'prod' : 'sandbox'}
/>
<Switch>
{SIGN_ON_ALIASES.map((a) => (
<Redirect key={a} from={a} to={SIGN_IN_PAGE} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const IS_PRODUCTION = process.env.VITE_ENVIRONMENT === 'production'

export const CoinflowOnrampModal = () => {
const {
data: { amount, serializedTransaction },
data: { amount, serializedTransaction, purchaseMetadata },
isOpen,
onClose,
onClosed
Expand Down Expand Up @@ -73,6 +73,7 @@ export const CoinflowOnrampModal = () => {
<CoinflowPurchase
transaction={transaction}
wallet={adapter.wallet}
chargebackProtectionData={purchaseMetadata ? [purchaseMetadata] : []}
connection={adapter.connection}
onSuccess={handleSuccess}
merchantId={MERCHANT_ID || ''}
Expand Down

0 comments on commit 1f24049

Please sign in to comment.