diff --git a/.changeset/dev-166-builder-fee-404.md b/.changeset/dev-166-builder-fee-404.md new file mode 100644 index 0000000..9e64f89 --- /dev/null +++ b/.changeset/dev-166-builder-fee-404.md @@ -0,0 +1,5 @@ +--- +"@polymarket/client": patch +--- + +Map unknown builder fee responses to `UserInputError`. diff --git a/packages/client/src/actions/clob.ts b/packages/client/src/actions/clob.ts index f20d012..9b04fdf 100644 --- a/packages/client/src/actions/clob.ts +++ b/packages/client/src/actions/clob.ts @@ -410,7 +410,17 @@ export async function fetchBuilderFeeRates( return unwrap( client.clob .get(`/fees/builder-fees/${params.builderCode}`) - .andThen(validateWith(FetchBuilderFeeRatesResponseSchema)), + .andThen(validateWith(FetchBuilderFeeRatesResponseSchema)) + .mapErr((error) => { + if (error instanceof RequestRejectedError && error.status === 404) { + return new UserInputError( + `Unknown builder code: ${params.builderCode}`, + { cause: error }, + ); + } + + return error; + }), ); } diff --git a/packages/client/tests/integration/orders.test.ts b/packages/client/tests/integration/orders.test.ts index e12d581..4d5ba09 100644 --- a/packages/client/tests/integration/orders.test.ts +++ b/packages/client/tests/integration/orders.test.ts @@ -1,10 +1,11 @@ -import { OrderSide, OrderType } from '@polymarket/bindings'; +import { BuilderCodeSchema, OrderSide, OrderType } from '@polymarket/bindings'; import { OrderPostStatus } from '@polymarket/bindings/clob'; import { createSecureClient, InsufficientLiquidityError, type Market, type SecureClient, + UserInputError, } from '@polymarket/client'; import { fetchNegRisk } from '@polymarket/client/actions'; import { expectPresent } from '@polymarket/types'; @@ -20,6 +21,9 @@ import { expectAcceptedOrderResponse } from './helpers'; import { findHighVolumeLowPriceMarket } from './markets'; const market = await findHighVolumeLowPriceMarket(publicClient); +const UNKNOWN_BUILDER_CODE = BuilderCodeSchema.parse( + '0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd', +); let marketOrderCleanup: | { market: Market; @@ -168,6 +172,26 @@ describe('Orders', { timeout: 60_000 }, () => { expect(order.builder).toBe(builderCode); }); + + it('reports unknown builder codes as user input errors when resolving buy amounts against max spend', async ({ + annotate, + secureClientWithDepositWallet, + }) => { + const yesTokenId = expectPresent(market.outcomes.yes.tokenId); + const minimumOrderSize = expectPresent(market.trading.minimumOrderSize); + annotate(`Market ID: ${market.id}`); + annotate(`Token ID: ${yesTokenId}`); + + await expect( + secureClientWithDepositWallet.createMarketOrder({ + amount: minimumOrderSize, + builderCode: UNKNOWN_BUILDER_CODE, + maxSpend: minimumOrderSize, + side: OrderSide.BUY, + tokenId: yesTokenId, + }), + ).rejects.toThrow(UserInputError); + }); }); describe('placeLimitOrder', () => {