From 69ff9a4e95b71dd7906d8e6484a939266f3ce267 Mon Sep 17 00:00:00 2001 From: portuu3 <61605646+portuu3@users.noreply.github.com> Date: Fri, 14 Feb 2025 13:35:57 +0100 Subject: [PATCH 01/16] Balance refactor (#3069) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * job launcher balance refactor * balance refactor * use utils operators to properly handle small decimal amounts * fix fee calculation * fix payment amount * job launcher balance refactor backend * set fund token for the job * fix rate direction * fix payment logic * update frontend and tests * refactor job service tests * Solve null issue with stringify * fix typo * fix pr comments --------- Co-authored-by: Francisco López --- .../server/src/common/constant/index.ts | 5 +- .../components/Jobs/Create/CryptoPayForm.tsx | 26 +- .../components/Jobs/Create/FiatPayForm.tsx | 30 +- .../src/components/TokenSelect/index.tsx | 10 +- .../TopUpAccount/CryptoTopUpForm.tsx | 11 +- .../client/src/constants/chains.ts | 2 +- .../job-launcher/client/src/services/job.ts | 20 +- .../job-launcher/client/src/types/index.ts | 10 +- .../server/src/common/config/env-schema.ts | 1 - .../common/config/server-config.service.ts | 9 +- .../server/src/common/constants/index.ts | 2 - .../server/src/common/constants/payment.ts | 3 - .../server/src/common/enums/job.ts | 4 +- .../server/src/common/enums/payment.ts | 57 +- .../migrations/1738321689843-addTokenToJob.ts | 28 + .../src/modules/cron-job/cron-job.service.ts | 2 + .../src/modules/job/job.controller.spec.ts | 31 +- .../server/src/modules/job/job.controller.ts | 88 +- .../server/src/modules/job/job.dto.ts | 46 +- .../server/src/modules/job/job.entity.ts | 12 +- .../server/src/modules/job/job.interface.ts | 11 +- .../src/modules/job/job.service.spec.ts | 4099 +------------ .../server/src/modules/job/job.service.ts | 127 +- .../src/modules/payment/payment.controller.ts | 2 +- .../server/src/modules/payment/payment.dto.ts | 20 +- .../src/modules/payment/payment.repository.ts | 3 + .../modules/payment/payment.service.spec.ts | 70 +- .../src/modules/payment/payment.service.ts | 54 +- .../src/modules/payment/rate.service.spec.ts | 45 - .../src/modules/payment/rate.service.ts | 39 +- .../modules/storage/storage.service.spec.ts | 3 +- .../src/modules/storage/storage.service.ts | 2 +- .../src/modules/user/user.controller.ts | 2 +- .../server/src/modules/user/user.dto.ts | 6 +- .../src/modules/user/user.service.spec.ts | 10 +- .../server/src/modules/user/user.service.ts | 8 +- .../job-launcher/server/test/utils/address.ts | 10 + yarn.lock | 5137 ++++++++++------- 38 files changed, 3595 insertions(+), 6450 deletions(-) create mode 100644 packages/apps/job-launcher/server/src/database/migrations/1738321689843-addTokenToJob.ts create mode 100644 packages/apps/job-launcher/server/test/utils/address.ts diff --git a/packages/apps/fortune/exchange-oracle/server/src/common/constant/index.ts b/packages/apps/fortune/exchange-oracle/server/src/common/constant/index.ts index d083a54a22..f68848e847 100644 --- a/packages/apps/fortune/exchange-oracle/server/src/common/constant/index.ts +++ b/packages/apps/fortune/exchange-oracle/server/src/common/constant/index.ts @@ -11,10 +11,7 @@ export const TESTNET_CHAIN_IDS = [ ChainId.BSC_TESTNET, ChainId.SEPOLIA, ]; -export const MAINNET_CHAIN_IDS = [ - ChainId.POLYGON, - ChainId.BSC_MAINNET, -]; +export const MAINNET_CHAIN_IDS = [ChainId.POLYGON, ChainId.BSC_MAINNET]; export const JWT_KVSTORE_KEY = 'jwt_public_key'; export const KYC_APPROVED = 'approved'; diff --git a/packages/apps/job-launcher/client/src/components/Jobs/Create/CryptoPayForm.tsx b/packages/apps/job-launcher/client/src/components/Jobs/Create/CryptoPayForm.tsx index cca95b4e36..a08ffdbbee 100644 --- a/packages/apps/job-launcher/client/src/components/Jobs/Create/CryptoPayForm.tsx +++ b/packages/apps/job-launcher/client/src/components/Jobs/Create/CryptoPayForm.tsx @@ -25,7 +25,7 @@ import { usePublicClient, } from 'wagmi'; import { TokenSelect } from '../../../components/TokenSelect'; -import { CURRENCY } from '../../../constants/payment'; +import { NETWORK_TOKENS } from '../../../constants/chains'; import { useTokenRate } from '../../../hooks/useTokenRate'; import { useCreateJobPageUI } from '../../../providers/CreateJobPageUIProvider'; import * as jobService from '../../../services/job'; @@ -46,6 +46,7 @@ export const CryptoPayForm = ({ const { chain } = useAccount(); const { jobRequest, goToPrevStep } = useCreateJobPageUI(); const [tokenAddress, setTokenAddress] = useState(); + const [tokenSymbol, setTokenSymbol] = useState(); const [payWithAccountBalance, setPayWithAccountBalance] = useState(false); const [amount, setAmount] = useState(); const [isLoading, setIsLoading] = useState(false); @@ -103,7 +104,7 @@ export const CryptoPayForm = ({ }, [payWithAccountBalance, totalAmount, accountAmount]); const handlePay = async () => { - if (signer && tokenAddress && amount && jobRequest.chainId) { + if (signer && tokenAddress && amount && jobRequest.chainId && tokenSymbol) { setIsLoading(true); try { if (walletPayAmount > 0) { @@ -145,15 +146,17 @@ export const CryptoPayForm = ({ await jobService.createFortuneJob( chainId, fortuneRequest, + tokenSymbol, Number(amount), - CURRENCY.hmt, + tokenSymbol, ); } else if (jobType === JobType.CVAT && cvatRequest) { await jobService.createCvatJob( chainId, cvatRequest, + tokenSymbol, Number(amount), - CURRENCY.hmt, + tokenSymbol, ); } else if (jobType === JobType.HCAPTCHA && hCaptchaRequest) { await jobService.createHCaptchaJob(chainId, hCaptchaRequest); @@ -223,7 +226,15 @@ export const CryptoPayForm = ({ setTokenAddress(e.target.value as string)} + onChange={(e) => { + const symbol = e.target.value as string; + setTokenSymbol(symbol); + setTokenAddress( + NETWORK_TOKENS[ + jobRequest.chainId! as keyof typeof NETWORK_TOKENS + ]?.[symbol.toLowerCase()], + ); + }} /> Account Balance - {user?.balance?.amount?.toFixed(2) ?? '0'}{' '} + ~ {user?.balance?.amount?.toFixed(2) ?? '0'}{' '} {user?.balance?.currency?.toUpperCase() ?? 'USD'} @@ -265,7 +276,7 @@ export const CryptoPayForm = ({ > Fund Amount - {fundAmount?.toFixed(2)} USD + ~ {fundAmount?.toFixed(2)} USD (); useEffect(() => { const fetchJobLauncherData = async () => { @@ -181,6 +183,11 @@ export const FiatPayForm = ({ return; } + if (!tokenAddress) { + onError('Please select a token.'); + return; + } + onStart(); setIsLoading(true); @@ -215,11 +222,18 @@ export const FiatPayForm = ({ await createFortuneJob( chainId, fortuneRequest, - fundAmount, CURRENCY.usd, + fundAmount, + tokenAddress, ); } else if (jobType === JobType.CVAT && cvatRequest) { - await createCvatJob(chainId, cvatRequest, fundAmount, CURRENCY.usd); + await createCvatJob( + chainId, + cvatRequest, + CURRENCY.usd, + fundAmount, + tokenAddress, + ); } else if (jobType === JobType.HCAPTCHA && hCaptchaRequest) { await createHCaptchaJob(chainId, hCaptchaRequest); } @@ -321,6 +335,13 @@ export const FiatPayForm = ({ Add Payment Method )} + + setTokenAddress(e.target.value as string) + } + /> @@ -348,7 +369,7 @@ export const FiatPayForm = ({ Account Balance {user?.balance && ( - {user?.balance?.amount?.toFixed(2)} USD + ~ {user?.balance?.amount?.toFixed(2)} USD )} @@ -427,7 +448,8 @@ export const FiatPayForm = ({ disabled={ !amount || (!payWithAccountBalance && !selectedCard) || - hasError + hasError || + !tokenAddress } > Pay now diff --git a/packages/apps/job-launcher/client/src/components/TokenSelect/index.tsx b/packages/apps/job-launcher/client/src/components/TokenSelect/index.tsx index 111c515b56..80bfa2bfb6 100644 --- a/packages/apps/job-launcher/client/src/components/TokenSelect/index.tsx +++ b/packages/apps/job-launcher/client/src/components/TokenSelect/index.tsx @@ -28,11 +28,11 @@ export const TokenSelect: FC = (props) => { return ( - Token + Funding token