From 1b00d48cb82c355b6c63e42ce58c2b442906e5d7 Mon Sep 17 00:00:00 2001 From: Fara Woolf Date: Thu, 23 Jan 2025 12:39:00 -0500 Subject: [PATCH] fix: sbtc swap validation --- src/app/pages/swap/form/use-swap-form.tsx | 16 ++++++++++++++-- src/app/query/sbtc/sbtc-limits.query.ts | 21 ++++++++++++--------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/app/pages/swap/form/use-swap-form.tsx b/src/app/pages/swap/form/use-swap-form.tsx index 30d94318d3..e716fc7ae2 100644 --- a/src/app/pages/swap/form/use-swap-form.tsx +++ b/src/app/pages/swap/form/use-swap-form.tsx @@ -10,6 +10,7 @@ import { convertAmountToBaseUnit, convertAmountToFractionalUnit, createMoney, + isUndefined, } from '@leather.io/utils'; import { FormErrorMessages } from '@shared/error-messages'; @@ -95,6 +96,14 @@ export function useSwapForm>() { return true; }, }) + .test({ + message: 'sBTC bridge temporarily disabled', + test() { + if (!isCrossChainSwap) return true; + if (isUndefined(sBtcLimits)) return false; + return true; + }, + }) .test({ message: `Min amount is ${convertAmountToBaseUnit(sBtcDepositCapMin).toString()} BTC`, test(value) { @@ -139,8 +148,11 @@ export function useSwapForm>() { swapAssetBase.balance.decimals ) ); - if (!remainingSbtcPegCapSupply) return true; - if (valueInFractionalUnit.isGreaterThan(remainingSbtcPegCapSupply)) return false; + if ( + !remainingSbtcPegCapSupply || + valueInFractionalUnit.isGreaterThan(remainingSbtcPegCapSupply) + ) + return false; return true; }, }) diff --git a/src/app/query/sbtc/sbtc-limits.query.ts b/src/app/query/sbtc/sbtc-limits.query.ts index df0e931af9..e4f2428dcd 100644 --- a/src/app/query/sbtc/sbtc-limits.query.ts +++ b/src/app/query/sbtc/sbtc-limits.query.ts @@ -1,5 +1,6 @@ import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; +import { z } from 'zod'; import { useStacksClient } from '@leather.io/query'; import { getStacksContractIdStringParts } from '@leather.io/stacks'; @@ -10,19 +11,21 @@ import { useConfigSbtc } from '../common/remote-config/remote-config.query'; export const defaultSbtcLimits = { pegCap: 1000000000000, - perDepositMinimum: 100000, perDepositCap: 100000000, + perDepositMinimum: 100000, perWithdrawalCap: 100000000, accountCaps: {}, }; -interface GetSbtcLimitsResponse { - pegCap: number; - perDepositCap: number; - perWithdrawalCap: number; - perDepositMinimum: number; - accountCaps: Record; -} +const sbtcLimitsResponseSchema = z.object({ + pegCap: z.number(), + perDepositCap: z.number(), + perDepositMinimum: z.number(), + perWithdrawalCap: z.number(), + accountCaps: z.record(z.any()), +}); + +type GetSbtcLimitsResponse = z.infer; async function getSbtcLimits(apiUrl: string): Promise { const resp = await axios.get(`${apiUrl}/limits`, { @@ -30,7 +33,7 @@ async function getSbtcLimits(apiUrl: string): Promise { 'Content-Type': 'application/json', }, }); - return resp.data; + return sbtcLimitsResponseSchema.parse(resp.data); } export function useGetSbtcLimits() {