From 4756dbfe019dc059caf14f61a887a5d1d131ab1b Mon Sep 17 00:00:00 2001 From: vindard <17693119+vindard@users.noreply.github.com> Date: Sun, 12 Nov 2023 13:41:33 -0600 Subject: [PATCH] chore: add critical error for funder balance --- core/api/src/app/payments/add-earn.ts | 30 +++++++++++++++++++++++++++ core/api/src/domain/errors.ts | 3 +++ core/api/src/graphql/error-map.ts | 5 +++++ 3 files changed, 38 insertions(+) diff --git a/core/api/src/app/payments/add-earn.ts b/core/api/src/app/payments/add-earn.ts index 74c14a476b..0ec6b265da 100644 --- a/core/api/src/app/payments/add-earn.ts +++ b/core/api/src/app/payments/add-earn.ts @@ -1,5 +1,7 @@ import { intraledgerPaymentSendWalletIdForBtcWallet } from "./send-intraledger" +import { getBalanceForWallet } from "@/app/wallets" + import { getRewardsConfig, OnboardingEarn } from "@/config" import { IPMetadataAuthorizer } from "@/domain/accounts-ips/ip-metadata-authorizer" import { @@ -7,6 +9,7 @@ import { InvalidQuizQuestionIdError, MissingIPMetadataError, NoBtcWalletExistsForAccountError, + NotEnoughBalanceForRewardError, UnauthorizedIPError, UnknownRepositoryError, } from "@/domain/errors" @@ -23,6 +26,24 @@ import { import { AccountsIpsRepository } from "@/services/mongoose/accounts-ips" import { checkedToAccountId } from "@/domain/accounts" +const FunderBalanceChecker = () => { + const check = ({ + balance, + amountToSend, + }: { + balance: Satoshis + amountToSend: Satoshis + }): ValidationError | true => { + if (balance < amountToSend) { + return new NotEnoughBalanceForRewardError(JSON.stringify({ balance, amountToSend })) + } + + return true + } + + return { check } +} + export const addEarn = async ({ quizQuestionId: quizQuestionIdString, accountId: accountIdRaw, @@ -88,6 +109,15 @@ export const addEarn = async ({ const shouldGiveReward = await RewardsRepository(accountId).add(quizQuestionId) if (shouldGiveReward instanceof Error) return shouldGiveReward + const funderBalance = await getBalanceForWallet({ walletId: funderWalletId }) + if (funderBalance instanceof Error) return funderBalance + + const sendCheck = FunderBalanceChecker().check({ + balance: funderBalance as Satoshis, + amountToSend: amount, + }) + if (sendCheck instanceof Error) return sendCheck + const payment = await intraledgerPaymentSendWalletIdForBtcWallet({ senderWalletId: funderWalletId, recipientWalletId, diff --git a/core/api/src/domain/errors.ts b/core/api/src/domain/errors.ts index 1b663b6d05..ba4c4dcda8 100644 --- a/core/api/src/domain/errors.ts +++ b/core/api/src/domain/errors.ts @@ -118,6 +118,9 @@ export class MissingIPMetadataError extends ValidationError {} export class InvalidIpMetadataError extends ValidationError { level = ErrorLevel.Critical } +export class NotEnoughBalanceForRewardError extends ValidationError { + level = ErrorLevel.Critical +} export class UnauthorizedIPForOnboardingError extends AuthorizationError {} diff --git a/core/api/src/graphql/error-map.ts b/core/api/src/graphql/error-map.ts index 696403e340..01ede2196d 100644 --- a/core/api/src/graphql/error-map.ts +++ b/core/api/src/graphql/error-map.ts @@ -272,6 +272,11 @@ export const mapError = (error: ApplicationError): CustomGraphQLError => { message = "Reward for quiz question was already claimed." return new ValidationInternalError({ message, logger: baseLogger }) + case "NotEnoughBalanceForRewardError": + message = + "Rewards wallet temporarily depleted. Please contact support if problem persists." + return new ValidationInternalError({ message, logger: baseLogger }) + case "SubOneCentSatAmountForUsdSelfSendError": case "SubOneCentSatAmountForUsdReceiveError": message = "Amount sent was too low for recipient's usd wallet."