Skip to content

Feat/limitAmount scaling - #255

Merged
Velenir merged 11 commits into
masterfrom
feat/limitAmount_scaling
Sep 2, 2026
Merged

Feat/limitAmount scaling#255
Velenir merged 11 commits into
masterfrom
feat/limitAmount_scaling

Conversation

@Velenir

@Velenir Velenir commented Sep 1, 2026

Copy link
Copy Markdown
Member

Centralizes limitAmount handling for Delta orders: the SDK now applies bridge scaling itself, and the parameter is gone from the two builders whose endpoint never accepted it.

⚠️ Breaking changes

1. buildDeltaOrder scales limitAmount on cross-chain SELL orders

limitAmount is passed in destination-token wei — the same units as route.destination.output.amount. On a bridge route the on-chain Order carries destAmount in bridge units, so the SDK now applies route.bridge.contractParams.scalingFactor for you, rounding up so the minimum you receive never lands below what you asked for.

Previously every integrator had to do this themselves, and missing it set a limit wrong by 10 ** scalingFactor.

Migration: if you were applying the bridge scaling before calling buildDeltaOrder, stop — it would now be applied twice.

Unaffected: same-chain routes, BUY orders, and scalingFactor === 0.

2. limitAmount removed from buildExternalDeltaOrder and buildTWAPDeltaOrder

The parameter could never work. POST /v2/delta/orders/build parses its body with a discriminated union whose members are all .strict(), and limitAmount is declared only on the Order variant — sending it from an External or TWAP builder was rejected as an unrecognized key. It stayed latent because undefined is dropped from the JSON body, so nobody had passed it.

Dropped from BuildExternalDeltaOrderParams, BuildTWAPSellDeltaOrderParams and BuildTWAPBuyDeltaOrderParams, which turns a runtime 400 into a compile-time error.

Migration: remove the argument. TWAP amounts are set by totalSrcAmount (sell) or totalDestAmount + maxSrcAmount (buy).

New

DeltaTransaction.originReceivedAmount / .destinationReceivedAmount

The server now reports both legs of a fill explicitly:

  • originReceivedAmountorder.destToken delivered on the origin chain by originTx; same leg, chain and decimals as spentAmount.
  • destinationReceivedAmountbridge.outputToken delivered on bridge.destinationChainId, already scaled by bridge.scalingFactor. null on same-chain fills and while a bridge leg is in flight.

The existing receivedAmount reports whichever leg matches the order and is not gated on the bridge having filled, so it can carry a destination amount recorded before delivery. Prefer the explicit pair. All four fields are now documented on the type.

Adding these as required fields is a type-level break for anyone constructing a DeltaTransaction (mocks, fixtures). Reading one is unaffected.

getAuctionAmounts reports the executed destAmount on the right leg

OrderHelpers.getters.getTransactionAmounts takes an optional { crosschain } and reads the leg the output token actually sits on — destinationReceivedAmount for bridge orders, originReceivedAmount otherwise — mirroring how the server derives output.executedAmount. Omitting the option keeps the previous receivedAmount sum, so the exported helper stays source-compatible.

Fixes

  • limitAmount docs are now side-specific. They previously said "destination-token wei" unconditionally, but on BUY the server assigns limitAmount to srcAmount and validates it against route.origin.input.amount — origin src-token units, never bridge-scaled.

Maintenance

  • TypeScript 5.6.3 → 5.9.3. This is the ceiling for the current toolchain: dts-cli@2.0.5 (already the latest) pins ts-jest@29.2.5 (>=4.3 <6) and rollup-plugin-dts@5.3.1 (^4.1 || ^5.0). TS 6 was tried and does typecheck cleanly, but ts-jest fails to resolve jest's globals under it and no tests run.
  • typedoc 0.26.11 → 0.28.20 plus its three plugins, so the docs chain supports 5.9.x. pnpm peers check is now clean.
  • viem and axios moved to current versions. Both are devDependency/lockfile moves — the viem runtime range stays ^2.21.0 and the axios peer range stays >=0.25.0 <2.0.0, so nothing narrows for consumers.
  • tsconfig.json gains "lib": ["es2022", "dom", "dom.iterable"] — viem's ox dependency ships .ts sources needing es2022 features, which skipLibCheck does not cover. target stays es2020, so emit is unchanged.

Tests

tests/limitAmount.test.ts covers the scaling and rounding edge cases, the build request payload, and guards that neither sibling builder puts limitAmount in the body. tests/auctionAmounts.test.ts pins which leg each amount is read from. 182 tests pass; tsc --noEmit and pnpm build are clean.


Note

Medium Risk
Changes how cross-chain SELL limit amounts are encoded and removes builder params; wrong migration (double scaling) or misunderstood leg amounts could mis-set order bounds for integrators.

