Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAY-2450][PAY-2451] Purchase indexing uses access from memo #7510

Merged
merged 3 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/common/src/models/PurchaseContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ export enum PurchaseVendor {
STRIPE = 'Stripe',
COINFLOW = 'Coinflow'
}

export enum PurchaseAccess {
STREAM = 'stream',
DOWNLOAD = 'download'
}
22 changes: 17 additions & 5 deletions packages/common/src/services/audius-backend/solana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ import BN from 'bn.js'

import { BN_USDC_CENT_WEI } from '~/utils/wallet'

import { AnalyticsEvent, ID, Name, SolanaWalletAddress } from '../../models'
import {
AnalyticsEvent,
ID,
Name,
SolanaWalletAddress,
PurchaseAccess
} from '../../models'

import { AudiusBackend } from './AudiusBackend'

Expand Down Expand Up @@ -378,6 +384,7 @@ export type PurchaseContentArgs = {
type: 'track'
splits: Record<string, number | BN>
purchaserUserId: ID
purchaseAccess: PurchaseAccess
}
export const purchaseContent = async (
audiusBackendInstance: AudiusBackend,
Expand All @@ -397,6 +404,7 @@ export type PurchaseContentWithPaymentRouterArgs = {
recentBlockhash?: string
purchaserUserId: ID
wallet: Keypair
purchaseAccess: PurchaseAccess
}

export const purchaseContentWithPaymentRouter = async (
Expand All @@ -408,7 +416,8 @@ export const purchaseContentWithPaymentRouter = async (
extraAmount = 0,
purchaserUserId,
splits,
wallet
wallet,
purchaseAccess
}: PurchaseContentWithPaymentRouterArgs
) => {
const solanaWeb3Manager = (await audiusBackendInstance.getAudiusLibs())
Expand All @@ -421,7 +430,8 @@ export const purchaseContentWithPaymentRouter = async (
splits,
purchaserUserId,
senderKeypair: wallet,
skipSendAndReturnTransaction: true
skipSendAndReturnTransaction: true,
purchaseAccess
})
return tx
}
Expand Down Expand Up @@ -474,7 +484,8 @@ export const createRootWalletRecoveryTransaction = async (
blocknumber: 0, // ignored
splits: { [userBank.toString()]: new BN(amount.toString()) },
purchaserUserId: 0, // ignored
senderAccount: wallet.publicKey
senderAccount: wallet.publicKey,
purchaseAccess: PurchaseAccess.STREAM //ignored
})

const recentBlockhash = await getRecentBlockhash(audiusBackendInstance)
Expand Down Expand Up @@ -660,7 +671,8 @@ export const createPaymentRouterRouteTransaction = async (
blocknumber: 0, // ignored
splits,
purchaserUserId: 0, // ignored
senderAccount: sender
senderAccount: sender,
purchaseAccess: PurchaseAccess.STREAM //ignored
})
return new Transaction({
recentBlockhash: blockhash,
Expand Down
41 changes: 30 additions & 11 deletions packages/common/src/store/purchase-content/sagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ import { call, put, race, select, take } from 'typed-redux-saga'
import { FavoriteSource, Name } from '~/models/Analytics'
import { ErrorLevel } from '~/models/ErrorReporting'
import { ID } from '~/models/Identifiers'
import { PurchaseMethod, PurchaseVendor } from '~/models/PurchaseContent'
import {
PurchaseMethod,
PurchaseVendor,
PurchaseAccess
} from '~/models/PurchaseContent'
import { Track, isContentUSDCPurchaseGated } from '~/models/Track'
import { User } from '~/models/User'
import { BNUSDC } from '~/models/Wallet'
Expand Down Expand Up @@ -94,6 +98,12 @@ function* getContentInfo({ contentId, contentType }: GetPurchaseConfigArgs) {
const trackInfo = yield* select(getTrack, { id: contentId })
const purchaseConditions =
trackInfo?.stream_conditions ?? trackInfo?.download_conditions
// Stream access is a superset of download access - purchasing a stream-gated
// track also gets you download access, but purchasing a download-gated track
// only gets you download access (because the track was already free to stream).
const purchaseAccess = trackInfo?.is_stream_gated
? PurchaseAccess.STREAM
: PurchaseAccess.DOWNLOAD
if (!trackInfo || !isContentUSDCPurchaseGated(purchaseConditions)) {
throw new Error('Content is missing purchase conditions')
}
Expand All @@ -105,7 +115,7 @@ function* getContentInfo({ contentId, contentType }: GetPurchaseConfigArgs) {
const title = trackInfo.title
const price = purchaseConditions.usdc_purchase.price

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

const getUserPurchaseMetadata = ({
Expand Down Expand Up @@ -261,6 +271,7 @@ type PurchaseWithCoinflowArgs = {
purchaserUserId: ID
/** USDC in dollars */
price: number
purchaseAccess: PurchaseAccess
}

function* purchaseWithCoinflow(args: PurchaseWithCoinflowArgs) {
Expand All @@ -270,7 +281,8 @@ function* purchaseWithCoinflow(args: PurchaseWithCoinflowArgs) {
splits,
contentId,
purchaserUserId,
price
price,
purchaseAccess
} = args
const audiusBackendInstance = yield* getContext('audiusBackendInstance')
const feePayerAddress = yield* select(getFeePayer)
Expand All @@ -292,7 +304,8 @@ function* purchaseWithCoinflow(args: PurchaseWithCoinflowArgs) {
blocknumber,
recentBlockhash,
purchaserUserId,
wallet: rootAccount
wallet: rootAccount,
purchaseAccess
}
)

Expand Down Expand Up @@ -399,10 +412,13 @@ function* doStartPurchaseContentFlow({
const reportToSentry = yield* getContext('reportToSentry')
const { track, make } = yield* getContext('analytics')

const { price, title, artistInfo } = yield* call(getContentInfo, {
contentId,
contentType
})
const { price, title, artistInfo, purchaseAccess } = yield* call(
getContentInfo,
{
contentId,
contentType
}
)

const analyticsInfo = {
price: price / 100,
Expand Down Expand Up @@ -471,7 +487,8 @@ function* doStartPurchaseContentFlow({
extraAmount: extraAmountBN,
splits,
type: 'track',
purchaserUserId
purchaserUserId,
purchaseAccess
})
} else {
// We need to acquire USDC before the purchase can continue
Expand All @@ -494,7 +511,8 @@ function* doStartPurchaseContentFlow({
contentId,
contentType,
purchaserUserId,
price: purchaseAmount
price: purchaseAmount,
purchaseAccess
})
break
case PurchaseVendor.STRIPE:
Expand All @@ -506,7 +524,8 @@ function* doStartPurchaseContentFlow({
extraAmount: extraAmountBN,
splits,
type: 'track',
purchaserUserId
purchaserUserId,
purchaseAccess
})
break
}
Expand Down
Loading