SDK (TypeScript)
@pendle/boros-sdk-public is a TypeScript wrapper around the Boros Open API and Send Txs Bot. It removes the boilerplate of building calldata, EIP-712 signing, and dispatching transactions. If you trade from Node, this is the recommended path.
For other languages — or if you want raw HTTP control — go to API instead. The SDK is a thin convenience layer; anything the SDK does, the API page documents end-to-end.
For the agent model the SDK depends on, see Agent Trading.
Install
npm install @pendle/boros-sdk-public viem
viem is a peer dependency. The SDK targets viem@2.x. The math helpers (FixedX18, estimateTickForRate, getRateAtTick) live in a separate package — install it when you need tick/rate conversion:
npm install @pendle/boros-offchain-math
Initialization
The SDK exposes two main classes:
Exchange— your read/write entry point. Wraps placing orders, cancelling, depositing, etc.Agent— manages the agent keypair used to sign trading actions on behalf of your root.
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { arbitrum } from 'viem/chains';
import { Agent, Exchange } from '@pendle/boros-sdk-public';
// 1. Root walletClient. For trading-only flows the account can be omitted —
// the agent signs every trading action. The root account is only needed
// for sensitive flows (deposit, approveAgent, withdraw).
const rootAccount = privateKeyToAccount(process.env.ROOT_PK as `0x${string}`);
const walletClient = createWalletClient({
account: rootAccount,
transport: http(process.env.RPC_URL),
chain: arbitrum,
});
// 2. Agent. Re-use a persisted private key in production; for first-time
// setup, `Agent.create(walletClient)` derives one deterministically from
// a root signature so users don't have to babysit an extra secret.
const agent = Agent.createFromPrivateKey(process.env.AGENT_PK as `0x${string}`);
// 3. Exchange.
const exchange = new Exchange(
walletClient,
rootAccount.address,
/* accountId */ 0,
[process.env.RPC_URL!],
agent,
);
The constructor signature is:
new Exchange(walletClient, root, accountId, rpcUrls, agent?)
agent is optional at construction time — set it later via exchange.setAgent(agent) if you bootstrap one with Agent.create() after the fact.
The SDK ships with the production backend pre-wired (api-boros.pendle.finance/apis). All endpoints — markets, accounts, calldata builders, and send-txs — go through this single host. For staging, override at startup:
import { setOpenApiBackendUrl } from '@pendle/boros-sdk-public';
setOpenApiBackendUrl('https://staging-api-boros.pendle.finance/apis');
Common flows
The SDK groups operations by who signs the calldata — root for sensitive actions, agent for everything else. Skim the table, then jump to whichever section you need.
| Flow | Method | Signed by | Backed by |
|---|---|---|---|
| Generate + approve agent | Agent.create(walletClient) → exchange.approveAgent(agent) | root | EIP-712 → Send Txs Bot |
| Check agent expiry | exchange.getAgentExpiryTime() | — | GET /v1/agents/expiry-time |
| Deposit collateral | exchange.deposit(params) | root | ERC20 approve + on-chain deposit |
| Withdraw collateral | exchange.withdraw(params) | root | request-withdraw (auto-finalized after cooldown) |
| Pay treasury (gas top-up) | exchange.payTreasury(params) | agent | calldata builder + Send Txs Bot |
| Place single order | exchange.placeOrder(params) | agent | calldata builder + Send Txs Bot |
| Place many in one tx | exchange.bulkPlaceOrders({orderRequests}) | agent | calldata builder + Send Txs Bot |
| Cancel orders | exchange.cancelOrders(params) | agent | calldata builder + Send Txs Bot |
| Bulk cancel | exchange.bulkCancelOrders(requests) | agent | calldata builder + Send Txs Bot |
| Enter market (cross) | exchange.enterMarkets(true, [marketId]) | agent | calldata builder + Send Txs Bot |
| Exit market | exchange.exitMarkets(true, [marketId]) | agent | calldata builder + Send Txs Bot |
| Cash transfer (cross↔isolated) | exchange.cashTransfer(params) | agent | calldata builder + Send Txs Bot |
| Read all markets | exchange.getAllMarkets(filters?) | — | GET /v1/markets (paginated, cached 5 min) |
| Read order book | exchange.getOrderBook({marketId, tickSize}) | — | GET /v1/markets/order-book |
| Read your active orders | exchange.getOrdersPage({isActive: true}) | — | GET /v1/accounts/orders (cursor) |
| Read on-chain orders (no indexer lag) | exchange.getActiveOrdersFromContract(params) | — | direct Explorer contract read |
| Read entered markets | exchange.getEnteredMarkets(rootAddress) | — | direct MarketHub contract read |
| Read user positions | exchange.getUserPositions(params) | — | direct contract read |
| Market summary (mid/bid/ask APR) | exchange.getMarketData(marketId) | — | GET /v1/markets/by-ids + contract |
| Gas balance (USD) | exchange.getGasBalance() | — | GET /v1/accounts/gas-balance |
| List assets | exchange.getAssets() | — | GET /v1/assets |
Place a limit order
import { Side, TimeInForce, MarketAccLib, CROSS_MARKET_ID } from '@pendle/boros-sdk-public';
const market = (await exchange.getAllMarkets({ isUiWhitelisted: true }))[0];
const marketAcc = MarketAccLib.pack(rootAccount.address, 0, market.tokenId, CROSS_MARKET_ID);
const { result, executeResponse } = await exchange.placeOrder({
marketAcc,
marketId: market.marketId,
side: Side.LONG,
size: 10n ** 18n,
rate: 0.05, // 5% APR — backend rounds to nearest valid tick
tif: TimeInForce.GOOD_TIL_CANCELLED,
});
Pass rate (human-friendly decimal APR) or limitTick (raw integer tick) — exactly one. rate is the easy path; the backend rounds it to the nearest valid tick for the market. Use limitTick only if you've already computed the tick yourself (e.g. via estimateTickForRate from @pendle/boros-offchain-math).
ammId is optional and defaults to orderbook-only routing. Pass a specific AMM id to route through that AMM instead.
Place many orders in one transaction
bulkPlaceOrders accepts a heterogeneous list — mix single-order requests and per-market bulks in one call. One on-chain submission, one nonce, one gas charge.
await exchange.bulkPlaceOrders({
orderRequests: [
{
cross: true,
bulks: [{
marketId: market.marketId,
orders: {
tif: TimeInForce.GOOD_TIL_CANCELLED,
side: Side.LONG,
sizes: [10n ** 18n, 2n * 10n ** 18n],
limitTicks: [limitTick - 10, limitTick - 20],
},
cancelData: { ids: [], isAll: false, isStrict: false },
}],
},
],
});
Read your active orders (paginated)
import { OrderType } from '@pendle/boros-sdk-public';
let resumeToken: string | undefined;
const all = [];
do {
const page = await exchange.getOrdersPage({
isActive: true,
orderType: [OrderType.LIMIT],
limit: 200,
resumeToken,
});
all.push(...page.results);
resumeToken = page.resumeToken ?? undefined;
} while (resumeToken);
The SDK keeps cursor pagination explicit — there's no getAllOrders() helper. Backends impose per-call CU costs, and the SDK refuses to hide them behind sugar. See Computing Units.
If you need fresh on-chain truth (no indexer lag, useful right after a placeOrder returns), call exchange.getActiveOrdersFromContract({ marketAcc, marketId }) instead — it reads the Explorer contract directly.
Cancel everything in one market
await exchange.cancelOrders({
marketAcc,
marketId: market.marketId,
cancelAll: true,
orderIds: [],
});
Top up gas balance
The Send Txs Bot debits each agent-signed transaction from your off-chain gas budget (USD). Top it up via payTreasury:
await exchange.payTreasury({
isCross: true,
marketId: market.marketId,
usdAmount: 1, // credits ~$1 to gas budget
});
console.log('Gas balance (USD):', await exchange.getGasBalance());
Escape hatch — raw open-api access
The wrapped methods cover common trading flows. For everything else (leaderboard, OHLCV, settlement events, indicators, conditional orders), drop down to the codegen client:
import { getOpenApiSdk } from '@pendle/boros-sdk-public';
const sdk = getOpenApiSdk();
// Anything in the open-api spec is reachable here, fully typed.
const { data } = await sdk.markets.marketsControllerGetOhlcv({
marketId: 1,
resolution: '1h',
from: 1735689600,
to: 1735693200,
});
getOpenApiSdk() returns a typed client generated from the live swagger. New endpoints land here automatically when the SDK is republished — no waiting for hand-written wrappers. Use this whenever the wrapper doesn't exist or you need to pass a parameter the wrapper doesn't expose.
The SDK also re-exports the codegen response types under OpenApi.*:
import { OpenApi } from '@pendle/boros-sdk-public';
function summarize(market: OpenApi.MarketListItemResponse) {
return `${market.marketId} ${market.imData.symbol}`;
}
What the SDK doesn't do
- WebSocket subscriptions — connect to the WebSocket feed using
socket.io-clientdirectly; see WebSocket. - Strategy logic — the SDK is plumbing. Indicators, sizing, risk management are yours to build.
- Stop / take-profit orders —
OrderType.TAKE_PROFIT_MARKETandOrderType.STOP_LOSS_MARKETexist on the type level but the SDK does not yet expose dedicatedplaceStopOrder/placeTakeProfitOrdermethods. UsegetOpenApiSdk()until they land. See Stop Orders.
End-to-end example
Bot Quickstart walks through a real grid bot built on top of the SDK — from approve-agent to a running reconcile loop. ~485 lines of TypeScript total, with full source embedded at the end of that page.
Migrating from @pendle/sdk-boros
@pendle/boros-sdk-public is the externally supported successor of the internal @pendle/sdk-boros package. Same trading surface — Exchange, Agent, calldata builders, codegen API client — minus internal-only helpers that did not belong on the public boundary.
Fresh integrators: skip this section. Lives here for users already wired up to the internal @pendle/sdk-boros.
TL;DR
| Change | Old import | New import |
|---|---|---|
| Package name | @pendle/sdk-boros | @pendle/boros-sdk-public |
| Backend wrapper namespace | BorosBackend (groups codegen client + URL setters) | none — flat top-level exports |
| Open API codegen namespace | BorosBackend.Core | OpenApi |
| Open API accessor | BorosBackend.getCoreSdk() | getOpenApiSdk() |
| Open API URL setter | BorosBackend.setCoreBackendUrl(url) | setOpenApiBackendUrl(url) |
| Send Txs Bot accessor | BorosBackend.getSendTxsBotSdk() | removed — use getOpenApiSdk().sendTxs.* |
| Send Txs Bot URL setter | BorosBackend.setSendTxsBotBackendUrl(url) | removed — same host as Open API |
| Default Open API base URL | https://api.boros.finance/core | https://api-boros.pendle.finance/apis |
| Pendle V2 client | BorosBackend.getPendleV2Sdk() / BorosBackend.setPendleV2BackendUrl() | removed |
| Structured-log client | LogStoreBackend.* namespace | removed |
| UI helpers | calculateIncentiveRange (from ui-support) | removed |
| Strategy/fee/margin calculators | Calculator exports (calculateExchangeFees, marginCalculator, strategyApr, strategyExecution, strategyFinder, strategyUtils) | removed |
| Reward distributors | multiTokenMerkleDistributor, lpRewardsDistributor, makerIncentiveRewardsDistributor, referralRewardsDistributor | removed |
Exchange methods | several renames + removals — see Method-level changes | — |
Token / TokenAmount | createFromLifi removed; createFromBorosCore param type tweaked; logoURI constructor arg dropped | see same section |
Everything else — Agent, Side, TimeInForce, MarketAccLib, Distributor (Pendle token), tick/rate math, the Explorer / MarketHub helpers, the error decoder, and the unchanged Exchange methods — keeps the same import path and signature.
Install
npm uninstall @pendle/sdk-boros
npm install @pendle/boros-sdk-public viem
# math helpers (tick/rate conversion):
npm install @pendle/boros-offchain-math
viem@2.x is required (see the Install section above). @pendle/boros-offchain-math is the same package the old SDK transitively depended on — install it explicitly if you import FixedX18, estimateTickForRate, or getRateAtTick directly.
Imports
Package rename is the bulk of the diff. Find-and-replace the module specifier in every import:
// old
import { Exchange, Agent, Side } from '@pendle/sdk-boros';
// new
import { Exchange, Agent, Side } from '@pendle/boros-sdk-public';
Most top-level entity exports (Exchange, Agent, Side, TimeInForce, MarketAccLib, CROSS_MARKET_ID, OrderType, Distributor, MarketHub helpers, error decoder, etc.) keep the same name. The two exceptions are the backend-client wrapper namespaces and a handful of Exchange methods — see the next two sections. Anything you imported under BorosBackend.*, LogStoreBackend.*, calculateIncentiveRange, or the strategy/margin/fee calculators is gone; see Removed surfaces.
Backend clients
The old package wrapped both codegen clients under a single BorosBackend namespace (and the structured-log client under LogStoreBackend). The new package drops the wrapper and exposes each piece at the top level. The codegen client itself was also regenerated against the public swagger and now points at a new default host — api-boros.pendle.finance/apis instead of api.boros.finance/core. Endpoint paths inside the SDK are still /v1/* in both versions; only the base URL differs. The regenerated client has fewer methods because internal-only endpoints (dApp settings, deposit-box intents, fear-greed-index, internal incentives admin, etc.) are not on the public swagger — calls that survived keep the same method names and request/response shapes.
Namespace + accessor rename:
// old
import { BorosBackend } from '@pendle/sdk-boros';
const core = BorosBackend.getCoreSdk();
const markets = await core.markets.marketsControllerGetAll({});
type MarketRow = BorosBackend.Core.MarketListItemResponse;
// new
import { getOpenApiSdk, OpenApi } from '@pendle/boros-sdk-public';
const sdk = getOpenApiSdk();
const markets = await sdk.markets.marketsControllerGetAll({});
type MarketRow = OpenApi.MarketListItemResponse;
Method names on the codegen client are unchanged. A handful of upstream NestJS @ApiProperty annotations were corrected before regeneration, so a few optional fields that used to type as any are now properly typed — TypeScript errors at the call site after the upgrade most likely fall here. The runtime payload did not change.
URL setters:
// Open API (renamed + new default host)
BorosBackend.setCoreBackendUrl('https://staging-api.boros.finance/core');
// ↓
setOpenApiBackendUrl('https://staging-api-boros.pendle.finance/apis');
// Send Txs Bot — removed; send-txs is now part of the Open API host
BorosBackend.setSendTxsBotBackendUrl(...); // no replacement
// Pendle V2 — removed
BorosBackend.setPendleV2BackendUrl(...); // no replacement
The env-driven prod/staging auto-switch from the old package is gone. Public SDK callers pass an explicit URL for staging; otherwise they inherit the production default baked into the package:
OPEN_API_BACKEND_URL = 'https://api-boros.pendle.finance/apis'
Send Txs Bot codegen client: removed. The send-txs endpoints (approve, trace, tx-status, tx-status-with-events, bulk-calls, dedicated/bulk-calls) are folded into the Open API SDK under sdk.sendTxs.* and live on the same host. The SendTxsBot namespace, SendTxsBotSdk interface, getSendTxsBotSdk() accessor, and setSendTxsBotBackendUrl() are gone. Callers using the high-level Exchange methods (placeOrder, bulkPlaceOrders, cancelOrders, payTreasury, …) do not see this — Exchange continues to dispatch through the bot internally.
// old
import { BorosBackend } from '@pendle/sdk-boros';
const bot = BorosBackend.getSendTxsBotSdk();
await bot.agent.agentControllerBulkDirectCall({ /* ... */ });
// new
import { getOpenApiSdk } from '@pendle/boros-sdk-public';
const sdk = getOpenApiSdk();
await sdk.sendTxs.sendTxsControllerBulkCalls({ /* ... */ });
Method-level changes
Exchange is the only class with breaking method-shape changes. Agent is unchanged at the API level. The other public entity classes (AccManager, Market, MarketHub, Distributor, Subaccount, VePendle, WrappedEth, Amm, the MarketAccLib helpers, Explorer reads) keep the same method signatures — only their internal references to the backend client were swapped from BorosCoreSdk to OpenApiSdk, which is transparent to callers. The Token / TokenAmount value classes had a small surface trim noted at the end of this section.
Exchange
A handful of Exchange methods were renamed or had their parameter / return types replaced. These don't show up under a package-name find-and-replace, so they fail at the call site after the import swap. The behavior of each method is unchanged — only the shape changed.
Renamed:
| Old | New | Notes |
|---|---|---|
bulkPlaceOrdersV5(BulkPlaceOrderV5Params) | bulkPlaceOrders(BulkPlaceOrderParams) | V5 was the latest internal version; renamed to drop the version suffix. Parameter shape unchanged apart from the type alias. |
getMarkets(GetMarketsParams): Promise<MarketsResponse> | getAllMarkets(filters?: GetAllMarketsFilters): Promise<MarketListItemResponse[]> | Now returns a flat array (already paginated through internally) and is cached for 5 min. Use filters.isUiWhitelisted for the equivalent of the old whitelisted flag. |
getPnlLimitOrders(GetPnlLimitOrdersParams) | getOrdersPage(GetOrdersPageParams) | Cursor-paginated reads of your orders; same backing endpoint, clearer name. Iterate with resumeToken (see "Read your active orders" above). |
getPnlLimitOrdersFromContract (private) | getActiveOrdersFromContract(GetActiveOrdersFromContractParams) | Was private in the old package; now public. Reads the Explorer contract directly — no indexer lag. |
getUserPositions(GetPnlLimitOrdersParams) | getUserPositions(GetUserPositionsParams) | Same method name; the parameter type was renamed and tightened. |
Removed (no replacement on Exchange):
| Method | Why | What to do |
|---|---|---|
bulkPlaceOrdersV2, bulkPlaceOrdersV4 | Legacy versions of bulkPlaceOrders. | Use bulkPlaceOrders. |
closeActivePositions(CloseActivePositionsParams) | Wrapper around an internal dApp flow that batched a cancel-all + market-close sweep. Couples directly to UI assumptions. | Do the equivalent yourself: bulkCancelOrders then a market placeOrder on the opposite side, or call the relevant /v1/calldata-builder/* endpoints via getOpenApiSdk(). |
updateSettings(UpdateSettingsParams) | dApp-only account settings (display preferences, notification opt-ins). | Not part of the public surface. |
getCollaterals(...) | Returned a dApp-shaped collateral summary. | Use exchange.getAssets() plus the on-chain reads (getUserPositions) for collateral balances. Raw collateral metadata is also reachable via getOpenApiSdk().assets.*. |
getAmmInfoByAmmId(ammId) | AMM inspection helper used by the dApp's AMM page. | Reach the same data via getOpenApiSdk().amm.* endpoints. |
getCumulativePnl({ marketAcc, marketId }) | Time-series PnL aggregation used by the dApp's account page. | Use the open-api /v1/accounts/* endpoints (settlement events, position-update events) via getOpenApiSdk(). |
approveAgentData / revokeAgentData (typed-data builders) and all other previously public methods (placeOrder, cancelOrders, bulkCancelOrders, enterMarkets, exitMarkets, cashTransfer, deposit, withdraw, payTreasury, scheduleCancel, approveAgent, getGasBalance, getOrderBook, getMarketData, getEnteredMarkets, getAmmCutOffTimestamp, getAssets, bulkSignAndExecute) keep the same signature.
Token / TokenAmount
Two small changes on the Token and TokenAmount value classes:
| Old | New | Notes |
|---|---|---|
new Token(..., logoURI?) | new Token(...) | The optional logoURI constructor argument is gone — the public SDK does not carry token logos. Drop the trailing argument. |
Token.createFromBorosCore(token: AssetResponse, ...) | Token.createFromBorosCore(token: AssetItemResponse & { chainId?: number; dstTokenId?: number }, ...) | The factory now takes the public-swagger response type (AssetItemResponse) and accepts optional chainId / dstTokenId for cross-chain plumbing. Same applies to TokenAmount.createFromBorosCore. |
Token.createFromLifi(...) / TokenAmount.createFromLifi(...) | removed | Li.Fi integration lived in the dApp-only crossChainDeposit helpers, which are no longer shipped. Construct tokens from on-chain / Open API data instead. |
Removed surfaces
Each row below names a symbol that used to be importable from @pendle/sdk-boros and is no longer exported from @pendle/boros-sdk-public. The "Why" column explains the reasoning; "What to do" is the migration path.
| Old import | Why removed | What to do |
|---|---|---|
calculateIncentiveRange (from the ui-support re-export) | Market-making UI helper — encodes the dApp's incentive-range rendering rules, not a stable trading API. | Re-implement in your client if you need it. The logic is small and depends only on estimateTickForRate / getRateAtTick from @pendle/boros-offchain-math. |
Calculator exports: calculateExchangeFees, marginCalculator, strategyApr, strategyExecution, strategyFinder, strategyUtils (plus their types) | Internal strategy & margin simulator used by the dApp's strategy preview UI. Tightly coupled to dApp-side state shapes, not safe as a public API. | Use the on-chain reads exposed by Exchange (getUserPositions, getActiveOrdersFromContract) and Open API endpoints under /v1/markets/*, /v1/accounts/* via getOpenApiSdk(). The contract + API are the source of truth; the calculator was a UI cache layer. |
BorosBackend.getPendleV2Sdk(), BorosBackend.setPendleV2BackendUrl(), BorosBackend.PendleV2.* | Pendle V2 (non-Boros) backend client. Out of scope for the Boros SDK. | If you actually need Pendle V2 data, call the V2 API directly. The Boros SDK no longer ships a client for it. |
LogStoreBackend.* namespace | Internal structured-logging dispatch — only used by the dApp. | No replacement; not part of the public surface. Use your own observability stack. |
multiTokenMerkleDistributorAbi, multiTokenMerkleDistributorContract | Multi-token Merkle distributor for internal incentive programs. | The single-token Pendle Distributor is still public. For multi-token programs, read the on-chain contract directly. |
lpRewardsDistributor, makerIncentiveRewardsDistributor, referralRewardsDistributor | Internal helper wrappers around the same multi-token distributor — UI conveniences. | Same as above. |
aggregatorHelpers, crossChainDeposit, collateralSwapper | dApp-side deposit/aggregator/cross-chain plumbing. | Not part of the public trading surface. If you need cross-chain deposits, drive them via your own wallet/aggregator. |
Things that stayed public despite touching internal-feeling concerns: the single-token Pendle Distributor (Merkle claim for PENDLE rewards), the Explorer and MarketHub contract helpers, the multicall utility, the error decoder, and the in-process cache used by Exchange for getAllMarkets / getAssets. If you depended on any of these, no action is needed.
Mapping cheat sheet
Symbol-for-symbol substitutions:
// Backend wrapper namespace — removed; everything below moves to top-level imports
BorosBackend.getCoreSdk() → getOpenApiSdk()
BorosBackend.Core.MarketListItemResponse → OpenApi.MarketListItemResponse
BorosBackend.setCoreBackendUrl(url) → setOpenApiBackendUrl(url)
BorosBackend.getSendTxsBotSdk() → removed (use getOpenApiSdk().sendTxs.*)
BorosBackend.setSendTxsBotBackendUrl(url) → removed (same host as Open API)
BorosBackend.SendTxsBot.* → removed (folded into OpenApi)
BorosBackend.getPendleV2Sdk() → removed
BorosBackend.setPendleV2BackendUrl(url) → removed
LogStoreBackend.* → removed
// Exchange methods (call-site renames)
exchange.bulkPlaceOrdersV5(...) → exchange.bulkPlaceOrders(...)
exchange.getMarkets(...) → exchange.getAllMarkets(...) // return type changed
exchange.getPnlLimitOrders(...) → exchange.getOrdersPage(...)
exchange.getPnlLimitOrdersFromContract(...) → exchange.getActiveOrdersFromContract(...) // was private
exchange.bulkPlaceOrdersV2 / V4 → removed (use bulkPlaceOrders)
exchange.closeActivePositions(...) → removed
exchange.updateSettings(...) → removed
exchange.getCollaterals(...) → removed
exchange.getAmmInfoByAmmId(...) → removed
exchange.getCumulativePnl(...) → removed
// UI helpers / calculators / distributors
calculateIncentiveRange(...) → removed (re-implement client-side)
Calculator.* → removed (use on-chain reads + Open API)
multiTokenMerkleDistributorAbi → removed
lpRewardsDistributor → removed
makerIncentiveRewardsDistributor → removed
referralRewardsDistributor → removed
Distributor (Pendle single-token claim) → unchanged
Verifying migration
After bumping the package, a clean tsc --noEmit is the fastest signal. Three failure modes are expected:
- Import-not-found on
BorosBackend,LogStoreBackend,calculateIncentiveRange,Calculator.*, or a removed distributor. Replace per the tables above. - Property-not-found on
exchange.*— likely one of the renames (bulkPlaceOrdersV5,getMarkets,getPnlLimitOrders, …). See Exchange method changes. - Type narrowing on an
OpenApi.*response field. Some upstream@ApiPropertyannotations were corrected; fields that previously typed asanymay now bestring | undefined,number, etc. Adjust the call site — the runtime payload is unchanged.
Once those are clean, behavioral parity is the same as the old package: calldata format, EIP-712 typed data, and endpoint contract were not changed by the extraction.