Overview
v11.0.0 ships Delta order-building and amount-reporting fixes that integrators on bridge routes should read before upgrading.

buildDeltaOrder now converts limitAmount for cross-chain SELL orders via toOrderLimitAmount: callers keep passing destination-token wei (like route.destination.output.amount), and the SDK scales into on-chain bridge units using route.bridge.contractParams.scalingFactor, rounding up so the minimum receive never falls below the requested amount. Integrators who already applied this scaling must stop — otherwise limits are applied twice. Same-chain SELL, BUY (origin srcAmount, never scaled), and scalingFactor === 0 are unchanged.

Breaking API cleanup: limitAmount is removed from buildExternalDeltaOrder and buildTWAPDeltaOrder because the build endpoint’s strict schema only allows it on the plain Order variant; the key is no longer sent on those requests.

Fill reporting: DeltaTransaction adds originReceivedAmount and destinationReceivedAmount (required on the type for constructors/mocks). getTransactionAmounts / getAuctionAmounts can sum executed destAmount from the leg where the auction output token lives when crosschain is set, instead of relying on legacy receivedAmount.

Dev-only: TypeScript 5.9.3, TypeDoc 0.28, lockfile updates, and tsconfig lib es2022 for viem/ox sources.

Reviewed by Cursor Bugbot for commit 579e51a. Bugbot is set up for automated code reviews on this repo. Configure here.

closes FRNT-1398, FRNT-1399

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

size-limit report 📦

Path Size
dist/sdk.cjs.production.min.js 17.29 KB (+0.76% 🔺)
dist/sdk.esm.js 17.56 KB (+1.24% 🔺)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Centralizes limitAmount scaling for cross-chain Delta SELL limit orders by converting integrator-provided destination-token wei into on-chain “bridge units” inside the SDK’s buildDeltaOrder request payload, reducing the chance of clients forgetting bridge scaling.

Changes:

  • Added toOrderLimitAmount helper that applies bridge scalingFactor (ceil-rounded when dividing) for SELL bridge routes; otherwise returns limitAmount unchanged.
  • Updated buildDeltaOrder to send limitAmount: toOrderLimitAmount(params) instead of passing through the caller string.
  • Added comprehensive Jest coverage for scaling edge cases and for the build request payload; clarified buildExternalDeltaOrder docs.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
tests/limitAmount.test.ts Adds unit tests for scaling/rounding behavior and verifies buildDeltaOrder sends the scaled/unscaled payload as intended.
src/methods/delta/helpers/limitAmount.ts Introduces toOrderLimitAmount and bridge scaling logic using BigInt with ceil rounding for SELL bridge routes.
src/methods/delta/buildExternalDeltaOrder.ts Doc clarification that external orders’ limitAmount is in on-chain units (no bridge scaling).
src/methods/delta/buildDeltaOrder.ts Applies centralized limit amount conversion before sending build request to the API; expands JSDoc around units/scaling behavior.
Suppressed comments (1)

src/methods/delta/helpers/limitAmount.ts:15

  • The top-level description says it converts a limit amount expressed in destination-token units, but the function only converts for SELL bridge routes and returns BUY amounts unchanged (BUY limitAmount is in src-token units). Reword the description to avoid implying BUY inputs are destination-denominated.
/**
 * @description Converts a limit amount expressed in destination-token units into the
 * units the on-chain Order carries.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/methods/delta/buildDeltaOrder.ts Outdated
Comment on lines +4 to +6
type ToOrderLimitAmountParams = {
/** @description The limit amount in destination-token wei. */
limitAmount?: string;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't true if I'm not mistaken

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked in API: on BUY limitAmount becomes srcAmount, so it is origin src-token units.
Changed the docs to match

@andriy-shymkiv andriy-shymkiv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great improvement
Wanna bump viem version together with this (breaking) change?

slippage?: number;
/** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */
/** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount.
* In on-chain Order units. External orders carry no bridge, so no scaling applies. */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't get what "In on-chain Order units" means until I checked Widget's code
Maybe:
In dest token units?
In output token units?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API actually has a strict no such field allowed for limitAmount in TWAP and External Orders.
So I removed the prop for them outright

@Velenir

Velenir commented Sep 2, 2026

Copy link
Copy Markdown
Member Author

Great improvement Wanna bump viem version together with this (breaking) change?

I updated local dev copy of viem but left the dependency range as is, so that projects installing the SDK can have older viem

@Velenir
Velenir merged commit 810cbaf into master Sep 2, 2026
3 of 4 checks passed
@Velenir
Velenir deleted the feat/limitAmount_scaling branch September 2, 2026 14:25
@linear-code

linear-code Bot commented Sep 2, 2026

Copy link
Copy Markdown

FRNT-1398

FRNT-1399

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants