Skip to content

Commit

Permalink
Merge branch 'main' into kyc-dev-test
Browse files Browse the repository at this point in the history
  • Loading branch information
IanPhilips committed Sep 16, 2024
2 parents 6083bc2 + f14ea3d commit 18a6612
Show file tree
Hide file tree
Showing 191 changed files with 2,932 additions and 1,560 deletions.
6 changes: 2 additions & 4 deletions backend/api/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ import { awardBounty } from './award-bounty'
import { addBounty } from './add-bounty'
import { cancelbounty } from './cancel-bounty'
import { createAnswerCPMM } from './create-answer-cpmm'
import { createportfolio } from './create-portfolio'
import { updateportfolio } from './update-portfolio'
import { searchgiphy } from './search-giphy'
import { manachantweet } from './manachan-tweet'
import { managram } from './managram'
Expand Down Expand Up @@ -147,6 +145,7 @@ import { createuser } from 'api/create-user'
import { verifyPhoneNumber } from 'api/verify-phone-number'
import { requestOTP } from 'api/request-phone-otp'
import { multiSell } from 'api/multi-sell'
import { convertCashToMana } from './convert-cash-to-mana'
import { convertSpiceToMana } from './convert-sp-to-mana'
import { donate } from './donate'
import { getFeed } from 'api/get-feed'
Expand Down Expand Up @@ -342,6 +341,7 @@ const handlers: { [k in APIPath]: APIHandler<k> } = {
managrams: getManagrams,
manalink: createManalink,
donate: donate,
'convert-cash-to-mana': convertCashToMana,
'convert-sp-to-mana': convertSpiceToMana,
'market/:id/positions': getPositions,
me: getMe,
Expand Down Expand Up @@ -484,8 +484,6 @@ app.post('/follow-topic', ...apiRoute(followtopic))
app.post('/league-activity', ...apiRoute(leagueActivity))
app.post('/cancel-bounty', ...apiRoute(cancelbounty))
app.post('/edit-answer-cpmm', ...apiRoute(editanswercpmm))
app.post('/createportfolio', ...apiRoute(createportfolio))
app.post('/updateportfolio', ...apiRoute(updateportfolio))
app.post('/searchgiphy', ...apiRoute(searchgiphy))
app.post('/manachantweet', ...apiRoute(manachantweet))
app.post('/refer-user', ...apiRoute(referuser))
Expand Down
60 changes: 60 additions & 0 deletions backend/api/src/convert-cash-to-mana.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { APIError, APIHandler } from './helpers/endpoint'
import { type TxnData, insertTxns } from 'shared/txn/run-txn'
import { createSupabaseDirectClient } from 'shared/supabase/init'
import { incrementBalance } from 'shared/supabase/users'
import { betsQueue } from 'shared/helpers/fn-queue'
import { CASH_TO_MANA_CONVERSION_RATE } from 'common/envs/constants'
import { calculateRedeemablePrizeCash } from 'shared/calculate-redeemable-prize-cash'

export const convertCashToMana: APIHandler<'convert-cash-to-mana'> = async (
{ amount },
auth
) => {
const pg = createSupabaseDirectClient()

await betsQueue.enqueueFn(async () => {
// check if user has enough cash
await pg.tx(async (tx) => {
const redeemable = await calculateRedeemablePrizeCash(auth.uid, tx)
if (redeemable < amount) {
throw new APIError(403, 'Not enough redeemable balance')
}

await incrementBalance(tx, auth.uid, {
cashBalance: -amount,
balance: amount * CASH_TO_MANA_CONVERSION_RATE,
})
})

// key for equivalence
const insertTime = Date.now()

const toBank: TxnData = {
category: 'CONVERT_CASH',
fromType: 'USER',
fromId: auth.uid,
toType: 'BANK',
toId: 'BANK',
amount: amount,
token: 'SPICE',
description: 'Convert cash to mana',
data: { insertTime },
}

const toYou: TxnData = {
category: 'CONVERT_CASH_DONE',
fromType: 'BANK',
fromId: 'BANK',
toType: 'USER',
toId: auth.uid,
amount: amount,
token: 'M$',
description: 'Convert cash to mana',
data: {
insertTime,
},
}

await pg.tx((tx) => insertTxns(tx, [toBank, toYou]))
}, [auth.uid])
}
90 changes: 0 additions & 90 deletions backend/api/src/create-portfolio.ts

This file was deleted.

2 changes: 1 addition & 1 deletion backend/api/src/create-public-chat-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const createPublicChatMessage: APIHandler<
throw new APIError(500, 'Failed to create chat message.')
}

