From a83aca6abc11e0f6ad2e5689bac9e39bb0c23bfc 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 | 29 +++++++++++++++++++++++++++ core/api/src/domain/errors.ts | 3 +++ core/api/src/graphql/error-map.ts | 5 +++++ 3 files changed, 37 insertions(+) diff --git a/core/api/src/app/payments/add-earn.ts b/core/api/src/app/payments/add-earn.ts index 74c14a476b4..3aa6da6b2c4 100644 --- a/core/api/src/app/payments/add-earn.ts +++ b/core/api/src/app/payments/add-earn.ts @@ -1,3 +1,4 @@ +import { getBalanceForWallet } from "@/app/wallets" import { intraledgerPaymentSendWalletIdForBtcWallet } from "./send-intraledger" import { getRewardsConfig, OnboardingEarn } from "@/config" @@ -7,6 +8,7 @@ import { InvalidQuizQuestionIdError, MissingIPMetadataError, NoBtcWalletExistsForAccountError, + NotEnoughBalanceForRewardError, UnauthorizedIPError, UnknownRepositoryError, } from "@/domain/errors" @@ -23,6 +25,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 +108,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 1b663b6d057..ba4c4dcda8e 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 3aff240216c..744426593bb 100644 --- a/core/api/src/graphql/error-map.ts +++ b/core/api/src/graphql/error-map.ts @@ -268,6 +268,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."