broadcast('chat_message', {})
broadcast('public-chat', {})

return convertPublicChatMessage({
...chatMessage,
Expand Down
27 changes: 20 additions & 7 deletions backend/api/src/donate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { charities } from 'common/charity'
import { APIError } from 'api/helpers/endpoint'
import { runTxn } from 'shared/txn/run-txn'
import { createSupabaseDirectClient } from 'shared/supabase/init'
import { CHARITY_FEE, MIN_SPICE_DONATION } from 'common/envs/constants'
import {
MIN_CASH_DONATION,
MIN_SPICE_DONATION,
CHARITY_FEE,
TWOMBA_ENABLED,
} from 'common/envs/constants'
import { getUser } from 'shared/utils'

export const donate: APIHandler<'donate'> = async ({ amount, to }, auth) => {
Expand All @@ -16,12 +21,20 @@ export const donate: APIHandler<'donate'> = async ({ amount, to }, auth) => {
const user = await getUser(auth.uid, tx)
if (!user) throw new APIError(401, 'Your account was not found')

if (user.spiceBalance < amount) {
throw new APIError(403, 'Insufficient prize points')
const balance = TWOMBA_ENABLED ? user.cashBalance : user.spiceBalance
if (balance < amount) {
throw new APIError(
403,
`Insufficient ${TWOMBA_ENABLED ? 'cash' : 'prize points'} balance`
)
}

if (amount < MIN_SPICE_DONATION) {
throw new APIError(400, 'Minimum donation is 25,000 prize points')
const min = TWOMBA_ENABLED ? MIN_CASH_DONATION : MIN_SPICE_DONATION
if (amount < min) {
throw new APIError(
400,
`Minimum donation is ${min} ${TWOMBA_ENABLED ? 'cash' : 'prize points'}`
)
}

// add donation to charity
Expand All @@ -35,7 +48,7 @@ export const donate: APIHandler<'donate'> = async ({ amount, to }, auth) => {
toType: 'BANK',
toId: 'BANK',
amount: fee,
token: 'SPICE',
token: TWOMBA_ENABLED ? 'CASH' : 'SPICE',
data: {
charityId: charity.id,
},
Expand All @@ -48,7 +61,7 @@ export const donate: APIHandler<'donate'> = async ({ amount, to }, auth) => {
toType: 'CHARITY',
toId: charity.id,
amount: donation,
token: 'SPICE',
token: TWOMBA_ENABLED ? 'CASH' : 'SPICE',
} as const

await runTxn(tx, feeTxn)
Expand Down
12 changes: 11 additions & 1 deletion backend/api/src/get-bets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
import { getContractIdFromSlug } from 'shared/supabase/contracts'
import { getUserIdFromUsername } from 'shared/supabase/users'
import { getBetsWithFilter } from 'shared/supabase/bets'
import { NON_POINTS_BETS_LIMIT } from 'common/supabase/bets'
import { convertBet, NON_POINTS_BETS_LIMIT } from 'common/supabase/bets'
import { filterDefined } from 'common/util/array'

export const getBets: APIHandler<'bets'> = async (props) => {
const {
Expand All @@ -24,6 +25,7 @@ export const getBets: APIHandler<'bets'> = async (props) => {
includeZeroShareRedemptions,
count,
points,
id,
} = props
if (limit === 0) {
return []
Expand All @@ -34,6 +36,14 @@ export const getBets: APIHandler<'bets'> = async (props) => {
)
}
const pg = createSupabaseDirectClient()
if (id) {
const bet = await pg.map(
`select * from contract_bets where bet_id = $1`,
[id],
(r) => (r ? convertBet(r) : undefined)
)
return filterDefined(bet)
}

const userId = props.userId ?? (await getUserIdFromUsername(pg, username))
const contractId =
Expand Down
4 changes: 3 additions & 1 deletion backend/api/src/get-mana-supply.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getManaSupply as fetchManaSupply } from 'shared/mana-supply'
import { APIHandler } from './helpers/endpoint'
import { createSupabaseDirectClient } from 'shared/supabase/init'

export const getManaSupply: APIHandler<'get-mana-supply'> = async () => {
return await fetchManaSupply(false)
const pg = createSupabaseDirectClient()
return await fetchManaSupply(pg)
}
31 changes: 29 additions & 2 deletions backend/api/src/gidx/callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { getGIDXCustomerProfile } from 'shared/gidx/helpers'
import { getVerificationStatusInternal } from 'api/gidx/get-verification-status'
import { createSupabaseDirectClient } from 'shared/supabase/init'
import { broadcast } from 'shared/websockets/server'
import { createPaymentSuccessNotification } from 'shared/create-notification'
import { PaymentCompletedData } from 'common/notification'

export const identityCallbackGIDX: APIHandler<
'identity-callback-gidx'
Expand Down Expand Up @@ -73,14 +75,39 @@ export const paymentCallbackGIDX: APIHandler<'payment-callback-gidx'> = async (
JSON.stringify(props),
]
)

broadcast('gidx-checkout-session/' + MerchantSessionID, {
StatusCode,
StatusMessage,
})

// TODO: if cashout txn is failed, give back the mana cash
if (TransactionStatusMessage === 'Complete' && TransactionStatusCode === 1) {
log('Payment successful')

// TODO: Double check here that the txns were sent given successful payment
// and if not, resend them
const paymentData = await pg.oneOrNone(
`select user_id, amount, currency, payment_method_type, payment_amount_type from gidx_receipts where merchant_transaction_id = $1
and user_id is not null
limit 1`,
[MerchantTransactionID],
(row) =>
({
userId: row.user_id as string,
amount: row.amount as number,
currency: row.currency as string,
paymentMethodType: row.payment_method_type as string,
paymentAmountType: row.payment_amount_type as string,
} as PaymentCompletedData | null)
)
log('userId for payment', paymentData)

// Debit for us = credit for user
if (paymentData && paymentData.paymentAmountType === 'Debit') {
await createPaymentSuccessNotification(paymentData, MerchantTransactionID)
}
}

// TODO: Double check here if txns were not sent given successful payment
// and if so, send them
return { MerchantTransactionID }
}
4 changes: 2 additions & 2 deletions backend/api/src/gidx/complete-cashout-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getGIDXStandardParams,
getUserRegistrationRequirements,
getLocalServerIP,
GIDX_BASE_URL,
} from 'shared/gidx/helpers'
import { log } from 'shared/monitoring/log'
import { createSupabaseDirectClient } from 'shared/supabase/init'
Expand All @@ -17,8 +18,7 @@ import { getUser, LOCAL_DEV } from 'shared/utils'
import { SWEEPIES_CASHOUT_FEE } from 'common/economy'
import { calculateRedeemablePrizeCash } from 'shared/calculate-redeemable-prize-cash'

const ENDPOINT =
'https://api.gidx-service.in/v3.0/api/DirectCashier/CompleteSession'
const ENDPOINT = GIDX_BASE_URL + '/v3.0/api/DirectCashier/CompleteSession'

export const completeCashoutSession: APIHandler<
'complete-cashout-session-gidx'
Expand Down
Loading

0 comments on commit 18a6612

Please sign in to comment.