From b03baeed5d229bca82890ecfc6261549c876c95b Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:24:58 +0300 Subject: [PATCH 01/52] deltaV2/types --- src/methods/delta/helpers/types.ts | 22 ++-- src/methods/deltaV2/types.ts | 191 +++++++++++++++++++++++++++++ src/types.ts | 9 ++ 3 files changed, 212 insertions(+), 10 deletions(-) create mode 100644 src/methods/deltaV2/types.ts diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index 19a153fcb..a00d2fb42 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -255,15 +255,16 @@ type DeltaAuctionBase = { type: 'MARKET' | 'LIMIT'; }; -export type DeltaAuction = - T extends T - ? Prettify< - DeltaAuctionBase & { - onChainOrderType: T; - order: OnChainOrderMap[T]; - } & BridgeAuctionFiledsMap[T] - > - : never; +export type DeltaAuction< + T extends keyof OnChainOrderMap = keyof OnChainOrderMap, +> = T extends T + ? Prettify< + DeltaAuctionBase & { + onChainOrderType: T; + order: OnChainOrderMap[T]; + } & BridgeAuctionFiledsMap[T] + > + : never; export type DeltaAuctionDelta = DeltaAuction<'Order'>; export type DeltaAuctionExternal = DeltaAuction<'ExternalOrder'>; @@ -298,7 +299,8 @@ export type OnChainOrderType = | 'Order' | 'ExternalOrder' | 'TWAPOrder' - | 'TWAPBuyOrder'; + | 'TWAPBuyOrder' + | 'ProductiveOrder'; export type TWAPOnChainOrderType = 'TWAPOrder' | 'TWAPBuyOrder'; diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts new file mode 100644 index 000000000..c802f19a9 --- /dev/null +++ b/src/methods/deltaV2/types.ts @@ -0,0 +1,191 @@ +import type { Address } from '../../types'; +import type { TypedDataField } from '../common/orders/buildOrderData'; +import type { + Bridge, + DeltaOrderUnion, + OnChainOrderType, +} from '../delta/helpers/types'; + +/** @description Response from POST /delta/v2/orders/build — EIP-712 typed data ready to sign. */ +export type BuiltDeltaOrderV2 = { + toSign: { + domain: { + name: string; + version: string; + chainId: number; + verifyingContract: string; + }; + /** EIP-712 type definitions keyed by type name. */ + types: Record; + /** The on-chain order struct value to sign. */ + value: Record; + }; + /** EIP-712 order hash. */ + orderHash: string; +}; + +/** @description Token identity used across v2 endpoints. */ +export type DeltaPriceToken = { + chainId: number; + address: Address; +}; + +/** @description A token amount with its USD value, used uniformly for inputs, outputs, and fees. */ +export type DeltaTokenAmount = { + token: DeltaPriceToken; + /** @description Amount in wei. */ + amount: string; + /** @description USD value of the amount. */ + amountUSD: string; +}; + +/** @description Bridge tag used to mark routes as recommended / fastest / best-return. */ +export type BridgeTag = 'recommended' | 'fastest' | 'best-return'; + +/** @description Subset of the on-chain Bridge struct returned in v2 price responses. + * (the full `route` object is passed to the server when building an order). */ +export type DeltaRouteBridgeContractParams = Omit; + +/** @description Bridge details on a route. Same-chain routes carry `null` for `route.bridge`. */ +export type DeltaRouteBridge = { + /** @description Bridge protocol identifier (e.g. "Across", "Relay", "Mayan"). */ + protocol: string; + /** @description Estimated bridging time in milliseconds. */ + estimatedTimeMs: number; + /** @description Tags for this route ("recommended", "fastest", "best-return"). May be empty. */ + tags: BridgeTag[]; + /** @description Bridge contract parameters as returned by the server. */ + contractParams: DeltaRouteBridgeContractParams; +}; + +/** @description A single step of a route (origin chain or destination chain). */ +export type DeltaRouteStep = { + /** @description The token amount entering this step (before any per-step swap). */ + input: DeltaTokenAmount; + /** @description The token amount exiting this step (after any per-step swap). */ + output: DeltaTokenAmount; +}; + +/** @description A route describes how the swap flows from origin chain to destination chain. */ +export type DeltaRoute = { + /** @description Source-chain step. The on-chain Delta order's amounts come from `origin.input` and `origin.output`. */ + origin: DeltaRouteStep; + /** @description Destination-chain step. For same-chain routes this mirrors `origin`. */ + destination: DeltaRouteStep; + /** @description Bridge details. `null` for same-chain routes. */ + bridge: DeltaRouteBridge | null; + /** @description Fee breakdown for this route. */ + fees: { + /** @description Gas fee (single DeltaTokenAmount on the source chain). */ + gas: DeltaTokenAmount; + /** @description Bridge fees (empty array for same-chain). */ + bridge: DeltaTokenAmount[]; + }; +}; + +/** @description v2 price response: route-based, cross-chain first. */ +export type DeltaPriceV2 = { + /** @description Unique request ID for tracing. */ + id: string; + /** @description Order side. */ + side: 'SELL' | 'BUY'; + /** @description Token the user trades (identity only — amounts live in route.origin.input). */ + inputToken: DeltaPriceToken; + /** @description Token the user receives (identity only — amounts live in route.destination.output). */ + outputToken: DeltaPriceToken; + /** @description Recommended route with full amounts and bridge details. */ + route: DeltaRoute; + /** @description Partner info attached to this price. */ + partner: { + name: string; + /** @description Partner fee in percent (e.g. 0.12 = 0.12%). */ + feePercent: number; + }; + /** @description Address to approve for spending the input token. */ + spender: Address; + /** @description Alternative routes (other bridges). Each is a full DeltaRoute. */ + alternatives: DeltaRoute[]; +}; + +/** @description A flat bridge-routes entry returned by GET /delta/v2/prices/bridge-routes. */ +export type BridgeRoute = { + srcChainId: number; + destChainId: number; + /** @description Output tokens supported on the dest chain for this src→dest pair. */ + tokens: Address[]; +}; + +/* ------------------------------------------------------------------ */ +/* Orders v2 response shape (different from v1's DeltaAuction) */ +/* ------------------------------------------------------------------ */ + +/** @description Integrator-facing order status returned by v2 order endpoints. */ +const DeltaOrderStatusV2Map = { + Pending: 'PENDING', + AwaitingSignature: 'AWAITING_SIGNATURE', + Active: 'ACTIVE', + Suspended: 'SUSPENDED', + Cancelling: 'CANCELLING', + Bridging: 'BRIDGING', + Completed: 'COMPLETED', + Failed: 'FAILED', + Expired: 'EXPIRED', + Cancelled: 'CANCELLED', + Refunded: 'REFUNDED', +} as const; + +export type DeltaOrderStatusV2 = + (typeof DeltaOrderStatusV2Map)[keyof typeof DeltaOrderStatusV2Map]; + +/** @description `OnChainOrderType` plus the synthetic `FillableOrder` label, used when a Standard `Order` is `partiallyFillable`. */ +export type DeltaOnChainOrderTypeReported = OnChainOrderType | 'FillableOrder'; + +/** @description Order kind: MARKET (immediate) vs LIMIT (rate-pegged). */ +export type DeltaOrderTypeV2 = 'MARKET' | 'LIMIT'; + +/** @description Token side on an order. SELL provides an explicit `amount`; BUY provides expected/executed amounts. */ +export type DeltaTokenSide = + | { + chainId: number; + token: Address; + amount: string; + } + | { + chainId: number; + token: Address; + expectedAmount: string | null; + executedAmount: string | null; + }; + +/** @description A single transaction entry on a v2 order. */ +export type DeltaTransactionV2 = { + originTx: string; + destinationTx: string | null; + /** @description Filled percent of the slice (0–100). */ + filledPercent: number; + spentAmount: string | null; + receivedAmount: string | null; +}; + +/** @description Order shape returned by GET /v2/orders, /v2/orders/:id, /v2/orders/hash/:hash. */ +export type DeltaOrderV2Response = { + id: string; + status: DeltaOrderStatusV2; + side: 'SELL' | 'BUY'; + type: DeltaOrderTypeV2; + onChainOrderType: DeltaOnChainOrderTypeReported | null; + input: DeltaTokenSide; + output: DeltaTokenSide; + owner: Address; + beneficiary: Address; + orderHash: string | null; + partner: string; + order: DeltaOrderUnion; + transactions: DeltaTransactionV2[]; + /** @description ISO datetime string. */ + createdAt: string | null; + /** @description ISO datetime string. */ + updatedAt: string | null; + /** @description ISO datetime string. */ + expiresAt: string | null; +}; diff --git a/src/types.ts b/src/types.ts index 345f85d9f..c19201145 100644 --- a/src/types.ts +++ b/src/types.ts @@ -241,3 +241,12 @@ export interface JsonFragment { */ readonly gas?: string; } + +/** @description Standard pagination envelope returned by paginated API endpoints. */ +export type PaginatedResponse = { + data: T[]; + total: number; + page: number; + limit: number; + hasMore: boolean; +}; From 8a0e6121dd29fd37e4ada8b725f15b5caa28283a Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:25:28 +0300 Subject: [PATCH 02/52] deltaV2/get methods --- src/methods/delta/getDeltaOrders.ts | 8 +- src/methods/delta/getDeltaPrice.ts | 9 +- src/methods/deltaV2/getAgentsListV2.ts | 34 +++++ src/methods/deltaV2/getBridgeRoutes.ts | 82 ++++++++++++ src/methods/deltaV2/getDeltaOrdersV2.ts | 120 ++++++++++++++++++ src/methods/deltaV2/getDeltaPriceV2.ts | 108 ++++++++++++++++ .../deltaV2/isTokenSupportedInDeltaV2.ts | 52 ++++++++ 7 files changed, 405 insertions(+), 8 deletions(-) create mode 100644 src/methods/deltaV2/getAgentsListV2.ts create mode 100644 src/methods/deltaV2/getBridgeRoutes.ts create mode 100644 src/methods/deltaV2/getDeltaOrdersV2.ts create mode 100644 src/methods/deltaV2/getDeltaPriceV2.ts create mode 100644 src/methods/deltaV2/isTokenSupportedInDeltaV2.ts diff --git a/src/methods/delta/getDeltaOrders.ts b/src/methods/delta/getDeltaOrders.ts index 412a1362e..21af0f941 100644 --- a/src/methods/delta/getDeltaOrders.ts +++ b/src/methods/delta/getDeltaOrders.ts @@ -8,7 +8,7 @@ import type { import type { DeltaAuction, DeltaAuctionStatus, - OnChainOrderType, + OnChainOrderMap, } from './helpers/types'; /** @deprecated Use DeltaAuction directly */ @@ -32,7 +32,7 @@ type GetDeltaOrderByHash = ( requestParams?: RequestParameters ) => Promise; -type OrdersFilter = { +type OrdersFilter = { /** @description Order.owner to fetch Delta Order for */ userAddress: Address; /** @description Pagination option, page. Default 1 */ @@ -62,7 +62,7 @@ type OrderFiltersQuery = Omit & { }; type GetDeltaOrders = { - ( + ( options: OrdersFilter & { onChainOrderType: T }, requestParams?: RequestParameters ): Promise[]>; @@ -126,7 +126,7 @@ export const constructGetDeltaOrders = ({ }; const getDeltaOrders: GetDeltaOrders = async < - T extends OnChainOrderType = OnChainOrderType + T extends keyof OnChainOrderMap = keyof OnChainOrderMap >( options: OrdersFilter, requestParams?: RequestParameters diff --git a/src/methods/delta/getDeltaPrice.ts b/src/methods/delta/getDeltaPrice.ts index 70e69c658..25268e559 100644 --- a/src/methods/delta/getDeltaPrice.ts +++ b/src/methods/delta/getDeltaPrice.ts @@ -12,7 +12,7 @@ import { BridgePriceInfo } from './helpers/types'; type SwapSideUnion = EnumerateLiteral; export type DeltaPriceParams = { - /** @description Source Token Address. Not Native Token */ + /** @description Source Token Address */ srcToken: string; /** @description Destination Token Address */ destToken: string; @@ -141,9 +141,10 @@ interface GetDeltaPrice { options: DeltaPriceParams & { destChainId?: undefined }, requestParams?: RequestParameters ): Promise; - (options: DeltaPriceParams, requestParams?: RequestParameters): Promise< - DeltaPrice | BridgePrice - >; + ( + options: DeltaPriceParams, + requestParams?: RequestParameters + ): Promise; } export type GetDeltaPriceFunctions = { diff --git a/src/methods/deltaV2/getAgentsListV2.ts b/src/methods/deltaV2/getAgentsListV2.ts new file mode 100644 index 000000000..558457f06 --- /dev/null +++ b/src/methods/deltaV2/getAgentsListV2.ts @@ -0,0 +1,34 @@ +import { API_URL } from '../../constants'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; + +export type AgentList = string[]; + +type AgentsListV2Response = AgentList; + +type GetAgentsListV2 = ( + requestParams?: RequestParameters +) => Promise; + +export type GetAgentsListV2Functions = { + /** @description List agents available on the current chain. */ + getAgentsListV2: GetAgentsListV2; +}; + +export const constructGetAgentsListV2 = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): GetAgentsListV2Functions => { + const baseUrl = `${apiURL}/delta/v2/agents/list/${chainId}` as const; + + const getAgentsListV2: GetAgentsListV2 = async (requestParams) => { + const data = await fetcher({ + url: baseUrl, + method: 'GET', + requestParams, + }); + return data; + }; + + return { getAgentsListV2 }; +}; diff --git a/src/methods/deltaV2/getBridgeRoutes.ts b/src/methods/deltaV2/getBridgeRoutes.ts new file mode 100644 index 000000000..7e0f9626b --- /dev/null +++ b/src/methods/deltaV2/getBridgeRoutes.ts @@ -0,0 +1,82 @@ +import { API_URL } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { BridgeProtocolResponse } from '../delta/getBridgeInfo'; +import type { BridgeRoute } from './types'; + +type GetBridgeRoutesParams = { + /** @description Include tokens that can be swapped on destChain after bridge. Default is true. */ + allowBridgeAndSwap?: boolean; + /** @description Include only the specified bridges. Default is all bridges. */ + bridges?: string[]; +}; + +type BridgeRoutesQuery = { + allowBridgeAndSwap?: boolean; + bridges?: string; +}; + +type BridgeRoutesResponse = { routes: BridgeRoute[] }; + +type GetBridgeRoutes = ( + params?: GetBridgeRoutesParams, + requestParams?: RequestParameters +) => Promise; + +type GetBridgeProtocolsV2 = ( + requestParams?: RequestParameters +) => Promise; + +type BridgeProtocolsV2Response = { + bridgeProtocols: BridgeProtocolResponse[]; +}; + +export type GetBridgeRoutesFunctions = { + /** @description Fetch supported bridge routes as a flat array (v2 replacement for bridge-info). */ + getBridgeRoutes: GetBridgeRoutes; + /** @description Fetch supported bridge protocols (falls through to v1 controller on the v2 path). */ + getBridgeProtocolsV2: GetBridgeProtocolsV2; +}; + +export const constructGetBridgeRoutes = ({ + apiURL = API_URL, + fetcher, +}: ConstructFetchInput): GetBridgeRoutesFunctions => { + const deltaPricesUrl = `${apiURL}/delta/v2/prices` as const; + + const getBridgeRoutes: GetBridgeRoutes = async ( + params = {}, + requestParams + ) => { + const { allowBridgeAndSwap, bridges } = params; + + const search = constructSearchString({ + allowBridgeAndSwap, + bridges: bridges?.join(','), + }); + + const fetchURL = `${deltaPricesUrl}/bridge-routes${search}` as const; + + const data = await fetcher({ + url: fetchURL, + method: 'GET', + requestParams, + }); + + return data.routes; + }; + + const getBridgeProtocolsV2: GetBridgeProtocolsV2 = async (requestParams) => { + const fetchURL = `${deltaPricesUrl}/bridge-protocols` as const; + + const data = await fetcher({ + url: fetchURL, + method: 'GET', + requestParams, + }); + + return data.bridgeProtocols; + }; + + return { getBridgeRoutes, getBridgeProtocolsV2 }; +}; diff --git a/src/methods/deltaV2/getDeltaOrdersV2.ts b/src/methods/deltaV2/getDeltaOrdersV2.ts new file mode 100644 index 000000000..c2df42b37 --- /dev/null +++ b/src/methods/deltaV2/getDeltaOrdersV2.ts @@ -0,0 +1,120 @@ +import { API_URL } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; +import type { + Address, + ConstructFetchInput, + PaginatedResponse, + RequestParameters, +} from '../../types'; +import type { OnChainOrderType } from '../delta/helpers/types'; +import type { + DeltaOrderStatusV2, + DeltaOrderTypeV2, + DeltaOrderV2Response, +} from './types'; + +type GetDeltaOrderByIdV2 = ( + orderId: string, + requestParams?: RequestParameters +) => Promise; + +type GetDeltaOrderByHashV2 = ( + orderHash: string, + requestParams?: RequestParameters +) => Promise; + +type OrdersV2Filter = { + /** @description `order.owner` to fetch Delta Orders for. */ + userAddress: Address; + /** @description Pagination option. Default 1. */ + page?: number; + /** @description Pagination option. Default 100, max 1000. */ + limit?: number; + /** @description Filter by chainId. Omitted = orders across all chains. */ + chainId?: number[]; + /** @description Filter by integrator-facing status. */ + status?: DeltaOrderStatusV2[]; + /** @description Filter by order type. MARKET or LIMIT. */ + type?: DeltaOrderTypeV2; + /** @description Filter by on-chain order type. */ + onChainOrderType?: OnChainOrderType; +}; + +type OrderFiltersV2Query = Omit & { + chainId?: string; + status?: string; +}; + +type GetDeltaOrdersV2 = ( + options: OrdersV2Filter, + requestParams?: RequestParameters +) => Promise>; + +export type GetDeltaOrdersV2Functions = { + /** @description Fetch a single order by its UUID. */ + getDeltaOrderByIdV2: GetDeltaOrderByIdV2; + /** @description Fetch a single order by its EIP-712 order hash. */ + getDeltaOrderByHashV2: GetDeltaOrderByHashV2; + /** @description List Delta orders with the v2 pagination envelope. */ + getDeltaOrdersV2: GetDeltaOrdersV2; +}; + +export const constructGetDeltaOrdersV2 = ({ + apiURL = API_URL, + fetcher, +}: ConstructFetchInput): GetDeltaOrdersV2Functions => { + const baseUrl = `${apiURL}/delta/v2/orders` as const; + + const getDeltaOrderByIdV2: GetDeltaOrderByIdV2 = async ( + orderId, + requestParams + ) => { + const fetchURL = `${baseUrl}/${orderId}` as const; + return fetcher({ + url: fetchURL, + method: 'GET', + requestParams, + }); + }; + + const getDeltaOrderByHashV2: GetDeltaOrderByHashV2 = async ( + orderHash, + requestParams + ) => { + const fetchURL = `${baseUrl}/hash/${orderHash}` as const; + return fetcher({ + url: fetchURL, + method: 'GET', + requestParams, + }); + }; + + const getDeltaOrdersV2: GetDeltaOrdersV2 = async (options, requestParams) => { + const chainIdString = options.chainId?.join(','); + const statusString = options.status?.join(','); + + const search = constructSearchString({ + userAddress: options.userAddress, + page: options.page, + limit: options.limit, + type: options.type, + onChainOrderType: options.onChainOrderType, + chainId: chainIdString, + status: statusString, + }); + + const fetchURL = `${baseUrl}${search}` as const; + + return fetcher>({ + url: fetchURL, + method: 'GET', + requestParams, + }); + }; + + return { + getDeltaOrderByIdV2, + getDeltaOrderByHashV2, + getDeltaOrdersV2, + }; +}; diff --git a/src/methods/deltaV2/getDeltaPriceV2.ts b/src/methods/deltaV2/getDeltaPriceV2.ts new file mode 100644 index 000000000..89558cb52 --- /dev/null +++ b/src/methods/deltaV2/getDeltaPriceV2.ts @@ -0,0 +1,108 @@ +import { API_URL, SwapSide } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; +import type { + ConstructFetchInput, + EnumerateLiteral, + RequestParameters, +} from '../../types'; +import type { DeltaPriceV2 } from './types'; + +type SwapSideUnion = EnumerateLiteral; + +export type DeltaPriceV2Params = { + /** @description Source Token Address */ + srcToken: string; + /** @description Destination Token Address. For Crosschain Orders, the destination token on the destination chain */ + destToken: string; + /** @description srcToken amount in wei */ + amount: string; + /** @description Source Token Decimals */ + srcDecimals: number; + /** @description Destination Token Decimals */ + destDecimals: number; + /** @description User's Wallet Address */ + userAddress?: string; + /** @description Beneficiary Address */ + beneficiary?: string; + /** @description Partner string. */ + partner?: string; + /** @description Partner fee in basis points (bps), 50bps=0.5% */ + partnerFeeBps?: number; + /** @description Destination Chain ID for Crosschain Orders */ + destChainId?: number; + /** @description SELL or BUY, default is SELL */ + side?: SwapSideUnion; + /** @description In %. Bypasses the API price impact check (default = 15%) */ + maxImpact?: number; + maxUSDImpact?: number; + + includeAgents?: string[]; + excludeAgents?: string[]; + includeBridges?: string[]; + excludeBridges?: string[]; + + /** @description Allow swap on destChain after bridge. Default is true. */ + allowBridgeAndSwap?: boolean; + degenMode?: boolean; +}; + +type DeltaPriceV2QueryOptions = Omit< + DeltaPriceV2Params, + 'includeAgents' | 'excludeAgents' | 'includeBridges' | 'excludeBridges' +> & { + chainId: number; + includeAgents?: string; + excludeAgents?: string; + includeBridges?: string; + excludeBridges?: string; +}; + +type GetDeltaPriceV2 = ( + options: DeltaPriceV2Params, + requestParams?: RequestParameters +) => Promise; + +export type GetDeltaPriceV2Functions = { + /** @description Fetch a v2 price quote (route-based response). */ + getDeltaPriceV2: GetDeltaPriceV2; +}; + +export const constructGetDeltaPriceV2 = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): GetDeltaPriceV2Functions => { + const pricesUrl = `${apiURL}/delta/v2/prices` as const; + + const getDeltaPriceV2: GetDeltaPriceV2 = async (options, requestParams) => { + const { + includeAgents, + excludeAgents, + includeBridges, + excludeBridges, + ...rest + } = options; + + const search = constructSearchString({ + ...rest, + chainId, + side: options.side ?? SwapSide.SELL, + includeAgents: includeAgents?.join(','), + excludeAgents: excludeAgents?.join(','), + includeBridges: includeBridges?.join(','), + excludeBridges: excludeBridges?.join(','), + }); + + const fetchURL = `${pricesUrl}${search}` as const; + + const data = await fetcher({ + url: fetchURL, + method: 'GET', + requestParams, + }); + + return data; + }; + + return { getDeltaPriceV2 }; +}; diff --git a/src/methods/deltaV2/isTokenSupportedInDeltaV2.ts b/src/methods/deltaV2/isTokenSupportedInDeltaV2.ts new file mode 100644 index 000000000..9315abc10 --- /dev/null +++ b/src/methods/deltaV2/isTokenSupportedInDeltaV2.ts @@ -0,0 +1,52 @@ +import { API_URL } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; +import type { + Address, + ConstructFetchInput, + RequestParameters, +} from '../../types'; + +type TokenSupportedResponse = { supported: boolean }; +type IsTokenSupportedQuery = { + token: Address; + chainId: number; +}; + +type IsTokenSupportedInDeltaV2 = ( + token: Address, + requestParams?: RequestParameters +) => Promise; + +export type IsTokenSupportedInDeltaV2Functions = { + isTokenSupportedInDeltaV2: IsTokenSupportedInDeltaV2; +}; + +export const constructIsTokenSupportedInDeltaV2 = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): IsTokenSupportedInDeltaV2Functions => { + const baseUrl = `${apiURL}/delta/v2/prices/is-token-supported` as const; + + const isTokenSupportedInDeltaV2: IsTokenSupportedInDeltaV2 = async ( + token, + requestParams + ) => { + const search = constructSearchString({ + token, + chainId, + }); + + const fetchURL = `${baseUrl}/${search}` as const; + + const data = await fetcher({ + url: fetchURL, + method: 'GET', + requestParams, + }); + + return data.supported; + }; + + return { isTokenSupportedInDeltaV2 }; +}; From c04277afbc456f30f3bfd0a5fffcee1fba9cd04c Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:25:45 +0300 Subject: [PATCH 03/52] deltaV2/post methods --- src/methods/delta/postDeltaOrder.ts | 8 +-- src/methods/deltaV2/postDeltaOrderV2.ts | 61 ++++++++++++++++++ .../deltaV2/postExternalDeltaOrderV2.ts | 45 +++++++++++++ src/methods/deltaV2/postTWAPDeltaOrderV2.ts | 63 +++++++++++++++++++ 4 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 src/methods/deltaV2/postDeltaOrderV2.ts create mode 100644 src/methods/deltaV2/postExternalDeltaOrderV2.ts create mode 100644 src/methods/deltaV2/postTWAPDeltaOrderV2.ts diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index 3956a32c5..1a3d5a6e2 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -1,13 +1,9 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { - DeltaAuction, - OnChainOrderMap, - OnChainOrderType, -} from './helpers/types'; +import type { DeltaAuction, OnChainOrderMap } from './helpers/types'; -export type DeltaOrderToPost = { +export type DeltaOrderToPost = { /** @description Partner string */ partner?: string; /** @description Referrer address */ diff --git a/src/methods/deltaV2/postDeltaOrderV2.ts b/src/methods/deltaV2/postDeltaOrderV2.ts new file mode 100644 index 000000000..aa54d74c0 --- /dev/null +++ b/src/methods/deltaV2/postDeltaOrderV2.ts @@ -0,0 +1,61 @@ +import { API_URL } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { DeltaAuction, OnChainOrderMap } from '../delta/helpers/types'; + +export type DeltaOrderToPostV2 = { + /** @description Partner string */ + partner?: string; + /** @description Referrer address */ + referrerAddress?: string; + order: OnChainOrderMap[T]; + /** @description Signature of the order from order.owner address. EOA signatures must be submitted in ERC-2098 Compact Representation. */ + signature: string; + chainId: number; + /** @description Designates the Order as being able to be partially filled, as opposed to fill-or-kill */ + partiallyFillable?: boolean; + /** @description Type of the order. MARKET or LIMIT. Default is MARKET */ + type?: 'MARKET' | 'LIMIT'; + includeAgents?: string[]; + excludeAgents?: string[]; +}; + +export type PostDeltaOrderV2Params = Omit & { + degenMode?: boolean; +}; + +type PostDeltaOrderV2 = ( + postData: PostDeltaOrderV2Params, + requestParams?: RequestParameters +) => Promise>; + +export type PostDeltaOrderV2Functions = { + postDeltaOrderV2: PostDeltaOrderV2; +}; + +export const constructPostDeltaOrderV2 = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): PostDeltaOrderV2Functions => { + const postOrderUrl = `${apiURL}/delta/v2/orders` as const; + + const postDeltaOrderV2: PostDeltaOrderV2 = (_postData, requestParams) => { + const { degenMode, ...postData } = _postData; + const deltaOrderToPost: DeltaOrderToPostV2 = { ...postData, chainId }; + + const search = constructSearchString<{ degenMode?: boolean }>({ + degenMode, + }); + const fetchURL = `${postOrderUrl}/${search}` as const; + + return fetcher>({ + url: fetchURL, + method: 'POST', + data: deltaOrderToPost, + requestParams, + }); + }; + + return { postDeltaOrderV2 }; +}; diff --git a/src/methods/deltaV2/postExternalDeltaOrderV2.ts b/src/methods/deltaV2/postExternalDeltaOrderV2.ts new file mode 100644 index 000000000..384183230 --- /dev/null +++ b/src/methods/deltaV2/postExternalDeltaOrderV2.ts @@ -0,0 +1,45 @@ +import { API_URL } from '../../constants'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { DeltaAuction } from '../delta/helpers/types'; +import type { DeltaOrderToPostV2 } from './postDeltaOrderV2'; + +export type PostExternalDeltaOrderV2Params = Omit< + DeltaOrderToPostV2<'ExternalOrder'>, + 'chainId' +>; + +type PostExternalDeltaOrderV2 = ( + postData: PostExternalDeltaOrderV2Params, + requestParams?: RequestParameters +) => Promise>; + +export type PostExternalDeltaOrderV2Functions = { + postExternalDeltaOrderV2: PostExternalDeltaOrderV2; +}; + +export const constructPostExternalDeltaOrderV2 = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): PostExternalDeltaOrderV2Functions => { + const postOrderUrl = `${apiURL}/delta/v2/orders` as const; + + const postExternalDeltaOrderV2: PostExternalDeltaOrderV2 = ( + postData, + requestParams + ) => { + const deltaOrderToPost: DeltaOrderToPostV2<'ExternalOrder'> = { + ...postData, + chainId, + }; + + return fetcher>({ + url: postOrderUrl, + method: 'POST', + data: deltaOrderToPost, + requestParams, + }); + }; + + return { postExternalDeltaOrderV2 }; +}; diff --git a/src/methods/deltaV2/postTWAPDeltaOrderV2.ts b/src/methods/deltaV2/postTWAPDeltaOrderV2.ts new file mode 100644 index 000000000..244c303ee --- /dev/null +++ b/src/methods/deltaV2/postTWAPDeltaOrderV2.ts @@ -0,0 +1,63 @@ +import type { Prettify } from 'ts-essentials'; +import { API_URL } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { + DeltaAuction, + TWAPOnChainOrderType, +} from '../delta/helpers/types'; +import type { DeltaOrderToPostV2 } from './postDeltaOrderV2'; + +export type PostTWAPDeltaOrderV2Params = Prettify< + Omit< + DeltaOrderToPostV2<'TWAPOrder'> | DeltaOrderToPostV2<'TWAPBuyOrder'>, + 'chainId' + > & { + /** @description Must be "TWAPOrder" or "TWAPBuyOrder" */ + onChainOrderType: TWAPOnChainOrderType; + degenMode?: boolean; + } +>; + +type PostTWAPDeltaOrderV2 = ( + postData: PostTWAPDeltaOrderV2Params, + requestParams?: RequestParameters +) => Promise | DeltaAuction<'TWAPBuyOrder'>>; + +export type PostTWAPDeltaOrderV2Functions = { + postTWAPDeltaOrderV2: PostTWAPDeltaOrderV2; +}; + +export const constructPostTWAPDeltaOrderV2 = ({ + apiURL = API_URL, + chainId, + fetcher, +}: ConstructFetchInput): PostTWAPDeltaOrderV2Functions => { + const postOrderUrl = `${apiURL}/delta/v2/orders` as const; + + const postTWAPDeltaOrderV2: PostTWAPDeltaOrderV2 = ( + _postData, + requestParams + ) => { + const { degenMode, ...postData } = _postData; + const deltaOrderToPost: DeltaOrderToPostV2<'TWAPOrder' | 'TWAPBuyOrder'> = { + ...postData, + chainId, + }; + + const search = constructSearchString<{ degenMode?: boolean }>({ + degenMode, + }); + + const fetchURL = `${postOrderUrl}/${search}` as const; + + return fetcher | DeltaAuction<'TWAPBuyOrder'>>({ + url: fetchURL, + method: 'POST', + data: deltaOrderToPost, + requestParams, + }); + }; + + return { postTWAPDeltaOrderV2 }; +}; From f04482c5a436b7dc3e3df038db69d5e675da8ad8 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:26:10 +0300 Subject: [PATCH 04/52] deltaV2/build methods --- src/methods/deltaV2/buildDeltaOrderV2.ts | 83 ++++++++++++ .../deltaV2/buildExternalDeltaOrderV2.ts | 92 +++++++++++++ src/methods/deltaV2/buildTWAPDeltaOrderV2.ts | 128 ++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 src/methods/deltaV2/buildDeltaOrderV2.ts create mode 100644 src/methods/deltaV2/buildExternalDeltaOrderV2.ts create mode 100644 src/methods/deltaV2/buildTWAPDeltaOrderV2.ts diff --git a/src/methods/deltaV2/buildDeltaOrderV2.ts b/src/methods/deltaV2/buildDeltaOrderV2.ts new file mode 100644 index 000000000..f2de8800f --- /dev/null +++ b/src/methods/deltaV2/buildDeltaOrderV2.ts @@ -0,0 +1,83 @@ +import { API_URL } from '../../constants'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { BuiltDeltaOrderV2, DeltaRoute } from './types'; +export type { BuiltDeltaOrderV2 } from './types'; + +export type BuildDeltaOrderV2Params = { + /** @description The address of the order owner */ + owner: string; + /** @description The address of the order beneficiary. Defaults to owner. */ + beneficiary?: string; + /** @description The deadline for the order (unix seconds) */ + deadline?: number; + /** @description The nonce of the order. Random if omitted. */ + nonce?: string; + /** @description Optional permit signature for the src token. Defaults to "0x". */ + permit?: string; + /** @description Partner string. Passed to the server to resolve partner fee details. */ + partner?: string; + /** @description Partner fee in basis points (bps), 50bps=0.5% */ + partnerFeeBps?: number; + /** @description Partner address */ + partnerAddress?: string; + /** @description Take surplus flag */ + partnerTakesSurplus?: boolean; + /** @description Whether the surplus should be capped. True by default. */ + capSurplus?: boolean; + /** @description Metadata for the order, hex string */ + metadata?: string; + /** @description Designates the Order as partially fillable instead of fill-or-kill. Default false. */ + partiallyFillable?: boolean; + + /** @description DeltaRoute from getDeltaPriceV2 — either priceV2.route or any priceV2.alternatives[i] */ + route: DeltaRoute; + /** @description Order side. SELL or BUY. */ + side: 'SELL' | 'BUY'; + /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ + slippage?: number; +}; + +type BuildDeltaOrderV2 = ( + buildOrderParams: BuildDeltaOrderV2Params, + requestParams?: RequestParameters +) => Promise; + +export type BuildDeltaOrderV2Functions = { + /** @description Build a Delta v2 order from a DeltaRoute via the server endpoint, ready to sign and post. */ + buildDeltaOrderV2: BuildDeltaOrderV2; +}; + +export const constructBuildDeltaOrderV2 = ( + options: ConstructFetchInput +): BuildDeltaOrderV2Functions => { + const { apiURL = API_URL, chainId, fetcher } = options; + const buildUrl = `${apiURL}/delta/v2/orders/build` as const; + + const buildDeltaOrderV2: BuildDeltaOrderV2 = async (params, requestParams) => + fetcher({ + url: buildUrl, + method: 'POST', + data: { + chainId, + side: params.side, + route: params.route, + owner: params.owner, + beneficiary: params.beneficiary, + deadline: params.deadline, + nonce: params.nonce, + permit: params.permit, + slippage: params.slippage, + metadata: params.metadata, + partiallyFillable: params.partiallyFillable, + partner: params.partner, + partnerAddress: params.partnerAddress, + partnerFeeBps: params.partnerFeeBps, + partnerTakesSurplus: params.partnerTakesSurplus, + capSurplus: params.capSurplus, + orderType: 'Order', + }, + requestParams, + }); + + return { buildDeltaOrderV2 }; +}; diff --git a/src/methods/deltaV2/buildExternalDeltaOrderV2.ts b/src/methods/deltaV2/buildExternalDeltaOrderV2.ts new file mode 100644 index 000000000..8f0d60165 --- /dev/null +++ b/src/methods/deltaV2/buildExternalDeltaOrderV2.ts @@ -0,0 +1,92 @@ +import { API_URL } from '../../constants'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { BuiltDeltaOrderV2, DeltaRoute } from './types'; +export type { BuiltDeltaOrderV2 } from './types'; + +export type BuildExternalDeltaOrderV2Params = { + /** @description The address of the order owner */ + owner: string; + /** @description The address of the external handler contract */ + handler: string; + /** @description Protocol-specific encoded bytes for the external handler */ + data: string; + /** @description The address of the order beneficiary. Defaults to owner. */ + beneficiary?: string; + /** @description The deadline for the order (unix seconds) */ + deadline?: number; + /** @description The nonce of the order. Random if omitted. */ + nonce?: string; + /** @description Optional permit signature for the src token. Defaults to "0x". */ + permit?: string; + /** @description Partner string. Passed to the server to resolve partner fee details. */ + partner?: string; + /** @description Partner fee in basis points (bps), 50bps=0.5% */ + partnerFeeBps?: number; + /** @description Partner address */ + partnerAddress?: string; + /** @description Take surplus flag */ + partnerTakesSurplus?: boolean; + /** @description Whether the surplus should be capped. True by default. */ + capSurplus?: boolean; + /** @description Metadata for the order, hex string */ + metadata?: string; + /** @description Designates the Order as partially fillable. Default false. */ + partiallyFillable?: boolean; + + /** @description DeltaRoute from getDeltaPriceV2 */ + route: DeltaRoute; + /** @description Order side. SELL or BUY. */ + side: 'SELL' | 'BUY'; + /** @description Slippage in basis points (bps). Default 0. */ + slippage?: number; +}; + +type BuildExternalDeltaOrderV2 = ( + buildOrderParams: BuildExternalDeltaOrderV2Params, + requestParams?: RequestParameters +) => Promise; + +export type BuildExternalDeltaOrderV2Functions = { + /** @description Build a Delta v2 External Order from a DeltaRoute via the server endpoint, ready to sign and post. */ + buildExternalDeltaOrderV2: BuildExternalDeltaOrderV2; +}; + +export const constructBuildExternalDeltaOrderV2 = ( + options: ConstructFetchInput +): BuildExternalDeltaOrderV2Functions => { + const { apiURL = API_URL, chainId, fetcher } = options; + const buildUrl = `${apiURL}/delta/v2/orders/build` as const; + + const buildExternalDeltaOrderV2: BuildExternalDeltaOrderV2 = async ( + params, + requestParams + ) => + fetcher({ + url: buildUrl, + method: 'POST', + data: { + chainId, + side: params.side, + route: params.route, + owner: params.owner, + handler: params.handler, + data: params.data, + beneficiary: params.beneficiary, + deadline: params.deadline, + nonce: params.nonce, + permit: params.permit, + slippage: params.slippage, + metadata: params.metadata, + partiallyFillable: params.partiallyFillable, + partner: params.partner, + partnerAddress: params.partnerAddress, + partnerFeeBps: params.partnerFeeBps, + partnerTakesSurplus: params.partnerTakesSurplus, + capSurplus: params.capSurplus, + orderType: 'ExternalOrder', + }, + requestParams, + }); + + return { buildExternalDeltaOrderV2 }; +}; diff --git a/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts b/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts new file mode 100644 index 000000000..9a0408a0b --- /dev/null +++ b/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts @@ -0,0 +1,128 @@ +import { API_URL } from '../../constants'; +import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { BuiltDeltaOrderV2, DeltaRoute } from './types'; +export type { BuiltDeltaOrderV2 } from './types'; + +type BuildTWAPDeltaOrderV2Base = { + /** @description The address of the order owner */ + owner: string; + /** @description The address of the order beneficiary. Defaults to owner. */ + beneficiary?: string; + /** @description The deadline for the order (unix seconds) */ + deadline?: number; + /** @description The nonce of the order. Random if omitted. */ + nonce?: string; + /** @description Optional permit signature for the src token. Defaults to "0x". */ + permit?: string; + /** @description Partner string. Passed to the server to resolve partner fee details. */ + partner?: string; + /** @description Seconds between slice executions (min 60) */ + interval: number; + /** @description Number of slices (min 2) */ + numSlices: number; + /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ + slippage?: number; + /** @description DeltaRoute from getDeltaPriceV2 for a single slice */ + route: DeltaRoute; + /** @description Partner fee in basis points (bps) */ + partnerFeeBps?: number; + /** @description Partner address */ + partnerAddress?: string; + /** @description Take surplus flag */ + partnerTakesSurplus?: boolean; + /** @description Whether the surplus should be capped. True by default. */ + capSurplus?: boolean; + /** @description Metadata for the order, hex string */ + metadata?: string; + /** @description Designates the Order as partially fillable. Default false. */ + partiallyFillable?: boolean; +}; + +export type BuildTWAPSellDeltaOrderV2Params = BuildTWAPDeltaOrderV2Base & { + onChainOrderType: 'TWAPOrder'; + /** @description Total source token amount across all slices. route.origin.input.amount must equal floor(totalSrcAmount / numSlices). */ + totalSrcAmount: string; +}; + +export type BuildTWAPBuyDeltaOrderV2Params = BuildTWAPDeltaOrderV2Base & { + onChainOrderType: 'TWAPBuyOrder'; + /** @description Total destination token amount to buy across all slices. route.origin.output.amount must equal floor(totalDestAmount / numSlices). */ + totalDestAmount: string; + /** @description Maximum source token amount willing to spend across all slices. */ + maxSrcAmount: string; +}; + +export type BuildTWAPDeltaOrderV2Params = + | BuildTWAPSellDeltaOrderV2Params + | BuildTWAPBuyDeltaOrderV2Params; + +type BuildTWAPDeltaOrderV2 = ( + buildOrderParams: BuildTWAPDeltaOrderV2Params, + requestParams?: RequestParameters +) => Promise; + +export type BuildTWAPDeltaOrderV2Functions = { + /** @description Build a Delta v2 TWAP Order (sell or buy) from a DeltaRoute via the server endpoint, ready to sign and post. */ + buildTWAPDeltaOrderV2: BuildTWAPDeltaOrderV2; +}; + +export const constructBuildTWAPDeltaOrderV2 = ( + options: ConstructFetchInput +): BuildTWAPDeltaOrderV2Functions => { + const { apiURL = API_URL, chainId, fetcher } = options; + const buildUrl = `${apiURL}/delta/v2/orders/build` as const; + + const buildTWAPDeltaOrderV2: BuildTWAPDeltaOrderV2 = async ( + params, + requestParams + ) => { + const commonBody = { + chainId, + route: params.route, + owner: params.owner, + beneficiary: params.beneficiary, + deadline: params.deadline, + nonce: params.nonce, + permit: params.permit, + slippage: params.slippage, + metadata: params.metadata, + partiallyFillable: params.partiallyFillable, + partner: params.partner, + partnerAddress: params.partnerAddress, + partnerFeeBps: params.partnerFeeBps, + partnerTakesSurplus: params.partnerTakesSurplus, + capSurplus: params.capSurplus, + interval: params.interval, + numSlices: params.numSlices, + }; + + if (params.onChainOrderType === 'TWAPOrder') { + return fetcher({ + url: buildUrl, + method: 'POST', + data: { + ...commonBody, + side: 'SELL', + orderType: 'TWAPOrder', + totalSrcAmount: params.totalSrcAmount, + }, + requestParams, + }); + } + + return fetcher({ + url: buildUrl, + method: 'POST', + data: { + ...commonBody, + side: 'BUY', + orderType: 'TWAPBuyOrder', + totalDestAmount: params.totalDestAmount, + maxSrcAmount: params.maxSrcAmount, + }, + requestParams, + }); + }; + + return { buildTWAPDeltaOrderV2 }; +}; From 21d82dd6b3f444b84e7431ca1cc5ae926d0e2867 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:26:45 +0300 Subject: [PATCH 05/52] deltaV2/cancel methods --- src/methods/deltaV2/cancelDeltaOrderV2.ts | 96 +++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 src/methods/deltaV2/cancelDeltaOrderV2.ts diff --git a/src/methods/deltaV2/cancelDeltaOrderV2.ts b/src/methods/deltaV2/cancelDeltaOrderV2.ts new file mode 100644 index 000000000..2aebcd6d1 --- /dev/null +++ b/src/methods/deltaV2/cancelDeltaOrderV2.ts @@ -0,0 +1,96 @@ +import type { + ConstructProviderFetchInput, + RequestParameters, +} from '../../types'; +import { constructGetDeltaContract } from '../delta/getDeltaContract'; +import { + buildCancelDeltaOrderSignableData, + type CancelDeltaOrderData, +} from '../delta/helpers/buildCancelDeltaOrderData'; + +type SuccessResponse = { success: true }; + +type CancelDeltaOrderRequestParams = { + orderIds: string[]; + signature: string; +}; + +export type SignCancelDeltaOrderRequestV2 = ( + params: CancelDeltaOrderData, + requestParams?: RequestParameters +) => Promise; + +export type PostCancelDeltaOrderRequestV2 = ( + params: CancelDeltaOrderRequestParams, + requestParams?: RequestParameters +) => Promise; + +export type CancelDeltaOrderV2 = ( + params: CancelDeltaOrderData, + requestParams?: RequestParameters +) => Promise; + +export type CancelDeltaOrderV2Functions = { + signCancelLimitDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2; + postCancelLimitDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2; + /** @description Cancel one or more Limit Delta orders via the v2 endpoint */ + cancelLimitDeltaOrdersV2: CancelDeltaOrderV2; +}; + +export const constructCancelDeltaOrderV2 = ( + options: Pick< + ConstructProviderFetchInput, + 'contractCaller' | 'fetcher' | 'apiURL' | 'chainId' + > +): CancelDeltaOrderV2Functions => { + const { getDeltaContract } = constructGetDeltaContract(options); + + const signCancelLimitDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2 = + async (params, requestParams) => { + const ParaswapDelta = await getDeltaContract(requestParams); + if (!ParaswapDelta) { + throw new Error(`Delta is not available on chain ${options.chainId}`); + } + + const typedData = buildCancelDeltaOrderSignableData({ + orderInput: params, + paraswapDeltaAddress: ParaswapDelta, + chainId: options.chainId, + }); + + return options.contractCaller.signTypedDataCall(typedData); + }; + + const postCancelLimitDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2 = + async (params, requestParams) => { + const cancelUrl = `${options.apiURL}/delta/v2/orders/cancel` as const; + + return options.fetcher({ + url: cancelUrl, + method: 'POST', + data: params, + requestParams, + }); + }; + + const cancelLimitDeltaOrdersV2: CancelDeltaOrderV2 = async ( + { orderIds }, + requestParams + ) => { + const signature = await signCancelLimitDeltaOrderRequestV2( + { orderIds }, + requestParams + ); + + return postCancelLimitDeltaOrderRequestV2( + { orderIds, signature }, + requestParams + ); + }; + + return { + signCancelLimitDeltaOrderRequestV2, + postCancelLimitDeltaOrderRequestV2, + cancelLimitDeltaOrdersV2, + }; +}; From 8436825523e4cb09422acfd1251c373cc9a0dc78 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:27:46 +0300 Subject: [PATCH 06/52] deltaV2/all handlers --- src/methods/deltaV2/index.ts | 304 +++++++++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 src/methods/deltaV2/index.ts diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts new file mode 100644 index 000000000..5ccdbd085 --- /dev/null +++ b/src/methods/deltaV2/index.ts @@ -0,0 +1,304 @@ +import type { ConstructProviderFetchInput } from '../../types'; +import type { DeltaAuction, OnChainOrderMap } from '../delta/helpers/types'; + +// reused v1 modules +import { + GetDeltaContractFunctions, + constructGetDeltaContract, +} from '../delta/getDeltaContract'; +import { + constructGetPartnerFee, + GetPartnerFeeFunctions, +} from '../delta/getPartnerFee'; +import { + ApproveTokenForDeltaFunctions, + constructApproveTokenForDelta, +} from '../delta/approveForDelta'; +import { + constructPreSignDeltaOrder, + PreSignDeltaOrderFunctions, +} from '../delta/preSignDeltaOrder'; +import { + constructPreSignExternalDeltaOrder, + PreSignExternalDeltaOrderFunctions, +} from '../delta/preSignExternalDeltaOrder'; +import { + constructPreSignTWAPDeltaOrder, + PreSignTWAPDeltaOrderFunctions, +} from '../delta/preSignTWAPDeltaOrder'; +import { + DeltaTokenModuleFunctions, + constructDeltaTokenModule, +} from '../delta/deltaTokenModule'; + +// new v2 modules +import { + BuildDeltaOrderV2Functions, + BuildDeltaOrderV2Params, + BuiltDeltaOrderV2, + constructBuildDeltaOrderV2, +} from './buildDeltaOrderV2'; +import { + BuildExternalDeltaOrderV2Functions, + BuildExternalDeltaOrderV2Params, + constructBuildExternalDeltaOrderV2, +} from './buildExternalDeltaOrderV2'; +import { + BuildTWAPDeltaOrderV2Functions, + BuildTWAPDeltaOrderV2Params, + constructBuildTWAPDeltaOrderV2, +} from './buildTWAPDeltaOrderV2'; +import { + constructPostDeltaOrderV2, + DeltaOrderToPostV2, + PostDeltaOrderV2Functions, +} from './postDeltaOrderV2'; +import { + constructPostExternalDeltaOrderV2, + PostExternalDeltaOrderV2Functions, +} from './postExternalDeltaOrderV2'; +import { + constructPostTWAPDeltaOrderV2, + PostTWAPDeltaOrderV2Functions, +} from './postTWAPDeltaOrderV2'; +import { + constructGetDeltaPriceV2, + GetDeltaPriceV2Functions, +} from './getDeltaPriceV2'; +import { + constructGetDeltaOrdersV2, + GetDeltaOrdersV2Functions, +} from './getDeltaOrdersV2'; +import { + constructGetBridgeRoutes, + GetBridgeRoutesFunctions, +} from './getBridgeRoutes'; +import { + constructIsTokenSupportedInDeltaV2, + IsTokenSupportedInDeltaV2Functions, +} from './isTokenSupportedInDeltaV2'; +import { + CancelDeltaOrderV2Functions, + constructCancelDeltaOrderV2, +} from './cancelDeltaOrderV2'; +import { + constructGetAgentsListV2, + GetAgentsListV2Functions, +} from './getAgentsListV2'; + +// ── Sign v2 ───────────────────────────────────────────────────────────────── + +type SignDeltaOrderV2 = (builtOrder: BuiltDeltaOrderV2) => Promise; + +export type SignDeltaOrderV2Functions = { + /** @description Sign a BuiltDeltaOrderV2 (any order type) using EIP-712 typed data. */ + signDeltaOrderV2: SignDeltaOrderV2; +}; + +export const constructSignDeltaOrderV2 = ( + options: Pick< + ConstructProviderFetchInput, + 'contractCaller' + > +): SignDeltaOrderV2Functions => { + const signDeltaOrderV2: SignDeltaOrderV2 = async (builtOrder) => { + return options.contractCaller.signTypedDataCall({ + types: builtOrder.toSign.types, + domain: builtOrder.toSign.domain, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data: builtOrder.toSign.value as Record, + }); + }; + return { signDeltaOrderV2 }; +}; + +// ── Submit orchestrators ───────────────────────────────────────────────────── + +export type SubmitDeltaOrderV2Params = BuildDeltaOrderV2Params & { + /** @description Referrer address */ + referrerAddress?: string; + degenMode?: boolean; +} & Pick; + +type SubmitDeltaOrderV2 = ( + orderParams: SubmitDeltaOrderV2Params +) => Promise>; + +export type SubmitDeltaOrderV2Funcs = { + submitDeltaOrderV2: SubmitDeltaOrderV2; +}; + +export const constructSubmitDeltaOrderV2 = ( + options: ConstructProviderFetchInput +): SubmitDeltaOrderV2Funcs => { + const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2(options); + const { signDeltaOrderV2 } = constructSignDeltaOrderV2(options); + const { postDeltaOrderV2 } = constructPostDeltaOrderV2(options); + + const submitDeltaOrderV2: SubmitDeltaOrderV2 = async (orderParams) => { + const orderData = await buildDeltaOrderV2(orderParams); + const signature = await signDeltaOrderV2(orderData); + + return postDeltaOrderV2({ + signature, + partner: orderParams.partner, + order: orderData.toSign.value as OnChainOrderMap['Order'], + partiallyFillable: orderParams.partiallyFillable, + referrerAddress: orderParams.referrerAddress, + type: orderParams.type, + includeAgents: orderParams.includeAgents, + excludeAgents: orderParams.excludeAgents, + degenMode: orderParams.degenMode, + }); + }; + + return { submitDeltaOrderV2 }; +}; + +export type SubmitExternalDeltaOrderV2Params = + BuildExternalDeltaOrderV2Params & { + referrerAddress?: string; + } & Pick; + +type SubmitExternalDeltaOrderV2 = ( + orderParams: SubmitExternalDeltaOrderV2Params +) => Promise>; + +export type SubmitExternalDeltaOrderV2Funcs = { + submitExternalDeltaOrderV2: SubmitExternalDeltaOrderV2; +}; + +export const constructSubmitExternalDeltaOrderV2 = ( + options: ConstructProviderFetchInput +): SubmitExternalDeltaOrderV2Funcs => { + const { buildExternalDeltaOrderV2 } = + constructBuildExternalDeltaOrderV2(options); + const { signDeltaOrderV2 } = constructSignDeltaOrderV2(options); + const { postExternalDeltaOrderV2 } = + constructPostExternalDeltaOrderV2(options); + + const submitExternalDeltaOrderV2: SubmitExternalDeltaOrderV2 = async ( + orderParams + ) => { + const orderData = await buildExternalDeltaOrderV2(orderParams); + const signature = await signDeltaOrderV2(orderData); + + return postExternalDeltaOrderV2({ + signature, + partner: orderParams.partner, + order: orderData.toSign.value as OnChainOrderMap['ExternalOrder'], + partiallyFillable: orderParams.partiallyFillable, + referrerAddress: orderParams.referrerAddress, + type: orderParams.type, + includeAgents: orderParams.includeAgents, + excludeAgents: orderParams.excludeAgents, + }); + }; + + return { submitExternalDeltaOrderV2 }; +}; + +export type SubmitTWAPDeltaOrderV2Params = BuildTWAPDeltaOrderV2Params & { + referrerAddress?: string; + degenMode?: boolean; +} & Pick; + +type SubmitTWAPDeltaOrderV2 = ( + orderParams: SubmitTWAPDeltaOrderV2Params +) => Promise | DeltaAuction<'TWAPBuyOrder'>>; + +export type SubmitTWAPDeltaOrderV2Funcs = { + submitTWAPDeltaOrderV2: SubmitTWAPDeltaOrderV2; +}; + +export const constructSubmitTWAPDeltaOrderV2 = ( + options: ConstructProviderFetchInput +): SubmitTWAPDeltaOrderV2Funcs => { + const { buildTWAPDeltaOrderV2 } = constructBuildTWAPDeltaOrderV2(options); + const { signDeltaOrderV2 } = constructSignDeltaOrderV2(options); + const { postTWAPDeltaOrderV2 } = constructPostTWAPDeltaOrderV2(options); + + const submitTWAPDeltaOrderV2: SubmitTWAPDeltaOrderV2 = async ( + orderParams + ) => { + const orderData = await buildTWAPDeltaOrderV2(orderParams); + const signature = await signDeltaOrderV2(orderData); + + return postTWAPDeltaOrderV2({ + signature, + partner: orderParams.partner, + order: orderData.toSign.value as + | OnChainOrderMap['TWAPOrder'] + | OnChainOrderMap['TWAPBuyOrder'], + onChainOrderType: orderParams.onChainOrderType, + partiallyFillable: orderParams.partiallyFillable, + referrerAddress: orderParams.referrerAddress, + type: orderParams.type, + includeAgents: orderParams.includeAgents, + excludeAgents: orderParams.excludeAgents, + degenMode: orderParams.degenMode, + }); + }; + + return { submitTWAPDeltaOrderV2 }; +}; + +// ── Handler bundle ─────────────────────────────────────────────────────────── + +export type DeltaV2OrderHandlers = SubmitDeltaOrderV2Funcs & + SubmitExternalDeltaOrderV2Funcs & + SubmitTWAPDeltaOrderV2Funcs & + BuildDeltaOrderV2Functions & + BuildExternalDeltaOrderV2Functions & + BuildTWAPDeltaOrderV2Functions & + PostDeltaOrderV2Functions & + PostExternalDeltaOrderV2Functions & + PostTWAPDeltaOrderV2Functions & + SignDeltaOrderV2Functions & + PreSignDeltaOrderFunctions & + PreSignExternalDeltaOrderFunctions & + PreSignTWAPDeltaOrderFunctions & + GetDeltaPriceV2Functions & + GetDeltaOrdersV2Functions & + GetBridgeRoutesFunctions & + IsTokenSupportedInDeltaV2Functions & + GetAgentsListV2Functions & + GetDeltaContractFunctions & + GetPartnerFeeFunctions & + ApproveTokenForDeltaFunctions & + DeltaTokenModuleFunctions & + CancelDeltaOrderV2Functions; + +/** @description Construct an SDK bundle exposing every Delta v2 method (queries, build/sign/post, on-chain helpers). */ +export const constructAllDeltaV2OrdersHandlers = ( + options: ConstructProviderFetchInput< + TxResponse, + 'signTypedDataCall' | 'transactCall' + > +): DeltaV2OrderHandlers => { + return { + ...constructSubmitDeltaOrderV2(options), + ...constructSubmitExternalDeltaOrderV2(options), + ...constructSubmitTWAPDeltaOrderV2(options), + ...constructBuildDeltaOrderV2(options), + ...constructBuildExternalDeltaOrderV2(options), + ...constructBuildTWAPDeltaOrderV2(options), + ...constructPostDeltaOrderV2(options), + ...constructPostExternalDeltaOrderV2(options), + ...constructPostTWAPDeltaOrderV2(options), + ...constructSignDeltaOrderV2(options), + ...constructPreSignDeltaOrder(options), + ...constructPreSignExternalDeltaOrder(options), + ...constructPreSignTWAPDeltaOrder(options), + ...constructGetDeltaPriceV2(options), + ...constructGetDeltaOrdersV2(options), + ...constructGetBridgeRoutes(options), + ...constructIsTokenSupportedInDeltaV2(options), + ...constructGetAgentsListV2(options), + ...constructGetDeltaContract(options), + ...constructGetPartnerFee(options), + ...constructApproveTokenForDelta(options), + ...constructDeltaTokenModule(options), + ...constructCancelDeltaOrderV2(options), + }; +}; From 84004c68e4fd826cfa1838f98713499bec0bf85a Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:27:56 +0300 Subject: [PATCH 07/52] deltaV2/export from SDK --- src/index.ts | 148 ++++++++++++++++++++++++++++++++++++++++++++++ src/sdk/full.ts | 8 +++ src/sdk/simple.ts | 56 ++++++++++++++++++ 3 files changed, 212 insertions(+) diff --git a/src/index.ts b/src/index.ts index 9a000901d..faf2dffbd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -135,6 +135,7 @@ import type { OptionalRate, APIVersion, ExtraFetchParams, + PaginatedResponse, } from './types'; import type { @@ -287,6 +288,85 @@ import { SignableCancelDeltaOrderData, } from './methods/delta/helpers/buildCancelDeltaOrderData'; +// Delta v2 modules +import { + BuildDeltaOrderV2Functions, + BuildDeltaOrderV2Params, + constructBuildDeltaOrderV2, +} from './methods/deltaV2/buildDeltaOrderV2'; +import { + BuildExternalDeltaOrderV2Functions, + BuildExternalDeltaOrderV2Params, + constructBuildExternalDeltaOrderV2, +} from './methods/deltaV2/buildExternalDeltaOrderV2'; +import { + BuildTWAPDeltaOrderV2Functions, + BuildTWAPDeltaOrderV2Params, + BuildTWAPSellDeltaOrderV2Params, + BuildTWAPBuyDeltaOrderV2Params, + constructBuildTWAPDeltaOrderV2, +} from './methods/deltaV2/buildTWAPDeltaOrderV2'; +import { + constructPostDeltaOrderV2, + DeltaOrderToPostV2, + PostDeltaOrderV2Functions, + PostDeltaOrderV2Params, +} from './methods/deltaV2/postDeltaOrderV2'; +import { + constructPostExternalDeltaOrderV2, + PostExternalDeltaOrderV2Functions, + PostExternalDeltaOrderV2Params, +} from './methods/deltaV2/postExternalDeltaOrderV2'; +import { + constructPostTWAPDeltaOrderV2, + PostTWAPDeltaOrderV2Functions, + PostTWAPDeltaOrderV2Params, +} from './methods/deltaV2/postTWAPDeltaOrderV2'; +import { + constructGetDeltaPriceV2, + DeltaPriceV2Params, + GetDeltaPriceV2Functions, +} from './methods/deltaV2/getDeltaPriceV2'; +import { + constructGetDeltaOrdersV2, + GetDeltaOrdersV2Functions, +} from './methods/deltaV2/getDeltaOrdersV2'; +import { + constructGetBridgeRoutes, + GetBridgeRoutesFunctions, +} from './methods/deltaV2/getBridgeRoutes'; +import { + constructIsTokenSupportedInDeltaV2, + IsTokenSupportedInDeltaV2Functions, +} from './methods/deltaV2/isTokenSupportedInDeltaV2'; +import { + CancelDeltaOrderV2Functions, + constructCancelDeltaOrderV2, +} from './methods/deltaV2/cancelDeltaOrderV2'; +import { + AgentList, + constructGetAgentsListV2, + GetAgentsListV2Functions, +} from './methods/deltaV2/getAgentsListV2'; +import type { + DeltaOrderStatusV2, + BuiltDeltaOrderV2, + DeltaPriceToken, + DeltaTokenAmount, + BridgeTag, + DeltaRouteBridge, + DeltaRouteBridgeContractParams, + DeltaRouteStep, + DeltaRoute, + DeltaPriceV2, + BridgeRoute, + DeltaOnChainOrderTypeReported, + DeltaOrderTypeV2, + DeltaTokenSide, + DeltaTransactionV2, + DeltaOrderV2Response, +} from './methods/deltaV2/types'; + export { constructSwapSDK, SwapSDKMethods } from './methods/swap'; export { @@ -306,6 +386,19 @@ export { SubmitTWAPDeltaOrderParams, } from './methods/delta'; +export { + constructAllDeltaV2OrdersHandlers, + constructSubmitDeltaOrderV2, + constructSubmitExternalDeltaOrderV2, + constructSubmitTWAPDeltaOrderV2, + constructSignDeltaOrderV2, + DeltaV2OrderHandlers, + SubmitDeltaOrderV2Params, + SubmitExternalDeltaOrderV2Params, + SubmitTWAPDeltaOrderV2Params, + SignDeltaOrderV2Functions, +} from './methods/deltaV2'; + export type { TransactionParams, BuildOptions, @@ -388,6 +481,21 @@ export { constructPreSignTWAPDeltaOrder, // Quote methods constructGetQuote, + // Delta v2 runtime values (const-object enums etc.) + DeltaOrderStatusV2, + // Delta V2 methods + constructBuildDeltaOrderV2, + constructBuildExternalDeltaOrderV2, + constructBuildTWAPDeltaOrderV2, + constructPostDeltaOrderV2, + constructPostExternalDeltaOrderV2, + constructPostTWAPDeltaOrderV2, + constructGetDeltaPriceV2, + constructGetDeltaOrdersV2, + constructGetBridgeRoutes, + constructIsTokenSupportedInDeltaV2, + constructCancelDeltaOrderV2, + constructGetAgentsListV2, // different helpers constructGetPartnerFee, constructGetBridgeInfo, @@ -521,6 +629,45 @@ export type { PostTWAPDeltaOrderFunctions, PostTWAPDeltaOrderParams, PreSignTWAPDeltaOrderFunctions, + // Delta v2 types + BuiltDeltaOrderV2, + DeltaPriceToken, + DeltaTokenAmount, + BridgeTag, + DeltaRouteBridge, + DeltaRouteBridgeContractParams, + DeltaRouteStep, + DeltaRoute, + DeltaPriceV2, + BridgeRoute, + DeltaOnChainOrderTypeReported, + DeltaOrderTypeV2, + DeltaTokenSide, + DeltaTransactionV2, + DeltaOrderV2Response, + DeltaPriceV2Params, + GetDeltaPriceV2Functions, + GetDeltaOrdersV2Functions, + GetBridgeRoutesFunctions, + IsTokenSupportedInDeltaV2Functions, + BuildDeltaOrderV2Params, + BuildDeltaOrderV2Functions, + BuildExternalDeltaOrderV2Params, + BuildExternalDeltaOrderV2Functions, + BuildTWAPDeltaOrderV2Params, + BuildTWAPSellDeltaOrderV2Params, + BuildTWAPBuyDeltaOrderV2Params, + BuildTWAPDeltaOrderV2Functions, + DeltaOrderToPostV2, + PostDeltaOrderV2Params, + PostDeltaOrderV2Functions, + PostExternalDeltaOrderV2Params, + PostExternalDeltaOrderV2Functions, + PostTWAPDeltaOrderV2Params, + PostTWAPDeltaOrderV2Functions, + CancelDeltaOrderV2Functions, + AgentList as AgentInfo, + GetAgentsListV2Functions, // types for Quote methods GetQuoteFunctions, QuoteParams, @@ -548,6 +695,7 @@ export type { APIVersion, SwapSideUnion, ExtraFetchParams, + PaginatedResponse, }; export { SDKConfig, constructPartialSDK } from './sdk/partial'; diff --git a/src/sdk/full.ts b/src/sdk/full.ts index e6d2dde54..f0b4ecb57 100644 --- a/src/sdk/full.ts +++ b/src/sdk/full.ts @@ -12,6 +12,10 @@ import { constructAllDeltaOrdersHandlers, DeltaOrderHandlers, } from '../methods/delta'; +import { + constructAllDeltaV2OrdersHandlers, + DeltaV2OrderHandlers, +} from '../methods/deltaV2'; import { constructGetQuote, GetQuoteFunctions, @@ -26,6 +30,7 @@ export type AllSDKMethods = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; + deltaV2: DeltaV2OrderHandlers; quote: GetQuoteFunctions; } & Required; @@ -41,6 +46,8 @@ export const constructFullSDK = ( constructAllNFTOrdersHandlers(config); const delta: DeltaOrderHandlers = constructAllDeltaOrdersHandlers(config); + const deltaV2: DeltaV2OrderHandlers = + constructAllDeltaV2OrdersHandlers(config); const quote = constructGetQuote(config); return { @@ -48,6 +55,7 @@ export const constructFullSDK = ( limitOrders, nftOrders, delta, + deltaV2, quote, apiURL: config.apiURL ?? API_URL, chainId: config.chainId, diff --git a/src/sdk/simple.ts b/src/sdk/simple.ts index 8d16a1860..ca6b7b887 100644 --- a/src/sdk/simple.ts +++ b/src/sdk/simple.ts @@ -136,6 +136,34 @@ import { constructIsTokenSupportedInDelta, IsTokenSupportedInDeltaFunctions, } from '../methods/delta/isTokenSupportedInDelta'; +import { + constructAllDeltaV2OrdersHandlers, + DeltaV2OrderHandlers, +} from '../methods/deltaV2'; +import { + BuildDeltaOrderV2Functions, + constructBuildDeltaOrderV2, +} from '../methods/deltaV2/buildDeltaOrderV2'; +import { + constructPostDeltaOrderV2, + PostDeltaOrderV2Functions, +} from '../methods/deltaV2/postDeltaOrderV2'; +import { + constructGetDeltaOrdersV2, + GetDeltaOrdersV2Functions, +} from '../methods/deltaV2/getDeltaOrdersV2'; +import { + constructGetDeltaPriceV2, + GetDeltaPriceV2Functions, +} from '../methods/deltaV2/getDeltaPriceV2'; +import { + constructGetBridgeRoutes, + GetBridgeRoutesFunctions, +} from '../methods/deltaV2/getBridgeRoutes'; +import { + constructIsTokenSupportedInDeltaV2, + IsTokenSupportedInDeltaV2Functions, +} from '../methods/deltaV2/isTokenSupportedInDeltaV2'; export type SwapFetchMethods = GetBalancesFunctions & GetTokensFunctions & @@ -168,6 +196,15 @@ export type DeltaFetchMethods = BuildDeltaOrderFunctions & IsTokenSupportedInDeltaFunctions & PostDeltaOrderFunctions; +export type DeltaV2FetchMethods = BuildDeltaOrderV2Functions & + GetDeltaOrdersV2Functions & + GetDeltaPriceV2Functions & + GetDeltaContractFunctions & + GetPartnerFeeFunctions & + GetBridgeRoutesFunctions & + IsTokenSupportedInDeltaV2Functions & + PostDeltaOrderV2Functions; + export type SimpleFetchSDK = { swap: SwapFetchMethods; /** @deprecated Limit Orders are deprecated and will be removed in a future version. */ @@ -175,6 +212,7 @@ export type SimpleFetchSDK = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrdersFetchMethods; delta: DeltaFetchMethods; + deltaV2: DeltaV2FetchMethods; quote: QuoteFetchMethods; } & Required; @@ -187,6 +225,7 @@ export type SimpleSDK = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; + deltaV2: DeltaV2OrderHandlers; quote: QuoteFetchMethods; } & Required; @@ -298,6 +337,18 @@ export function constructSimpleSDK( constructIsTokenSupportedInDelta ); + const deltaV2 = constructPartialSDK( + config, + constructBuildDeltaOrderV2, + constructPostDeltaOrderV2, + constructGetDeltaOrdersV2, + constructGetDeltaPriceV2, + constructGetDeltaContract, + constructGetPartnerFee, + constructGetBridgeRoutes, + constructIsTokenSupportedInDeltaV2 + ); + const quote = constructPartialSDK(config, constructGetQuote); return { @@ -305,6 +356,7 @@ export function constructSimpleSDK( limitOrders, nftOrders, delta, + deltaV2, quote, apiURL: options.apiURL ?? API_URL, chainId: options.chainId, @@ -333,6 +385,9 @@ export function constructSimpleSDK( const delta: DeltaOrderHandlers = constructAllDeltaOrdersHandlers(config); + const deltaV2: DeltaV2OrderHandlers = + constructAllDeltaV2OrdersHandlers(config); + const quote = constructGetQuote(config); return { @@ -340,6 +395,7 @@ export function constructSimpleSDK( limitOrders, nftOrders, delta, + deltaV2, quote, apiURL: options.apiURL ?? API_URL, chainId: options.chainId, From 7201ceaf3197945d8904a0ee308ff87ff613442e Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:28:03 +0300 Subject: [PATCH 08/52] deltaV2/tests --- tests/deltaV2.test.ts | 969 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 969 insertions(+) create mode 100644 tests/deltaV2.test.ts diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts new file mode 100644 index 000000000..97220fa69 --- /dev/null +++ b/tests/deltaV2.test.ts @@ -0,0 +1,969 @@ +import * as dotenv from 'dotenv'; +import fetch from 'isomorphic-unfetch'; +import { + constructPartialSDK, + constructFetchFetcher, + constructBuildDeltaOrderV2, + constructPostDeltaOrderV2, + constructGetDeltaOrdersV2, + constructGetDeltaPriceV2, + constructGetDeltaContract, + constructGetPartnerFee, + constructGetBridgeRoutes, + constructIsTokenSupportedInDeltaV2, + constructCancelDeltaOrderV2, + constructGetAgentsListV2, + constructBuildExternalDeltaOrderV2, + constructPostExternalDeltaOrderV2, + constructBuildTWAPDeltaOrderV2, + constructPostTWAPDeltaOrderV2, + constructAllDeltaV2OrdersHandlers, + constructSubmitDeltaOrderV2, + DeltaPriceV2, + DeltaRoute, + PaginatedResponse, + BridgeRoute, + FetcherFunction, + BuiltDeltaOrderV2, +} from '../src'; +import type { ContractCallerFunctions, TxHash } from '../src/types'; +import type { DeltaAuction } from '../src/methods/delta/helpers/types'; +import type { DeltaOrderV2Response } from '../src/methods/deltaV2/types'; + +dotenv.config(); + +const PARASWAP_DELTA = '0x1111111111111111111111111111111111111111'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f'; +const USDC_ARB = '0xaf88d065e77c8cc2239327c5edb3a432268e5831'; +const OWNER = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9'; +const API_URL = 'https://api.test.invalid'; +const FAKE_SIGNATURE = '0x' + 'ab'.repeat(64); + +type FetchSpy = jest.Mock, Parameters>; + +function buildPriceV2Fixture(overrides: Partial = {}): DeltaPriceV2 { + const srcInput = { + token: { chainId: 1, address: WETH }, + amount: '1000000000000000000', + amountUSD: '3000', + }; + const destOutput = { + token: { chainId: 1, address: DAI }, + amount: '2950000000000000000000', + amountUSD: '2950', + }; + + const route: DeltaRoute = { + origin: { input: srcInput, output: destOutput }, + destination: { input: destOutput, output: destOutput }, + bridge: null, + fees: { + gas: { + token: { + chainId: 1, + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + }, + amount: '500000', + amountUSD: '0.5', + }, + bridge: [], + }, + }; + + return { + id: 'price-id-1', + side: 'SELL', + inputToken: { chainId: 1, address: WETH }, + outputToken: { chainId: 1, address: DAI }, + route, + partner: { name: 'sdk-test', feePercent: 0 }, + spender: PARASWAP_DELTA, + alternatives: [], + ...overrides, + }; +} + +function buildCrosschainRoute(): DeltaRoute { + const srcInput = { + token: { chainId: 1, address: WETH }, + amount: '1000000000000000000', + amountUSD: '3000', + }; + const srcOutputIntermediate = { + token: { + chainId: 1, + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + }, + amount: '2980000000', + amountUSD: '2980', + }; + const destInput = { + token: { chainId: 42161, address: USDC_ARB }, + amount: '2978000000', + amountUSD: '2978', + }; + const destOutput = { + token: { chainId: 42161, address: USDC_ARB }, + amount: '2978000000', + amountUSD: '2978', + }; + + return { + origin: { input: srcInput, output: srcOutputIntermediate }, + destination: { input: destInput, output: destOutput }, + bridge: { + protocol: 'Across', + tags: ['recommended', 'fastest'], + estimatedTimeMs: 90_000, + contractParams: { + protocolSelector: '0xdeadbeef', + outputToken: USDC_ARB, + scalingFactor: -12, + protocolData: '0xabcd', + }, + }, + fees: { + gas: { + token: { chainId: 1, address: WETH }, + amount: '7000000000000000', + amountUSD: '21', + }, + bridge: [ + { + token: { chainId: 42161, address: USDC_ARB }, + amount: '200000', + amountUSD: '0.2', + }, + ], + }, + }; +} + +/** Minimal BuiltDeltaOrderV2 fixture representing a server-built order. */ +function buildBuiltOrderFixture( + value: Record = {}, + orderHash = '0xdeadbeef1234' +): BuiltDeltaOrderV2 { + return { + toSign: { + domain: { + name: 'Portikus', + version: '2.0.0', + chainId: 1, + verifyingContract: PARASWAP_DELTA, + }, + types: { + Order: [ + { name: 'owner', type: 'address' }, + { name: 'beneficiary', type: 'address' }, + { name: 'srcToken', type: 'address' }, + { name: 'destToken', type: 'address' }, + { name: 'srcAmount', type: 'uint256' }, + { name: 'destAmount', type: 'uint256' }, + { name: 'expectedAmount', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + { name: 'kind', type: 'uint8' }, + { name: 'nonce', type: 'uint256' }, + { name: 'partnerAndFee', type: 'uint256' }, + { name: 'permit', type: 'bytes' }, + { name: 'metadata', type: 'bytes' }, + { name: 'bridge', type: 'Bridge' }, + ], + Bridge: [ + { name: 'protocolSelector', type: 'bytes4' }, + { name: 'destinationChainId', type: 'uint256' }, + { name: 'outputToken', type: 'address' }, + { name: 'scalingFactor', type: 'int8' }, + { name: 'protocolData', type: 'bytes' }, + ], + }, + value: { + owner: OWNER, + beneficiary: OWNER, + srcToken: WETH, + destToken: DAI, + srcAmount: '1000000000000000000', + destAmount: '2950000000000000000000', + expectedAmount: '2950000000000000000000', + deadline: 9999999999, + kind: 0, + nonce: '12345', + permit: '0x', + partnerAndFee: '0', + metadata: '0x', + bridge: { + protocolSelector: '0x00000000', + destinationChainId: 0, + outputToken: '0x0000000000000000000000000000000000000000', + scalingFactor: 0, + protocolData: '0x', + }, + ...value, + }, + }, + orderHash, + }; +} + +function makeMockContractCaller(): ContractCallerFunctions { + return { + staticCall: jest.fn(async () => { + throw new Error( + 'staticCall should not be invoked in v2 fetch-only tests' + ); + }), + transactCall: jest.fn(async () => '0xfeedface' as TxHash), + signTypedDataCall: jest.fn(async () => FAKE_SIGNATURE), + }; +} + +function makeFetcher(handler: (params: any) => any): FetchSpy { + return jest.fn(async (params) => handler(params)) as FetchSpy; +} + +describe('Delta v2: fetch methods', () => { + test('getDeltaPriceV2 hits /delta/v2/prices and returns DeltaPriceV2', async () => { + const fixture = buildPriceV2Fixture(); + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url.startsWith(`${API_URL}/delta/v2/prices?`)).toBe(true); + expect(url).toContain(`srcToken=${WETH}`); + expect(url).toContain(`destToken=${DAI}`); + expect(url).toContain('amount=1000000000000000000'); + expect(url).toContain('chainId=1'); + expect(url).toContain('side=SELL'); + return fixture; + }); + + const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const price = await getDeltaPriceV2({ + srcToken: WETH, + destToken: DAI, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 18, + }); + + expect(price).toEqual(fixture); + expect(price.route.origin.input.amount).toBe('1000000000000000000'); + expect(price.route.bridge).toBeNull(); + expect(fetcher).toHaveBeenCalledTimes(1); + }); + + test('getDeltaPriceV2 passes destChainId for cross-chain', async () => { + const fixture = buildPriceV2Fixture({ + route: buildCrosschainRoute(), + outputToken: { chainId: 42161, address: USDC_ARB }, + }); + const fetcher = makeFetcher(({ url }) => { + expect(url).toContain('destChainId=42161'); + return fixture; + }); + + const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const price = await getDeltaPriceV2({ + srcToken: WETH, + destToken: USDC_ARB, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 6, + destChainId: 42161, + }); + + expect(price.route.bridge?.protocol).toBe('Across'); + expect(price.route.destination.input.token.chainId).toBe(42161); + }); + + test('getBridgeRoutes hits /delta/v2/prices/bridge-routes and unwraps `routes`', async () => { + const routes: BridgeRoute[] = [ + { srcChainId: 1, destChainId: 42161, tokens: [USDC_ARB] }, + { srcChainId: 1, destChainId: 10, tokens: [DAI] }, + ]; + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url).toBe(`${API_URL}/delta/v2/prices/bridge-routes`); + return { routes }; + }); + + const { getBridgeRoutes } = constructGetBridgeRoutes({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + expect(await getBridgeRoutes()).toEqual(routes); + }); + + test('getBridgeRoutes passes filter params', async () => { + const fetcher = makeFetcher(({ url }) => { + expect(url).toContain('allowBridgeAndSwap=false'); + expect(url).toContain('bridges=Across%2CRelay'); + return { routes: [] }; + }); + + const { getBridgeRoutes } = constructGetBridgeRoutes({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + await getBridgeRoutes({ + allowBridgeAndSwap: false, + bridges: ['Across', 'Relay'], + }); + }); + + test('isTokenSupportedInDeltaV2 unwraps `supported`', async () => { + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect( + url.startsWith(`${API_URL}/delta/v2/prices/is-token-supported/?`) + ).toBe(true); + expect(url).toContain(`token=${WETH}`); + expect(url).toContain('chainId=1'); + return { supported: true }; + }); + + const { isTokenSupportedInDeltaV2 } = constructIsTokenSupportedInDeltaV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + expect(await isTokenSupportedInDeltaV2(WETH)).toBe(true); + }); + + test('getDeltaOrdersV2 returns the pagination envelope', async () => { + const order = { id: 'auction-1' } as unknown as DeltaOrderV2Response; + const envelope: PaginatedResponse = { + data: [order], + total: 1, + page: 1, + limit: 100, + hasMore: false, + }; + + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url.startsWith(`${API_URL}/delta/v2/orders?`)).toBe(true); + expect(url).toContain(`userAddress=${OWNER}`); + expect(url).toContain('page=2'); + expect(url).toContain('limit=10'); + return envelope; + }); + + const { getDeltaOrdersV2 } = constructGetDeltaOrdersV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const result = await getDeltaOrdersV2({ + userAddress: OWNER, + page: 2, + limit: 10, + }); + + expect(result).toEqual(envelope); + expect(result.hasMore).toBe(false); + expect(result.data).toHaveLength(1); + }); + + test('getDeltaOrdersV2 by id / by hash use the v2 path', async () => { + const order = { id: 'auction-1' } as unknown as DeltaOrderV2Response; + const fetcher = makeFetcher(({ url }) => { + if (url === `${API_URL}/delta/v2/orders/auction-1`) return order; + if (url === `${API_URL}/delta/v2/orders/hash/0xhash`) return order; + throw new Error(`unexpected URL ${url}`); + }); + + const { getDeltaOrderByIdV2, getDeltaOrderByHashV2 } = + constructGetDeltaOrdersV2({ apiURL: API_URL, chainId: 1, fetcher }); + + expect(await getDeltaOrderByIdV2('auction-1')).toBe(order); + expect(await getDeltaOrderByHashV2('0xhash')).toBe(order); + }); + + test('getAgentsListV2 hits /delta/v2/agents/list/:chainId and returns agent names', async () => { + const agents = ['agent-a', 'agent-b']; + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url).toBe(`${API_URL}/delta/v2/agents/list/42161`); + return agents; // server returns string[] directly + }); + + const { getAgentsListV2 } = constructGetAgentsListV2({ + apiURL: API_URL, + chainId: 42161, + fetcher, + }); + + expect(await getAgentsListV2()).toEqual(agents); + }); +}); + +describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { + test('buildDeltaOrderV2 POSTs to /delta/v2/orders/build with correct body', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, method, data }) => { + expect(method).toBe('POST'); + expect(url).toBe(`${API_URL}/delta/v2/orders/build`); + postedBody = data; + return builtFixture; + }); + + const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const route = buildPriceV2Fixture().route; + const result = await buildDeltaOrderV2({ + owner: OWNER, + route, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(result).toEqual(builtFixture); + expect(postedBody.chainId).toBe(1); + expect(postedBody.side).toBe('SELL'); + expect(postedBody.owner).toBe(OWNER); + expect(postedBody.route).toBe(route); + expect(postedBody.slippage).toBeUndefined(); + expect(postedBody.orderType).toBe('Order'); + }); + + test('buildDeltaOrderV2 passes slippage to server for SELL', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + await buildDeltaOrderV2({ + owner: OWNER, + route: buildPriceV2Fixture().route, + side: 'SELL', + slippage: 100, + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + // slippage is forwarded to server; server applies it to destAmount + expect(postedBody.slippage).toBe(100); + expect(postedBody.side).toBe('SELL'); + }); + + test('buildDeltaOrderV2 passes slippage to server for BUY', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + await buildDeltaOrderV2({ + owner: OWNER, + route: buildPriceV2Fixture().route, + side: 'BUY', + slippage: 100, + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postedBody.slippage).toBe(100); + expect(postedBody.side).toBe('BUY'); + }); + + test('buildDeltaOrderV2 passes cross-chain route as-is; server injects destinationChainId', async () => { + const ccRoute = buildCrosschainRoute(); + const builtFixture = buildBuiltOrderFixture({ + srcToken: WETH, + destToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + bridge: { + protocolSelector: '0xdeadbeef', + destinationChainId: 42161, + outputToken: USDC_ARB, + scalingFactor: -12, + protocolData: '0xabcd', + }, + }); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const result = await buildDeltaOrderV2({ + owner: OWNER, + route: ccRoute, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + // route is forwarded as-is; bridge in route.contractParams has no destinationChainId + expect(postedBody.route).toBe(ccRoute); + // the server (fixture) fills in destinationChainId + expect(result.toSign.value.bridge).toMatchObject({ + protocolSelector: '0xdeadbeef', + destinationChainId: 42161, + }); + }); + + test('buildExternalDeltaOrderV2 sends orderType ExternalOrder with handler/data', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildExternalDeltaOrderV2 } = constructBuildExternalDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const route = buildPriceV2Fixture().route; + await buildExternalDeltaOrderV2({ + owner: OWNER, + handler: '0x2222222222222222222222222222222222222222', + data: '0xdeadbeef', + route, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postedBody.orderType).toBe('ExternalOrder'); + expect(postedBody.handler).toBe( + '0x2222222222222222222222222222222222222222' + ); + expect(postedBody.data).toBe('0xdeadbeef'); + expect(postedBody.route).toBe(route); + }); + + test('buildTWAPDeltaOrderV2 (sell) sends TWAPOrder body; slippage forwarded to server', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildTWAPDeltaOrderV2 } = constructBuildTWAPDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const route = buildPriceV2Fixture().route; + await buildTWAPDeltaOrderV2({ + owner: OWNER, + onChainOrderType: 'TWAPOrder', + route, + totalSrcAmount: '5000000000000000000', + interval: 300, + numSlices: 5, + slippage: 50, + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postedBody.orderType).toBe('TWAPOrder'); + expect(postedBody.interval).toBe(300); + expect(postedBody.numSlices).toBe(5); + expect(postedBody.totalSrcAmount).toBe('5000000000000000000'); + expect(postedBody.slippage).toBe(50); // server applies slippage to destAmountPerSlice + expect(postedBody.side).toBe('SELL'); + }); + + test('buildTWAPDeltaOrderV2 (buy) forwards slippage and maxSrcAmount to server', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildTWAPDeltaOrderV2 } = constructBuildTWAPDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const route = buildPriceV2Fixture().route; + await buildTWAPDeltaOrderV2({ + owner: OWNER, + onChainOrderType: 'TWAPBuyOrder', + route, + totalDestAmount: '5000000000000000000', + maxSrcAmount: '1000000000000000000', + interval: 300, + numSlices: 5, + slippage: 100, + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postedBody.orderType).toBe('TWAPBuyOrder'); + expect(postedBody.side).toBe('BUY'); + expect(postedBody.maxSrcAmount).toBe('1000000000000000000'); + expect(postedBody.slippage).toBe(100); + }); +}); + +describe('Delta v2: submit (build → sign → post)', () => { + test('submitDeltaOrderV2 posts to /delta/v2/orders with signed order', async () => { + const builtFixture = buildBuiltOrderFixture(); + let posted: any; + let postUrl = ''; + + const fetcher = makeFetcher(({ url, method, data }) => { + if (method === 'POST' && url === `${API_URL}/delta/v2/orders/build`) { + return builtFixture; + } + if (method === 'POST' && url.startsWith(`${API_URL}/delta/v2/orders`)) { + postUrl = url; + posted = data; + return { + id: 'auction-99', + order: data.order, + onChainOrderType: 'Order', + } as unknown as DeltaAuction<'Order'>; + } + throw new Error(`unexpected request ${method} ${url}`); + }); + + const { submitDeltaOrderV2 } = constructSubmitDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + contractCaller: makeMockContractCaller(), + }); + + const response = await submitDeltaOrderV2({ + owner: OWNER, + route: buildPriceV2Fixture().route, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postUrl.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); + expect(posted.signature).toBe(FAKE_SIGNATURE); + expect(posted.chainId).toBe(1); + // order comes from builtFixture.toSign.value + expect(posted.order.owner).toBe(OWNER); + expect(posted.order.srcToken).toBe(WETH); + expect(posted.order.destToken).toBe(DAI); + expect(response.id).toBe('auction-99'); + }); + + test('postDeltaOrderV2 forwards degenMode as a query param', async () => { + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('POST'); + expect(url).toContain('degenMode=true'); + return { id: 'x' } as unknown as DeltaAuction<'Order'>; + }); + + const { postDeltaOrderV2 } = constructPostDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + await postDeltaOrderV2({ + signature: FAKE_SIGNATURE, + order: {} as any, + degenMode: true, + }); + }); + + test('postExternalDeltaOrderV2 sends to /delta/v2/orders', async () => { + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('POST'); + expect(url).toBe(`${API_URL}/delta/v2/orders`); + return { id: 'ext-1' } as unknown as DeltaAuction<'ExternalOrder'>; + }); + + const { postExternalDeltaOrderV2 } = constructPostExternalDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + await postExternalDeltaOrderV2({ + signature: FAKE_SIGNATURE, + order: {} as any, + }); + }); + + test('postTWAPDeltaOrderV2 sends to /delta/v2/orders with onChainOrderType', async () => { + const fetcher = makeFetcher(({ url, method, data }) => { + expect(method).toBe('POST'); + expect(url.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); + expect(data.onChainOrderType).toBe('TWAPOrder'); + return { id: 'twap-1' } as unknown as DeltaAuction<'TWAPOrder'>; + }); + + const { postTWAPDeltaOrderV2 } = constructPostTWAPDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + await postTWAPDeltaOrderV2({ + signature: FAKE_SIGNATURE, + order: {} as any, + onChainOrderType: 'TWAPOrder', + }); + }); +}); + +describe('Delta v2: cancel', () => { + test('cancelLimitDeltaOrdersV2 signs then posts to /delta/v2/orders/cancel', async () => { + let postedTo = ''; + let postedBody: any; + + const fetcher = makeFetcher(({ url, method, data }) => { + const adapter = url.includes('/adapters/contracts') + ? { + AugustusSwapper: '0x', + TokenTransferProxy: '0x', + AugustusRFQ: '0x', + Executors: {}, + ParaswapDelta: '0x1111111111111111111111111111111111111111', + } + : undefined; + if (adapter) return adapter; + if (method === 'POST') { + postedTo = url; + postedBody = data; + return { success: true }; + } + throw new Error('unexpected'); + }); + + const { cancelLimitDeltaOrdersV2 } = constructCancelDeltaOrderV2({ + apiURL: API_URL, + chainId: 1, + fetcher, + contractCaller: makeMockContractCaller(), + }); + + const result = await cancelLimitDeltaOrdersV2({ + orderIds: ['a', 'b'], + }); + + expect(result).toEqual({ success: true }); + expect(postedTo).toBe(`${API_URL}/delta/v2/orders/cancel`); + expect(postedBody.orderIds).toEqual(['a', 'b']); + expect(postedBody.signature).toBe(FAKE_SIGNATURE); + }); +}); + +describe('Delta v2: live API contract', () => { + jest.setTimeout(30_000); + + const LIVE_API = process.env.API_URL; + const fetchFetcher = constructFetchFetcher(fetch); + + test('GET /delta/v2/prices (same-chain) matches DeltaPriceV2 shape', async () => { + const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, + }); + + const price = await getDeltaPriceV2({ + srcToken: WETH, + destToken: DAI, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 18, + side: 'SELL', + }); + + expect(price.side).toBe('SELL'); + expect(price.inputToken.chainId).toBe(1); + expect(price.outputToken.chainId).toBe(1); + expect(typeof price.id).toBe('string'); + expect(typeof price.spender).toBe('string'); + expect(price.route.origin.input.token.address.toLowerCase()).toBe(WETH); + expect(typeof price.route.origin.input.amount).toBe('string'); + expect(typeof price.route.origin.input.amountUSD).toBe('string'); + // same-chain: bridge is null + expect(price.route.bridge).toBeNull(); + // fees.gas is a single DeltaTokenAmount, fees.bridge is an array + expect(typeof price.route.fees.gas.amount).toBe('string'); + expect(Array.isArray(price.route.fees.bridge)).toBe(true); + }); + + test('GET /delta/v2/prices (cross-chain) returns DeltaRoute with bridge.contractParams (no destinationChainId)', async () => { + const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, + }); + + const price = await getDeltaPriceV2({ + srcToken: WETH, + destToken: USDC_ARB, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 6, + destChainId: 42161, + side: 'SELL', + }); + + expect(price.outputToken.chainId).toBe(42161); + expect(price.route.destination.input.token.chainId).toBe(42161); + expect(price.route.bridge).not.toBeNull(); + if (price.route.bridge) { + expect(typeof price.route.bridge.protocol).toBe('string'); + expect(Array.isArray(price.route.bridge.tags)).toBe(true); + expect(typeof price.route.bridge.contractParams.protocolSelector).toBe( + 'string' + ); + expect(typeof price.route.bridge.contractParams.outputToken).toBe( + 'string' + ); + // destinationChainId is NOT present on the wire — the SDK injects it at build time + expect('destinationChainId' in price.route.bridge.contractParams).toBe( + false + ); + } + }); + + test('GET /delta/v2/prices/bridge-routes returns flat array', async () => { + const { getBridgeRoutes } = constructGetBridgeRoutes({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, + }); + + const routes = await getBridgeRoutes(); + expect(Array.isArray(routes)).toBe(true); + expect(routes.length).toBeGreaterThan(0); + const first = routes[0]!; + expect(typeof first.srcChainId).toBe('number'); + expect(typeof first.destChainId).toBe('number'); + expect(Array.isArray(first.tokens)).toBe(true); + }); + + test('GET /delta/v2/prices/bridge-protocols returns protocols', async () => { + const { getBridgeProtocolsV2 } = constructGetBridgeRoutes({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, + }); + + const protocols = await getBridgeProtocolsV2(); + expect(protocols.length).toBeGreaterThan(0); + expect(protocols.some((p) => p.protocol === 'Across')).toBe(true); + }); +}); + +describe('Delta v2: SDK wiring', () => { + test('constructAllDeltaV2OrdersHandlers exposes all v2 methods', () => { + const sdk = constructAllDeltaV2OrdersHandlers({ + apiURL: API_URL, + chainId: 1, + fetcher: makeFetcher(() => ({})), + contractCaller: makeMockContractCaller(), + }); + + expect(typeof sdk.getDeltaPriceV2).toBe('function'); + expect(typeof sdk.getDeltaOrdersV2).toBe('function'); + expect(typeof sdk.getBridgeRoutes).toBe('function'); + expect(typeof sdk.buildDeltaOrderV2).toBe('function'); + expect(typeof sdk.postDeltaOrderV2).toBe('function'); + expect(typeof sdk.submitDeltaOrderV2).toBe('function'); + expect(typeof sdk.submitExternalDeltaOrderV2).toBe('function'); + expect(typeof sdk.submitTWAPDeltaOrderV2).toBe('function'); + expect(typeof sdk.cancelLimitDeltaOrdersV2).toBe('function'); + expect(typeof sdk.isTokenSupportedInDeltaV2).toBe('function'); + expect(typeof sdk.getAgentsListV2).toBe('function'); + // reused v1 utilities + expect(typeof sdk.getDeltaContract).toBe('function'); + expect(typeof sdk.getPartnerFee).toBe('function'); + expect(typeof sdk.approveTokenForDelta).toBe('function'); + // v2 sign function (replaces v1 sign in deltaV2 namespace) + expect(typeof sdk.signDeltaOrderV2).toBe('function'); + }); + + test('constructPartialSDK accepts v2 constructors individually', () => { + const fetcher = makeFetcher(() => ({})); + const sdk = constructPartialSDK( + { apiURL: API_URL, chainId: 1, fetcher }, + constructBuildDeltaOrderV2, + constructPostDeltaOrderV2, + constructGetDeltaOrdersV2, + constructGetDeltaPriceV2, + constructGetDeltaContract, + constructGetPartnerFee, + constructGetBridgeRoutes, + constructIsTokenSupportedInDeltaV2 + ); + + expect(typeof sdk.getDeltaPriceV2).toBe('function'); + expect(typeof sdk.getBridgeRoutes).toBe('function'); + expect(typeof sdk.getDeltaOrdersV2).toBe('function'); + expect(typeof sdk.buildDeltaOrderV2).toBe('function'); + expect(typeof sdk.postDeltaOrderV2).toBe('function'); + expect(typeof sdk.isTokenSupportedInDeltaV2).toBe('function'); + }); +}); From 6dc136b09e9adb960167a92a078ab42b9b8a90d0 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:28:11 +0300 Subject: [PATCH 09/52] deltaV2/update CLAUDE.md --- CLAUDE.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index efa4263f2..9a990a209 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,6 +33,8 @@ Three ways to construct the SDK: `constructSimpleSDK` accepts `{ axios }`, `{ fetch }`, or `{ fetcher }` for the network layer, and optionally `{ ethersProviderOrSigner | ethersV6ProviderOrSigner | viemClient | web3, account }` for signing/transacting. +`constructFullSDK` exposes namespaced methods: `sdk.delta.*` (v1), `sdk.deltaV2.*` (v2), `sdk.swap.*`, etc. + ## Provider Adapters (`src/helpers/providers/`) Each file exports `constructContractCaller(provider, account)` → `ContractCallerFunctions`: @@ -43,7 +45,8 @@ Each file exports `constructContractCaller(provider, account)` → `ContractCall ## Module Structure (`src/methods/`) -- `delta/` — Core feature: Delta auction orders (see detail below) +- `delta/` — Core feature: Delta auction orders v1 (see detail below) +- `deltaV2/` — Delta v2: server-side order building, route-based pricing, paginated orders (see detail below) - `swap/` — Token swap: rates, transaction building, approvals, balances - `limitOrders/` — **Deprecated.** EIP-712 signed limit orders - `nftOrders/` — **Deprecated.** EIP-712 signed NFT orders @@ -105,7 +108,7 @@ Each family has four files: `build*`, `sign*`, `post*`, `preSign*`. High-level o | `constants.ts` | — | `DEFAULT_BRIDGE` constant (all-zero values for same-chain orders) | — | — | ### Delta Helpers (`src/methods/delta/helpers/`) -- `types.ts` — `DeltaAuctionOrder`, `Bridge`, `DeltaAuction`, `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `BridgePriceInfo`, `SwapSideToOrderKind`, `OnChainOrderType`, `DeltaAuctionUnion` +- `types.ts` — `DeltaAuctionOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap`, `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType` (includes `'ProductiveOrder'`), `DeltaAuctionUnion` - `buildDeltaOrderData.ts` — `buildDeltaSignableOrderData`, `produceDeltaOrderTypedData`, `SignableDeltaOrderData`, `BuildDeltaOrderDataInput`, `DELTA_DEFAULT_EXPIRY` - `buildCancelDeltaOrderData.ts` — `buildCancelDeltaOrderSignableData`, `SignableCancelDeltaOrderData`, `CancelDeltaOrderData` - `buildTWAPOrderData.ts` — `buildTWAPSignableOrderData`, `SignableTWAPOrderData`, `BuildTWAPOrderDataInput` @@ -115,10 +118,73 @@ Each family has four files: `build*`, `sign*`, `post*`, `preSign*`. High-level o - `abi.ts` — shared ABI fragments ### Core Types (`src/`) -- `types.ts` — `ConstructProviderFetchInput`, `ContractCallerFunctions`, `TxSendOverrides` +- `types.ts` — `ConstructProviderFetchInput`, `ContractCallerFunctions`, `TxSendOverrides`, `PaginatedResponse` - `helpers/misc.ts` — `ExtractAbiMethodNames` - `sdk/partial.ts` — `constructPartialSDK`, `InferWithTxResponse` type tuple +## Delta V2 Module (`src/methods/deltaV2/`) + +Exposed as `sdk.deltaV2.*` on the full/simple SDK. Ships alongside v1 (non-breaking). All URLs use the `/delta/v2/...` prefix. + +### Key differences from v1 + +| Concern | v1 | v2 | +|---------|----|----| +| Order building | Local EIP-712 computation | `POST /delta/v2/orders/build` → returns `BuiltDeltaOrderV2 { toSign, orderHash }` | +| Signing | Family-specific sign functions | Single `signDeltaOrderV2(builtOrder)` for all order types | +| Price response | `DeltaPrice` / `BridgePrice` overload | `DeltaPriceV2` with `route: DeltaRoute` and `alternatives: DeltaRoute[]` | +| Order list | Flat array | `PaginatedResponse` envelope | +| Partner fee | Resolved locally via `getPartnerFee` | Passed as raw params to server (`partner`, `partnerAddress`, `partnerFeeBps`) | + +### Order families + +Same three families as v1, all built via `POST /delta/v2/orders/build` with an `orderType` field: + +| Family | `orderType` | Build params type | +|--------|-------------|-------------------| +| Standard | `'Order'` | `BuildDeltaOrderV2Params` | +| External | `'ExternalOrder'` | `BuildExternalDeltaOrderV2Params` (adds `handler`, `data`) | +| TWAP Sell | `'TWAPOrder'` | `BuildTWAPSellDeltaOrderV2Params` | +| TWAP Buy | `'TWAPBuyOrder'` | `BuildTWAPBuyDeltaOrderV2Params` | + +### Key files + +| File | Constructor | Purpose | +|------|-------------|---------| +| `index.ts` | `constructAllDeltaV2OrdersHandlers`, `constructSubmitDeltaOrderV2` etc. | Composite: orchestrates all v2 modules, defines `DeltaV2OrderHandlers`. Submit orchestrators wrap build→sign→post. | +| `buildDeltaOrderV2.ts` | `constructBuildDeltaOrderV2` | POST to `/v2/orders/build` → `BuiltDeltaOrderV2` | +| `buildExternalDeltaOrderV2.ts` | `constructBuildExternalDeltaOrderV2` | Same, `orderType: 'ExternalOrder'` | +| `buildTWAPDeltaOrderV2.ts` | `constructBuildTWAPDeltaOrderV2` | Same, `orderType: 'TWAPOrder'` or `'TWAPBuyOrder'` | +| `getDeltaPriceV2.ts` | `constructGetDeltaPriceV2` | GET `/v2/prices` → `DeltaPriceV2` | +| `getDeltaOrdersV2.ts` | `constructGetDeltaOrdersV2` | `getDeltaOrdersV2` (paginated list), `getDeltaOrderByIdV2`, `getDeltaOrderByHashV2` | +| `postDeltaOrderV2.ts` | `constructPostDeltaOrderV2` | POST `/v2/orders` → `DeltaAuction<'Order'>` | +| `cancelDeltaOrderV2.ts` | `constructCancelDeltaOrderV2` | Sign + POST `/v2/orders/cancel` | +| `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocolsV2` | +| `isTokenSupportedInDeltaV2.ts` | `constructIsTokenSupportedInDeltaV2` | GET `/v2/prices/is-token-supported` → `boolean` | +| `getAgentsListV2.ts` | `constructGetAgentsListV2` | GET `/v2/agents/list/:chainId` → `string[]` | + +On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDeltaContract` are **reused from v1** — no duplication. + +### V2 Types (`src/methods/deltaV2/types.ts`) + +- `BuiltDeltaOrderV2` — server build response: `{ toSign: { domain, types, value }, orderHash }` +- `DeltaPriceV2` — v2 price response with `route: DeltaRoute` and `alternatives: DeltaRoute[]` +- `DeltaRoute` / `DeltaRouteStep` / `DeltaRouteBridge` / `DeltaRouteBridgeContractParams` — route shape +- `DeltaPriceToken` / `DeltaTokenAmount` — token identity and amount with USD value +- `BridgeTag` — `'recommended' | 'fastest' | 'best-return'` +- `BridgeRoute` — flat bridge route entry `{ srcChainId, destChainId, tokens }` +- `DeltaOrderV2Response` — order shape from v2 order endpoints (different from v1's `DeltaAuction`) +- `DeltaOrderStatusV2` — integrator-facing status enum values +- `DeltaOrderTypeV2` — `'MARKET' | 'LIMIT'` +- `DeltaOnChainOrderTypeReported` — `OnChainOrderType | 'FillableOrder'` +- `DeltaTokenSide` / `DeltaTransactionV2` — order input/output and transaction entry types + +`PaginatedResponse` lives in `src/types.ts` (shared). + +### `OnChainOrderType` note + +`'ProductiveOrder'` is part of `OnChainOrderType` (in `delta/helpers/types.ts`) but is **not** in `OnChainOrderMap` (no SDK build support yet). Generics constrained to `keyof OnChainOrderMap` (`DeltaAuction`, `getDeltaOrders`) will not accept `'ProductiveOrder'` as `T`. + ## Checklist: Adding a New On-Chain Method 1. Add ABI to the module file (inline `as const`) From 43300302fa96605cb4f142311bd275e9a46cbb6c Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:34:02 +0300 Subject: [PATCH 10/52] deltaV2/examples --- src/examples/deltaV2.ts | 198 ++++++++++++++++++++++++++++++++ src/examples/helpers/deltaV2.ts | 29 +++++ 2 files changed, 227 insertions(+) create mode 100644 src/examples/deltaV2.ts create mode 100644 src/examples/helpers/deltaV2.ts diff --git a/src/examples/deltaV2.ts b/src/examples/deltaV2.ts new file mode 100644 index 000000000..db3413c7d --- /dev/null +++ b/src/examples/deltaV2.ts @@ -0,0 +1,198 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import axios from 'axios'; +import { ethers, Wallet } from 'ethersV5'; +import { + constructPartialSDK, + constructEthersContractCaller, + constructAxiosFetcher, + constructAllDeltaV2OrdersHandlers, +} from '..'; +import { startStatusCheckV2 } from './helpers/deltaV2'; + +const fetcher = constructAxiosFetcher(axios); + +const provider = ethers.getDefaultProvider(1); +const signer = Wallet.createRandom().connect(provider); +const account = signer.address; +const contractCaller = constructEthersContractCaller( + { + ethersProviderOrSigner: provider, + EthersContract: ethers.Contract, + }, + account +); + +const deltaSDK = constructPartialSDK( + { + chainId: 1, + fetcher, + contractCaller, + }, + constructAllDeltaV2OrdersHandlers +); + +const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f'; +const USDC_TOKEN = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; + +async function simpleDeltaV2Flow() { + const amount = '1000000000000'; // wei + + const deltaPrice = await deltaSDK.getDeltaPriceV2({ + srcToken: DAI_TOKEN, + destToken: USDC_TOKEN, + amount, + userAddress: account, + srcDecimals: 18, + destDecimals: 6, + // partner: "..." // if available + }); + + const DeltaContract = await deltaSDK.getDeltaContract(); + + // or sign a Permit1 or Permit2 TransferFrom for DeltaContract + const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); + await tx.wait(); + + const deltaAuction = await deltaSDK.submitDeltaOrderV2({ + route: deltaPrice.route, // or pick from deltaPrice.alternatives + side: deltaPrice.side, + owner: account, + // beneficiary: anotherAccount, // if need to send destToken to another account + // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract + slippage: 50, // 50 bps = 0.5% slippage + }); + + // poll if necessary + startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); +} + +async function manualDeltaV2Flow() { + const amount = '1000000000000'; // wei + + const deltaPrice = await deltaSDK.getDeltaPriceV2({ + srcToken: DAI_TOKEN, + destToken: USDC_TOKEN, + amount, + userAddress: account, + srcDecimals: 18, + destDecimals: 6, + // partner: "..." // if available + }); + + const DeltaContract = await deltaSDK.getDeltaContract(); + + // or sign a Permit1 or Permit2 TransferFrom for DeltaContract + const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); + await tx.wait(); + + // server-side build (returns EIP-712 typed data + orderHash) + const builtOrder = await deltaSDK.buildDeltaOrderV2({ + route: deltaPrice.route, // or pick from deltaPrice.alternatives + side: deltaPrice.side, + owner: account, + // beneficiary: anotherAccount, // if need to send destToken to another account + // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract + slippage: 50, // 50 bps = 0.5% slippage + }); + + // one signer for every v2 order type (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) + const signature = await deltaSDK.signDeltaOrderV2(builtOrder); + + const deltaAuction = await deltaSDK.postDeltaOrderV2({ + // partner: "..." // if available + order: builtOrder.toSign.value as Parameters< + typeof deltaSDK.postDeltaOrderV2 + >[0]['order'], + signature, + }); + + // poll if necessary + startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); +} + +// External orders forward execution to an integrator-provided handler contract. +// Same build/sign/post shape as standard orders, plus { handler, data }. +// See externalDelta.ts for handler-specific examples (Aave collateral swap, etc.). +async function externalDeltaV2Flow() { + const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC + + const deltaPrice = await deltaSDK.getDeltaPriceV2({ + srcToken: USDC_TOKEN, + destToken: DAI_TOKEN, + amount, + userAddress: account, + srcDecimals: 6, + destDecimals: 18, + }); + + const HANDLER = '0xb4a2c36668cf8b19fe08f263e3685a5e16e82912'; // handler contract + const HANDLER_DATA = + '0x0000000000000000000000000000000000000000000000000000000000000000'; // handler-specific encoded bytes + + const builtOrder = await deltaSDK.buildExternalDeltaOrderV2({ + route: deltaPrice.route, + side: deltaPrice.side, + owner: account, + handler: HANDLER, + data: HANDLER_DATA, + slippage: 50, + }); + + const signature = await deltaSDK.signDeltaOrderV2(builtOrder); + + const deltaAuction = await deltaSDK.postExternalDeltaOrderV2({ + order: builtOrder.toSign.value as Parameters< + typeof deltaSDK.postExternalDeltaOrderV2 + >[0]['order'], + signature, + }); + + startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); +} + +// TWAP sell splits a total srcAmount into N equal slices executed `interval` seconds apart. +// The price quote is fetched for a single slice; the server multiplies amounts by numSlices. +async function twapSellDeltaV2Flow() { + const numSlices = 4; + const totalSrcAmount = ethers.utils.parseUnits('100', 18).toString(); // 100 DAI total + const perSliceAmount = (BigInt(totalSrcAmount) / BigInt(numSlices)).toString(); + + // quote a single slice — route amounts must match floor(totalSrcAmount / numSlices) + const deltaPrice = await deltaSDK.getDeltaPriceV2({ + srcToken: DAI_TOKEN, + destToken: USDC_TOKEN, + amount: perSliceAmount, + userAddress: account, + srcDecimals: 18, + destDecimals: 6, + }); + + const tx = await deltaSDK.approveTokenForDelta(totalSrcAmount, DAI_TOKEN); + await tx.wait(); + + const deltaAuction = await deltaSDK.submitTWAPDeltaOrderV2({ + onChainOrderType: 'TWAPOrder', + route: deltaPrice.route, + owner: account, + totalSrcAmount, + numSlices, + interval: 300, // 5 minutes between slices (min 60) + slippage: 50, + }); + + startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); +} + +// Paginated list of a user's orders (v2 returns a { results, pagination } envelope). +async function listUserOrders() { + const page1 = await deltaSDK.getDeltaOrdersV2({ + userAddress: account, + page: 1, + limit: 50, + // status: ['ACTIVE', 'BRIDGING'], + // type: 'MARKET', + }); + + console.log('orders:', page1.data); + console.log('total:', page1.total, 'hasMore:', page1.hasMore); +} diff --git a/src/examples/helpers/deltaV2.ts b/src/examples/helpers/deltaV2.ts new file mode 100644 index 000000000..2910a2fd4 --- /dev/null +++ b/src/examples/helpers/deltaV2.ts @@ -0,0 +1,29 @@ +import { DeltaOrderV2Response } from '../..'; + +// v2 status COMPLETED already accounts for destChain bridge settlement +// (crosschain orders sit in BRIDGING until the destChain leg is done). +function isCompletedDeltaV2Order(order: DeltaOrderV2Response) { + return order.status === 'COMPLETED'; +} + +type GetDeltaOrderV2Fn = () => Promise; + +function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderV2Fn) { + const intervalId = setInterval(async () => { + const order = await getDeltaOrder(); + console.log('checks: ', order); // Handle or log the fetched order as needed + + if (isCompletedDeltaV2Order(order)) { + clearInterval(intervalId); // Stop interval if completed + console.log('Order completed'); + } + }, 3000); + console.log('Order Pending'); + // Return intervalId to enable clearing the interval if needed externally + return intervalId; +} + +export function startStatusCheckV2(getDeltaOrder: GetDeltaOrderV2Fn) { + const intervalId = fetchOrderPeriodically(getDeltaOrder); + setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes +} From 9ee5d8930b72cd74a64e3faa562f5a7035493fe9 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 22 May 2026 12:37:04 +0300 Subject: [PATCH 11/52] pnpm run lint --- src/examples/deltaV2.ts | 4 +++- src/methods/delta/getDeltaPrice.ts | 7 +++---- src/methods/delta/helpers/types.ts | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/examples/deltaV2.ts b/src/examples/deltaV2.ts index db3413c7d..c35ee1fc7 100644 --- a/src/examples/deltaV2.ts +++ b/src/examples/deltaV2.ts @@ -155,7 +155,9 @@ async function externalDeltaV2Flow() { async function twapSellDeltaV2Flow() { const numSlices = 4; const totalSrcAmount = ethers.utils.parseUnits('100', 18).toString(); // 100 DAI total - const perSliceAmount = (BigInt(totalSrcAmount) / BigInt(numSlices)).toString(); + const perSliceAmount = ( + BigInt(totalSrcAmount) / BigInt(numSlices) + ).toString(); // quote a single slice — route amounts must match floor(totalSrcAmount / numSlices) const deltaPrice = await deltaSDK.getDeltaPriceV2({ diff --git a/src/methods/delta/getDeltaPrice.ts b/src/methods/delta/getDeltaPrice.ts index 25268e559..7f6d7a7ee 100644 --- a/src/methods/delta/getDeltaPrice.ts +++ b/src/methods/delta/getDeltaPrice.ts @@ -141,10 +141,9 @@ interface GetDeltaPrice { options: DeltaPriceParams & { destChainId?: undefined }, requestParams?: RequestParameters ): Promise; - ( - options: DeltaPriceParams, - requestParams?: RequestParameters - ): Promise; + (options: DeltaPriceParams, requestParams?: RequestParameters): Promise< + DeltaPrice | BridgePrice + >; } export type GetDeltaPriceFunctions = { diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index a00d2fb42..fc19086a0 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -256,7 +256,7 @@ type DeltaAuctionBase = { }; export type DeltaAuction< - T extends keyof OnChainOrderMap = keyof OnChainOrderMap, + T extends keyof OnChainOrderMap = keyof OnChainOrderMap > = T extends T ? Prettify< DeltaAuctionBase & { From 2ae10a7d77c988e00563d3de8a3ccedeb000af5c Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 11:24:26 +0300 Subject: [PATCH 12/52] common DeltaOrderType --- src/index.ts | 4 ++-- src/methods/delta/getDeltaOrders.ts | 3 ++- src/methods/delta/helpers/types.ts | 5 ++++- src/methods/delta/postDeltaOrder.ts | 8 ++++++-- src/methods/deltaV2/getDeltaOrdersV2.ts | 11 +++++------ src/methods/deltaV2/postDeltaOrderV2.ts | 8 ++++++-- src/methods/deltaV2/types.ts | 6 ++---- 7 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/index.ts b/src/index.ts index faf2dffbd..5903b2c3e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -151,6 +151,7 @@ import type { TWAPBuyDeltaOrder, TWAPOnChainOrderType, OnChainOrderType, + DeltaOrderType, SwapSideUnion, DeltaAmountsWithSlippage, DeltaAmountsSellSlippage, @@ -361,7 +362,6 @@ import type { DeltaPriceV2, BridgeRoute, DeltaOnChainOrderTypeReported, - DeltaOrderTypeV2, DeltaTokenSide, DeltaTransactionV2, DeltaOrderV2Response, @@ -608,6 +608,7 @@ export type { TWAPBuyDeltaOrder, TWAPOnChainOrderType, OnChainOrderType, + DeltaOrderType, DeltaAmountsWithSlippage, DeltaAmountsSellSlippage, DeltaAmountsBuySlippage, @@ -641,7 +642,6 @@ export type { DeltaPriceV2, BridgeRoute, DeltaOnChainOrderTypeReported, - DeltaOrderTypeV2, DeltaTokenSide, DeltaTransactionV2, DeltaOrderV2Response, diff --git a/src/methods/delta/getDeltaOrders.ts b/src/methods/delta/getDeltaOrders.ts index 21af0f941..26bebd142 100644 --- a/src/methods/delta/getDeltaOrders.ts +++ b/src/methods/delta/getDeltaOrders.ts @@ -8,6 +8,7 @@ import type { import type { DeltaAuction, DeltaAuctionStatus, + DeltaOrderType, OnChainOrderMap, } from './helpers/types'; @@ -52,7 +53,7 @@ type OrdersFilter = { */ status?: DeltaOrderFilterByStatus[]; /** @description Filter by type. MARKET, LIMIT. Orders with both types are returned if not specified */ - type?: 'MARKET' | 'LIMIT'; + type?: DeltaOrderType; /** @description Filter by on-chain order type. Order, ExternalOrder. Orders of all types are returned if not specified */ onChainOrderType?: T; }; diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index fc19086a0..e0dc6f91a 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -252,7 +252,7 @@ type DeltaAuctionBase = { bridgeMetadata: BridgeMetadata | null; bridgeStatus: BridgeStatus | null; - type: 'MARKET' | 'LIMIT'; + type: DeltaOrderType; }; export type DeltaAuction< @@ -304,6 +304,9 @@ export type OnChainOrderType = export type TWAPOnChainOrderType = 'TWAPOrder' | 'TWAPBuyOrder'; +/** @description Order kind: MARKET (immediate) vs LIMIT (rate-pegged). */ +export type DeltaOrderType = 'MARKET' | 'LIMIT'; + //// available on BridgePrice //// type BridgeQuoteFee = { diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index 1a3d5a6e2..224d82e0e 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -1,7 +1,11 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaAuction, OnChainOrderMap } from './helpers/types'; +import type { + DeltaAuction, + DeltaOrderType, + OnChainOrderMap, +} from './helpers/types'; export type DeltaOrderToPost = { /** @description Partner string */ @@ -16,7 +20,7 @@ export type DeltaOrderToPost = { partiallyFillable?: boolean; /** @description Type of the order. MARKET or LIMIT. Default is MARKET */ - type?: 'MARKET' | 'LIMIT'; + type?: DeltaOrderType; includeAgents?: string[]; excludeAgents?: string[]; diff --git a/src/methods/deltaV2/getDeltaOrdersV2.ts b/src/methods/deltaV2/getDeltaOrdersV2.ts index c2df42b37..e5522d2c6 100644 --- a/src/methods/deltaV2/getDeltaOrdersV2.ts +++ b/src/methods/deltaV2/getDeltaOrdersV2.ts @@ -6,12 +6,11 @@ import type { PaginatedResponse, RequestParameters, } from '../../types'; -import type { OnChainOrderType } from '../delta/helpers/types'; import type { - DeltaOrderStatusV2, - DeltaOrderTypeV2, - DeltaOrderV2Response, -} from './types'; + DeltaOrderType, + OnChainOrderType, +} from '../delta/helpers/types'; +import type { DeltaOrderStatusV2, DeltaOrderV2Response } from './types'; type GetDeltaOrderByIdV2 = ( orderId: string, @@ -35,7 +34,7 @@ type OrdersV2Filter = { /** @description Filter by integrator-facing status. */ status?: DeltaOrderStatusV2[]; /** @description Filter by order type. MARKET or LIMIT. */ - type?: DeltaOrderTypeV2; + type?: DeltaOrderType; /** @description Filter by on-chain order type. */ onChainOrderType?: OnChainOrderType; }; diff --git a/src/methods/deltaV2/postDeltaOrderV2.ts b/src/methods/deltaV2/postDeltaOrderV2.ts index aa54d74c0..f8364e980 100644 --- a/src/methods/deltaV2/postDeltaOrderV2.ts +++ b/src/methods/deltaV2/postDeltaOrderV2.ts @@ -1,7 +1,11 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaAuction, OnChainOrderMap } from '../delta/helpers/types'; +import type { + DeltaAuction, + DeltaOrderType, + OnChainOrderMap, +} from '../delta/helpers/types'; export type DeltaOrderToPostV2 = { /** @description Partner string */ @@ -15,7 +19,7 @@ export type DeltaOrderToPostV2 = { /** @description Designates the Order as being able to be partially filled, as opposed to fill-or-kill */ partiallyFillable?: boolean; /** @description Type of the order. MARKET or LIMIT. Default is MARKET */ - type?: 'MARKET' | 'LIMIT'; + type?: DeltaOrderType; includeAgents?: string[]; excludeAgents?: string[]; }; diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts index c802f19a9..1874d5624 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/deltaV2/types.ts @@ -2,6 +2,7 @@ import type { Address } from '../../types'; import type { TypedDataField } from '../common/orders/buildOrderData'; import type { Bridge, + DeltaOrderType, DeltaOrderUnion, OnChainOrderType, } from '../delta/helpers/types'; @@ -140,9 +141,6 @@ export type DeltaOrderStatusV2 = /** @description `OnChainOrderType` plus the synthetic `FillableOrder` label, used when a Standard `Order` is `partiallyFillable`. */ export type DeltaOnChainOrderTypeReported = OnChainOrderType | 'FillableOrder'; -/** @description Order kind: MARKET (immediate) vs LIMIT (rate-pegged). */ -export type DeltaOrderTypeV2 = 'MARKET' | 'LIMIT'; - /** @description Token side on an order. SELL provides an explicit `amount`; BUY provides expected/executed amounts. */ export type DeltaTokenSide = | { @@ -172,7 +170,7 @@ export type DeltaOrderV2Response = { id: string; status: DeltaOrderStatusV2; side: 'SELL' | 'BUY'; - type: DeltaOrderTypeV2; + type: DeltaOrderType; onChainOrderType: DeltaOnChainOrderTypeReported | null; input: DeltaTokenSide; output: DeltaTokenSide; From db19ae2a04769d2cd19cc65bdb5346ebb1ffd113 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 11:26:33 +0300 Subject: [PATCH 13/52] cancelDeltaOrderV2/drop limit from naming --- src/methods/deltaV2/cancelDeltaOrderV2.ts | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/methods/deltaV2/cancelDeltaOrderV2.ts b/src/methods/deltaV2/cancelDeltaOrderV2.ts index 2aebcd6d1..bb9604098 100644 --- a/src/methods/deltaV2/cancelDeltaOrderV2.ts +++ b/src/methods/deltaV2/cancelDeltaOrderV2.ts @@ -31,10 +31,10 @@ export type CancelDeltaOrderV2 = ( ) => Promise; export type CancelDeltaOrderV2Functions = { - signCancelLimitDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2; - postCancelLimitDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2; - /** @description Cancel one or more Limit Delta orders via the v2 endpoint */ - cancelLimitDeltaOrdersV2: CancelDeltaOrderV2; + signCancelDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2; + postCancelDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2; + /** @description Cancel one or more Delta orders via the v2 endpoint */ + cancelDeltaOrdersV2: CancelDeltaOrderV2; }; export const constructCancelDeltaOrderV2 = ( @@ -45,7 +45,7 @@ export const constructCancelDeltaOrderV2 = ( ): CancelDeltaOrderV2Functions => { const { getDeltaContract } = constructGetDeltaContract(options); - const signCancelLimitDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2 = + const signCancelDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2 = async (params, requestParams) => { const ParaswapDelta = await getDeltaContract(requestParams); if (!ParaswapDelta) { @@ -61,7 +61,7 @@ export const constructCancelDeltaOrderV2 = ( return options.contractCaller.signTypedDataCall(typedData); }; - const postCancelLimitDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2 = + const postCancelDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2 = async (params, requestParams) => { const cancelUrl = `${options.apiURL}/delta/v2/orders/cancel` as const; @@ -73,24 +73,24 @@ export const constructCancelDeltaOrderV2 = ( }); }; - const cancelLimitDeltaOrdersV2: CancelDeltaOrderV2 = async ( + const cancelDeltaOrdersV2: CancelDeltaOrderV2 = async ( { orderIds }, requestParams ) => { - const signature = await signCancelLimitDeltaOrderRequestV2( + const signature = await signCancelDeltaOrderRequestV2( { orderIds }, requestParams ); - return postCancelLimitDeltaOrderRequestV2( + return postCancelDeltaOrderRequestV2( { orderIds, signature }, requestParams ); }; return { - signCancelLimitDeltaOrderRequestV2, - postCancelLimitDeltaOrderRequestV2, - cancelLimitDeltaOrdersV2, + signCancelDeltaOrderRequestV2, + postCancelDeltaOrderRequestV2, + cancelDeltaOrdersV2, }; }; From 8c388c61478ee41371bdbbe4c5714a401c19ebf2 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 11:28:17 +0300 Subject: [PATCH 14/52] cancelDeltaOrdersV2/fix tests --- tests/deltaV2.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts index 97220fa69..8c89ba547 100644 --- a/tests/deltaV2.test.ts +++ b/tests/deltaV2.test.ts @@ -797,14 +797,14 @@ describe('Delta v2: cancel', () => { throw new Error('unexpected'); }); - const { cancelLimitDeltaOrdersV2 } = constructCancelDeltaOrderV2({ + const { cancelDeltaOrdersV2 } = constructCancelDeltaOrderV2({ apiURL: API_URL, chainId: 1, fetcher, contractCaller: makeMockContractCaller(), }); - const result = await cancelLimitDeltaOrdersV2({ + const result = await cancelDeltaOrdersV2({ orderIds: ['a', 'b'], }); @@ -934,7 +934,7 @@ describe('Delta v2: SDK wiring', () => { expect(typeof sdk.submitDeltaOrderV2).toBe('function'); expect(typeof sdk.submitExternalDeltaOrderV2).toBe('function'); expect(typeof sdk.submitTWAPDeltaOrderV2).toBe('function'); - expect(typeof sdk.cancelLimitDeltaOrdersV2).toBe('function'); + expect(typeof sdk.cancelDeltaOrdersV2).toBe('function'); expect(typeof sdk.isTokenSupportedInDeltaV2).toBe('function'); expect(typeof sdk.getAgentsListV2).toBe('function'); // reused v1 utilities From e01e0a40f14f1d2c43684cdc45e25280f005711c Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 11:28:22 +0300 Subject: [PATCH 15/52] update CLAUDE.md --- CLAUDE.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 9a990a209..192999203 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,7 +108,7 @@ Each family has four files: `build*`, `sign*`, `post*`, `preSign*`. High-level o | `constants.ts` | — | `DEFAULT_BRIDGE` constant (all-zero values for same-chain orders) | — | — | ### Delta Helpers (`src/methods/delta/helpers/`) -- `types.ts` — `DeltaAuctionOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap`, `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType` (includes `'ProductiveOrder'`), `DeltaAuctionUnion` +- `types.ts` — `DeltaAuctionOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap`, `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType` (includes `'ProductiveOrder'`), `DeltaOrderType` (`'MARKET' | 'LIMIT'`, shared by v1 & v2), `DeltaAuctionUnion` - `buildDeltaOrderData.ts` — `buildDeltaSignableOrderData`, `produceDeltaOrderTypedData`, `SignableDeltaOrderData`, `BuildDeltaOrderDataInput`, `DELTA_DEFAULT_EXPIRY` - `buildCancelDeltaOrderData.ts` — `buildCancelDeltaOrderSignableData`, `SignableCancelDeltaOrderData`, `CancelDeltaOrderData` - `buildTWAPOrderData.ts` — `buildTWAPSignableOrderData`, `SignableTWAPOrderData`, `BuildTWAPOrderDataInput` @@ -158,7 +158,7 @@ Same three families as v1, all built via `POST /delta/v2/orders/build` with an ` | `getDeltaPriceV2.ts` | `constructGetDeltaPriceV2` | GET `/v2/prices` → `DeltaPriceV2` | | `getDeltaOrdersV2.ts` | `constructGetDeltaOrdersV2` | `getDeltaOrdersV2` (paginated list), `getDeltaOrderByIdV2`, `getDeltaOrderByHashV2` | | `postDeltaOrderV2.ts` | `constructPostDeltaOrderV2` | POST `/v2/orders` → `DeltaAuction<'Order'>` | -| `cancelDeltaOrderV2.ts` | `constructCancelDeltaOrderV2` | Sign + POST `/v2/orders/cancel` | +| `cancelDeltaOrderV2.ts` | `constructCancelDeltaOrderV2` | `signCancelDeltaOrderRequestV2` → `postCancelDeltaOrderRequestV2` → `cancelDeltaOrdersV2` (orchestrator). POSTs to `/v2/orders/cancel`. | | `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocolsV2` | | `isTokenSupportedInDeltaV2.ts` | `constructIsTokenSupportedInDeltaV2` | GET `/v2/prices/is-token-supported` → `boolean` | | `getAgentsListV2.ts` | `constructGetAgentsListV2` | GET `/v2/agents/list/:chainId` → `string[]` | @@ -175,7 +175,6 @@ On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDe - `BridgeRoute` — flat bridge route entry `{ srcChainId, destChainId, tokens }` - `DeltaOrderV2Response` — order shape from v2 order endpoints (different from v1's `DeltaAuction`) - `DeltaOrderStatusV2` — integrator-facing status enum values -- `DeltaOrderTypeV2` — `'MARKET' | 'LIMIT'` - `DeltaOnChainOrderTypeReported` — `OnChainOrderType | 'FillableOrder'` - `DeltaTokenSide` / `DeltaTransactionV2` — order input/output and transaction entry types From 2087b9fc0c29f6fb5bda73d1cd19fb7dc8ed1a8d Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 14:51:28 +0300 Subject: [PATCH 16/52] deltaV2/limitAmount param --- src/methods/deltaV2/buildDeltaOrderV2.ts | 3 +++ src/methods/deltaV2/buildExternalDeltaOrderV2.ts | 3 +++ src/methods/deltaV2/buildTWAPDeltaOrderV2.ts | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/methods/deltaV2/buildDeltaOrderV2.ts b/src/methods/deltaV2/buildDeltaOrderV2.ts index f2de8800f..fbbab83d7 100644 --- a/src/methods/deltaV2/buildDeltaOrderV2.ts +++ b/src/methods/deltaV2/buildDeltaOrderV2.ts @@ -35,6 +35,8 @@ export type BuildDeltaOrderV2Params = { side: 'SELL' | 'BUY'; /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ slippage?: number; + /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ + limitAmount?: string; }; type BuildDeltaOrderV2 = ( @@ -67,6 +69,7 @@ export const constructBuildDeltaOrderV2 = ( nonce: params.nonce, permit: params.permit, slippage: params.slippage, + limitAmount: params.limitAmount, metadata: params.metadata, partiallyFillable: params.partiallyFillable, partner: params.partner, diff --git a/src/methods/deltaV2/buildExternalDeltaOrderV2.ts b/src/methods/deltaV2/buildExternalDeltaOrderV2.ts index 8f0d60165..a4c4226a7 100644 --- a/src/methods/deltaV2/buildExternalDeltaOrderV2.ts +++ b/src/methods/deltaV2/buildExternalDeltaOrderV2.ts @@ -39,6 +39,8 @@ export type BuildExternalDeltaOrderV2Params = { side: 'SELL' | 'BUY'; /** @description Slippage in basis points (bps). Default 0. */ slippage?: number; + /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ + limitAmount?: string; }; type BuildExternalDeltaOrderV2 = ( @@ -76,6 +78,7 @@ export const constructBuildExternalDeltaOrderV2 = ( nonce: params.nonce, permit: params.permit, slippage: params.slippage, + limitAmount: params.limitAmount, metadata: params.metadata, partiallyFillable: params.partiallyFillable, partner: params.partner, diff --git a/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts b/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts index 9a0408a0b..836ceb88c 100644 --- a/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts +++ b/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts @@ -36,6 +36,8 @@ type BuildTWAPDeltaOrderV2Base = { metadata?: string; /** @description Designates the Order as partially fillable. Default false. */ partiallyFillable?: boolean; + /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount for each slice */ + limitAmount?: string; }; export type BuildTWAPSellDeltaOrderV2Params = BuildTWAPDeltaOrderV2Base & { @@ -85,6 +87,7 @@ export const constructBuildTWAPDeltaOrderV2 = ( nonce: params.nonce, permit: params.permit, slippage: params.slippage, + limitAmount: params.limitAmount, metadata: params.metadata, partiallyFillable: params.partiallyFillable, partner: params.partner, From cd2e5866d1d4476d465764d7c7e7a23c5fc8206b Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 15:22:27 +0300 Subject: [PATCH 17/52] signDeltaOrderV2/cleanup --- src/methods/deltaV2/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 5ccdbd085..765382721 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -105,8 +105,7 @@ export const constructSignDeltaOrderV2 = ( return options.contractCaller.signTypedDataCall({ types: builtOrder.toSign.types, domain: builtOrder.toSign.domain, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - data: builtOrder.toSign.value as Record, + data: builtOrder.toSign.value, }); }; return { signDeltaOrderV2 }; From dde81a68ba74aed019778d9179f2c8fdd65ed350 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 15:22:44 +0300 Subject: [PATCH 18/52] BridgeMetadata/expectedOutputAmount --- src/methods/delta/helpers/types.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index e0dc6f91a..0d5377246 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -282,6 +282,11 @@ export type DeltaOrderUnion = OnChainOrderMap[keyof OnChainOrderMap]; export type BridgeMetadata = { /** @description The amount that user should expect to get */ outputAmount: string; + /** @description Field is present iff: order was built via POST /v2/orders/build, + * the route is cross-chain (route.bridge !== null and not an external handler), + * and the order is posted before the per-order cache entry expires. + */ + expectedOutputAmount?: string; /** @description The cross-chain deadline. If deadline passes, the bridgeStatus would be expired */ fillDeadline?: number; // available for Across protocol /** @description The deposit id */ From 93275e713c3dfd98e7f5d0789ad6e2d61e48c761 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 15:34:39 +0300 Subject: [PATCH 19/52] BridgeMetadata/better comment for outputAmount --- src/methods/delta/helpers/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index 0d5377246..305abc9dd 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -280,7 +280,7 @@ export type DeltaAuctionUnion = export type DeltaOrderUnion = OnChainOrderMap[keyof OnChainOrderMap]; export type BridgeMetadata = { - /** @description The amount that user should expect to get */ + /** @description Actual amount received on the destination chain. */ outputAmount: string; /** @description Field is present iff: order was built via POST /v2/orders/build, * the route is cross-chain (route.bridge !== null and not an external handler), From 6942fb98efcc429af8c4282320a094cb06b508dd Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 15:49:20 +0300 Subject: [PATCH 20/52] more generic submit/post delta order types (v1 and v2) --- src/methods/delta/index.ts | 2 +- src/methods/delta/postDeltaOrder.ts | 4 ++-- src/methods/deltaV2/index.ts | 2 +- src/methods/deltaV2/postDeltaOrderV2.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/methods/delta/index.ts b/src/methods/delta/index.ts index dd0a1452f..32225e13d 100644 --- a/src/methods/delta/index.ts +++ b/src/methods/delta/index.ts @@ -99,7 +99,7 @@ export type SubmitDeltaOrderParams = BuildDeltaOrderDataParams & { type SubmitDeltaOrder = ( orderParams: SubmitDeltaOrderParams -) => Promise>; +) => Promise; export type SubmitDeltaOrderFuncs = { submitDeltaOrder: SubmitDeltaOrder; diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index 224d82e0e..b405c6fd0 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -33,7 +33,7 @@ export type PostDeltaOrderParams = Omit & { type PostDeltaOrder = ( postData: PostDeltaOrderParams, requestParams?: RequestParameters -) => Promise>; +) => Promise; export type PostDeltaOrderFunctions = { postDeltaOrder: PostDeltaOrder; @@ -55,7 +55,7 @@ export const constructPostDeltaOrder = ({ }); const fetchURL = `${postOrderUrl}/${search}` as const; - return fetcher>({ + return fetcher({ url: fetchURL, method: 'POST', data: deltaOrderToPost, diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 765382721..22b7edd30 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -121,7 +121,7 @@ export type SubmitDeltaOrderV2Params = BuildDeltaOrderV2Params & { type SubmitDeltaOrderV2 = ( orderParams: SubmitDeltaOrderV2Params -) => Promise>; +) => Promise; export type SubmitDeltaOrderV2Funcs = { submitDeltaOrderV2: SubmitDeltaOrderV2; diff --git a/src/methods/deltaV2/postDeltaOrderV2.ts b/src/methods/deltaV2/postDeltaOrderV2.ts index f8364e980..fc5184b86 100644 --- a/src/methods/deltaV2/postDeltaOrderV2.ts +++ b/src/methods/deltaV2/postDeltaOrderV2.ts @@ -31,7 +31,7 @@ export type PostDeltaOrderV2Params = Omit & { type PostDeltaOrderV2 = ( postData: PostDeltaOrderV2Params, requestParams?: RequestParameters -) => Promise>; +) => Promise; export type PostDeltaOrderV2Functions = { postDeltaOrderV2: PostDeltaOrderV2; @@ -53,7 +53,7 @@ export const constructPostDeltaOrderV2 = ({ }); const fetchURL = `${postOrderUrl}/${search}` as const; - return fetcher>({ + return fetcher({ url: fetchURL, method: 'POST', data: deltaOrderToPost, From 6894500e3760c732529f28ce031307bf4d6729d1 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 15:50:57 +0300 Subject: [PATCH 21/52] postOrder/get rid of extra hash from fetchURL --- src/methods/delta/postDeltaOrder.ts | 2 +- src/methods/deltaV2/postDeltaOrderV2.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index b405c6fd0..1f08ec096 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -53,7 +53,7 @@ export const constructPostDeltaOrder = ({ const search = constructSearchString<{ degenMode?: boolean }>({ degenMode, }); - const fetchURL = `${postOrderUrl}/${search}` as const; + const fetchURL = `${postOrderUrl}${search}` as const; return fetcher({ url: fetchURL, diff --git a/src/methods/deltaV2/postDeltaOrderV2.ts b/src/methods/deltaV2/postDeltaOrderV2.ts index fc5184b86..14b7a93a7 100644 --- a/src/methods/deltaV2/postDeltaOrderV2.ts +++ b/src/methods/deltaV2/postDeltaOrderV2.ts @@ -51,7 +51,7 @@ export const constructPostDeltaOrderV2 = ({ const search = constructSearchString<{ degenMode?: boolean }>({ degenMode, }); - const fetchURL = `${postOrderUrl}/${search}` as const; + const fetchURL = `${postOrderUrl}${search}` as const; return fetcher({ url: fetchURL, From 73ec6a230af0dd7150c7e80424e9eaf1d157b24b Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 15:54:33 +0300 Subject: [PATCH 22/52] postTWAP/consistent fetchURL without slash --- src/methods/delta/postTWAPDeltaOrder.ts | 2 +- src/methods/deltaV2/postTWAPDeltaOrderV2.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/methods/delta/postTWAPDeltaOrder.ts b/src/methods/delta/postTWAPDeltaOrder.ts index ec2279758..0fce7555b 100644 --- a/src/methods/delta/postTWAPDeltaOrder.ts +++ b/src/methods/delta/postTWAPDeltaOrder.ts @@ -43,7 +43,7 @@ export const constructPostTWAPDeltaOrder = ({ degenMode, }); - const fetchURL = `${postOrderUrl}/${search}` as const; + const fetchURL = `${postOrderUrl}${search}` as const; return fetcher | DeltaAuction<'TWAPBuyOrder'>>({ url: fetchURL, diff --git a/src/methods/deltaV2/postTWAPDeltaOrderV2.ts b/src/methods/deltaV2/postTWAPDeltaOrderV2.ts index 244c303ee..62130ba02 100644 --- a/src/methods/deltaV2/postTWAPDeltaOrderV2.ts +++ b/src/methods/deltaV2/postTWAPDeltaOrderV2.ts @@ -49,7 +49,7 @@ export const constructPostTWAPDeltaOrderV2 = ({ degenMode, }); - const fetchURL = `${postOrderUrl}/${search}` as const; + const fetchURL = `${postOrderUrl}${search}` as const; return fetcher | DeltaAuction<'TWAPBuyOrder'>>({ url: fetchURL, From 6183708ee9d9e20eef05e4bc3d6b72f132590c7d Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 16:01:20 +0300 Subject: [PATCH 23/52] cancelDeltaOrder/fallback apiURL --- src/methods/delta/cancelDeltaOrder.ts | 5 +- src/methods/deltaV2/cancelDeltaOrderV2.ts | 61 +++++++++++++---------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/methods/delta/cancelDeltaOrder.ts b/src/methods/delta/cancelDeltaOrder.ts index b35c215a6..20ca8de6b 100644 --- a/src/methods/delta/cancelDeltaOrder.ts +++ b/src/methods/delta/cancelDeltaOrder.ts @@ -1,3 +1,4 @@ +import { API_URL } from '../../constants'; import type { ConstructProviderFetchInput, RequestParameters, @@ -43,6 +44,8 @@ export const constructCancelDeltaOrder = ( 'contractCaller' | 'fetcher' | 'apiURL' | 'chainId' > ): CancelDeltaOrderFunctions => { + const apiURL = options.apiURL ?? API_URL; + // cached internally const { getDeltaContract } = constructGetDeltaContract(options); @@ -69,7 +72,7 @@ export const constructCancelDeltaOrder = ( params, requestParams ) => { - const cancelUrl = `${options.apiURL}/delta/orders/cancel` as const; + const cancelUrl = `${apiURL}/delta/orders/cancel` as const; const res = await options.fetcher({ url: cancelUrl, diff --git a/src/methods/deltaV2/cancelDeltaOrderV2.ts b/src/methods/deltaV2/cancelDeltaOrderV2.ts index bb9604098..0fce676d3 100644 --- a/src/methods/deltaV2/cancelDeltaOrderV2.ts +++ b/src/methods/deltaV2/cancelDeltaOrderV2.ts @@ -1,3 +1,4 @@ +import { API_URL } from '../../constants'; import type { ConstructProviderFetchInput, RequestParameters, @@ -43,35 +44,41 @@ export const constructCancelDeltaOrderV2 = ( 'contractCaller' | 'fetcher' | 'apiURL' | 'chainId' > ): CancelDeltaOrderV2Functions => { + const apiURL = options.apiURL ?? API_URL; + const { getDeltaContract } = constructGetDeltaContract(options); - const signCancelDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2 = - async (params, requestParams) => { - const ParaswapDelta = await getDeltaContract(requestParams); - if (!ParaswapDelta) { - throw new Error(`Delta is not available on chain ${options.chainId}`); - } - - const typedData = buildCancelDeltaOrderSignableData({ - orderInput: params, - paraswapDeltaAddress: ParaswapDelta, - chainId: options.chainId, - }); - - return options.contractCaller.signTypedDataCall(typedData); - }; - - const postCancelDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2 = - async (params, requestParams) => { - const cancelUrl = `${options.apiURL}/delta/v2/orders/cancel` as const; - - return options.fetcher({ - url: cancelUrl, - method: 'POST', - data: params, - requestParams, - }); - }; + const signCancelDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2 = async ( + params, + requestParams + ) => { + const ParaswapDelta = await getDeltaContract(requestParams); + if (!ParaswapDelta) { + throw new Error(`Delta is not available on chain ${options.chainId}`); + } + + const typedData = buildCancelDeltaOrderSignableData({ + orderInput: params, + paraswapDeltaAddress: ParaswapDelta, + chainId: options.chainId, + }); + + return options.contractCaller.signTypedDataCall(typedData); + }; + + const postCancelDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2 = async ( + params, + requestParams + ) => { + const cancelUrl = `${apiURL}/delta/v2/orders/cancel` as const; + + return options.fetcher({ + url: cancelUrl, + method: 'POST', + data: params, + requestParams, + }); + }; const cancelDeltaOrdersV2: CancelDeltaOrderV2 = async ( { orderIds }, From 1acea76c67fc85d647d515a9783ec1d44e00be97 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 16:07:57 +0300 Subject: [PATCH 24/52] Revert "more generic submit/post delta order types (v1 and v2)" This reverts commit 6942fb98efcc429af8c4282320a094cb06b508dd. --- src/methods/delta/index.ts | 2 +- src/methods/delta/postDeltaOrder.ts | 4 ++-- src/methods/deltaV2/index.ts | 2 +- src/methods/deltaV2/postDeltaOrderV2.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/methods/delta/index.ts b/src/methods/delta/index.ts index 32225e13d..dd0a1452f 100644 --- a/src/methods/delta/index.ts +++ b/src/methods/delta/index.ts @@ -99,7 +99,7 @@ export type SubmitDeltaOrderParams = BuildDeltaOrderDataParams & { type SubmitDeltaOrder = ( orderParams: SubmitDeltaOrderParams -) => Promise; +) => Promise>; export type SubmitDeltaOrderFuncs = { submitDeltaOrder: SubmitDeltaOrder; diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index 1f08ec096..b5c7fa8ac 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -33,7 +33,7 @@ export type PostDeltaOrderParams = Omit & { type PostDeltaOrder = ( postData: PostDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type PostDeltaOrderFunctions = { postDeltaOrder: PostDeltaOrder; @@ -55,7 +55,7 @@ export const constructPostDeltaOrder = ({ }); const fetchURL = `${postOrderUrl}${search}` as const; - return fetcher({ + return fetcher>({ url: fetchURL, method: 'POST', data: deltaOrderToPost, diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 22b7edd30..765382721 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -121,7 +121,7 @@ export type SubmitDeltaOrderV2Params = BuildDeltaOrderV2Params & { type SubmitDeltaOrderV2 = ( orderParams: SubmitDeltaOrderV2Params -) => Promise; +) => Promise>; export type SubmitDeltaOrderV2Funcs = { submitDeltaOrderV2: SubmitDeltaOrderV2; diff --git a/src/methods/deltaV2/postDeltaOrderV2.ts b/src/methods/deltaV2/postDeltaOrderV2.ts index 14b7a93a7..1cebf152c 100644 --- a/src/methods/deltaV2/postDeltaOrderV2.ts +++ b/src/methods/deltaV2/postDeltaOrderV2.ts @@ -31,7 +31,7 @@ export type PostDeltaOrderV2Params = Omit & { type PostDeltaOrderV2 = ( postData: PostDeltaOrderV2Params, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type PostDeltaOrderV2Functions = { postDeltaOrderV2: PostDeltaOrderV2; @@ -53,7 +53,7 @@ export const constructPostDeltaOrderV2 = ({ }); const fetchURL = `${postOrderUrl}${search}` as const; - return fetcher({ + return fetcher>({ url: fetchURL, method: 'POST', data: deltaOrderToPost, From 03c165903eae6b22da800ff4bfd23e6dfdb047cb Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 16:29:29 +0300 Subject: [PATCH 25/52] Release 9.5.4-dev.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07053e395..ec0c6022d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@velora-dex/sdk", - "version": "9.5.3", + "version": "9.5.4-dev.0", "main": "dist/index.js", "module": "dist/sdk.esm.js", "typings": "dist/index.d.ts", From 329004050ca1869e0c7e6daa8d051f67f40f9d13 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 16:45:00 +0300 Subject: [PATCH 26/52] add ProductiveOrder types --- CLAUDE.md | 9 +++--- src/index.ts | 5 ++++ src/methods/delta/helpers/orders.ts | 26 +++++++++++++++++ src/methods/delta/helpers/types.ts | 43 +++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 192999203..ff96c5785 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -76,7 +76,7 @@ Every feature module exports a `constructXxx(options) => XxxFunctions` factory: ## Delta Module (`src/methods/delta/`) -Three order families, each with build/sign/post/preSign constructors: +Four order families with build/sign/post/preSign constructors, plus a read-only Productive family: | Family | `onChainOrderType` | Order type | Build input key | |--------|-------------------|-----------|-----------------| @@ -84,8 +84,9 @@ Three order families, each with build/sign/post/preSign constructors: | External | `'ExternalOrder'` | `ExternalDeltaOrder` | `buildExternalDeltaOrder` (has `handler` field instead of `bridge`) | | TWAP Sell | `'TWAPOrder'` | `TWAPDeltaOrder` | `buildTWAPDeltaOrder` | | TWAP Buy | `'TWAPBuyOrder'` | `TWAPBuyDeltaOrder` | `buildTWAPDeltaOrder` | +| Productive | `'ProductiveOrder'` | `ProductiveDeltaOrder` | _read-only_ — no SDK builder (server-produced) | -Each family has four files: `build*`, `sign*`, `post*`, `preSign*`. High-level orchestrators (`constructSubmitDeltaOrder`, `constructSubmitExternalDeltaOrder`, `constructSubmitTWAPDeltaOrder`) in `index.ts` wrap build→sign→post. +The first four families have four files each: `build*`, `sign*`, `post*`, `preSign*`. High-level orchestrators (`constructSubmitDeltaOrder`, `constructSubmitExternalDeltaOrder`, `constructSubmitTWAPDeltaOrder`) in `index.ts` wrap build→sign→post. Productive orders surface only through the read paths (`getDeltaOrders*` / `getDeltaOrderById*` / `DeltaAuctionUnion`). ### Key Files @@ -108,7 +109,7 @@ Each family has four files: `build*`, `sign*`, `post*`, `preSign*`. High-level o | `constants.ts` | — | `DEFAULT_BRIDGE` constant (all-zero values for same-chain orders) | — | — | ### Delta Helpers (`src/methods/delta/helpers/`) -- `types.ts` — `DeltaAuctionOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap`, `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType` (includes `'ProductiveOrder'`), `DeltaOrderType` (`'MARKET' | 'LIMIT'`, shared by v1 & v2), `DeltaAuctionUnion` +- `types.ts` — `DeltaAuctionOrder`, `ExternalDeltaOrder`, `ProductiveDeltaOrder`, `TWAPDeltaOrder`, `TWAPBuyDeltaOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap` (covers all five families), `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType`, `DeltaOrderType` (`'MARKET' | 'LIMIT'`, shared by v1 & v2), `DeltaAuctionUnion` (= `DeltaAuctionDelta | DeltaAuctionExternal | DeltaAuctionTWAP | DeltaAuctionTWAPBuy | DeltaAuctionProductive`) - `buildDeltaOrderData.ts` — `buildDeltaSignableOrderData`, `produceDeltaOrderTypedData`, `SignableDeltaOrderData`, `BuildDeltaOrderDataInput`, `DELTA_DEFAULT_EXPIRY` - `buildCancelDeltaOrderData.ts` — `buildCancelDeltaOrderSignableData`, `SignableCancelDeltaOrderData`, `CancelDeltaOrderData` - `buildTWAPOrderData.ts` — `buildTWAPSignableOrderData`, `SignableTWAPOrderData`, `BuildTWAPOrderDataInput` @@ -182,7 +183,7 @@ On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDe ### `OnChainOrderType` note -`'ProductiveOrder'` is part of `OnChainOrderType` (in `delta/helpers/types.ts`) but is **not** in `OnChainOrderMap` (no SDK build support yet). Generics constrained to `keyof OnChainOrderMap` (`DeltaAuction`, `getDeltaOrders`) will not accept `'ProductiveOrder'` as `T`. +`'ProductiveOrder'` is part of `OnChainOrderType` and `OnChainOrderMap` — `DeltaAuction<'ProductiveOrder'>` (also exported as `DeltaAuctionProductive`) resolves to `ProductiveDeltaOrder`. The type is wired through the public surface, but **no build/sign/post helpers** exist for productive orders yet (`constructSubmit*` / `construct(Build|Sign|Post)*` cover only `Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`). Productive orders are read-only from the SDK's perspective — produced and managed by the server. Sides are inferred as `SELL` (productive orders carry no `OrderKind`). ## Checklist: Adding a New On-Chain Method diff --git a/src/index.ts b/src/index.ts index 5903b2c3e..79ae863e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -147,6 +147,7 @@ import type { BridgeStatus, Bridge, ExternalDeltaOrder, + ProductiveDeltaOrder, TWAPDeltaOrder, TWAPBuyDeltaOrder, TWAPOnChainOrderType, @@ -161,6 +162,7 @@ import type { DeltaAuctionTWAP, DeltaAuctionTWAPBuy, DeltaAuctionExternal, + DeltaAuctionProductive, DeltaOrderUnion, DeltaAuctionUnion, UnifiedDeltaOrderData, @@ -569,6 +571,7 @@ export type { DeltaAuctionTWAP, DeltaAuctionTWAPBuy, DeltaAuctionExternal, + DeltaAuctionProductive, DeltaOrderUnion, DeltaAuctionUnion, UnifiedDeltaOrderData, @@ -604,6 +607,8 @@ export type { DepositNativeAndPreSignDeltaOrderParams, // External Delta types ExternalDeltaOrder, + // Productive Delta types + ProductiveDeltaOrder, TWAPDeltaOrder, TWAPBuyDeltaOrder, TWAPOnChainOrderType, diff --git a/src/methods/delta/helpers/orders.ts b/src/methods/delta/helpers/orders.ts index d88d11c51..e134d4ce6 100644 --- a/src/methods/delta/helpers/orders.ts +++ b/src/methods/delta/helpers/orders.ts @@ -11,6 +11,7 @@ import { ExternalDeltaOrder, OnChainOrderType, OrderKind, + ProductiveDeltaOrder, SwapSideUnion, TWAPBuyDeltaOrder, TWAPDeltaOrder, @@ -65,6 +66,16 @@ function isDeltaOrder(order: DeltaOrderUnion): order is DeltaAuctionOrder { ); } +/** + * @description Checks whether an order is a Productive Delta order + * (strategy-routed order without an explicit OrderKind). + */ +function isProductiveOrder( + order: DeltaOrderUnion +): order is ProductiveDeltaOrder { + return 'strategy' in order && typeof order.strategy === 'string'; +} + /** * @description Checks whether an auction is a TWAP auction. */ @@ -110,17 +121,28 @@ function isExternalAuction(auction: { return auction.onChainOrderType === 'ExternalOrder'; } +/** + * @description Checks whether an auction is a Productive auction. + */ +function isProductiveAuction(auction: { + onChainOrderType: T; +}): auction is { onChainOrderType: 'ProductiveOrder' & T } { + return auction.onChainOrderType === 'ProductiveOrder'; +} + const checks = { isTWAPOrder, isTWAPSellOrder, isTWAPBuyOrder, isExternalOrder, isDeltaOrder, + isProductiveOrder, isTWAPAuction, isTWAPSellAuction, isTWAPBuyAuction, isDeltaAuction, isExternalAuction, + isProductiveAuction, isOrderCrosschain, isExecutedAuction, isPartiallyExecutedAuction, @@ -271,6 +293,10 @@ function getAuctionSwapSide(auction: DeltaAuction): SwapSideUnion { // TWAP orders have onChainOrderType instead of kind return getSwapSideFromTwapOrderType(auction.onChainOrderType); } + if (isProductiveAuction(auction)) { + // ProductiveOrders don't carry an explicit OrderKind; treated as SELL. + return 'SELL'; + } return getSwapSideFromDeltaOrder(auction.order); } diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index 305abc9dd..e060f7baa 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -123,6 +123,41 @@ export type ExternalDeltaOrder = { data: string; }; +export type ProductiveDeltaOrder = { + /** @description The address of the order owner */ + owner: string; + /** @description The address of the order beneficiary */ + beneficiary: string; + /** @description The address of the src token */ + srcToken: string; + /** @description The address of the dest token */ + destToken: string; + /** @description The amount of src token to swap */ + srcAmount: string; + /** @description The minimum amount of dest token to receive */ + destAmount: string; + /** @description The expected amount of token to receive */ + expectedAmount: string; + /** @description The deadline for the order */ + deadline: number; + /** @description The nonce of the order */ + nonce: string; + /** @description Metadata for the order, hex string */ + metadata: string; + /** @description Encoded partner address, fee bps, and flags for the order. partnerAndFee = (partner << 96) | (partnerTakesSurplus << 8) | fee in bps (max fee is 2%) */ + partnerAndFee: string; + /** @description Optional permit signature for the src token */ + permit: string; + /** @description The strategy address. */ + strategy: string; + /** @description The number of shares to execute for this order. */ + shares: string; + /** @description Whether the order uses shares or raw amounts. */ + useShares: boolean; + /** @description The bridge input */ + bridge: Bridge; +}; + type TWAPDeltaOrderBase = { /** @description The address of the order owner */ owner: string; @@ -216,6 +251,7 @@ export type OnChainOrderMap = { ExternalOrder: ExternalDeltaOrder; TWAPOrder: TWAPDeltaOrder; TWAPBuyOrder: TWAPBuyDeltaOrder; + ProductiveOrder: ProductiveDeltaOrder; }; type BaseBridgeAuctionFields = Pick< @@ -228,6 +264,7 @@ type BridgeAuctionFiledsMap = { ExternalOrder: BaseBridgeAuctionFields; TWAPOrder: Record; TWAPBuyOrder: Record; + ProductiveOrder: BaseBridgeAuctionFields; }; type DeltaAuctionBase = { @@ -256,7 +293,7 @@ type DeltaAuctionBase = { }; export type DeltaAuction< - T extends keyof OnChainOrderMap = keyof OnChainOrderMap + T extends keyof OnChainOrderMap = keyof OnChainOrderMap, > = T extends T ? Prettify< DeltaAuctionBase & { @@ -270,12 +307,14 @@ export type DeltaAuctionDelta = DeltaAuction<'Order'>; export type DeltaAuctionExternal = DeltaAuction<'ExternalOrder'>; export type DeltaAuctionTWAP = DeltaAuction<'TWAPOrder'>; export type DeltaAuctionTWAPBuy = DeltaAuction<'TWAPBuyOrder'>; +export type DeltaAuctionProductive = DeltaAuction<'ProductiveOrder'>; export type DeltaAuctionUnion = | DeltaAuctionDelta | DeltaAuctionExternal | DeltaAuctionTWAP - | DeltaAuctionTWAPBuy; + | DeltaAuctionTWAPBuy + | DeltaAuctionProductive; export type DeltaOrderUnion = OnChainOrderMap[keyof OnChainOrderMap]; From 264330cc18fd12bf2b5184442b480cd17c67ed78 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Mon, 25 May 2026 16:56:15 +0300 Subject: [PATCH 27/52] Release 9.5.4-dev.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec0c6022d..cfd9cd44f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@velora-dex/sdk", - "version": "9.5.4-dev.0", + "version": "9.5.4-dev.1", "main": "dist/index.js", "module": "dist/sdk.esm.js", "typings": "dist/index.d.ts", From c5179826825168e122710d0f5689adc4c7c714fd Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 13:42:44 +0300 Subject: [PATCH 28/52] startStatusCheck/return unsubscriber --- src/examples/helpers/delta.ts | 7 ++++++- src/examples/helpers/deltaV2.ts | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/examples/helpers/delta.ts b/src/examples/helpers/delta.ts index 0c1247380..fb04b0150 100644 --- a/src/examples/helpers/delta.ts +++ b/src/examples/helpers/delta.ts @@ -37,5 +37,10 @@ function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderFn) { export function startStatusCheck(getDeltaOrder: GetDeltaOrderFn) { const intervalId = fetchOrderPeriodically(getDeltaOrder); - setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + const timeoutId = setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + + return () => { + clearInterval(intervalId); + clearTimeout(timeoutId); + }; } diff --git a/src/examples/helpers/deltaV2.ts b/src/examples/helpers/deltaV2.ts index 2910a2fd4..3003b0244 100644 --- a/src/examples/helpers/deltaV2.ts +++ b/src/examples/helpers/deltaV2.ts @@ -25,5 +25,10 @@ function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderV2Fn) { export function startStatusCheckV2(getDeltaOrder: GetDeltaOrderV2Fn) { const intervalId = fetchOrderPeriodically(getDeltaOrder); - setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + const timeoutId = setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + + return () => { + clearInterval(intervalId); + clearTimeout(timeoutId); + }; } From 4c07225fb8b24d27901fc2fed2ef9ef1066ebc89 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 13:53:31 +0300 Subject: [PATCH 29/52] BridgeMetadata/make outputAmount optional --- src/methods/delta/helpers/types.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index e060f7baa..34a1d1b27 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -319,8 +319,11 @@ export type DeltaAuctionUnion = export type DeltaOrderUnion = OnChainOrderMap[keyof OnChainOrderMap]; export type BridgeMetadata = { - /** @description Actual amount received on the destination chain. */ - outputAmount: string; + /** @description Fild is present after bridge is executed. + * The actual amount received from the bridge, which may differ + * from the expectedOutputAmount due to bridge slippage or other factors. + * */ + outputAmount?: string; /** @description Field is present iff: order was built via POST /v2/orders/build, * the route is cross-chain (route.bridge !== null and not an external handler), * and the order is posted before the per-order cache entry expires. From 37990296e4f7c146e19e0a96bf3625718298565f Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 13:55:37 +0300 Subject: [PATCH 30/52] DeltaAuction/better types --- src/methods/delta/helpers/types.ts | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index 34a1d1b27..2b8db2456 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -292,16 +292,15 @@ type DeltaAuctionBase = { type: DeltaOrderType; }; -export type DeltaAuction< - T extends keyof OnChainOrderMap = keyof OnChainOrderMap, -> = T extends T - ? Prettify< - DeltaAuctionBase & { - onChainOrderType: T; - order: OnChainOrderMap[T]; - } & BridgeAuctionFiledsMap[T] - > - : never; +export type DeltaAuction = + T extends T + ? Prettify< + DeltaAuctionBase & { + onChainOrderType: T; + order: OnChainOrderMap[T]; + } & BridgeAuctionFiledsMap[T] + > + : never; export type DeltaAuctionDelta = DeltaAuction<'Order'>; export type DeltaAuctionExternal = DeltaAuction<'ExternalOrder'>; @@ -342,12 +341,7 @@ export type BridgeMetadata = { // refunded is basically failed export type BridgeStatus = 'pending' | 'filled' | 'expired' | 'refunded'; -export type OnChainOrderType = - | 'Order' - | 'ExternalOrder' - | 'TWAPOrder' - | 'TWAPBuyOrder' - | 'ProductiveOrder'; +export type OnChainOrderType = keyof OnChainOrderMap; export type TWAPOnChainOrderType = 'TWAPOrder' | 'TWAPBuyOrder'; From 5f2d69bcce92b7cb36d58568165ae6b10559b779 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 13:57:07 +0300 Subject: [PATCH 31/52] getBridgeProtocolsV2/better description --- src/methods/deltaV2/getBridgeRoutes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/methods/deltaV2/getBridgeRoutes.ts b/src/methods/deltaV2/getBridgeRoutes.ts index 7e0f9626b..230164e02 100644 --- a/src/methods/deltaV2/getBridgeRoutes.ts +++ b/src/methods/deltaV2/getBridgeRoutes.ts @@ -34,7 +34,7 @@ type BridgeProtocolsV2Response = { export type GetBridgeRoutesFunctions = { /** @description Fetch supported bridge routes as a flat array (v2 replacement for bridge-info). */ getBridgeRoutes: GetBridgeRoutes; - /** @description Fetch supported bridge protocols (falls through to v1 controller on the v2 path). */ + /** @description Fetch supported bridge protocols (unchanged from v1). */ getBridgeProtocolsV2: GetBridgeProtocolsV2; }; From 91f83573b7197af529d20d72539dedd1ff577214 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 13:59:18 +0300 Subject: [PATCH 32/52] BridgeRoute/better description --- src/methods/deltaV2/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts index 1874d5624..768e498a7 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/deltaV2/types.ts @@ -108,7 +108,7 @@ export type DeltaPriceV2 = { alternatives: DeltaRoute[]; }; -/** @description A flat bridge-routes entry returned by GET /delta/v2/prices/bridge-routes. */ +/** @description A flat bridge-routes entry returned by GET /delta/v2/prices/bridge-routes. (better version of v1 prices/bridge-info) */ export type BridgeRoute = { srcChainId: number; destChainId: number; From 6a5bfc6f13244b68ac9a7de685cb5e0199648cef Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 14:04:29 +0300 Subject: [PATCH 33/52] getTransactionAmounts/fix outputAmount usage --- src/methods/delta/helpers/orders.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/methods/delta/helpers/orders.ts b/src/methods/delta/helpers/orders.ts index e134d4ce6..5c99bed85 100644 --- a/src/methods/delta/helpers/orders.ts +++ b/src/methods/delta/helpers/orders.ts @@ -358,7 +358,11 @@ function getTransactionAmounts(transactions: DeltaAuctionTransaction[]) { srcAmount: acc.srcAmount + BigInt(spentAmount), destAmount: acc.destAmount + - BigInt(bridgeMetadata ? bridgeMetadata.outputAmount : receivedAmount), + BigInt( + bridgeMetadata?.outputAmount + ? bridgeMetadata.outputAmount + : receivedAmount + ), }; }, { @@ -446,7 +450,7 @@ type ExecutedDeltaAuctionProps = { * @description Checks whether an auction is fully executed. */ function isExecutedAuction< - T extends Pick + T extends Pick, >(auction: T): auction is T & ExecutedDeltaAuctionProps { if (auction.status !== 'EXECUTED') return false; @@ -482,7 +486,7 @@ type FailedDeltaAuctionProps = * @description Checks whether an auction is failed on source or destination chain. */ function isFailedAuction< - T extends Pick + T extends Pick, >(auction: T): auction is T & FailedDeltaAuctionProps { // already failed on srcChain, whether Order is crosschain or not if (failedAuctionStatusesSet.has(auction.status)) return true; @@ -547,7 +551,7 @@ function isPendingAuction>( * Orders in the middle of normal execution can also be considered partially executed if they have any transactions. */ function isPartiallyExecutedAuction< - T extends Pick + T extends Pick, >( auction: T ): auction is T & { transactions: NonEmptyArray } { From c232a595117af6b268d1cb146fce7ebf20c58f9c Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 14:04:36 +0300 Subject: [PATCH 34/52] fix broken delta v1 test --- tests/delta.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/delta.test.ts b/tests/delta.test.ts index bcd71e71b..ee25fa81c 100644 --- a/tests/delta.test.ts +++ b/tests/delta.test.ts @@ -871,7 +871,7 @@ describe('Delta:methods', () => { expect(mockFetch).toHaveBeenLastCalledWith({ data: { ...input, chainId: dummySDK.chainId }, method: 'POST', - url: `${dummySDK.apiURL}/delta/orders/`, + url: `${dummySDK.apiURL}/delta/orders`, }); }); From d55f43edfbf59d978c31383abe842e4208586124 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 15:46:51 +0300 Subject: [PATCH 35/52] simplify migration with common DeltaV2 mapping --- src/examples/deltaV2.ts | 42 +-- src/examples/helpers/deltaV2.ts | 6 +- src/index.ts | 168 ++--------- ...uildDeltaOrderV2.ts => buildDeltaOrder.ts} | 28 +- ...aOrderV2.ts => buildExternalDeltaOrder.ts} | 28 +- ...DeltaOrderV2.ts => buildTWAPDeltaOrder.ts} | 40 +-- ...celDeltaOrderV2.ts => cancelDeltaOrder.ts} | 34 +-- .../{getAgentsListV2.ts => getAgentsList.ts} | 18 +- src/methods/deltaV2/getBridgeRoutes.ts | 12 +- ...{getDeltaOrdersV2.ts => getDeltaOrders.ts} | 54 ++-- .../{getDeltaPriceV2.ts => getDeltaPrice.ts} | 30 +- src/methods/deltaV2/index.ts | 274 +++++++++--------- ...nDeltaV2.ts => isTokenSupportedInDelta.ts} | 14 +- ...{postDeltaOrderV2.ts => postDeltaOrder.ts} | 22 +- ...taOrderV2.ts => postExternalDeltaOrder.ts} | 24 +- ...PDeltaOrderV2.ts => postTWAPDeltaOrder.ts} | 24 +- src/methods/deltaV2/types.ts | 18 +- src/sdk/full.ts | 4 +- src/sdk/simple.ts | 34 +-- tests/deltaV2.test.ts | 238 +++++++-------- 20 files changed, 496 insertions(+), 616 deletions(-) rename src/methods/deltaV2/{buildDeltaOrderV2.ts => buildDeltaOrder.ts} (79%) rename src/methods/deltaV2/{buildExternalDeltaOrderV2.ts => buildExternalDeltaOrder.ts} (80%) rename src/methods/deltaV2/{buildTWAPDeltaOrderV2.ts => buildTWAPDeltaOrder.ts} (79%) rename src/methods/deltaV2/{cancelDeltaOrderV2.ts => cancelDeltaOrder.ts} (70%) rename src/methods/deltaV2/{getAgentsListV2.ts => getAgentsList.ts} (55%) rename src/methods/deltaV2/{getDeltaOrdersV2.ts => getDeltaOrders.ts} (64%) rename src/methods/deltaV2/{getDeltaPriceV2.ts => getDeltaPrice.ts} (79%) rename src/methods/deltaV2/{isTokenSupportedInDeltaV2.ts => isTokenSupportedInDelta.ts} (70%) rename src/methods/deltaV2/{postDeltaOrderV2.ts => postDeltaOrder.ts} (71%) rename src/methods/deltaV2/{postExternalDeltaOrderV2.ts => postExternalDeltaOrder.ts} (50%) rename src/methods/deltaV2/{postTWAPDeltaOrderV2.ts => postTWAPDeltaOrder.ts} (65%) diff --git a/src/examples/deltaV2.ts b/src/examples/deltaV2.ts index c35ee1fc7..3d03b7522 100644 --- a/src/examples/deltaV2.ts +++ b/src/examples/deltaV2.ts @@ -5,7 +5,7 @@ import { constructPartialSDK, constructEthersContractCaller, constructAxiosFetcher, - constructAllDeltaV2OrdersHandlers, + DeltaV2, } from '..'; import { startStatusCheckV2 } from './helpers/deltaV2'; @@ -28,7 +28,7 @@ const deltaSDK = constructPartialSDK( fetcher, contractCaller, }, - constructAllDeltaV2OrdersHandlers + DeltaV2.constructAllDeltaOrdersHandlers ); const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f'; @@ -37,7 +37,7 @@ const USDC_TOKEN = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; async function simpleDeltaV2Flow() { const amount = '1000000000000'; // wei - const deltaPrice = await deltaSDK.getDeltaPriceV2({ + const deltaPrice = await deltaSDK.getDeltaPrice({ srcToken: DAI_TOKEN, destToken: USDC_TOKEN, amount, @@ -53,7 +53,7 @@ async function simpleDeltaV2Flow() { const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); await tx.wait(); - const deltaAuction = await deltaSDK.submitDeltaOrderV2({ + const deltaAuction = await deltaSDK.submitDeltaOrder({ route: deltaPrice.route, // or pick from deltaPrice.alternatives side: deltaPrice.side, owner: account, @@ -63,13 +63,13 @@ async function simpleDeltaV2Flow() { }); // poll if necessary - startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); + startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); } async function manualDeltaV2Flow() { const amount = '1000000000000'; // wei - const deltaPrice = await deltaSDK.getDeltaPriceV2({ + const deltaPrice = await deltaSDK.getDeltaPrice({ srcToken: DAI_TOKEN, destToken: USDC_TOKEN, amount, @@ -86,7 +86,7 @@ async function manualDeltaV2Flow() { await tx.wait(); // server-side build (returns EIP-712 typed data + orderHash) - const builtOrder = await deltaSDK.buildDeltaOrderV2({ + const builtOrder = await deltaSDK.buildDeltaOrder({ route: deltaPrice.route, // or pick from deltaPrice.alternatives side: deltaPrice.side, owner: account, @@ -96,18 +96,18 @@ async function manualDeltaV2Flow() { }); // one signer for every v2 order type (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) - const signature = await deltaSDK.signDeltaOrderV2(builtOrder); + const signature = await deltaSDK.signDeltaOrder(builtOrder); - const deltaAuction = await deltaSDK.postDeltaOrderV2({ + const deltaAuction = await deltaSDK.postDeltaOrder({ // partner: "..." // if available order: builtOrder.toSign.value as Parameters< - typeof deltaSDK.postDeltaOrderV2 + typeof deltaSDK.postDeltaOrder >[0]['order'], signature, }); // poll if necessary - startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); + startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); } // External orders forward execution to an integrator-provided handler contract. @@ -116,7 +116,7 @@ async function manualDeltaV2Flow() { async function externalDeltaV2Flow() { const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC - const deltaPrice = await deltaSDK.getDeltaPriceV2({ + const deltaPrice = await deltaSDK.getDeltaPrice({ srcToken: USDC_TOKEN, destToken: DAI_TOKEN, amount, @@ -129,7 +129,7 @@ async function externalDeltaV2Flow() { const HANDLER_DATA = '0x0000000000000000000000000000000000000000000000000000000000000000'; // handler-specific encoded bytes - const builtOrder = await deltaSDK.buildExternalDeltaOrderV2({ + const builtOrder = await deltaSDK.buildExternalDeltaOrder({ route: deltaPrice.route, side: deltaPrice.side, owner: account, @@ -138,16 +138,16 @@ async function externalDeltaV2Flow() { slippage: 50, }); - const signature = await deltaSDK.signDeltaOrderV2(builtOrder); + const signature = await deltaSDK.signDeltaOrder(builtOrder); - const deltaAuction = await deltaSDK.postExternalDeltaOrderV2({ + const deltaAuction = await deltaSDK.postExternalDeltaOrder({ order: builtOrder.toSign.value as Parameters< - typeof deltaSDK.postExternalDeltaOrderV2 + typeof deltaSDK.postExternalDeltaOrder >[0]['order'], signature, }); - startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); + startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); } // TWAP sell splits a total srcAmount into N equal slices executed `interval` seconds apart. @@ -160,7 +160,7 @@ async function twapSellDeltaV2Flow() { ).toString(); // quote a single slice — route amounts must match floor(totalSrcAmount / numSlices) - const deltaPrice = await deltaSDK.getDeltaPriceV2({ + const deltaPrice = await deltaSDK.getDeltaPrice({ srcToken: DAI_TOKEN, destToken: USDC_TOKEN, amount: perSliceAmount, @@ -172,7 +172,7 @@ async function twapSellDeltaV2Flow() { const tx = await deltaSDK.approveTokenForDelta(totalSrcAmount, DAI_TOKEN); await tx.wait(); - const deltaAuction = await deltaSDK.submitTWAPDeltaOrderV2({ + const deltaAuction = await deltaSDK.submitTWAPDeltaOrder({ onChainOrderType: 'TWAPOrder', route: deltaPrice.route, owner: account, @@ -182,12 +182,12 @@ async function twapSellDeltaV2Flow() { slippage: 50, }); - startStatusCheckV2(() => deltaSDK.getDeltaOrderByIdV2(deltaAuction.id)); + startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); } // Paginated list of a user's orders (v2 returns a { results, pagination } envelope). async function listUserOrders() { - const page1 = await deltaSDK.getDeltaOrdersV2({ + const page1 = await deltaSDK.getDeltaOrders({ userAddress: account, page: 1, limit: 50, diff --git a/src/examples/helpers/deltaV2.ts b/src/examples/helpers/deltaV2.ts index 3003b0244..227eca6c0 100644 --- a/src/examples/helpers/deltaV2.ts +++ b/src/examples/helpers/deltaV2.ts @@ -1,12 +1,12 @@ -import { DeltaOrderV2Response } from '../..'; +import { DeltaV2 } from '../..'; // v2 status COMPLETED already accounts for destChain bridge settlement // (crosschain orders sit in BRIDGING until the destChain leg is done). -function isCompletedDeltaV2Order(order: DeltaOrderV2Response) { +function isCompletedDeltaV2Order(order: DeltaV2.DeltaOrderResponse) { return order.status === 'COMPLETED'; } -type GetDeltaOrderV2Fn = () => Promise; +type GetDeltaOrderV2Fn = () => Promise; function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderV2Fn) { const intervalId = setInterval(async () => { diff --git a/src/index.ts b/src/index.ts index 79ae863e2..a2076eaa5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -291,84 +291,6 @@ import { SignableCancelDeltaOrderData, } from './methods/delta/helpers/buildCancelDeltaOrderData'; -// Delta v2 modules -import { - BuildDeltaOrderV2Functions, - BuildDeltaOrderV2Params, - constructBuildDeltaOrderV2, -} from './methods/deltaV2/buildDeltaOrderV2'; -import { - BuildExternalDeltaOrderV2Functions, - BuildExternalDeltaOrderV2Params, - constructBuildExternalDeltaOrderV2, -} from './methods/deltaV2/buildExternalDeltaOrderV2'; -import { - BuildTWAPDeltaOrderV2Functions, - BuildTWAPDeltaOrderV2Params, - BuildTWAPSellDeltaOrderV2Params, - BuildTWAPBuyDeltaOrderV2Params, - constructBuildTWAPDeltaOrderV2, -} from './methods/deltaV2/buildTWAPDeltaOrderV2'; -import { - constructPostDeltaOrderV2, - DeltaOrderToPostV2, - PostDeltaOrderV2Functions, - PostDeltaOrderV2Params, -} from './methods/deltaV2/postDeltaOrderV2'; -import { - constructPostExternalDeltaOrderV2, - PostExternalDeltaOrderV2Functions, - PostExternalDeltaOrderV2Params, -} from './methods/deltaV2/postExternalDeltaOrderV2'; -import { - constructPostTWAPDeltaOrderV2, - PostTWAPDeltaOrderV2Functions, - PostTWAPDeltaOrderV2Params, -} from './methods/deltaV2/postTWAPDeltaOrderV2'; -import { - constructGetDeltaPriceV2, - DeltaPriceV2Params, - GetDeltaPriceV2Functions, -} from './methods/deltaV2/getDeltaPriceV2'; -import { - constructGetDeltaOrdersV2, - GetDeltaOrdersV2Functions, -} from './methods/deltaV2/getDeltaOrdersV2'; -import { - constructGetBridgeRoutes, - GetBridgeRoutesFunctions, -} from './methods/deltaV2/getBridgeRoutes'; -import { - constructIsTokenSupportedInDeltaV2, - IsTokenSupportedInDeltaV2Functions, -} from './methods/deltaV2/isTokenSupportedInDeltaV2'; -import { - CancelDeltaOrderV2Functions, - constructCancelDeltaOrderV2, -} from './methods/deltaV2/cancelDeltaOrderV2'; -import { - AgentList, - constructGetAgentsListV2, - GetAgentsListV2Functions, -} from './methods/deltaV2/getAgentsListV2'; -import type { - DeltaOrderStatusV2, - BuiltDeltaOrderV2, - DeltaPriceToken, - DeltaTokenAmount, - BridgeTag, - DeltaRouteBridge, - DeltaRouteBridgeContractParams, - DeltaRouteStep, - DeltaRoute, - DeltaPriceV2, - BridgeRoute, - DeltaOnChainOrderTypeReported, - DeltaTokenSide, - DeltaTransactionV2, - DeltaOrderV2Response, -} from './methods/deltaV2/types'; - export { constructSwapSDK, SwapSDKMethods } from './methods/swap'; export { @@ -388,18 +310,31 @@ export { SubmitTWAPDeltaOrderParams, } from './methods/delta'; -export { - constructAllDeltaV2OrdersHandlers, - constructSubmitDeltaOrderV2, - constructSubmitExternalDeltaOrderV2, - constructSubmitTWAPDeltaOrderV2, - constructSignDeltaOrderV2, - DeltaV2OrderHandlers, - SubmitDeltaOrderV2Params, - SubmitExternalDeltaOrderV2Params, - SubmitTWAPDeltaOrderV2Params, - SignDeltaOrderV2Functions, -} from './methods/deltaV2'; +// Delta v2 is exposed as a single namespace so it can ship alongside v1 without +// colliding at the top level. v2 source uses unsuffixed names internally +// (constructBuildDeltaOrder, BuiltDeltaOrder, DeltaPrice, ...); consumers reach +// them via `DeltaV2.constructBuildDeltaOrder` etc. +// +// Migration plan when deprecating v1 (breaking change): +// 1. Replace the bare `export { ... } from './methods/delta'` block above with +// `export * from './methods/deltaV2'` (or named re-exports of v2 symbols). +// Top-level `constructPostDeltaOrder` now resolves to v2. +// 2. Move v1 behind its own namespace for backcompat: +// `export * as DeltaV1 from './methods/delta'`. +// 3. Keep `export * as DeltaV2 from './methods/deltaV2'` as a redundant alias +// so code written against the v2 namespace today keeps compiling. +// 4. Mirror this on the bundled SDKs in sdk/full.ts and sdk/simple.ts: +// `sdk.delta.*` flips to v2 (use `constructAllDeltaOrdersHandlers` from +// './methods/deltaV2'), and add `sdk.deltaV1.*` for backcompat. +// +// Migration plan when dropping v1 entirely: +// - Delete the `DeltaV1` namespace export and `sdk.deltaV1` field. +// - Delete `src/methods/delta/`. +// - Delete the `DeltaV2` re-export alias (consumers can move to bare names). +// - The `methods/deltaV2/` folder can be renamed to `methods/delta/` (and the +// `/delta/v2/` URL prefix in the leaf modules updated if the server has by +// then collapsed v1 and v2 endpoints). +export * as DeltaV2 from './methods/deltaV2'; export type { TransactionParams, @@ -483,21 +418,6 @@ export { constructPreSignTWAPDeltaOrder, // Quote methods constructGetQuote, - // Delta v2 runtime values (const-object enums etc.) - DeltaOrderStatusV2, - // Delta V2 methods - constructBuildDeltaOrderV2, - constructBuildExternalDeltaOrderV2, - constructBuildTWAPDeltaOrderV2, - constructPostDeltaOrderV2, - constructPostExternalDeltaOrderV2, - constructPostTWAPDeltaOrderV2, - constructGetDeltaPriceV2, - constructGetDeltaOrdersV2, - constructGetBridgeRoutes, - constructIsTokenSupportedInDeltaV2, - constructCancelDeltaOrderV2, - constructGetAgentsListV2, // different helpers constructGetPartnerFee, constructGetBridgeInfo, @@ -635,44 +555,6 @@ export type { PostTWAPDeltaOrderFunctions, PostTWAPDeltaOrderParams, PreSignTWAPDeltaOrderFunctions, - // Delta v2 types - BuiltDeltaOrderV2, - DeltaPriceToken, - DeltaTokenAmount, - BridgeTag, - DeltaRouteBridge, - DeltaRouteBridgeContractParams, - DeltaRouteStep, - DeltaRoute, - DeltaPriceV2, - BridgeRoute, - DeltaOnChainOrderTypeReported, - DeltaTokenSide, - DeltaTransactionV2, - DeltaOrderV2Response, - DeltaPriceV2Params, - GetDeltaPriceV2Functions, - GetDeltaOrdersV2Functions, - GetBridgeRoutesFunctions, - IsTokenSupportedInDeltaV2Functions, - BuildDeltaOrderV2Params, - BuildDeltaOrderV2Functions, - BuildExternalDeltaOrderV2Params, - BuildExternalDeltaOrderV2Functions, - BuildTWAPDeltaOrderV2Params, - BuildTWAPSellDeltaOrderV2Params, - BuildTWAPBuyDeltaOrderV2Params, - BuildTWAPDeltaOrderV2Functions, - DeltaOrderToPostV2, - PostDeltaOrderV2Params, - PostDeltaOrderV2Functions, - PostExternalDeltaOrderV2Params, - PostExternalDeltaOrderV2Functions, - PostTWAPDeltaOrderV2Params, - PostTWAPDeltaOrderV2Functions, - CancelDeltaOrderV2Functions, - AgentList as AgentInfo, - GetAgentsListV2Functions, // types for Quote methods GetQuoteFunctions, QuoteParams, diff --git a/src/methods/deltaV2/buildDeltaOrderV2.ts b/src/methods/deltaV2/buildDeltaOrder.ts similarity index 79% rename from src/methods/deltaV2/buildDeltaOrderV2.ts rename to src/methods/deltaV2/buildDeltaOrder.ts index fbbab83d7..14460cf5c 100644 --- a/src/methods/deltaV2/buildDeltaOrderV2.ts +++ b/src/methods/deltaV2/buildDeltaOrder.ts @@ -1,9 +1,9 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { BuiltDeltaOrderV2, DeltaRoute } from './types'; -export type { BuiltDeltaOrderV2 } from './types'; +import type { BuiltDeltaOrder, DeltaRoute } from './types'; +export type { BuiltDeltaOrder } from './types'; -export type BuildDeltaOrderV2Params = { +export type BuildDeltaOrderParams = { /** @description The address of the order owner */ owner: string; /** @description The address of the order beneficiary. Defaults to owner. */ @@ -29,7 +29,7 @@ export type BuildDeltaOrderV2Params = { /** @description Designates the Order as partially fillable instead of fill-or-kill. Default false. */ partiallyFillable?: boolean; - /** @description DeltaRoute from getDeltaPriceV2 — either priceV2.route or any priceV2.alternatives[i] */ + /** @description DeltaRoute from getDeltaPrice — either price.route or any price.alternatives[i] */ route: DeltaRoute; /** @description Order side. SELL or BUY. */ side: 'SELL' | 'BUY'; @@ -39,24 +39,24 @@ export type BuildDeltaOrderV2Params = { limitAmount?: string; }; -type BuildDeltaOrderV2 = ( - buildOrderParams: BuildDeltaOrderV2Params, +type BuildDeltaOrder = ( + buildOrderParams: BuildDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise; -export type BuildDeltaOrderV2Functions = { +export type BuildDeltaOrderFunctions = { /** @description Build a Delta v2 order from a DeltaRoute via the server endpoint, ready to sign and post. */ - buildDeltaOrderV2: BuildDeltaOrderV2; + buildDeltaOrder: BuildDeltaOrder; }; -export const constructBuildDeltaOrderV2 = ( +export const constructBuildDeltaOrder = ( options: ConstructFetchInput -): BuildDeltaOrderV2Functions => { +): BuildDeltaOrderFunctions => { const { apiURL = API_URL, chainId, fetcher } = options; const buildUrl = `${apiURL}/delta/v2/orders/build` as const; - const buildDeltaOrderV2: BuildDeltaOrderV2 = async (params, requestParams) => - fetcher({ + const buildDeltaOrder: BuildDeltaOrder = async (params, requestParams) => + fetcher({ url: buildUrl, method: 'POST', data: { @@ -82,5 +82,5 @@ export const constructBuildDeltaOrderV2 = ( requestParams, }); - return { buildDeltaOrderV2 }; + return { buildDeltaOrder }; }; diff --git a/src/methods/deltaV2/buildExternalDeltaOrderV2.ts b/src/methods/deltaV2/buildExternalDeltaOrder.ts similarity index 80% rename from src/methods/deltaV2/buildExternalDeltaOrderV2.ts rename to src/methods/deltaV2/buildExternalDeltaOrder.ts index a4c4226a7..b139355c0 100644 --- a/src/methods/deltaV2/buildExternalDeltaOrderV2.ts +++ b/src/methods/deltaV2/buildExternalDeltaOrder.ts @@ -1,9 +1,9 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { BuiltDeltaOrderV2, DeltaRoute } from './types'; -export type { BuiltDeltaOrderV2 } from './types'; +import type { BuiltDeltaOrder, DeltaRoute } from './types'; +export type { BuiltDeltaOrder } from './types'; -export type BuildExternalDeltaOrderV2Params = { +export type BuildExternalDeltaOrderParams = { /** @description The address of the order owner */ owner: string; /** @description The address of the external handler contract */ @@ -33,7 +33,7 @@ export type BuildExternalDeltaOrderV2Params = { /** @description Designates the Order as partially fillable. Default false. */ partiallyFillable?: boolean; - /** @description DeltaRoute from getDeltaPriceV2 */ + /** @description DeltaRoute from getDeltaPrice */ route: DeltaRoute; /** @description Order side. SELL or BUY. */ side: 'SELL' | 'BUY'; @@ -43,27 +43,27 @@ export type BuildExternalDeltaOrderV2Params = { limitAmount?: string; }; -type BuildExternalDeltaOrderV2 = ( - buildOrderParams: BuildExternalDeltaOrderV2Params, +type BuildExternalDeltaOrder = ( + buildOrderParams: BuildExternalDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise; -export type BuildExternalDeltaOrderV2Functions = { +export type BuildExternalDeltaOrderFunctions = { /** @description Build a Delta v2 External Order from a DeltaRoute via the server endpoint, ready to sign and post. */ - buildExternalDeltaOrderV2: BuildExternalDeltaOrderV2; + buildExternalDeltaOrder: BuildExternalDeltaOrder; }; -export const constructBuildExternalDeltaOrderV2 = ( +export const constructBuildExternalDeltaOrder = ( options: ConstructFetchInput -): BuildExternalDeltaOrderV2Functions => { +): BuildExternalDeltaOrderFunctions => { const { apiURL = API_URL, chainId, fetcher } = options; const buildUrl = `${apiURL}/delta/v2/orders/build` as const; - const buildExternalDeltaOrderV2: BuildExternalDeltaOrderV2 = async ( + const buildExternalDeltaOrder: BuildExternalDeltaOrder = async ( params, requestParams ) => - fetcher({ + fetcher({ url: buildUrl, method: 'POST', data: { @@ -91,5 +91,5 @@ export const constructBuildExternalDeltaOrderV2 = ( requestParams, }); - return { buildExternalDeltaOrderV2 }; + return { buildExternalDeltaOrder }; }; diff --git a/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts b/src/methods/deltaV2/buildTWAPDeltaOrder.ts similarity index 79% rename from src/methods/deltaV2/buildTWAPDeltaOrderV2.ts rename to src/methods/deltaV2/buildTWAPDeltaOrder.ts index 836ceb88c..395746b16 100644 --- a/src/methods/deltaV2/buildTWAPDeltaOrderV2.ts +++ b/src/methods/deltaV2/buildTWAPDeltaOrder.ts @@ -1,9 +1,9 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { BuiltDeltaOrderV2, DeltaRoute } from './types'; -export type { BuiltDeltaOrderV2 } from './types'; +import type { BuiltDeltaOrder, DeltaRoute } from './types'; +export type { BuiltDeltaOrder } from './types'; -type BuildTWAPDeltaOrderV2Base = { +type BuildTWAPDeltaOrderBase = { /** @description The address of the order owner */ owner: string; /** @description The address of the order beneficiary. Defaults to owner. */ @@ -22,7 +22,7 @@ type BuildTWAPDeltaOrderV2Base = { numSlices: number; /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ slippage?: number; - /** @description DeltaRoute from getDeltaPriceV2 for a single slice */ + /** @description DeltaRoute from getDeltaPrice for a single slice */ route: DeltaRoute; /** @description Partner fee in basis points (bps) */ partnerFeeBps?: number; @@ -40,13 +40,13 @@ type BuildTWAPDeltaOrderV2Base = { limitAmount?: string; }; -export type BuildTWAPSellDeltaOrderV2Params = BuildTWAPDeltaOrderV2Base & { +export type BuildTWAPSellDeltaOrderParams = BuildTWAPDeltaOrderBase & { onChainOrderType: 'TWAPOrder'; /** @description Total source token amount across all slices. route.origin.input.amount must equal floor(totalSrcAmount / numSlices). */ totalSrcAmount: string; }; -export type BuildTWAPBuyDeltaOrderV2Params = BuildTWAPDeltaOrderV2Base & { +export type BuildTWAPBuyDeltaOrderParams = BuildTWAPDeltaOrderBase & { onChainOrderType: 'TWAPBuyOrder'; /** @description Total destination token amount to buy across all slices. route.origin.output.amount must equal floor(totalDestAmount / numSlices). */ totalDestAmount: string; @@ -54,27 +54,27 @@ export type BuildTWAPBuyDeltaOrderV2Params = BuildTWAPDeltaOrderV2Base & { maxSrcAmount: string; }; -export type BuildTWAPDeltaOrderV2Params = - | BuildTWAPSellDeltaOrderV2Params - | BuildTWAPBuyDeltaOrderV2Params; +export type BuildTWAPDeltaOrderParams = + | BuildTWAPSellDeltaOrderParams + | BuildTWAPBuyDeltaOrderParams; -type BuildTWAPDeltaOrderV2 = ( - buildOrderParams: BuildTWAPDeltaOrderV2Params, +type BuildTWAPDeltaOrder = ( + buildOrderParams: BuildTWAPDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise; -export type BuildTWAPDeltaOrderV2Functions = { +export type BuildTWAPDeltaOrderFunctions = { /** @description Build a Delta v2 TWAP Order (sell or buy) from a DeltaRoute via the server endpoint, ready to sign and post. */ - buildTWAPDeltaOrderV2: BuildTWAPDeltaOrderV2; + buildTWAPDeltaOrder: BuildTWAPDeltaOrder; }; -export const constructBuildTWAPDeltaOrderV2 = ( +export const constructBuildTWAPDeltaOrder = ( options: ConstructFetchInput -): BuildTWAPDeltaOrderV2Functions => { +): BuildTWAPDeltaOrderFunctions => { const { apiURL = API_URL, chainId, fetcher } = options; const buildUrl = `${apiURL}/delta/v2/orders/build` as const; - const buildTWAPDeltaOrderV2: BuildTWAPDeltaOrderV2 = async ( + const buildTWAPDeltaOrder: BuildTWAPDeltaOrder = async ( params, requestParams ) => { @@ -100,7 +100,7 @@ export const constructBuildTWAPDeltaOrderV2 = ( }; if (params.onChainOrderType === 'TWAPOrder') { - return fetcher({ + return fetcher({ url: buildUrl, method: 'POST', data: { @@ -113,7 +113,7 @@ export const constructBuildTWAPDeltaOrderV2 = ( }); } - return fetcher({ + return fetcher({ url: buildUrl, method: 'POST', data: { @@ -127,5 +127,5 @@ export const constructBuildTWAPDeltaOrderV2 = ( }); }; - return { buildTWAPDeltaOrderV2 }; + return { buildTWAPDeltaOrder }; }; diff --git a/src/methods/deltaV2/cancelDeltaOrderV2.ts b/src/methods/deltaV2/cancelDeltaOrder.ts similarity index 70% rename from src/methods/deltaV2/cancelDeltaOrderV2.ts rename to src/methods/deltaV2/cancelDeltaOrder.ts index 0fce676d3..1199a831a 100644 --- a/src/methods/deltaV2/cancelDeltaOrderV2.ts +++ b/src/methods/deltaV2/cancelDeltaOrder.ts @@ -16,39 +16,39 @@ type CancelDeltaOrderRequestParams = { signature: string; }; -export type SignCancelDeltaOrderRequestV2 = ( +export type SignCancelDeltaOrderRequest = ( params: CancelDeltaOrderData, requestParams?: RequestParameters ) => Promise; -export type PostCancelDeltaOrderRequestV2 = ( +export type PostCancelDeltaOrderRequest = ( params: CancelDeltaOrderRequestParams, requestParams?: RequestParameters ) => Promise; -export type CancelDeltaOrderV2 = ( +export type CancelDeltaOrder = ( params: CancelDeltaOrderData, requestParams?: RequestParameters ) => Promise; -export type CancelDeltaOrderV2Functions = { - signCancelDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2; - postCancelDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2; +export type CancelDeltaOrderFunctions = { + signCancelDeltaOrderRequest: SignCancelDeltaOrderRequest; + postCancelDeltaOrderRequest: PostCancelDeltaOrderRequest; /** @description Cancel one or more Delta orders via the v2 endpoint */ - cancelDeltaOrdersV2: CancelDeltaOrderV2; + cancelDeltaOrders: CancelDeltaOrder; }; -export const constructCancelDeltaOrderV2 = ( +export const constructCancelDeltaOrder = ( options: Pick< ConstructProviderFetchInput, 'contractCaller' | 'fetcher' | 'apiURL' | 'chainId' > -): CancelDeltaOrderV2Functions => { +): CancelDeltaOrderFunctions => { const apiURL = options.apiURL ?? API_URL; const { getDeltaContract } = constructGetDeltaContract(options); - const signCancelDeltaOrderRequestV2: SignCancelDeltaOrderRequestV2 = async ( + const signCancelDeltaOrderRequest: SignCancelDeltaOrderRequest = async ( params, requestParams ) => { @@ -66,7 +66,7 @@ export const constructCancelDeltaOrderV2 = ( return options.contractCaller.signTypedDataCall(typedData); }; - const postCancelDeltaOrderRequestV2: PostCancelDeltaOrderRequestV2 = async ( + const postCancelDeltaOrderRequest: PostCancelDeltaOrderRequest = async ( params, requestParams ) => { @@ -80,24 +80,24 @@ export const constructCancelDeltaOrderV2 = ( }); }; - const cancelDeltaOrdersV2: CancelDeltaOrderV2 = async ( + const cancelDeltaOrders: CancelDeltaOrder = async ( { orderIds }, requestParams ) => { - const signature = await signCancelDeltaOrderRequestV2( + const signature = await signCancelDeltaOrderRequest( { orderIds }, requestParams ); - return postCancelDeltaOrderRequestV2( + return postCancelDeltaOrderRequest( { orderIds, signature }, requestParams ); }; return { - signCancelDeltaOrderRequestV2, - postCancelDeltaOrderRequestV2, - cancelDeltaOrdersV2, + signCancelDeltaOrderRequest, + postCancelDeltaOrderRequest, + cancelDeltaOrders, }; }; diff --git a/src/methods/deltaV2/getAgentsListV2.ts b/src/methods/deltaV2/getAgentsList.ts similarity index 55% rename from src/methods/deltaV2/getAgentsListV2.ts rename to src/methods/deltaV2/getAgentsList.ts index 558457f06..39c6db8c5 100644 --- a/src/methods/deltaV2/getAgentsListV2.ts +++ b/src/methods/deltaV2/getAgentsList.ts @@ -3,26 +3,26 @@ import type { ConstructFetchInput, RequestParameters } from '../../types'; export type AgentList = string[]; -type AgentsListV2Response = AgentList; +type AgentsListResponse = AgentList; -type GetAgentsListV2 = ( +type GetAgentsList = ( requestParams?: RequestParameters ) => Promise; -export type GetAgentsListV2Functions = { +export type GetAgentsListFunctions = { /** @description List agents available on the current chain. */ - getAgentsListV2: GetAgentsListV2; + getAgentsList: GetAgentsList; }; -export const constructGetAgentsListV2 = ({ +export const constructGetAgentsList = ({ apiURL = API_URL, chainId, fetcher, -}: ConstructFetchInput): GetAgentsListV2Functions => { +}: ConstructFetchInput): GetAgentsListFunctions => { const baseUrl = `${apiURL}/delta/v2/agents/list/${chainId}` as const; - const getAgentsListV2: GetAgentsListV2 = async (requestParams) => { - const data = await fetcher({ + const getAgentsList: GetAgentsList = async (requestParams) => { + const data = await fetcher({ url: baseUrl, method: 'GET', requestParams, @@ -30,5 +30,5 @@ export const constructGetAgentsListV2 = ({ return data; }; - return { getAgentsListV2 }; + return { getAgentsList }; }; diff --git a/src/methods/deltaV2/getBridgeRoutes.ts b/src/methods/deltaV2/getBridgeRoutes.ts index 230164e02..6ae9f12f5 100644 --- a/src/methods/deltaV2/getBridgeRoutes.ts +++ b/src/methods/deltaV2/getBridgeRoutes.ts @@ -23,11 +23,11 @@ type GetBridgeRoutes = ( requestParams?: RequestParameters ) => Promise; -type GetBridgeProtocolsV2 = ( +type GetBridgeProtocols = ( requestParams?: RequestParameters ) => Promise; -type BridgeProtocolsV2Response = { +type BridgeProtocolsResponse = { bridgeProtocols: BridgeProtocolResponse[]; }; @@ -35,7 +35,7 @@ export type GetBridgeRoutesFunctions = { /** @description Fetch supported bridge routes as a flat array (v2 replacement for bridge-info). */ getBridgeRoutes: GetBridgeRoutes; /** @description Fetch supported bridge protocols (unchanged from v1). */ - getBridgeProtocolsV2: GetBridgeProtocolsV2; + getBridgeProtocols: GetBridgeProtocols; }; export const constructGetBridgeRoutes = ({ @@ -66,10 +66,10 @@ export const constructGetBridgeRoutes = ({ return data.routes; }; - const getBridgeProtocolsV2: GetBridgeProtocolsV2 = async (requestParams) => { + const getBridgeProtocols: GetBridgeProtocols = async (requestParams) => { const fetchURL = `${deltaPricesUrl}/bridge-protocols` as const; - const data = await fetcher({ + const data = await fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -78,5 +78,5 @@ export const constructGetBridgeRoutes = ({ return data.bridgeProtocols; }; - return { getBridgeRoutes, getBridgeProtocolsV2 }; + return { getBridgeRoutes, getBridgeProtocols }; }; diff --git a/src/methods/deltaV2/getDeltaOrdersV2.ts b/src/methods/deltaV2/getDeltaOrders.ts similarity index 64% rename from src/methods/deltaV2/getDeltaOrdersV2.ts rename to src/methods/deltaV2/getDeltaOrders.ts index e5522d2c6..10efb4914 100644 --- a/src/methods/deltaV2/getDeltaOrdersV2.ts +++ b/src/methods/deltaV2/getDeltaOrders.ts @@ -10,19 +10,19 @@ import type { DeltaOrderType, OnChainOrderType, } from '../delta/helpers/types'; -import type { DeltaOrderStatusV2, DeltaOrderV2Response } from './types'; +import type { DeltaOrderStatus, DeltaOrderResponse } from './types'; -type GetDeltaOrderByIdV2 = ( +type GetDeltaOrderById = ( orderId: string, requestParams?: RequestParameters -) => Promise; +) => Promise; -type GetDeltaOrderByHashV2 = ( +type GetDeltaOrderByHash = ( orderHash: string, requestParams?: RequestParameters -) => Promise; +) => Promise; -type OrdersV2Filter = { +type OrdersFilter = { /** @description `order.owner` to fetch Delta Orders for. */ userAddress: Address; /** @description Pagination option. Default 1. */ @@ -32,67 +32,67 @@ type OrdersV2Filter = { /** @description Filter by chainId. Omitted = orders across all chains. */ chainId?: number[]; /** @description Filter by integrator-facing status. */ - status?: DeltaOrderStatusV2[]; + status?: DeltaOrderStatus[]; /** @description Filter by order type. MARKET or LIMIT. */ type?: DeltaOrderType; /** @description Filter by on-chain order type. */ onChainOrderType?: OnChainOrderType; }; -type OrderFiltersV2Query = Omit & { +type OrderFiltersQuery = Omit & { chainId?: string; status?: string; }; -type GetDeltaOrdersV2 = ( - options: OrdersV2Filter, +type GetDeltaOrders = ( + options: OrdersFilter, requestParams?: RequestParameters -) => Promise>; +) => Promise>; -export type GetDeltaOrdersV2Functions = { +export type GetDeltaOrdersFunctions = { /** @description Fetch a single order by its UUID. */ - getDeltaOrderByIdV2: GetDeltaOrderByIdV2; + getDeltaOrderById: GetDeltaOrderById; /** @description Fetch a single order by its EIP-712 order hash. */ - getDeltaOrderByHashV2: GetDeltaOrderByHashV2; + getDeltaOrderByHash: GetDeltaOrderByHash; /** @description List Delta orders with the v2 pagination envelope. */ - getDeltaOrdersV2: GetDeltaOrdersV2; + getDeltaOrders: GetDeltaOrders; }; -export const constructGetDeltaOrdersV2 = ({ +export const constructGetDeltaOrders = ({ apiURL = API_URL, fetcher, -}: ConstructFetchInput): GetDeltaOrdersV2Functions => { +}: ConstructFetchInput): GetDeltaOrdersFunctions => { const baseUrl = `${apiURL}/delta/v2/orders` as const; - const getDeltaOrderByIdV2: GetDeltaOrderByIdV2 = async ( + const getDeltaOrderById: GetDeltaOrderById = async ( orderId, requestParams ) => { const fetchURL = `${baseUrl}/${orderId}` as const; - return fetcher({ + return fetcher({ url: fetchURL, method: 'GET', requestParams, }); }; - const getDeltaOrderByHashV2: GetDeltaOrderByHashV2 = async ( + const getDeltaOrderByHash: GetDeltaOrderByHash = async ( orderHash, requestParams ) => { const fetchURL = `${baseUrl}/hash/${orderHash}` as const; - return fetcher({ + return fetcher({ url: fetchURL, method: 'GET', requestParams, }); }; - const getDeltaOrdersV2: GetDeltaOrdersV2 = async (options, requestParams) => { + const getDeltaOrders: GetDeltaOrders = async (options, requestParams) => { const chainIdString = options.chainId?.join(','); const statusString = options.status?.join(','); - const search = constructSearchString({ + const search = constructSearchString({ userAddress: options.userAddress, page: options.page, limit: options.limit, @@ -104,7 +104,7 @@ export const constructGetDeltaOrdersV2 = ({ const fetchURL = `${baseUrl}${search}` as const; - return fetcher>({ + return fetcher>({ url: fetchURL, method: 'GET', requestParams, @@ -112,8 +112,8 @@ export const constructGetDeltaOrdersV2 = ({ }; return { - getDeltaOrderByIdV2, - getDeltaOrderByHashV2, - getDeltaOrdersV2, + getDeltaOrderById, + getDeltaOrderByHash, + getDeltaOrders, }; }; diff --git a/src/methods/deltaV2/getDeltaPriceV2.ts b/src/methods/deltaV2/getDeltaPrice.ts similarity index 79% rename from src/methods/deltaV2/getDeltaPriceV2.ts rename to src/methods/deltaV2/getDeltaPrice.ts index 89558cb52..6ca39cb6e 100644 --- a/src/methods/deltaV2/getDeltaPriceV2.ts +++ b/src/methods/deltaV2/getDeltaPrice.ts @@ -5,11 +5,11 @@ import type { EnumerateLiteral, RequestParameters, } from '../../types'; -import type { DeltaPriceV2 } from './types'; +import type { DeltaPrice } from './types'; type SwapSideUnion = EnumerateLiteral; -export type DeltaPriceV2Params = { +export type DeltaPriceParams = { /** @description Source Token Address */ srcToken: string; /** @description Destination Token Address. For Crosschain Orders, the destination token on the destination chain */ @@ -46,8 +46,8 @@ export type DeltaPriceV2Params = { degenMode?: boolean; }; -type DeltaPriceV2QueryOptions = Omit< - DeltaPriceV2Params, +type DeltaPriceQueryOptions = Omit< + DeltaPriceParams, 'includeAgents' | 'excludeAgents' | 'includeBridges' | 'excludeBridges' > & { chainId: number; @@ -57,24 +57,24 @@ type DeltaPriceV2QueryOptions = Omit< excludeBridges?: string; }; -type GetDeltaPriceV2 = ( - options: DeltaPriceV2Params, +type GetDeltaPrice = ( + options: DeltaPriceParams, requestParams?: RequestParameters -) => Promise; +) => Promise; -export type GetDeltaPriceV2Functions = { +export type GetDeltaPriceFunctions = { /** @description Fetch a v2 price quote (route-based response). */ - getDeltaPriceV2: GetDeltaPriceV2; + getDeltaPrice: GetDeltaPrice; }; -export const constructGetDeltaPriceV2 = ({ +export const constructGetDeltaPrice = ({ apiURL = API_URL, chainId, fetcher, -}: ConstructFetchInput): GetDeltaPriceV2Functions => { +}: ConstructFetchInput): GetDeltaPriceFunctions => { const pricesUrl = `${apiURL}/delta/v2/prices` as const; - const getDeltaPriceV2: GetDeltaPriceV2 = async (options, requestParams) => { + const getDeltaPrice: GetDeltaPrice = async (options, requestParams) => { const { includeAgents, excludeAgents, @@ -83,7 +83,7 @@ export const constructGetDeltaPriceV2 = ({ ...rest } = options; - const search = constructSearchString({ + const search = constructSearchString({ ...rest, chainId, side: options.side ?? SwapSide.SELL, @@ -95,7 +95,7 @@ export const constructGetDeltaPriceV2 = ({ const fetchURL = `${pricesUrl}${search}` as const; - const data = await fetcher({ + const data = await fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -104,5 +104,5 @@ export const constructGetDeltaPriceV2 = ({ return data; }; - return { getDeltaPriceV2 }; + return { getDeltaPrice }; }; diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 765382721..933c82b79 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -1,6 +1,21 @@ import type { ConstructProviderFetchInput } from '../../types'; import type { DeltaAuction, OnChainOrderMap } from '../delta/helpers/types'; +// Re-export public surface so `import * as DeltaV2` carries everything. +export * from './types'; +export * from './buildDeltaOrder'; +export * from './buildExternalDeltaOrder'; +export * from './buildTWAPDeltaOrder'; +export * from './postDeltaOrder'; +export * from './postExternalDeltaOrder'; +export * from './postTWAPDeltaOrder'; +export * from './getDeltaPrice'; +export * from './getDeltaOrders'; +export * from './getBridgeRoutes'; +export * from './isTokenSupportedInDelta'; +export * from './cancelDeltaOrder'; +export * from './getAgentsList'; + // reused v1 modules import { GetDeltaContractFunctions, @@ -33,112 +48,112 @@ import { // new v2 modules import { - BuildDeltaOrderV2Functions, - BuildDeltaOrderV2Params, - BuiltDeltaOrderV2, - constructBuildDeltaOrderV2, -} from './buildDeltaOrderV2'; + BuildDeltaOrderFunctions, + BuildDeltaOrderParams, + BuiltDeltaOrder, + constructBuildDeltaOrder, +} from './buildDeltaOrder'; import { - BuildExternalDeltaOrderV2Functions, - BuildExternalDeltaOrderV2Params, - constructBuildExternalDeltaOrderV2, -} from './buildExternalDeltaOrderV2'; + BuildExternalDeltaOrderFunctions, + BuildExternalDeltaOrderParams, + constructBuildExternalDeltaOrder, +} from './buildExternalDeltaOrder'; import { - BuildTWAPDeltaOrderV2Functions, - BuildTWAPDeltaOrderV2Params, - constructBuildTWAPDeltaOrderV2, -} from './buildTWAPDeltaOrderV2'; + BuildTWAPDeltaOrderFunctions, + BuildTWAPDeltaOrderParams, + constructBuildTWAPDeltaOrder, +} from './buildTWAPDeltaOrder'; import { - constructPostDeltaOrderV2, - DeltaOrderToPostV2, - PostDeltaOrderV2Functions, -} from './postDeltaOrderV2'; + constructPostDeltaOrder, + DeltaOrderToPost, + PostDeltaOrderFunctions, +} from './postDeltaOrder'; import { - constructPostExternalDeltaOrderV2, - PostExternalDeltaOrderV2Functions, -} from './postExternalDeltaOrderV2'; + constructPostExternalDeltaOrder, + PostExternalDeltaOrderFunctions, +} from './postExternalDeltaOrder'; import { - constructPostTWAPDeltaOrderV2, - PostTWAPDeltaOrderV2Functions, -} from './postTWAPDeltaOrderV2'; + constructPostTWAPDeltaOrder, + PostTWAPDeltaOrderFunctions, +} from './postTWAPDeltaOrder'; import { - constructGetDeltaPriceV2, - GetDeltaPriceV2Functions, -} from './getDeltaPriceV2'; + constructGetDeltaPrice, + GetDeltaPriceFunctions, +} from './getDeltaPrice'; import { - constructGetDeltaOrdersV2, - GetDeltaOrdersV2Functions, -} from './getDeltaOrdersV2'; + constructGetDeltaOrders, + GetDeltaOrdersFunctions, +} from './getDeltaOrders'; import { constructGetBridgeRoutes, GetBridgeRoutesFunctions, } from './getBridgeRoutes'; import { - constructIsTokenSupportedInDeltaV2, - IsTokenSupportedInDeltaV2Functions, -} from './isTokenSupportedInDeltaV2'; + constructIsTokenSupportedInDelta, + IsTokenSupportedInDeltaFunctions, +} from './isTokenSupportedInDelta'; import { - CancelDeltaOrderV2Functions, - constructCancelDeltaOrderV2, -} from './cancelDeltaOrderV2'; + CancelDeltaOrderFunctions, + constructCancelDeltaOrder, +} from './cancelDeltaOrder'; import { - constructGetAgentsListV2, - GetAgentsListV2Functions, -} from './getAgentsListV2'; + constructGetAgentsList, + GetAgentsListFunctions, +} from './getAgentsList'; // ── Sign v2 ───────────────────────────────────────────────────────────────── -type SignDeltaOrderV2 = (builtOrder: BuiltDeltaOrderV2) => Promise; +type SignDeltaOrder = (builtOrder: BuiltDeltaOrder) => Promise; -export type SignDeltaOrderV2Functions = { - /** @description Sign a BuiltDeltaOrderV2 (any order type) using EIP-712 typed data. */ - signDeltaOrderV2: SignDeltaOrderV2; +export type SignDeltaOrderFunctions = { + /** @description Sign a BuiltDeltaOrder (any order type) using EIP-712 typed data. */ + signDeltaOrder: SignDeltaOrder; }; -export const constructSignDeltaOrderV2 = ( +export const constructSignDeltaOrder = ( options: Pick< ConstructProviderFetchInput, 'contractCaller' > -): SignDeltaOrderV2Functions => { - const signDeltaOrderV2: SignDeltaOrderV2 = async (builtOrder) => { +): SignDeltaOrderFunctions => { + const signDeltaOrder: SignDeltaOrder = async (builtOrder) => { return options.contractCaller.signTypedDataCall({ types: builtOrder.toSign.types, domain: builtOrder.toSign.domain, data: builtOrder.toSign.value, }); }; - return { signDeltaOrderV2 }; + return { signDeltaOrder }; }; // ── Submit orchestrators ───────────────────────────────────────────────────── -export type SubmitDeltaOrderV2Params = BuildDeltaOrderV2Params & { +export type SubmitDeltaOrderParams = BuildDeltaOrderParams & { /** @description Referrer address */ referrerAddress?: string; degenMode?: boolean; -} & Pick; +} & Pick; -type SubmitDeltaOrderV2 = ( - orderParams: SubmitDeltaOrderV2Params +type SubmitDeltaOrder = ( + orderParams: SubmitDeltaOrderParams ) => Promise>; -export type SubmitDeltaOrderV2Funcs = { - submitDeltaOrderV2: SubmitDeltaOrderV2; +export type SubmitDeltaOrderFuncs = { + submitDeltaOrder: SubmitDeltaOrder; }; -export const constructSubmitDeltaOrderV2 = ( +export const constructSubmitDeltaOrder = ( options: ConstructProviderFetchInput -): SubmitDeltaOrderV2Funcs => { - const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2(options); - const { signDeltaOrderV2 } = constructSignDeltaOrderV2(options); - const { postDeltaOrderV2 } = constructPostDeltaOrderV2(options); +): SubmitDeltaOrderFuncs => { + const { buildDeltaOrder } = constructBuildDeltaOrder(options); + const { signDeltaOrder } = constructSignDeltaOrder(options); + const { postDeltaOrder } = constructPostDeltaOrder(options); - const submitDeltaOrderV2: SubmitDeltaOrderV2 = async (orderParams) => { - const orderData = await buildDeltaOrderV2(orderParams); - const signature = await signDeltaOrderV2(orderData); + const submitDeltaOrder: SubmitDeltaOrder = async (orderParams) => { + const orderData = await buildDeltaOrder(orderParams); + const signature = await signDeltaOrder(orderData); - return postDeltaOrderV2({ + return postDeltaOrder({ signature, partner: orderParams.partner, order: orderData.toSign.value as OnChainOrderMap['Order'], @@ -151,38 +166,37 @@ export const constructSubmitDeltaOrderV2 = ( }); }; - return { submitDeltaOrderV2 }; + return { submitDeltaOrder }; }; -export type SubmitExternalDeltaOrderV2Params = - BuildExternalDeltaOrderV2Params & { +export type SubmitExternalDeltaOrderParams = + BuildExternalDeltaOrderParams & { referrerAddress?: string; - } & Pick; + } & Pick; -type SubmitExternalDeltaOrderV2 = ( - orderParams: SubmitExternalDeltaOrderV2Params +type SubmitExternalDeltaOrder = ( + orderParams: SubmitExternalDeltaOrderParams ) => Promise>; -export type SubmitExternalDeltaOrderV2Funcs = { - submitExternalDeltaOrderV2: SubmitExternalDeltaOrderV2; +export type SubmitExternalDeltaOrderFuncs = { + submitExternalDeltaOrder: SubmitExternalDeltaOrder; }; -export const constructSubmitExternalDeltaOrderV2 = ( +export const constructSubmitExternalDeltaOrder = ( options: ConstructProviderFetchInput -): SubmitExternalDeltaOrderV2Funcs => { - const { buildExternalDeltaOrderV2 } = - constructBuildExternalDeltaOrderV2(options); - const { signDeltaOrderV2 } = constructSignDeltaOrderV2(options); - const { postExternalDeltaOrderV2 } = - constructPostExternalDeltaOrderV2(options); - - const submitExternalDeltaOrderV2: SubmitExternalDeltaOrderV2 = async ( +): SubmitExternalDeltaOrderFuncs => { + const { buildExternalDeltaOrder } = + constructBuildExternalDeltaOrder(options); + const { signDeltaOrder } = constructSignDeltaOrder(options); + const { postExternalDeltaOrder } = constructPostExternalDeltaOrder(options); + + const submitExternalDeltaOrder: SubmitExternalDeltaOrder = async ( orderParams ) => { - const orderData = await buildExternalDeltaOrderV2(orderParams); - const signature = await signDeltaOrderV2(orderData); + const orderData = await buildExternalDeltaOrder(orderParams); + const signature = await signDeltaOrder(orderData); - return postExternalDeltaOrderV2({ + return postExternalDeltaOrder({ signature, partner: orderParams.partner, order: orderData.toSign.value as OnChainOrderMap['ExternalOrder'], @@ -194,36 +208,36 @@ export const constructSubmitExternalDeltaOrderV2 = ( }); }; - return { submitExternalDeltaOrderV2 }; + return { submitExternalDeltaOrder }; }; -export type SubmitTWAPDeltaOrderV2Params = BuildTWAPDeltaOrderV2Params & { +export type SubmitTWAPDeltaOrderParams = BuildTWAPDeltaOrderParams & { referrerAddress?: string; degenMode?: boolean; -} & Pick; +} & Pick; -type SubmitTWAPDeltaOrderV2 = ( - orderParams: SubmitTWAPDeltaOrderV2Params +type SubmitTWAPDeltaOrder = ( + orderParams: SubmitTWAPDeltaOrderParams ) => Promise | DeltaAuction<'TWAPBuyOrder'>>; -export type SubmitTWAPDeltaOrderV2Funcs = { - submitTWAPDeltaOrderV2: SubmitTWAPDeltaOrderV2; +export type SubmitTWAPDeltaOrderFuncs = { + submitTWAPDeltaOrder: SubmitTWAPDeltaOrder; }; -export const constructSubmitTWAPDeltaOrderV2 = ( +export const constructSubmitTWAPDeltaOrder = ( options: ConstructProviderFetchInput -): SubmitTWAPDeltaOrderV2Funcs => { - const { buildTWAPDeltaOrderV2 } = constructBuildTWAPDeltaOrderV2(options); - const { signDeltaOrderV2 } = constructSignDeltaOrderV2(options); - const { postTWAPDeltaOrderV2 } = constructPostTWAPDeltaOrderV2(options); +): SubmitTWAPDeltaOrderFuncs => { + const { buildTWAPDeltaOrder } = constructBuildTWAPDeltaOrder(options); + const { signDeltaOrder } = constructSignDeltaOrder(options); + const { postTWAPDeltaOrder } = constructPostTWAPDeltaOrder(options); - const submitTWAPDeltaOrderV2: SubmitTWAPDeltaOrderV2 = async ( + const submitTWAPDeltaOrder: SubmitTWAPDeltaOrder = async ( orderParams ) => { - const orderData = await buildTWAPDeltaOrderV2(orderParams); - const signature = await signDeltaOrderV2(orderData); + const orderData = await buildTWAPDeltaOrder(orderParams); + const signature = await signDeltaOrder(orderData); - return postTWAPDeltaOrderV2({ + return postTWAPDeltaOrder({ signature, partner: orderParams.partner, order: orderData.toSign.value as @@ -239,65 +253,65 @@ export const constructSubmitTWAPDeltaOrderV2 = ( }); }; - return { submitTWAPDeltaOrderV2 }; + return { submitTWAPDeltaOrder }; }; // ── Handler bundle ─────────────────────────────────────────────────────────── -export type DeltaV2OrderHandlers = SubmitDeltaOrderV2Funcs & - SubmitExternalDeltaOrderV2Funcs & - SubmitTWAPDeltaOrderV2Funcs & - BuildDeltaOrderV2Functions & - BuildExternalDeltaOrderV2Functions & - BuildTWAPDeltaOrderV2Functions & - PostDeltaOrderV2Functions & - PostExternalDeltaOrderV2Functions & - PostTWAPDeltaOrderV2Functions & - SignDeltaOrderV2Functions & +export type DeltaOrderHandlers = SubmitDeltaOrderFuncs & + SubmitExternalDeltaOrderFuncs & + SubmitTWAPDeltaOrderFuncs & + BuildDeltaOrderFunctions & + BuildExternalDeltaOrderFunctions & + BuildTWAPDeltaOrderFunctions & + PostDeltaOrderFunctions & + PostExternalDeltaOrderFunctions & + PostTWAPDeltaOrderFunctions & + SignDeltaOrderFunctions & PreSignDeltaOrderFunctions & PreSignExternalDeltaOrderFunctions & PreSignTWAPDeltaOrderFunctions & - GetDeltaPriceV2Functions & - GetDeltaOrdersV2Functions & + GetDeltaPriceFunctions & + GetDeltaOrdersFunctions & GetBridgeRoutesFunctions & - IsTokenSupportedInDeltaV2Functions & - GetAgentsListV2Functions & + IsTokenSupportedInDeltaFunctions & + GetAgentsListFunctions & GetDeltaContractFunctions & GetPartnerFeeFunctions & ApproveTokenForDeltaFunctions & DeltaTokenModuleFunctions & - CancelDeltaOrderV2Functions; + CancelDeltaOrderFunctions; /** @description Construct an SDK bundle exposing every Delta v2 method (queries, build/sign/post, on-chain helpers). */ -export const constructAllDeltaV2OrdersHandlers = ( +export const constructAllDeltaOrdersHandlers = ( options: ConstructProviderFetchInput< TxResponse, 'signTypedDataCall' | 'transactCall' > -): DeltaV2OrderHandlers => { +): DeltaOrderHandlers => { return { - ...constructSubmitDeltaOrderV2(options), - ...constructSubmitExternalDeltaOrderV2(options), - ...constructSubmitTWAPDeltaOrderV2(options), - ...constructBuildDeltaOrderV2(options), - ...constructBuildExternalDeltaOrderV2(options), - ...constructBuildTWAPDeltaOrderV2(options), - ...constructPostDeltaOrderV2(options), - ...constructPostExternalDeltaOrderV2(options), - ...constructPostTWAPDeltaOrderV2(options), - ...constructSignDeltaOrderV2(options), + ...constructSubmitDeltaOrder(options), + ...constructSubmitExternalDeltaOrder(options), + ...constructSubmitTWAPDeltaOrder(options), + ...constructBuildDeltaOrder(options), + ...constructBuildExternalDeltaOrder(options), + ...constructBuildTWAPDeltaOrder(options), + ...constructPostDeltaOrder(options), + ...constructPostExternalDeltaOrder(options), + ...constructPostTWAPDeltaOrder(options), + ...constructSignDeltaOrder(options), ...constructPreSignDeltaOrder(options), ...constructPreSignExternalDeltaOrder(options), ...constructPreSignTWAPDeltaOrder(options), - ...constructGetDeltaPriceV2(options), - ...constructGetDeltaOrdersV2(options), + ...constructGetDeltaPrice(options), + ...constructGetDeltaOrders(options), ...constructGetBridgeRoutes(options), - ...constructIsTokenSupportedInDeltaV2(options), - ...constructGetAgentsListV2(options), + ...constructIsTokenSupportedInDelta(options), + ...constructGetAgentsList(options), ...constructGetDeltaContract(options), ...constructGetPartnerFee(options), ...constructApproveTokenForDelta(options), ...constructDeltaTokenModule(options), - ...constructCancelDeltaOrderV2(options), + ...constructCancelDeltaOrder(options), }; }; diff --git a/src/methods/deltaV2/isTokenSupportedInDeltaV2.ts b/src/methods/deltaV2/isTokenSupportedInDelta.ts similarity index 70% rename from src/methods/deltaV2/isTokenSupportedInDeltaV2.ts rename to src/methods/deltaV2/isTokenSupportedInDelta.ts index 9315abc10..ee14a94df 100644 --- a/src/methods/deltaV2/isTokenSupportedInDeltaV2.ts +++ b/src/methods/deltaV2/isTokenSupportedInDelta.ts @@ -12,23 +12,23 @@ type IsTokenSupportedQuery = { chainId: number; }; -type IsTokenSupportedInDeltaV2 = ( +type IsTokenSupportedInDelta = ( token: Address, requestParams?: RequestParameters ) => Promise; -export type IsTokenSupportedInDeltaV2Functions = { - isTokenSupportedInDeltaV2: IsTokenSupportedInDeltaV2; +export type IsTokenSupportedInDeltaFunctions = { + isTokenSupportedInDelta: IsTokenSupportedInDelta; }; -export const constructIsTokenSupportedInDeltaV2 = ({ +export const constructIsTokenSupportedInDelta = ({ apiURL = API_URL, chainId, fetcher, -}: ConstructFetchInput): IsTokenSupportedInDeltaV2Functions => { +}: ConstructFetchInput): IsTokenSupportedInDeltaFunctions => { const baseUrl = `${apiURL}/delta/v2/prices/is-token-supported` as const; - const isTokenSupportedInDeltaV2: IsTokenSupportedInDeltaV2 = async ( + const isTokenSupportedInDelta: IsTokenSupportedInDelta = async ( token, requestParams ) => { @@ -48,5 +48,5 @@ export const constructIsTokenSupportedInDeltaV2 = ({ return data.supported; }; - return { isTokenSupportedInDeltaV2 }; + return { isTokenSupportedInDelta }; }; diff --git a/src/methods/deltaV2/postDeltaOrderV2.ts b/src/methods/deltaV2/postDeltaOrder.ts similarity index 71% rename from src/methods/deltaV2/postDeltaOrderV2.ts rename to src/methods/deltaV2/postDeltaOrder.ts index 1cebf152c..01c941b1b 100644 --- a/src/methods/deltaV2/postDeltaOrderV2.ts +++ b/src/methods/deltaV2/postDeltaOrder.ts @@ -7,7 +7,7 @@ import type { OnChainOrderMap, } from '../delta/helpers/types'; -export type DeltaOrderToPostV2 = { +export type DeltaOrderToPost = { /** @description Partner string */ partner?: string; /** @description Referrer address */ @@ -24,29 +24,29 @@ export type DeltaOrderToPostV2 = { excludeAgents?: string[]; }; -export type PostDeltaOrderV2Params = Omit & { +export type PostDeltaOrderParams = Omit & { degenMode?: boolean; }; -type PostDeltaOrderV2 = ( - postData: PostDeltaOrderV2Params, +type PostDeltaOrder = ( + postData: PostDeltaOrderParams, requestParams?: RequestParameters ) => Promise>; -export type PostDeltaOrderV2Functions = { - postDeltaOrderV2: PostDeltaOrderV2; +export type PostDeltaOrderFunctions = { + postDeltaOrder: PostDeltaOrder; }; -export const constructPostDeltaOrderV2 = ({ +export const constructPostDeltaOrder = ({ apiURL = API_URL, chainId, fetcher, -}: ConstructFetchInput): PostDeltaOrderV2Functions => { +}: ConstructFetchInput): PostDeltaOrderFunctions => { const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - const postDeltaOrderV2: PostDeltaOrderV2 = (_postData, requestParams) => { + const postDeltaOrder: PostDeltaOrder = (_postData, requestParams) => { const { degenMode, ...postData } = _postData; - const deltaOrderToPost: DeltaOrderToPostV2 = { ...postData, chainId }; + const deltaOrderToPost: DeltaOrderToPost = { ...postData, chainId }; const search = constructSearchString<{ degenMode?: boolean }>({ degenMode, @@ -61,5 +61,5 @@ export const constructPostDeltaOrderV2 = ({ }); }; - return { postDeltaOrderV2 }; + return { postDeltaOrder }; }; diff --git a/src/methods/deltaV2/postExternalDeltaOrderV2.ts b/src/methods/deltaV2/postExternalDeltaOrder.ts similarity index 50% rename from src/methods/deltaV2/postExternalDeltaOrderV2.ts rename to src/methods/deltaV2/postExternalDeltaOrder.ts index 384183230..5657af53c 100644 --- a/src/methods/deltaV2/postExternalDeltaOrderV2.ts +++ b/src/methods/deltaV2/postExternalDeltaOrder.ts @@ -1,34 +1,34 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; import type { DeltaAuction } from '../delta/helpers/types'; -import type { DeltaOrderToPostV2 } from './postDeltaOrderV2'; +import type { DeltaOrderToPost } from './postDeltaOrder'; -export type PostExternalDeltaOrderV2Params = Omit< - DeltaOrderToPostV2<'ExternalOrder'>, +export type PostExternalDeltaOrderParams = Omit< + DeltaOrderToPost<'ExternalOrder'>, 'chainId' >; -type PostExternalDeltaOrderV2 = ( - postData: PostExternalDeltaOrderV2Params, +type PostExternalDeltaOrder = ( + postData: PostExternalDeltaOrderParams, requestParams?: RequestParameters ) => Promise>; -export type PostExternalDeltaOrderV2Functions = { - postExternalDeltaOrderV2: PostExternalDeltaOrderV2; +export type PostExternalDeltaOrderFunctions = { + postExternalDeltaOrder: PostExternalDeltaOrder; }; -export const constructPostExternalDeltaOrderV2 = ({ +export const constructPostExternalDeltaOrder = ({ apiURL = API_URL, chainId, fetcher, -}: ConstructFetchInput): PostExternalDeltaOrderV2Functions => { +}: ConstructFetchInput): PostExternalDeltaOrderFunctions => { const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - const postExternalDeltaOrderV2: PostExternalDeltaOrderV2 = ( + const postExternalDeltaOrder: PostExternalDeltaOrder = ( postData, requestParams ) => { - const deltaOrderToPost: DeltaOrderToPostV2<'ExternalOrder'> = { + const deltaOrderToPost: DeltaOrderToPost<'ExternalOrder'> = { ...postData, chainId, }; @@ -41,5 +41,5 @@ export const constructPostExternalDeltaOrderV2 = ({ }); }; - return { postExternalDeltaOrderV2 }; + return { postExternalDeltaOrder }; }; diff --git a/src/methods/deltaV2/postTWAPDeltaOrderV2.ts b/src/methods/deltaV2/postTWAPDeltaOrder.ts similarity index 65% rename from src/methods/deltaV2/postTWAPDeltaOrderV2.ts rename to src/methods/deltaV2/postTWAPDeltaOrder.ts index 62130ba02..71314b679 100644 --- a/src/methods/deltaV2/postTWAPDeltaOrderV2.ts +++ b/src/methods/deltaV2/postTWAPDeltaOrder.ts @@ -6,11 +6,11 @@ import type { DeltaAuction, TWAPOnChainOrderType, } from '../delta/helpers/types'; -import type { DeltaOrderToPostV2 } from './postDeltaOrderV2'; +import type { DeltaOrderToPost } from './postDeltaOrder'; -export type PostTWAPDeltaOrderV2Params = Prettify< +export type PostTWAPDeltaOrderParams = Prettify< Omit< - DeltaOrderToPostV2<'TWAPOrder'> | DeltaOrderToPostV2<'TWAPBuyOrder'>, + DeltaOrderToPost<'TWAPOrder'> | DeltaOrderToPost<'TWAPBuyOrder'>, 'chainId' > & { /** @description Must be "TWAPOrder" or "TWAPBuyOrder" */ @@ -19,28 +19,28 @@ export type PostTWAPDeltaOrderV2Params = Prettify< } >; -type PostTWAPDeltaOrderV2 = ( - postData: PostTWAPDeltaOrderV2Params, +type PostTWAPDeltaOrder = ( + postData: PostTWAPDeltaOrderParams, requestParams?: RequestParameters ) => Promise | DeltaAuction<'TWAPBuyOrder'>>; -export type PostTWAPDeltaOrderV2Functions = { - postTWAPDeltaOrderV2: PostTWAPDeltaOrderV2; +export type PostTWAPDeltaOrderFunctions = { + postTWAPDeltaOrder: PostTWAPDeltaOrder; }; -export const constructPostTWAPDeltaOrderV2 = ({ +export const constructPostTWAPDeltaOrder = ({ apiURL = API_URL, chainId, fetcher, -}: ConstructFetchInput): PostTWAPDeltaOrderV2Functions => { +}: ConstructFetchInput): PostTWAPDeltaOrderFunctions => { const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - const postTWAPDeltaOrderV2: PostTWAPDeltaOrderV2 = ( + const postTWAPDeltaOrder: PostTWAPDeltaOrder = ( _postData, requestParams ) => { const { degenMode, ...postData } = _postData; - const deltaOrderToPost: DeltaOrderToPostV2<'TWAPOrder' | 'TWAPBuyOrder'> = { + const deltaOrderToPost: DeltaOrderToPost<'TWAPOrder' | 'TWAPBuyOrder'> = { ...postData, chainId, }; @@ -59,5 +59,5 @@ export const constructPostTWAPDeltaOrderV2 = ({ }); }; - return { postTWAPDeltaOrderV2 }; + return { postTWAPDeltaOrder }; }; diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts index 768e498a7..aa4a068db 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/deltaV2/types.ts @@ -8,7 +8,7 @@ import type { } from '../delta/helpers/types'; /** @description Response from POST /delta/v2/orders/build — EIP-712 typed data ready to sign. */ -export type BuiltDeltaOrderV2 = { +export type BuiltDeltaOrder = { toSign: { domain: { name: string; @@ -85,7 +85,7 @@ export type DeltaRoute = { }; /** @description v2 price response: route-based, cross-chain first. */ -export type DeltaPriceV2 = { +export type DeltaPrice = { /** @description Unique request ID for tracing. */ id: string; /** @description Order side. */ @@ -121,7 +121,7 @@ export type BridgeRoute = { /* ------------------------------------------------------------------ */ /** @description Integrator-facing order status returned by v2 order endpoints. */ -const DeltaOrderStatusV2Map = { +const DeltaOrderStatusMap = { Pending: 'PENDING', AwaitingSignature: 'AWAITING_SIGNATURE', Active: 'ACTIVE', @@ -135,8 +135,8 @@ const DeltaOrderStatusV2Map = { Refunded: 'REFUNDED', } as const; -export type DeltaOrderStatusV2 = - (typeof DeltaOrderStatusV2Map)[keyof typeof DeltaOrderStatusV2Map]; +export type DeltaOrderStatus = + (typeof DeltaOrderStatusMap)[keyof typeof DeltaOrderStatusMap]; /** @description `OnChainOrderType` plus the synthetic `FillableOrder` label, used when a Standard `Order` is `partiallyFillable`. */ export type DeltaOnChainOrderTypeReported = OnChainOrderType | 'FillableOrder'; @@ -156,7 +156,7 @@ export type DeltaTokenSide = }; /** @description A single transaction entry on a v2 order. */ -export type DeltaTransactionV2 = { +export type DeltaTransaction = { originTx: string; destinationTx: string | null; /** @description Filled percent of the slice (0–100). */ @@ -166,9 +166,9 @@ export type DeltaTransactionV2 = { }; /** @description Order shape returned by GET /v2/orders, /v2/orders/:id, /v2/orders/hash/:hash. */ -export type DeltaOrderV2Response = { +export type DeltaOrderResponse = { id: string; - status: DeltaOrderStatusV2; + status: DeltaOrderStatus; side: 'SELL' | 'BUY'; type: DeltaOrderType; onChainOrderType: DeltaOnChainOrderTypeReported | null; @@ -179,7 +179,7 @@ export type DeltaOrderV2Response = { orderHash: string | null; partner: string; order: DeltaOrderUnion; - transactions: DeltaTransactionV2[]; + transactions: DeltaTransaction[]; /** @description ISO datetime string. */ createdAt: string | null; /** @description ISO datetime string. */ diff --git a/src/sdk/full.ts b/src/sdk/full.ts index f0b4ecb57..e134ed757 100644 --- a/src/sdk/full.ts +++ b/src/sdk/full.ts @@ -13,8 +13,8 @@ import { DeltaOrderHandlers, } from '../methods/delta'; import { - constructAllDeltaV2OrdersHandlers, - DeltaV2OrderHandlers, + constructAllDeltaOrdersHandlers as constructAllDeltaV2OrdersHandlers, + DeltaOrderHandlers as DeltaV2OrderHandlers, } from '../methods/deltaV2'; import { constructGetQuote, diff --git a/src/sdk/simple.ts b/src/sdk/simple.ts index ca6b7b887..f05d81866 100644 --- a/src/sdk/simple.ts +++ b/src/sdk/simple.ts @@ -137,33 +137,33 @@ import { IsTokenSupportedInDeltaFunctions, } from '../methods/delta/isTokenSupportedInDelta'; import { - constructAllDeltaV2OrdersHandlers, - DeltaV2OrderHandlers, + constructAllDeltaOrdersHandlers as constructAllDeltaV2OrdersHandlers, + DeltaOrderHandlers as DeltaV2OrderHandlers, } from '../methods/deltaV2'; import { - BuildDeltaOrderV2Functions, - constructBuildDeltaOrderV2, -} from '../methods/deltaV2/buildDeltaOrderV2'; + BuildDeltaOrderFunctions as BuildDeltaOrderV2Functions, + constructBuildDeltaOrder as constructBuildDeltaOrderV2, +} from '../methods/deltaV2/buildDeltaOrder'; import { - constructPostDeltaOrderV2, - PostDeltaOrderV2Functions, -} from '../methods/deltaV2/postDeltaOrderV2'; + constructPostDeltaOrder as constructPostDeltaOrderV2, + PostDeltaOrderFunctions as PostDeltaOrderV2Functions, +} from '../methods/deltaV2/postDeltaOrder'; import { - constructGetDeltaOrdersV2, - GetDeltaOrdersV2Functions, -} from '../methods/deltaV2/getDeltaOrdersV2'; + constructGetDeltaOrders as constructGetDeltaOrdersV2, + GetDeltaOrdersFunctions as GetDeltaOrdersV2Functions, +} from '../methods/deltaV2/getDeltaOrders'; import { - constructGetDeltaPriceV2, - GetDeltaPriceV2Functions, -} from '../methods/deltaV2/getDeltaPriceV2'; + constructGetDeltaPrice as constructGetDeltaPriceV2, + GetDeltaPriceFunctions as GetDeltaPriceV2Functions, +} from '../methods/deltaV2/getDeltaPrice'; import { constructGetBridgeRoutes, GetBridgeRoutesFunctions, } from '../methods/deltaV2/getBridgeRoutes'; import { - constructIsTokenSupportedInDeltaV2, - IsTokenSupportedInDeltaV2Functions, -} from '../methods/deltaV2/isTokenSupportedInDeltaV2'; + constructIsTokenSupportedInDelta as constructIsTokenSupportedInDeltaV2, + IsTokenSupportedInDeltaFunctions as IsTokenSupportedInDeltaV2Functions, +} from '../methods/deltaV2/isTokenSupportedInDelta'; export type SwapFetchMethods = GetBalancesFunctions & GetTokensFunctions & diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts index 8c89ba547..c1c16f7f9 100644 --- a/tests/deltaV2.test.ts +++ b/tests/deltaV2.test.ts @@ -3,32 +3,14 @@ import fetch from 'isomorphic-unfetch'; import { constructPartialSDK, constructFetchFetcher, - constructBuildDeltaOrderV2, - constructPostDeltaOrderV2, - constructGetDeltaOrdersV2, - constructGetDeltaPriceV2, constructGetDeltaContract, constructGetPartnerFee, - constructGetBridgeRoutes, - constructIsTokenSupportedInDeltaV2, - constructCancelDeltaOrderV2, - constructGetAgentsListV2, - constructBuildExternalDeltaOrderV2, - constructPostExternalDeltaOrderV2, - constructBuildTWAPDeltaOrderV2, - constructPostTWAPDeltaOrderV2, - constructAllDeltaV2OrdersHandlers, - constructSubmitDeltaOrderV2, - DeltaPriceV2, - DeltaRoute, + DeltaV2, PaginatedResponse, - BridgeRoute, FetcherFunction, - BuiltDeltaOrderV2, } from '../src'; import type { ContractCallerFunctions, TxHash } from '../src/types'; import type { DeltaAuction } from '../src/methods/delta/helpers/types'; -import type { DeltaOrderV2Response } from '../src/methods/deltaV2/types'; dotenv.config(); @@ -42,7 +24,9 @@ const FAKE_SIGNATURE = '0x' + 'ab'.repeat(64); type FetchSpy = jest.Mock, Parameters>; -function buildPriceV2Fixture(overrides: Partial = {}): DeltaPriceV2 { +function buildPriceFixture( + overrides: Partial = {} +): DeltaV2.DeltaPrice { const srcInput = { token: { chainId: 1, address: WETH }, amount: '1000000000000000000', @@ -54,7 +38,7 @@ function buildPriceV2Fixture(overrides: Partial = {}): DeltaPriceV amountUSD: '2950', }; - const route: DeltaRoute = { + const route: DeltaV2.DeltaRoute = { origin: { input: srcInput, output: destOutput }, destination: { input: destOutput, output: destOutput }, bridge: null, @@ -84,7 +68,7 @@ function buildPriceV2Fixture(overrides: Partial = {}): DeltaPriceV }; } -function buildCrosschainRoute(): DeltaRoute { +function buildCrosschainRoute(): DeltaV2.DeltaRoute { const srcInput = { token: { chainId: 1, address: WETH }, amount: '1000000000000000000', @@ -140,11 +124,11 @@ function buildCrosschainRoute(): DeltaRoute { }; } -/** Minimal BuiltDeltaOrderV2 fixture representing a server-built order. */ +/** Minimal BuiltDeltaOrder fixture representing a server-built order. */ function buildBuiltOrderFixture( value: Record = {}, orderHash = '0xdeadbeef1234' -): BuiltDeltaOrderV2 { +): DeltaV2.BuiltDeltaOrder { return { toSign: { domain: { @@ -223,8 +207,8 @@ function makeFetcher(handler: (params: any) => any): FetchSpy { } describe('Delta v2: fetch methods', () => { - test('getDeltaPriceV2 hits /delta/v2/prices and returns DeltaPriceV2', async () => { - const fixture = buildPriceV2Fixture(); + test('getDeltaPrice hits /delta/v2/prices and returns DeltaPrice', async () => { + const fixture = buildPriceFixture(); const fetcher = makeFetcher(({ url, method }) => { expect(method).toBe('GET'); expect(url.startsWith(`${API_URL}/delta/v2/prices?`)).toBe(true); @@ -236,13 +220,13 @@ describe('Delta v2: fetch methods', () => { return fixture; }); - const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ apiURL: API_URL, chainId: 1, fetcher, }); - const price = await getDeltaPriceV2({ + const price = await getDeltaPrice({ srcToken: WETH, destToken: DAI, amount: '1000000000000000000', @@ -256,8 +240,8 @@ describe('Delta v2: fetch methods', () => { expect(fetcher).toHaveBeenCalledTimes(1); }); - test('getDeltaPriceV2 passes destChainId for cross-chain', async () => { - const fixture = buildPriceV2Fixture({ + test('getDeltaPrice passes destChainId for cross-chain', async () => { + const fixture = buildPriceFixture({ route: buildCrosschainRoute(), outputToken: { chainId: 42161, address: USDC_ARB }, }); @@ -266,13 +250,13 @@ describe('Delta v2: fetch methods', () => { return fixture; }); - const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ apiURL: API_URL, chainId: 1, fetcher, }); - const price = await getDeltaPriceV2({ + const price = await getDeltaPrice({ srcToken: WETH, destToken: USDC_ARB, amount: '1000000000000000000', @@ -286,7 +270,7 @@ describe('Delta v2: fetch methods', () => { }); test('getBridgeRoutes hits /delta/v2/prices/bridge-routes and unwraps `routes`', async () => { - const routes: BridgeRoute[] = [ + const routes: DeltaV2.BridgeRoute[] = [ { srcChainId: 1, destChainId: 42161, tokens: [USDC_ARB] }, { srcChainId: 1, destChainId: 10, tokens: [DAI] }, ]; @@ -296,7 +280,7 @@ describe('Delta v2: fetch methods', () => { return { routes }; }); - const { getBridgeRoutes } = constructGetBridgeRoutes({ + const { getBridgeRoutes } = DeltaV2.constructGetBridgeRoutes({ apiURL: API_URL, chainId: 1, fetcher, @@ -312,7 +296,7 @@ describe('Delta v2: fetch methods', () => { return { routes: [] }; }); - const { getBridgeRoutes } = constructGetBridgeRoutes({ + const { getBridgeRoutes } = DeltaV2.constructGetBridgeRoutes({ apiURL: API_URL, chainId: 1, fetcher, @@ -324,7 +308,7 @@ describe('Delta v2: fetch methods', () => { }); }); - test('isTokenSupportedInDeltaV2 unwraps `supported`', async () => { + test('isTokenSupportedInDelta unwraps `supported`', async () => { const fetcher = makeFetcher(({ url, method }) => { expect(method).toBe('GET'); expect( @@ -335,18 +319,18 @@ describe('Delta v2: fetch methods', () => { return { supported: true }; }); - const { isTokenSupportedInDeltaV2 } = constructIsTokenSupportedInDeltaV2({ + const { isTokenSupportedInDelta } = DeltaV2.constructIsTokenSupportedInDelta({ apiURL: API_URL, chainId: 1, fetcher, }); - expect(await isTokenSupportedInDeltaV2(WETH)).toBe(true); + expect(await isTokenSupportedInDelta(WETH)).toBe(true); }); - test('getDeltaOrdersV2 returns the pagination envelope', async () => { - const order = { id: 'auction-1' } as unknown as DeltaOrderV2Response; - const envelope: PaginatedResponse = { + test('getDeltaOrders returns the pagination envelope', async () => { + const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaOrderResponse; + const envelope: PaginatedResponse = { data: [order], total: 1, page: 1, @@ -363,13 +347,13 @@ describe('Delta v2: fetch methods', () => { return envelope; }); - const { getDeltaOrdersV2 } = constructGetDeltaOrdersV2({ + const { getDeltaOrders } = DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher, }); - const result = await getDeltaOrdersV2({ + const result = await getDeltaOrders({ userAddress: OWNER, page: 2, limit: 10, @@ -380,22 +364,22 @@ describe('Delta v2: fetch methods', () => { expect(result.data).toHaveLength(1); }); - test('getDeltaOrdersV2 by id / by hash use the v2 path', async () => { - const order = { id: 'auction-1' } as unknown as DeltaOrderV2Response; + test('getDeltaOrders by id / by hash use the v2 path', async () => { + const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaOrderResponse; const fetcher = makeFetcher(({ url }) => { if (url === `${API_URL}/delta/v2/orders/auction-1`) return order; if (url === `${API_URL}/delta/v2/orders/hash/0xhash`) return order; throw new Error(`unexpected URL ${url}`); }); - const { getDeltaOrderByIdV2, getDeltaOrderByHashV2 } = - constructGetDeltaOrdersV2({ apiURL: API_URL, chainId: 1, fetcher }); + const { getDeltaOrderById, getDeltaOrderByHash } = + DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); - expect(await getDeltaOrderByIdV2('auction-1')).toBe(order); - expect(await getDeltaOrderByHashV2('0xhash')).toBe(order); + expect(await getDeltaOrderById('auction-1')).toBe(order); + expect(await getDeltaOrderByHash('0xhash')).toBe(order); }); - test('getAgentsListV2 hits /delta/v2/agents/list/:chainId and returns agent names', async () => { + test('getAgentsList hits /delta/v2/agents/list/:chainId and returns agent names', async () => { const agents = ['agent-a', 'agent-b']; const fetcher = makeFetcher(({ url, method }) => { expect(method).toBe('GET'); @@ -403,18 +387,18 @@ describe('Delta v2: fetch methods', () => { return agents; // server returns string[] directly }); - const { getAgentsListV2 } = constructGetAgentsListV2({ + const { getAgentsList } = DeltaV2.constructGetAgentsList({ apiURL: API_URL, chainId: 42161, fetcher, }); - expect(await getAgentsListV2()).toEqual(agents); + expect(await getAgentsList()).toEqual(agents); }); }); describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { - test('buildDeltaOrderV2 POSTs to /delta/v2/orders/build with correct body', async () => { + test('buildDeltaOrder POSTs to /delta/v2/orders/build with correct body', async () => { const builtFixture = buildBuiltOrderFixture(); let postedBody: any; @@ -425,14 +409,14 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { return builtFixture; }); - const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - const route = buildPriceV2Fixture().route; - const result = await buildDeltaOrderV2({ + const route = buildPriceFixture().route; + const result = await buildDeltaOrder({ owner: OWNER, route, side: 'SELL', @@ -448,7 +432,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { expect(postedBody.orderType).toBe('Order'); }); - test('buildDeltaOrderV2 passes slippage to server for SELL', async () => { + test('buildDeltaOrder passes slippage to server for SELL', async () => { const builtFixture = buildBuiltOrderFixture(); let postedBody: any; @@ -460,15 +444,15 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { throw new Error(`unexpected ${url}`); }); - const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - await buildDeltaOrderV2({ + await buildDeltaOrder({ owner: OWNER, - route: buildPriceV2Fixture().route, + route: buildPriceFixture().route, side: 'SELL', slippage: 100, partnerAddress: '0x0000000000000000000000000000000000000000', @@ -479,7 +463,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { expect(postedBody.side).toBe('SELL'); }); - test('buildDeltaOrderV2 passes slippage to server for BUY', async () => { + test('buildDeltaOrder passes slippage to server for BUY', async () => { const builtFixture = buildBuiltOrderFixture(); let postedBody: any; @@ -491,15 +475,15 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { throw new Error(`unexpected ${url}`); }); - const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - await buildDeltaOrderV2({ + await buildDeltaOrder({ owner: OWNER, - route: buildPriceV2Fixture().route, + route: buildPriceFixture().route, side: 'BUY', slippage: 100, partnerAddress: '0x0000000000000000000000000000000000000000', @@ -509,7 +493,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { expect(postedBody.side).toBe('BUY'); }); - test('buildDeltaOrderV2 passes cross-chain route as-is; server injects destinationChainId', async () => { + test('buildDeltaOrder passes cross-chain route as-is; server injects destinationChainId', async () => { const ccRoute = buildCrosschainRoute(); const builtFixture = buildBuiltOrderFixture({ srcToken: WETH, @@ -532,13 +516,13 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { throw new Error(`unexpected ${url}`); }); - const { buildDeltaOrderV2 } = constructBuildDeltaOrderV2({ + const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - const result = await buildDeltaOrderV2({ + const result = await buildDeltaOrder({ owner: OWNER, route: ccRoute, side: 'SELL', @@ -554,7 +538,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { }); }); - test('buildExternalDeltaOrderV2 sends orderType ExternalOrder with handler/data', async () => { + test('buildExternalDeltaOrder sends orderType ExternalOrder with handler/data', async () => { const builtFixture = buildBuiltOrderFixture(); let postedBody: any; @@ -566,14 +550,14 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { throw new Error(`unexpected ${url}`); }); - const { buildExternalDeltaOrderV2 } = constructBuildExternalDeltaOrderV2({ + const { buildExternalDeltaOrder } = DeltaV2.constructBuildExternalDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - const route = buildPriceV2Fixture().route; - await buildExternalDeltaOrderV2({ + const route = buildPriceFixture().route; + await buildExternalDeltaOrder({ owner: OWNER, handler: '0x2222222222222222222222222222222222222222', data: '0xdeadbeef', @@ -590,7 +574,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { expect(postedBody.route).toBe(route); }); - test('buildTWAPDeltaOrderV2 (sell) sends TWAPOrder body; slippage forwarded to server', async () => { + test('buildTWAPDeltaOrder (sell) sends TWAPOrder body; slippage forwarded to server', async () => { const builtFixture = buildBuiltOrderFixture(); let postedBody: any; @@ -602,14 +586,14 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { throw new Error(`unexpected ${url}`); }); - const { buildTWAPDeltaOrderV2 } = constructBuildTWAPDeltaOrderV2({ + const { buildTWAPDeltaOrder } = DeltaV2.constructBuildTWAPDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - const route = buildPriceV2Fixture().route; - await buildTWAPDeltaOrderV2({ + const route = buildPriceFixture().route; + await buildTWAPDeltaOrder({ owner: OWNER, onChainOrderType: 'TWAPOrder', route, @@ -628,7 +612,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { expect(postedBody.side).toBe('SELL'); }); - test('buildTWAPDeltaOrderV2 (buy) forwards slippage and maxSrcAmount to server', async () => { + test('buildTWAPDeltaOrder (buy) forwards slippage and maxSrcAmount to server', async () => { const builtFixture = buildBuiltOrderFixture(); let postedBody: any; @@ -640,14 +624,14 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { throw new Error(`unexpected ${url}`); }); - const { buildTWAPDeltaOrderV2 } = constructBuildTWAPDeltaOrderV2({ + const { buildTWAPDeltaOrder } = DeltaV2.constructBuildTWAPDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - const route = buildPriceV2Fixture().route; - await buildTWAPDeltaOrderV2({ + const route = buildPriceFixture().route; + await buildTWAPDeltaOrder({ owner: OWNER, onChainOrderType: 'TWAPBuyOrder', route, @@ -667,7 +651,7 @@ describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { }); describe('Delta v2: submit (build → sign → post)', () => { - test('submitDeltaOrderV2 posts to /delta/v2/orders with signed order', async () => { + test('submitDeltaOrder posts to /delta/v2/orders with signed order', async () => { const builtFixture = buildBuiltOrderFixture(); let posted: any; let postUrl = ''; @@ -688,16 +672,16 @@ describe('Delta v2: submit (build → sign → post)', () => { throw new Error(`unexpected request ${method} ${url}`); }); - const { submitDeltaOrderV2 } = constructSubmitDeltaOrderV2({ + const { submitDeltaOrder } = DeltaV2.constructSubmitDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, contractCaller: makeMockContractCaller(), }); - const response = await submitDeltaOrderV2({ + const response = await submitDeltaOrder({ owner: OWNER, - route: buildPriceV2Fixture().route, + route: buildPriceFixture().route, side: 'SELL', partnerAddress: '0x0000000000000000000000000000000000000000', }); @@ -712,46 +696,46 @@ describe('Delta v2: submit (build → sign → post)', () => { expect(response.id).toBe('auction-99'); }); - test('postDeltaOrderV2 forwards degenMode as a query param', async () => { + test('postDeltaOrder forwards degenMode as a query param', async () => { const fetcher = makeFetcher(({ url, method }) => { expect(method).toBe('POST'); expect(url).toContain('degenMode=true'); return { id: 'x' } as unknown as DeltaAuction<'Order'>; }); - const { postDeltaOrderV2 } = constructPostDeltaOrderV2({ + const { postDeltaOrder } = DeltaV2.constructPostDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - await postDeltaOrderV2({ + await postDeltaOrder({ signature: FAKE_SIGNATURE, order: {} as any, degenMode: true, }); }); - test('postExternalDeltaOrderV2 sends to /delta/v2/orders', async () => { + test('postExternalDeltaOrder sends to /delta/v2/orders', async () => { const fetcher = makeFetcher(({ url, method }) => { expect(method).toBe('POST'); expect(url).toBe(`${API_URL}/delta/v2/orders`); return { id: 'ext-1' } as unknown as DeltaAuction<'ExternalOrder'>; }); - const { postExternalDeltaOrderV2 } = constructPostExternalDeltaOrderV2({ + const { postExternalDeltaOrder } = DeltaV2.constructPostExternalDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - await postExternalDeltaOrderV2({ + await postExternalDeltaOrder({ signature: FAKE_SIGNATURE, order: {} as any, }); }); - test('postTWAPDeltaOrderV2 sends to /delta/v2/orders with onChainOrderType', async () => { + test('postTWAPDeltaOrder sends to /delta/v2/orders with onChainOrderType', async () => { const fetcher = makeFetcher(({ url, method, data }) => { expect(method).toBe('POST'); expect(url.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); @@ -759,13 +743,13 @@ describe('Delta v2: submit (build → sign → post)', () => { return { id: 'twap-1' } as unknown as DeltaAuction<'TWAPOrder'>; }); - const { postTWAPDeltaOrderV2 } = constructPostTWAPDeltaOrderV2({ + const { postTWAPDeltaOrder } = DeltaV2.constructPostTWAPDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, }); - await postTWAPDeltaOrderV2({ + await postTWAPDeltaOrder({ signature: FAKE_SIGNATURE, order: {} as any, onChainOrderType: 'TWAPOrder', @@ -774,7 +758,7 @@ describe('Delta v2: submit (build → sign → post)', () => { }); describe('Delta v2: cancel', () => { - test('cancelLimitDeltaOrdersV2 signs then posts to /delta/v2/orders/cancel', async () => { + test('cancelDeltaOrders signs then posts to /delta/v2/orders/cancel', async () => { let postedTo = ''; let postedBody: any; @@ -797,14 +781,14 @@ describe('Delta v2: cancel', () => { throw new Error('unexpected'); }); - const { cancelDeltaOrdersV2 } = constructCancelDeltaOrderV2({ + const { cancelDeltaOrders } = DeltaV2.constructCancelDeltaOrder({ apiURL: API_URL, chainId: 1, fetcher, contractCaller: makeMockContractCaller(), }); - const result = await cancelDeltaOrdersV2({ + const result = await cancelDeltaOrders({ orderIds: ['a', 'b'], }); @@ -821,14 +805,14 @@ describe('Delta v2: live API contract', () => { const LIVE_API = process.env.API_URL; const fetchFetcher = constructFetchFetcher(fetch); - test('GET /delta/v2/prices (same-chain) matches DeltaPriceV2 shape', async () => { - const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + test('GET /delta/v2/prices (same-chain) matches DeltaPrice shape', async () => { + const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ apiURL: LIVE_API, chainId: 1, fetcher: fetchFetcher, }); - const price = await getDeltaPriceV2({ + const price = await getDeltaPrice({ srcToken: WETH, destToken: DAI, amount: '1000000000000000000', @@ -853,13 +837,13 @@ describe('Delta v2: live API contract', () => { }); test('GET /delta/v2/prices (cross-chain) returns DeltaRoute with bridge.contractParams (no destinationChainId)', async () => { - const { getDeltaPriceV2 } = constructGetDeltaPriceV2({ + const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ apiURL: LIVE_API, chainId: 1, fetcher: fetchFetcher, }); - const price = await getDeltaPriceV2({ + const price = await getDeltaPrice({ srcToken: WETH, destToken: USDC_ARB, amount: '1000000000000000000', @@ -889,7 +873,7 @@ describe('Delta v2: live API contract', () => { }); test('GET /delta/v2/prices/bridge-routes returns flat array', async () => { - const { getBridgeRoutes } = constructGetBridgeRoutes({ + const { getBridgeRoutes } = DeltaV2.constructGetBridgeRoutes({ apiURL: LIVE_API, chainId: 1, fetcher: fetchFetcher, @@ -905,65 +889,65 @@ describe('Delta v2: live API contract', () => { }); test('GET /delta/v2/prices/bridge-protocols returns protocols', async () => { - const { getBridgeProtocolsV2 } = constructGetBridgeRoutes({ + const { getBridgeProtocols } = DeltaV2.constructGetBridgeRoutes({ apiURL: LIVE_API, chainId: 1, fetcher: fetchFetcher, }); - const protocols = await getBridgeProtocolsV2(); + const protocols = await getBridgeProtocols(); expect(protocols.length).toBeGreaterThan(0); expect(protocols.some((p) => p.protocol === 'Across')).toBe(true); }); }); describe('Delta v2: SDK wiring', () => { - test('constructAllDeltaV2OrdersHandlers exposes all v2 methods', () => { - const sdk = constructAllDeltaV2OrdersHandlers({ + test('constructAllDeltaOrdersHandlers exposes all v2 methods', () => { + const sdk = DeltaV2.constructAllDeltaOrdersHandlers({ apiURL: API_URL, chainId: 1, fetcher: makeFetcher(() => ({})), contractCaller: makeMockContractCaller(), }); - expect(typeof sdk.getDeltaPriceV2).toBe('function'); - expect(typeof sdk.getDeltaOrdersV2).toBe('function'); + expect(typeof sdk.getDeltaPrice).toBe('function'); + expect(typeof sdk.getDeltaOrders).toBe('function'); expect(typeof sdk.getBridgeRoutes).toBe('function'); - expect(typeof sdk.buildDeltaOrderV2).toBe('function'); - expect(typeof sdk.postDeltaOrderV2).toBe('function'); - expect(typeof sdk.submitDeltaOrderV2).toBe('function'); - expect(typeof sdk.submitExternalDeltaOrderV2).toBe('function'); - expect(typeof sdk.submitTWAPDeltaOrderV2).toBe('function'); - expect(typeof sdk.cancelDeltaOrdersV2).toBe('function'); - expect(typeof sdk.isTokenSupportedInDeltaV2).toBe('function'); - expect(typeof sdk.getAgentsListV2).toBe('function'); + expect(typeof sdk.buildDeltaOrder).toBe('function'); + expect(typeof sdk.postDeltaOrder).toBe('function'); + expect(typeof sdk.submitDeltaOrder).toBe('function'); + expect(typeof sdk.submitExternalDeltaOrder).toBe('function'); + expect(typeof sdk.submitTWAPDeltaOrder).toBe('function'); + expect(typeof sdk.cancelDeltaOrders).toBe('function'); + expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); + expect(typeof sdk.getAgentsList).toBe('function'); // reused v1 utilities expect(typeof sdk.getDeltaContract).toBe('function'); expect(typeof sdk.getPartnerFee).toBe('function'); expect(typeof sdk.approveTokenForDelta).toBe('function'); // v2 sign function (replaces v1 sign in deltaV2 namespace) - expect(typeof sdk.signDeltaOrderV2).toBe('function'); + expect(typeof sdk.signDeltaOrder).toBe('function'); }); test('constructPartialSDK accepts v2 constructors individually', () => { const fetcher = makeFetcher(() => ({})); const sdk = constructPartialSDK( { apiURL: API_URL, chainId: 1, fetcher }, - constructBuildDeltaOrderV2, - constructPostDeltaOrderV2, - constructGetDeltaOrdersV2, - constructGetDeltaPriceV2, + DeltaV2.constructBuildDeltaOrder, + DeltaV2.constructPostDeltaOrder, + DeltaV2.constructGetDeltaOrders, + DeltaV2.constructGetDeltaPrice, constructGetDeltaContract, constructGetPartnerFee, - constructGetBridgeRoutes, - constructIsTokenSupportedInDeltaV2 + DeltaV2.constructGetBridgeRoutes, + DeltaV2.constructIsTokenSupportedInDelta ); - expect(typeof sdk.getDeltaPriceV2).toBe('function'); + expect(typeof sdk.getDeltaPrice).toBe('function'); expect(typeof sdk.getBridgeRoutes).toBe('function'); - expect(typeof sdk.getDeltaOrdersV2).toBe('function'); - expect(typeof sdk.buildDeltaOrderV2).toBe('function'); - expect(typeof sdk.postDeltaOrderV2).toBe('function'); - expect(typeof sdk.isTokenSupportedInDeltaV2).toBe('function'); + expect(typeof sdk.getDeltaOrders).toBe('function'); + expect(typeof sdk.buildDeltaOrder).toBe('function'); + expect(typeof sdk.postDeltaOrder).toBe('function'); + expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); }); }); From 50e69bf666fc2ce032413ccd831b229ea4eff710 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv <102289654+andriy-shymkiv@users.noreply.github.com> Date: Thu, 28 May 2026 16:44:12 +0300 Subject: [PATCH 36/52] Update src/methods/delta/helpers/types.ts Co-authored-by: Velenir --- src/methods/delta/helpers/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index 2b8db2456..ff880b9e3 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -318,7 +318,7 @@ export type DeltaAuctionUnion = export type DeltaOrderUnion = OnChainOrderMap[keyof OnChainOrderMap]; export type BridgeMetadata = { - /** @description Fild is present after bridge is executed. + /** @description Field is present after bridge is executed. * The actual amount received from the bridge, which may differ * from the expectedOutputAmount due to bridge slippage or other factors. * */ From 494f747cb27ec3a9ae5615c850b89791796dfb88 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 17:04:40 +0300 Subject: [PATCH 37/52] constructSimpleSDK/simplify deltaV2 import --- src/sdk/simple.ts | 60 ++++++++++++++--------------------------------- 1 file changed, 17 insertions(+), 43 deletions(-) diff --git a/src/sdk/simple.ts b/src/sdk/simple.ts index f05d81866..3d8ecaea8 100644 --- a/src/sdk/simple.ts +++ b/src/sdk/simple.ts @@ -136,34 +136,8 @@ import { constructIsTokenSupportedInDelta, IsTokenSupportedInDeltaFunctions, } from '../methods/delta/isTokenSupportedInDelta'; -import { - constructAllDeltaOrdersHandlers as constructAllDeltaV2OrdersHandlers, - DeltaOrderHandlers as DeltaV2OrderHandlers, -} from '../methods/deltaV2'; -import { - BuildDeltaOrderFunctions as BuildDeltaOrderV2Functions, - constructBuildDeltaOrder as constructBuildDeltaOrderV2, -} from '../methods/deltaV2/buildDeltaOrder'; -import { - constructPostDeltaOrder as constructPostDeltaOrderV2, - PostDeltaOrderFunctions as PostDeltaOrderV2Functions, -} from '../methods/deltaV2/postDeltaOrder'; -import { - constructGetDeltaOrders as constructGetDeltaOrdersV2, - GetDeltaOrdersFunctions as GetDeltaOrdersV2Functions, -} from '../methods/deltaV2/getDeltaOrders'; -import { - constructGetDeltaPrice as constructGetDeltaPriceV2, - GetDeltaPriceFunctions as GetDeltaPriceV2Functions, -} from '../methods/deltaV2/getDeltaPrice'; -import { - constructGetBridgeRoutes, - GetBridgeRoutesFunctions, -} from '../methods/deltaV2/getBridgeRoutes'; -import { - constructIsTokenSupportedInDelta as constructIsTokenSupportedInDeltaV2, - IsTokenSupportedInDeltaFunctions as IsTokenSupportedInDeltaV2Functions, -} from '../methods/deltaV2/isTokenSupportedInDelta'; + +import * as DeltaV2 from '../methods/deltaV2'; export type SwapFetchMethods = GetBalancesFunctions & GetTokensFunctions & @@ -196,14 +170,14 @@ export type DeltaFetchMethods = BuildDeltaOrderFunctions & IsTokenSupportedInDeltaFunctions & PostDeltaOrderFunctions; -export type DeltaV2FetchMethods = BuildDeltaOrderV2Functions & - GetDeltaOrdersV2Functions & - GetDeltaPriceV2Functions & +export type DeltaV2FetchMethods = DeltaV2.BuildDeltaOrderFunctions & + DeltaV2.GetDeltaOrdersFunctions & + DeltaV2.GetDeltaPriceFunctions & GetDeltaContractFunctions & GetPartnerFeeFunctions & - GetBridgeRoutesFunctions & - IsTokenSupportedInDeltaV2Functions & - PostDeltaOrderV2Functions; + DeltaV2.GetBridgeRoutesFunctions & + DeltaV2.IsTokenSupportedInDeltaFunctions & + DeltaV2.PostDeltaOrderFunctions; export type SimpleFetchSDK = { swap: SwapFetchMethods; @@ -225,7 +199,7 @@ export type SimpleSDK = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; - deltaV2: DeltaV2OrderHandlers; + deltaV2: DeltaV2.DeltaOrderHandlers; quote: QuoteFetchMethods; } & Required; @@ -339,14 +313,14 @@ export function constructSimpleSDK( const deltaV2 = constructPartialSDK( config, - constructBuildDeltaOrderV2, - constructPostDeltaOrderV2, - constructGetDeltaOrdersV2, - constructGetDeltaPriceV2, + DeltaV2.constructBuildDeltaOrder, + DeltaV2.constructPostDeltaOrder, + DeltaV2.constructGetDeltaOrders, + DeltaV2.constructGetDeltaPrice, constructGetDeltaContract, constructGetPartnerFee, - constructGetBridgeRoutes, - constructIsTokenSupportedInDeltaV2 + DeltaV2.constructGetBridgeRoutes, + DeltaV2.constructIsTokenSupportedInDelta ); const quote = constructPartialSDK(config, constructGetQuote); @@ -385,8 +359,8 @@ export function constructSimpleSDK( const delta: DeltaOrderHandlers = constructAllDeltaOrdersHandlers(config); - const deltaV2: DeltaV2OrderHandlers = - constructAllDeltaV2OrdersHandlers(config); + const deltaV2: DeltaV2.DeltaOrderHandlers = + DeltaV2.constructAllDeltaOrdersHandlers(config); const quote = constructGetQuote(config); From 033b951195ff38f75577fb494377d91d1de4179a Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 17:05:36 +0300 Subject: [PATCH 38/52] update deltaV2 tests --- tests/deltaV2.test.ts | 44 +++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts index c1c16f7f9..794313692 100644 --- a/tests/deltaV2.test.ts +++ b/tests/deltaV2.test.ts @@ -302,10 +302,12 @@ describe('Delta v2: fetch methods', () => { fetcher, }); - await getBridgeRoutes({ - allowBridgeAndSwap: false, - bridges: ['Across', 'Relay'], - }); + expect( + await getBridgeRoutes({ + allowBridgeAndSwap: false, + bridges: ['Across', 'Relay'], + }) + ).toEqual([]); }); test('isTokenSupportedInDelta unwraps `supported`', async () => { @@ -709,11 +711,13 @@ describe('Delta v2: submit (build → sign → post)', () => { fetcher, }); - await postDeltaOrder({ - signature: FAKE_SIGNATURE, - order: {} as any, - degenMode: true, - }); + expect( + await postDeltaOrder({ + signature: FAKE_SIGNATURE, + order: {} as any, + degenMode: true, + }) + ).toEqual({ id: 'x' }); }); test('postExternalDeltaOrder sends to /delta/v2/orders', async () => { @@ -729,10 +733,12 @@ describe('Delta v2: submit (build → sign → post)', () => { fetcher, }); - await postExternalDeltaOrder({ - signature: FAKE_SIGNATURE, - order: {} as any, - }); + expect( + await postExternalDeltaOrder({ + signature: FAKE_SIGNATURE, + order: {} as any, + }) + ).toEqual({ id: 'ext-1' }); }); test('postTWAPDeltaOrder sends to /delta/v2/orders with onChainOrderType', async () => { @@ -749,11 +755,13 @@ describe('Delta v2: submit (build → sign → post)', () => { fetcher, }); - await postTWAPDeltaOrder({ - signature: FAKE_SIGNATURE, - order: {} as any, - onChainOrderType: 'TWAPOrder', - }); + expect( + await postTWAPDeltaOrder({ + signature: FAKE_SIGNATURE, + order: {} as any, + onChainOrderType: 'TWAPOrder', + }) + ).toEqual({ id: 'twap-1' }); }); }); From 34bb0d5e7dd5b1908a5457cf1a2aa6a30dd45bea Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 17:05:43 +0300 Subject: [PATCH 39/52] update claude.md --- CLAUDE.md | 81 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ff96c5785..bd5269a46 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -125,61 +125,84 @@ The first four families have four files each: `build*`, `sign*`, `post*`, `preSi ## Delta V2 Module (`src/methods/deltaV2/`) -Exposed as `sdk.deltaV2.*` on the full/simple SDK. Ships alongside v1 (non-breaking). All URLs use the `/delta/v2/...` prefix. +Exposed as `sdk.deltaV2.*` on the full/simple SDK, and as the **`DeltaV2` namespace** at the top of the package. Ships alongside v1 (non-breaking). All URLs use the `/delta/v2/...` prefix. + +### Public access pattern — the `DeltaV2` namespace + +`src/index.ts` re-exports the v2 surface as `export * as DeltaV2 from './methods/deltaV2'`. Inside the v2 folder, symbols use unsuffixed names (`constructBuildDeltaOrder`, `BuiltDeltaOrder`, `DeltaPrice`, …); consumers reach them as `DeltaV2.X`. This avoids top-level collisions with v1 (which also exports `DeltaPrice`, `constructBuildDeltaOrder`, etc.) while letting the v2 source live under the canonical names it will eventually inherit. + +```ts +import { DeltaV2 } from '@velora-dex/sdk'; + +// runtime: DeltaV2.constructBuildDeltaOrder, DeltaV2.constructAllDeltaOrdersHandlers, ... +// types: DeltaV2.DeltaPrice, DeltaV2.BuiltDeltaOrder, DeltaV2.DeltaRoute, ... +``` + +`import type { DeltaV2 } from '@velora-dex/sdk'` works the same way for type-only consumers (no runtime cost). Types live *inside* the namespace — destructuring at the import site (`const { DeltaPrice } = DeltaV2`) does not bring the type; alias via `type DeltaPrice = DeltaV2.DeltaPrice;` instead. + +The migration story (1) v1 bare + DeltaV2 namespace, (2) flip to v2 bare + DeltaV1 backcompat, (3) drop v1 — is documented inline in [src/index.ts](src/index.ts) above the `export * as DeltaV2` line. ### Key differences from v1 | Concern | v1 | v2 | |---------|----|----| -| Order building | Local EIP-712 computation | `POST /delta/v2/orders/build` → returns `BuiltDeltaOrderV2 { toSign, orderHash }` | -| Signing | Family-specific sign functions | Single `signDeltaOrderV2(builtOrder)` for all order types | -| Price response | `DeltaPrice` / `BridgePrice` overload | `DeltaPriceV2` with `route: DeltaRoute` and `alternatives: DeltaRoute[]` | -| Order list | Flat array | `PaginatedResponse` envelope | +| Order building | Local EIP-712 computation | `POST /delta/v2/orders/build` → returns `DeltaV2.BuiltDeltaOrder { toSign, orderHash }` | +| Signing | Family-specific sign functions | Single `signDeltaOrder(builtOrder)` for all order types | +| Price response | `DeltaPrice` / `BridgePrice` overload | `DeltaV2.DeltaPrice` with `route: DeltaRoute` and `alternatives: DeltaRoute[]` | +| Order list | Flat array | `PaginatedResponse` envelope | | Partner fee | Resolved locally via `getPartnerFee` | Passed as raw params to server (`partner`, `partnerAddress`, `partnerFeeBps`) | ### Order families Same three families as v1, all built via `POST /delta/v2/orders/build` with an `orderType` field: -| Family | `orderType` | Build params type | +| Family | `orderType` | Build params type (under `DeltaV2.*`) | |--------|-------------|-------------------| -| Standard | `'Order'` | `BuildDeltaOrderV2Params` | -| External | `'ExternalOrder'` | `BuildExternalDeltaOrderV2Params` (adds `handler`, `data`) | -| TWAP Sell | `'TWAPOrder'` | `BuildTWAPSellDeltaOrderV2Params` | -| TWAP Buy | `'TWAPBuyOrder'` | `BuildTWAPBuyDeltaOrderV2Params` | +| Standard | `'Order'` | `BuildDeltaOrderParams` | +| External | `'ExternalOrder'` | `BuildExternalDeltaOrderParams` (adds `handler`, `data`) | +| TWAP Sell | `'TWAPOrder'` | `BuildTWAPSellDeltaOrderParams` | +| TWAP Buy | `'TWAPBuyOrder'` | `BuildTWAPBuyDeltaOrderParams` | ### Key files +Symbol names below are as they appear **inside** the v2 folder (no V2 suffix). Through the namespace they are `DeltaV2.constructBuildDeltaOrder`, etc. + | File | Constructor | Purpose | |------|-------------|---------| -| `index.ts` | `constructAllDeltaV2OrdersHandlers`, `constructSubmitDeltaOrderV2` etc. | Composite: orchestrates all v2 modules, defines `DeltaV2OrderHandlers`. Submit orchestrators wrap build→sign→post. | -| `buildDeltaOrderV2.ts` | `constructBuildDeltaOrderV2` | POST to `/v2/orders/build` → `BuiltDeltaOrderV2` | -| `buildExternalDeltaOrderV2.ts` | `constructBuildExternalDeltaOrderV2` | Same, `orderType: 'ExternalOrder'` | -| `buildTWAPDeltaOrderV2.ts` | `constructBuildTWAPDeltaOrderV2` | Same, `orderType: 'TWAPOrder'` or `'TWAPBuyOrder'` | -| `getDeltaPriceV2.ts` | `constructGetDeltaPriceV2` | GET `/v2/prices` → `DeltaPriceV2` | -| `getDeltaOrdersV2.ts` | `constructGetDeltaOrdersV2` | `getDeltaOrdersV2` (paginated list), `getDeltaOrderByIdV2`, `getDeltaOrderByHashV2` | -| `postDeltaOrderV2.ts` | `constructPostDeltaOrderV2` | POST `/v2/orders` → `DeltaAuction<'Order'>` | -| `cancelDeltaOrderV2.ts` | `constructCancelDeltaOrderV2` | `signCancelDeltaOrderRequestV2` → `postCancelDeltaOrderRequestV2` → `cancelDeltaOrdersV2` (orchestrator). POSTs to `/v2/orders/cancel`. | -| `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocolsV2` | -| `isTokenSupportedInDeltaV2.ts` | `constructIsTokenSupportedInDeltaV2` | GET `/v2/prices/is-token-supported` → `boolean` | -| `getAgentsListV2.ts` | `constructGetAgentsListV2` | GET `/v2/agents/list/:chainId` → `string[]` | - -On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDeltaContract` are **reused from v1** — no duplication. +| `index.ts` | `constructAllDeltaOrdersHandlers`, `constructSubmitDeltaOrder` etc. | Composite: orchestrates all v2 modules, defines `DeltaOrderHandlers`. Submit orchestrators wrap build→sign→post. Re-exports every leaf module so `import * as DeltaV2` carries the full surface. | +| `buildDeltaOrder.ts` | `constructBuildDeltaOrder` | POST to `/v2/orders/build` → `BuiltDeltaOrder` | +| `buildExternalDeltaOrder.ts` | `constructBuildExternalDeltaOrder` | Same, `orderType: 'ExternalOrder'` | +| `buildTWAPDeltaOrder.ts` | `constructBuildTWAPDeltaOrder` | Same, `orderType: 'TWAPOrder'` or `'TWAPBuyOrder'` | +| `getDeltaPrice.ts` | `constructGetDeltaPrice` | GET `/v2/prices` → `DeltaPrice` | +| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash` | +| `postDeltaOrder.ts` | `constructPostDeltaOrder` | POST `/v2/orders` → `DeltaAuction<'Order'>` | +| `cancelDeltaOrder.ts` | `constructCancelDeltaOrder` | `signCancelDeltaOrderRequest` → `postCancelDeltaOrderRequest` → `cancelDeltaOrders` (orchestrator). POSTs to `/v2/orders/cancel`. | +| `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocols` | +| `isTokenSupportedInDelta.ts` | `constructIsTokenSupportedInDelta` | GET `/v2/prices/is-token-supported` → `boolean` | +| `getAgentsList.ts` | `constructGetAgentsList` | GET `/v2/agents/list/:chainId` → `string[]` | + +On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDeltaContract` are **reused from v1** — no duplication. Inside the v2 folder they're imported from `../delta/*`. + +### SDK wiring (`sdk/full.ts`, `sdk/simple.ts`) + +Because v1 and v2 share unsuffixed names, the SDK assembly files import v2 either as a namespace (`import * as DeltaV2 from '../methods/deltaV2'`, used in `simple.ts`) or with local aliases that re-add the `V2` suffix (e.g., `constructAllDeltaOrdersHandlers as constructAllDeltaV2OrdersHandlers`, used in `full.ts`). Either form keeps the v1/v2 distinction visible in the wiring code. The pre-bound bag on `sdk.deltaV2.*` exposes methods under their unsuffixed names — `sdk.deltaV2.buildDeltaOrder()`, `sdk.deltaV2.postDeltaOrder()`, etc. ### V2 Types (`src/methods/deltaV2/types.ts`) -- `BuiltDeltaOrderV2` — server build response: `{ toSign: { domain, types, value }, orderHash }` -- `DeltaPriceV2` — v2 price response with `route: DeltaRoute` and `alternatives: DeltaRoute[]` +(Access via `DeltaV2.X` at the package boundary.) + +- `BuiltDeltaOrder` — server build response: `{ toSign: { domain, types, value }, orderHash }` +- `DeltaPrice` — v2 price response with `route: DeltaRoute` and `alternatives: DeltaRoute[]` - `DeltaRoute` / `DeltaRouteStep` / `DeltaRouteBridge` / `DeltaRouteBridgeContractParams` — route shape - `DeltaPriceToken` / `DeltaTokenAmount` — token identity and amount with USD value - `BridgeTag` — `'recommended' | 'fastest' | 'best-return'` - `BridgeRoute` — flat bridge route entry `{ srcChainId, destChainId, tokens }` -- `DeltaOrderV2Response` — order shape from v2 order endpoints (different from v1's `DeltaAuction`) -- `DeltaOrderStatusV2` — integrator-facing status enum values +- `DeltaOrderResponse` — order shape from v2 order endpoints (different from v1's `DeltaAuction`) +- `DeltaOrderStatus` — integrator-facing status enum values - `DeltaOnChainOrderTypeReported` — `OnChainOrderType | 'FillableOrder'` -- `DeltaTokenSide` / `DeltaTransactionV2` — order input/output and transaction entry types +- `DeltaTokenSide` / `DeltaTransaction` — order input/output and transaction entry types -`PaginatedResponse` lives in `src/types.ts` (shared). +`PaginatedResponse` lives in `src/types.ts` (shared, still exported bare from the top of the package). ### `OnChainOrderType` note From 1ae4fa66faaf02e16bd1819f11561202d5364951 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 17:05:50 +0300 Subject: [PATCH 40/52] add deltaV2 to readme --- README.md | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/README.md b/README.md index 4f4005fb5..4de8afa48 100644 --- a/README.md +++ b/README.md @@ -475,6 +475,130 @@ For **External Delta Orders** (orders that delegate token handling to an externa ------------ +### Delta V2 (server-built orders) + +Delta V2 ships alongside v1. It moves order construction to the server (`POST /delta/v2/orders/build`), returns route-based prices with same-chain and cross-chain alternatives in one response, and uses a single signer for every order family (standard, external, TWAP). The pre-bound bag is available as `simpleSDK.deltaV2.*`. The raw constructors and types live under the `DeltaV2` namespace at the package root. + +```ts +import { constructSimpleSDK, DeltaV2 } from '@velora-dex/sdk'; + +// types: DeltaV2.DeltaPrice, DeltaV2.DeltaRoute, DeltaV2.BuiltDeltaOrder, +// DeltaV2.DeltaOrderResponse, DeltaV2.BridgeRoute, ... +// values: DeltaV2.constructBuildDeltaOrder, DeltaV2.constructPostDeltaOrder, +// DeltaV2.constructAllDeltaOrdersHandlers, ... +``` + +#### Quick flow (simple SDK) + +```ts +const simpleSDK = constructSimpleSDK({ chainId: 1, axios }, { + ethersProviderOrSigner: signer, + EthersContract: ethers.Contract, + account, +}); + +const deltaPrice = await simpleSDK.deltaV2.getDeltaPrice({ + srcToken: Token1, + destToken: Token2, + amount, + srcDecimals: 18, + destDecimals: 18, + userAddress: account, + // destChainId: 42161, // for cross-chain — bridge details land in deltaPrice.route.bridge +}); + +// approve once (Permit1 / Permit2 also supported — see v1 flow above) +await simpleSDK.deltaV2.approveTokenForDelta(amount, Token1); + +// build → sign → post in one call +const deltaAuction = await simpleSDK.deltaV2.submitDeltaOrder({ + route: deltaPrice.route, // or any deltaPrice.alternatives[i] + side: deltaPrice.side, + owner: account, + slippage: 50, // 50 bps = 0.5% + // partner, partnerAddress, partnerFeeBps — passed through to the server +}); + +// status polling — v2 status COMPLETED already accounts for the dest-chain bridge +const isDone = (o: DeltaV2.DeltaOrderResponse) => o.status === 'COMPLETED'; +``` + +#### Manual flow (full control over signing) + +```ts +const built = await simpleSDK.deltaV2.buildDeltaOrder({ + route: deltaPrice.route, + side: deltaPrice.side, + owner: account, + slippage: 50, +}); + +// one signer for every v2 family (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) +const signature = await simpleSDK.deltaV2.signDeltaOrder(built); + +const deltaAuction = await simpleSDK.deltaV2.postDeltaOrder({ + order: built.toSign.value as Parameters< + typeof simpleSDK.deltaV2.postDeltaOrder + >[0]['order'], + signature, +}); +``` + +#### TWAP order + +A TWAP sell splits `totalSrcAmount` into `numSlices` equal slices executed `interval` seconds apart. Price is quoted for a single slice — the server multiplies amounts internally. + +```ts +const perSliceAmount = (BigInt(totalSrcAmount) / BigInt(numSlices)).toString(); + +const slicePrice = await simpleSDK.deltaV2.getDeltaPrice({ + srcToken: Token1, + destToken: Token2, + amount: perSliceAmount, + srcDecimals: 18, + destDecimals: 18, + userAddress: account, +}); + +await simpleSDK.deltaV2.approveTokenForDelta(totalSrcAmount, Token1); + +const twapAuction = await simpleSDK.deltaV2.submitTWAPDeltaOrder({ + onChainOrderType: 'TWAPOrder', // or 'TWAPBuyOrder' + route: slicePrice.route, + owner: account, + totalSrcAmount, + numSlices, + interval: 300, // seconds (min 60) + slippage: 50, +}); +``` + +#### Partial SDK with v2 + +For bundle-savvy code, pull only the v2 constructors you need. The `DeltaV2` namespace doubles as a runtime object, so it tree-shakes cleanly. + +```ts +import { + constructPartialSDK, + constructFetchFetcher, + DeltaV2, +} from '@velora-dex/sdk'; + +const sdk = constructPartialSDK( + { chainId: 1, fetcher: constructFetchFetcher(fetch) }, + DeltaV2.constructGetDeltaPrice, + DeltaV2.constructGetDeltaOrders, + DeltaV2.constructGetBridgeRoutes, +); + +const price = await sdk.getDeltaPrice({ /* ... */ }); +const orders = await sdk.getDeltaOrders({ userAddress: account, page: 1, limit: 50 }); +``` + +A complete v2 example (standard, external handler, TWAP, and order listing) is in [examples/deltaV2](./src/examples/deltaV2.ts). + +------------ + ### Market Swap handling #### A more detailed overview of the Trade Flow, Market variant. From c1f7ef4231cffa650ebf41cfe6dab9144c3b3685 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 17:12:35 +0300 Subject: [PATCH 41/52] BridgeRoute/better description --- src/methods/deltaV2/types.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts index aa4a068db..e0ac0af8b 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/deltaV2/types.ts @@ -108,7 +108,10 @@ export type DeltaPrice = { alternatives: DeltaRoute[]; }; -/** @description A flat bridge-routes entry returned by GET /delta/v2/prices/bridge-routes. (better version of v1 prices/bridge-info) */ +/** @description + * A flat bridge-routes entry returned by GET /delta/v2/prices/bridge-routes (better version of v1 prices/bridge-info). + * Can be used to populate bridge selection UIs and to validate that bridge is possible for a given src/dest pair before calling GET /delta/v2/prices. + * */ export type BridgeRoute = { srcChainId: number; destChainId: number; From da02444a33d82c3b66b0b8df740710aed218af85 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 17:12:50 +0300 Subject: [PATCH 42/52] add ProductiveDeltaOrder to readme --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 4de8afa48..e6a316b92 100644 --- a/README.md +++ b/README.md @@ -597,6 +597,22 @@ const orders = await sdk.getDeltaOrders({ userAddress: account, page: 1, limit: A complete v2 example (standard, external handler, TWAP, and order listing) is in [examples/deltaV2](./src/examples/deltaV2.ts). +#### Productive Orders (read-only) + +Alongside the four buildable families (`Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`), the SDK surfaces a fifth `onChainOrderType` — **`ProductiveOrder`** — through the read endpoints (`sdk.delta.getDeltaOrderById`, `sdk.deltaV2.getDeltaOrders`, etc.). Productive orders are produced and managed entirely by the server: there are deliberately **no `buildProductiveOrder`, `signProductiveOrder`, or `submitProductiveOrder` helpers**. The shape is wired through `OnChainOrderType`, `OnChainOrderMap`, and `DeltaAuctionUnion` (also exported individually as `DeltaAuctionProductive`) so that consumers iterating over an order list can type-narrow on `onChainOrderType === 'ProductiveOrder'` and read the order safely — productive orders carry no `OrderKind`, so the side is always `SELL`. + +```ts +import { OrderHelpers, type DeltaAuctionUnion } from '@velora-dex/sdk'; + +function describe(order: DeltaAuctionUnion) { + if (order.onChainOrderType === 'ProductiveOrder') { + // order: DeltaAuctionProductive — read-only, no SDK builder + return `productive: ${order.order.srcToken}`; + } + // ... handle Order / ExternalOrder / TWAPOrder / TWAPBuyOrder +} +``` + ------------ ### Market Swap handling From ca8f05e0a4657954029ab6cea21521ad81b76cb9 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Thu, 28 May 2026 19:35:05 +0300 Subject: [PATCH 43/52] deltaV2/getRequiredBalanceForDeltaOrders --- CLAUDE.md | 2 +- src/methods/deltaV2/getDeltaOrders.ts | 33 +++++++++++++++++++++ tests/deltaV2.test.ts | 41 +++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index bd5269a46..0cbb058b4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -174,7 +174,7 @@ Symbol names below are as they appear **inside** the v2 folder (no V2 suffix). T | `buildExternalDeltaOrder.ts` | `constructBuildExternalDeltaOrder` | Same, `orderType: 'ExternalOrder'` | | `buildTWAPDeltaOrder.ts` | `constructBuildTWAPDeltaOrder` | Same, `orderType: 'TWAPOrder'` or `'TWAPBuyOrder'` | | `getDeltaPrice.ts` | `constructGetDeltaPrice` | GET `/v2/prices` → `DeltaPrice` | -| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash` | +| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash`, `getRequiredBalanceForDeltaOrders` (mirrors v1's `getRequiredBalanceForDeltaLimitOrders` under `/delta/v2/orders/fillablebalance/...`) | | `postDeltaOrder.ts` | `constructPostDeltaOrder` | POST `/v2/orders` → `DeltaAuction<'Order'>` | | `cancelDeltaOrder.ts` | `constructCancelDeltaOrder` | `signCancelDeltaOrderRequest` → `postCancelDeltaOrderRequest` → `cancelDeltaOrders` (orchestrator). POSTs to `/v2/orders/cancel`. | | `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocols` | diff --git a/src/methods/deltaV2/getDeltaOrders.ts b/src/methods/deltaV2/getDeltaOrders.ts index 10efb4914..f30902cbc 100644 --- a/src/methods/deltaV2/getDeltaOrders.ts +++ b/src/methods/deltaV2/getDeltaOrders.ts @@ -49,6 +49,16 @@ type GetDeltaOrders = ( requestParams?: RequestParameters ) => Promise>; +type GetRequiredBalanceParams = { + userAddress: Address; + tokenAddress?: Address; +}; + +type GetRequiredBalance = ( + userParams: GetRequiredBalanceParams, + requestParams?: RequestParameters +) => Promise>; // token -> required balance across open Delta orders + export type GetDeltaOrdersFunctions = { /** @description Fetch a single order by its UUID. */ getDeltaOrderById: GetDeltaOrderById; @@ -56,11 +66,14 @@ export type GetDeltaOrdersFunctions = { getDeltaOrderByHash: GetDeltaOrderByHash; /** @description List Delta orders with the v2 pagination envelope. */ getDeltaOrders: GetDeltaOrders; + /** @description Required balance per token across the user's open Delta v2 orders. Pass `tokenAddress` to narrow the result to a single token. */ + getRequiredBalanceForDeltaOrders: GetRequiredBalance; }; export const constructGetDeltaOrders = ({ apiURL = API_URL, fetcher, + chainId, }: ConstructFetchInput): GetDeltaOrdersFunctions => { const baseUrl = `${apiURL}/delta/v2/orders` as const; @@ -111,9 +124,29 @@ export const constructGetDeltaOrders = ({ }); }; + const getRequiredBalanceForDeltaOrders: GetRequiredBalance = async ( + userParams, + requestParams + ) => { + const userURL = + `${baseUrl}/fillablebalance/${chainId}/${userParams.userAddress}` as const; + const fetchURL = userParams.tokenAddress + ? (`${userURL}/${userParams.tokenAddress}` as const) + : userURL; + + const response = await fetcher>({ + url: fetchURL, + method: 'GET', + requestParams, + }); + + return response; + }; + return { getDeltaOrderById, getDeltaOrderByHash, getDeltaOrders, + getRequiredBalanceForDeltaOrders, }; }; diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts index 794313692..100e94acf 100644 --- a/tests/deltaV2.test.ts +++ b/tests/deltaV2.test.ts @@ -381,6 +381,45 @@ describe('Delta v2: fetch methods', () => { expect(await getDeltaOrderByHash('0xhash')).toBe(order); }); + test('getRequiredBalanceForDeltaOrders hits /delta/v2/orders/fillablebalance/:chainId/:userAddress', async () => { + const required = { + [WETH]: '500000000000000000', + [DAI]: '1500000000000000000000', + }; + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url).toBe( + `${API_URL}/delta/v2/orders/fillablebalance/1/${OWNER}` + ); + return required; + }); + + const { getRequiredBalanceForDeltaOrders } = + DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); + + expect( + await getRequiredBalanceForDeltaOrders({ userAddress: OWNER }) + ).toEqual(required); + }); + + test('getRequiredBalanceForDeltaOrders narrows the URL when tokenAddress is passed', async () => { + const fetcher = makeFetcher(({ url }) => { + expect(url).toBe( + `${API_URL}/delta/v2/orders/fillablebalance/1/${OWNER}/${WETH}` + ); + return { [WETH]: '500000000000000000' }; + }); + + const { getRequiredBalanceForDeltaOrders } = + DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); + + const balance = await getRequiredBalanceForDeltaOrders({ + userAddress: OWNER, + tokenAddress: WETH, + }); + expect(balance[WETH]).toBe('500000000000000000'); + }); + test('getAgentsList hits /delta/v2/agents/list/:chainId and returns agent names', async () => { const agents = ['agent-a', 'agent-b']; const fetcher = makeFetcher(({ url, method }) => { @@ -920,6 +959,7 @@ describe('Delta v2: SDK wiring', () => { expect(typeof sdk.getDeltaPrice).toBe('function'); expect(typeof sdk.getDeltaOrders).toBe('function'); + expect(typeof sdk.getRequiredBalanceForDeltaOrders).toBe('function'); expect(typeof sdk.getBridgeRoutes).toBe('function'); expect(typeof sdk.buildDeltaOrder).toBe('function'); expect(typeof sdk.postDeltaOrder).toBe('function'); @@ -954,6 +994,7 @@ describe('Delta v2: SDK wiring', () => { expect(typeof sdk.getDeltaPrice).toBe('function'); expect(typeof sdk.getBridgeRoutes).toBe('function'); expect(typeof sdk.getDeltaOrders).toBe('function'); + expect(typeof sdk.getRequiredBalanceForDeltaOrders).toBe('function'); expect(typeof sdk.buildDeltaOrder).toBe('function'); expect(typeof sdk.postDeltaOrder).toBe('function'); expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); From b7f95468e97104f07ded623e413943d8a47426b1 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 29 May 2026 13:49:42 +0300 Subject: [PATCH 44/52] better DeltaAuction type for v2 + usage everywhere for v2 --- CLAUDE.md | 15 ++++---- README.md | 6 ++-- src/examples/helpers/deltaV2.ts | 4 +-- src/index.ts | 2 ++ src/methods/delta/helpers/types.ts | 4 +++ src/methods/deltaV2/getDeltaOrders.ts | 14 ++++---- src/methods/deltaV2/index.ts | 3 +- src/methods/deltaV2/postDeltaOrder.ts | 7 ++-- src/methods/deltaV2/postExternalDeltaOrder.ts | 2 +- src/methods/deltaV2/postTWAPDeltaOrder.ts | 6 ++-- src/methods/deltaV2/types.ts | 35 ++++++++++++------- tests/deltaV2.test.ts | 6 ++-- 12 files changed, 60 insertions(+), 44 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0cbb058b4..361ec8add 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,6 +86,8 @@ Four order families with build/sign/post/preSign constructors, plus a read-only | TWAP Buy | `'TWAPBuyOrder'` | `TWAPBuyDeltaOrder` | `buildTWAPDeltaOrder` | | Productive | `'ProductiveOrder'` | `ProductiveDeltaOrder` | _read-only_ — no SDK builder (server-produced) | +`'FillableOrder'` is also a key in `OnChainOrderMap`/`OnChainOrderType`, mapping to the same `DeltaAuctionOrder` shape as `'Order'`. It is not a separate buildable family — it's the `onChainOrderType` the server reports when a Standard order is `partiallyFillable`. Built/signed/posted exactly as a Standard `Order`; only surfaces (read-only) on the way back through the read paths. + The first four families have four files each: `build*`, `sign*`, `post*`, `preSign*`. High-level orchestrators (`constructSubmitDeltaOrder`, `constructSubmitExternalDeltaOrder`, `constructSubmitTWAPDeltaOrder`) in `index.ts` wrap build→sign→post. Productive orders surface only through the read paths (`getDeltaOrders*` / `getDeltaOrderById*` / `DeltaAuctionUnion`). ### Key Files @@ -109,7 +111,7 @@ The first four families have four files each: `build*`, `sign*`, `post*`, `preSi | `constants.ts` | — | `DEFAULT_BRIDGE` constant (all-zero values for same-chain orders) | — | — | ### Delta Helpers (`src/methods/delta/helpers/`) -- `types.ts` — `DeltaAuctionOrder`, `ExternalDeltaOrder`, `ProductiveDeltaOrder`, `TWAPDeltaOrder`, `TWAPBuyDeltaOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap` (covers all five families), `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType`, `DeltaOrderType` (`'MARKET' | 'LIMIT'`, shared by v1 & v2), `DeltaAuctionUnion` (= `DeltaAuctionDelta | DeltaAuctionExternal | DeltaAuctionTWAP | DeltaAuctionTWAPBuy | DeltaAuctionProductive`) +- `types.ts` — `DeltaAuctionOrder`, `ExternalDeltaOrder`, `ProductiveDeltaOrder`, `TWAPDeltaOrder`, `TWAPBuyDeltaOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap` (Standard/External/TWAP Sell/TWAP Buy/Productive families, plus the `FillableOrder` variant of Standard), `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType`, `DeltaOrderType` (`'MARKET' | 'LIMIT'`, shared by v1 & v2), `DeltaAuctionUnion` (= `DeltaAuctionDelta | DeltaAuctionFillable | DeltaAuctionExternal | DeltaAuctionTWAP | DeltaAuctionTWAPBuy | DeltaAuctionProductive`) - `buildDeltaOrderData.ts` — `buildDeltaSignableOrderData`, `produceDeltaOrderTypedData`, `SignableDeltaOrderData`, `BuildDeltaOrderDataInput`, `DELTA_DEFAULT_EXPIRY` - `buildCancelDeltaOrderData.ts` — `buildCancelDeltaOrderSignableData`, `SignableCancelDeltaOrderData`, `CancelDeltaOrderData` - `buildTWAPOrderData.ts` — `buildTWAPSignableOrderData`, `SignableTWAPOrderData`, `BuildTWAPOrderDataInput` @@ -149,7 +151,7 @@ The migration story (1) v1 bare + DeltaV2 namespace, (2) flip to v2 bare + Delta | Order building | Local EIP-712 computation | `POST /delta/v2/orders/build` → returns `DeltaV2.BuiltDeltaOrder { toSign, orderHash }` | | Signing | Family-specific sign functions | Single `signDeltaOrder(builtOrder)` for all order types | | Price response | `DeltaPrice` / `BridgePrice` overload | `DeltaV2.DeltaPrice` with `route: DeltaRoute` and `alternatives: DeltaRoute[]` | -| Order list | Flat array | `PaginatedResponse` envelope | +| Order list | Flat array | `PaginatedResponse` envelope | | Partner fee | Resolved locally via `getPartnerFee` | Passed as raw params to server (`partner`, `partnerAddress`, `partnerFeeBps`) | ### Order families @@ -174,8 +176,8 @@ Symbol names below are as they appear **inside** the v2 folder (no V2 suffix). T | `buildExternalDeltaOrder.ts` | `constructBuildExternalDeltaOrder` | Same, `orderType: 'ExternalOrder'` | | `buildTWAPDeltaOrder.ts` | `constructBuildTWAPDeltaOrder` | Same, `orderType: 'TWAPOrder'` or `'TWAPBuyOrder'` | | `getDeltaPrice.ts` | `constructGetDeltaPrice` | GET `/v2/prices` → `DeltaPrice` | -| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash`, `getRequiredBalanceForDeltaOrders` (mirrors v1's `getRequiredBalanceForDeltaLimitOrders` under `/delta/v2/orders/fillablebalance/...`) | -| `postDeltaOrder.ts` | `constructPostDeltaOrder` | POST `/v2/orders` → `DeltaAuction<'Order'>` | +| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash`, `getRequiredBalanceForDeltaOrders` (mirrors v1's `getRequiredBalanceForDeltaLimitOrders` under `/delta/v2/orders/fillablebalance/...`). Read endpoints return the v2 `DeltaAuction` (= `DeltaV2.DeltaAuction`). | +| `postDeltaOrder.ts` | `constructPostDeltaOrder` | POST `/v2/orders` → `DeltaAuction<'Order'>` (the v2 `DeltaV2.DeltaAuction`) | | `cancelDeltaOrder.ts` | `constructCancelDeltaOrder` | `signCancelDeltaOrderRequest` → `postCancelDeltaOrderRequest` → `cancelDeltaOrders` (orchestrator). POSTs to `/v2/orders/cancel`. | | `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocols` | | `isTokenSupportedInDelta.ts` | `constructIsTokenSupportedInDelta` | GET `/v2/prices/is-token-supported` → `boolean` | @@ -197,9 +199,8 @@ Because v1 and v2 share unsuffixed names, the SDK assembly files import v2 eithe - `DeltaPriceToken` / `DeltaTokenAmount` — token identity and amount with USD value - `BridgeTag` — `'recommended' | 'fastest' | 'best-return'` - `BridgeRoute` — flat bridge route entry `{ srcChainId, destChainId, tokens }` -- `DeltaOrderResponse` — order shape from v2 order endpoints (different from v1's `DeltaAuction`) +- `DeltaAuction` — the order shape returned by **every** v2 order method, both reads (`getDeltaOrders*` / `getDeltaOrderById*`) and posts (`postDeltaOrder` / `postExternalDeltaOrder` / `postTWAPDeltaOrder`). Generic over `onChainOrderType` exactly like v1's `DeltaAuction` (distributes over `OnChainOrderType`, narrowing `order` to `OnChainOrderMap[T]`), but with the v2 base fields (`status: DeltaOrderStatus`, `input`/`output: DeltaTokenSide`, flat `transactions`, etc.) instead of v1's. Reached as `DeltaV2.DeltaAuction` — a distinct type from the top-level v1 `DeltaAuction`; v2 method files import it from `./types`, never from `../delta`. - `DeltaOrderStatus` — integrator-facing status enum values -- `DeltaOnChainOrderTypeReported` — `OnChainOrderType | 'FillableOrder'` - `DeltaTokenSide` / `DeltaTransaction` — order input/output and transaction entry types `PaginatedResponse` lives in `src/types.ts` (shared, still exported bare from the top of the package). @@ -208,6 +209,8 @@ Because v1 and v2 share unsuffixed names, the SDK assembly files import v2 eithe `'ProductiveOrder'` is part of `OnChainOrderType` and `OnChainOrderMap` — `DeltaAuction<'ProductiveOrder'>` (also exported as `DeltaAuctionProductive`) resolves to `ProductiveDeltaOrder`. The type is wired through the public surface, but **no build/sign/post helpers** exist for productive orders yet (`constructSubmit*` / `construct(Build|Sign|Post)*` cover only `Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`). Productive orders are read-only from the SDK's perspective — produced and managed by the server. Sides are inferred as `SELL` (productive orders carry no `OrderKind`). +`'FillableOrder'` is likewise a member of `OnChainOrderType`/`OnChainOrderMap`, resolving (via `DeltaAuction<'FillableOrder'>`, also exported as `DeltaAuctionFillable` and included in `DeltaAuctionUnion`) to the same `DeltaAuctionOrder` shape as `'Order'`. It's the `onChainOrderType` the server reports for a `partiallyFillable` Standard order — there is no separate builder. Consumers narrowing a `DeltaAuction` (v1 or v2) should treat `onChainOrderType === 'FillableOrder'` the same as `'Order'`. + ## Checklist: Adding a New On-Chain Method 1. Add ABI to the module file (inline `as const`) diff --git a/README.md b/README.md index e6a316b92..00855b9c0 100644 --- a/README.md +++ b/README.md @@ -483,7 +483,7 @@ Delta V2 ships alongside v1. It moves order construction to the server (`POST /d import { constructSimpleSDK, DeltaV2 } from '@velora-dex/sdk'; // types: DeltaV2.DeltaPrice, DeltaV2.DeltaRoute, DeltaV2.BuiltDeltaOrder, -// DeltaV2.DeltaOrderResponse, DeltaV2.BridgeRoute, ... +// DeltaV2.DeltaAuction, DeltaV2.BridgeRoute, ... // values: DeltaV2.constructBuildDeltaOrder, DeltaV2.constructPostDeltaOrder, // DeltaV2.constructAllDeltaOrdersHandlers, ... ``` @@ -520,7 +520,7 @@ const deltaAuction = await simpleSDK.deltaV2.submitDeltaOrder({ }); // status polling — v2 status COMPLETED already accounts for the dest-chain bridge -const isDone = (o: DeltaV2.DeltaOrderResponse) => o.status === 'COMPLETED'; +const isDone = (o: DeltaV2.DeltaAuction) => o.status === 'COMPLETED'; ``` #### Manual flow (full control over signing) @@ -601,6 +601,8 @@ A complete v2 example (standard, external handler, TWAP, and order listing) is i Alongside the four buildable families (`Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`), the SDK surfaces a fifth `onChainOrderType` — **`ProductiveOrder`** — through the read endpoints (`sdk.delta.getDeltaOrderById`, `sdk.deltaV2.getDeltaOrders`, etc.). Productive orders are produced and managed entirely by the server: there are deliberately **no `buildProductiveOrder`, `signProductiveOrder`, or `submitProductiveOrder` helpers**. The shape is wired through `OnChainOrderType`, `OnChainOrderMap`, and `DeltaAuctionUnion` (also exported individually as `DeltaAuctionProductive`) so that consumers iterating over an order list can type-narrow on `onChainOrderType === 'ProductiveOrder'` and read the order safely — productive orders carry no `OrderKind`, so the side is always `SELL`. +`OnChainOrderType` additionally includes **`'FillableOrder'`**, which maps to the same shape as a Standard `'Order'` (`DeltaAuctionOrder`, also exported as `DeltaAuctionFillable` and part of `DeltaAuctionUnion`). It is not a separate buildable family — it's the `onChainOrderType` the server reports for a `partiallyFillable` Standard order, so treat it the same as `'Order'` when narrowing. + ```ts import { OrderHelpers, type DeltaAuctionUnion } from '@velora-dex/sdk'; diff --git a/src/examples/helpers/deltaV2.ts b/src/examples/helpers/deltaV2.ts index 227eca6c0..3b2bf6ba4 100644 --- a/src/examples/helpers/deltaV2.ts +++ b/src/examples/helpers/deltaV2.ts @@ -2,11 +2,11 @@ import { DeltaV2 } from '../..'; // v2 status COMPLETED already accounts for destChain bridge settlement // (crosschain orders sit in BRIDGING until the destChain leg is done). -function isCompletedDeltaV2Order(order: DeltaV2.DeltaOrderResponse) { +function isCompletedDeltaV2Order(order: DeltaV2.DeltaAuction) { return order.status === 'COMPLETED'; } -type GetDeltaOrderV2Fn = () => Promise; +type GetDeltaOrderV2Fn = () => Promise; function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderV2Fn) { const intervalId = setInterval(async () => { diff --git a/src/index.ts b/src/index.ts index a2076eaa5..69774fdab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -159,6 +159,7 @@ import type { DeltaAmountsBuySlippage, DeltaAmountsExplicit, DeltaAuctionDelta, + DeltaAuctionFillable, DeltaAuctionTWAP, DeltaAuctionTWAPBuy, DeltaAuctionExternal, @@ -488,6 +489,7 @@ export type { DeltaAuctionOrder, DeltaAuction, DeltaAuctionDelta, + DeltaAuctionFillable, DeltaAuctionTWAP, DeltaAuctionTWAPBuy, DeltaAuctionExternal, diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index ff880b9e3..da3075ce7 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -248,6 +248,7 @@ export type DeltaAuctionTransaction = { export type OnChainOrderMap = { Order: DeltaAuctionOrder; + FillableOrder: DeltaAuctionOrder; ExternalOrder: ExternalDeltaOrder; TWAPOrder: TWAPDeltaOrder; TWAPBuyOrder: TWAPBuyDeltaOrder; @@ -261,6 +262,7 @@ type BaseBridgeAuctionFields = Pick< type BridgeAuctionFiledsMap = { Order: BaseBridgeAuctionFields; + FillableOrder: BaseBridgeAuctionFields; ExternalOrder: BaseBridgeAuctionFields; TWAPOrder: Record; TWAPBuyOrder: Record; @@ -303,6 +305,7 @@ export type DeltaAuction = : never; export type DeltaAuctionDelta = DeltaAuction<'Order'>; +export type DeltaAuctionFillable = DeltaAuction<'FillableOrder'>; export type DeltaAuctionExternal = DeltaAuction<'ExternalOrder'>; export type DeltaAuctionTWAP = DeltaAuction<'TWAPOrder'>; export type DeltaAuctionTWAPBuy = DeltaAuction<'TWAPBuyOrder'>; @@ -310,6 +313,7 @@ export type DeltaAuctionProductive = DeltaAuction<'ProductiveOrder'>; export type DeltaAuctionUnion = | DeltaAuctionDelta + | DeltaAuctionFillable | DeltaAuctionExternal | DeltaAuctionTWAP | DeltaAuctionTWAPBuy diff --git a/src/methods/deltaV2/getDeltaOrders.ts b/src/methods/deltaV2/getDeltaOrders.ts index f30902cbc..653ae7352 100644 --- a/src/methods/deltaV2/getDeltaOrders.ts +++ b/src/methods/deltaV2/getDeltaOrders.ts @@ -10,17 +10,17 @@ import type { DeltaOrderType, OnChainOrderType, } from '../delta/helpers/types'; -import type { DeltaOrderStatus, DeltaOrderResponse } from './types'; +import type { DeltaOrderStatus, DeltaAuction } from './types'; type GetDeltaOrderById = ( orderId: string, requestParams?: RequestParameters -) => Promise; +) => Promise; type GetDeltaOrderByHash = ( orderHash: string, requestParams?: RequestParameters -) => Promise; +) => Promise; type OrdersFilter = { /** @description `order.owner` to fetch Delta Orders for. */ @@ -47,7 +47,7 @@ type OrderFiltersQuery = Omit & { type GetDeltaOrders = ( options: OrdersFilter, requestParams?: RequestParameters -) => Promise>; +) => Promise>; type GetRequiredBalanceParams = { userAddress: Address; @@ -82,7 +82,7 @@ export const constructGetDeltaOrders = ({ requestParams ) => { const fetchURL = `${baseUrl}/${orderId}` as const; - return fetcher({ + return fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -94,7 +94,7 @@ export const constructGetDeltaOrders = ({ requestParams ) => { const fetchURL = `${baseUrl}/hash/${orderHash}` as const; - return fetcher({ + return fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -117,7 +117,7 @@ export const constructGetDeltaOrders = ({ const fetchURL = `${baseUrl}${search}` as const; - return fetcher>({ + return fetcher>({ url: fetchURL, method: 'GET', requestParams, diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 933c82b79..74bc8ba5d 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -1,5 +1,6 @@ import type { ConstructProviderFetchInput } from '../../types'; -import type { DeltaAuction, OnChainOrderMap } from '../delta/helpers/types'; +import type { OnChainOrderMap } from '../delta/helpers/types'; +import type { DeltaAuction } from './types'; // Re-export public surface so `import * as DeltaV2` carries everything. export * from './types'; diff --git a/src/methods/deltaV2/postDeltaOrder.ts b/src/methods/deltaV2/postDeltaOrder.ts index 01c941b1b..e1e54f3f4 100644 --- a/src/methods/deltaV2/postDeltaOrder.ts +++ b/src/methods/deltaV2/postDeltaOrder.ts @@ -1,11 +1,8 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { - DeltaAuction, - DeltaOrderType, - OnChainOrderMap, -} from '../delta/helpers/types'; +import type { DeltaOrderType, OnChainOrderMap } from '../delta/helpers/types'; +import type { DeltaAuction } from './types'; export type DeltaOrderToPost = { /** @description Partner string */ diff --git a/src/methods/deltaV2/postExternalDeltaOrder.ts b/src/methods/deltaV2/postExternalDeltaOrder.ts index 5657af53c..90b4455cd 100644 --- a/src/methods/deltaV2/postExternalDeltaOrder.ts +++ b/src/methods/deltaV2/postExternalDeltaOrder.ts @@ -1,7 +1,7 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaAuction } from '../delta/helpers/types'; import type { DeltaOrderToPost } from './postDeltaOrder'; +import type { DeltaAuction } from './types'; export type PostExternalDeltaOrderParams = Omit< DeltaOrderToPost<'ExternalOrder'>, diff --git a/src/methods/deltaV2/postTWAPDeltaOrder.ts b/src/methods/deltaV2/postTWAPDeltaOrder.ts index 71314b679..10b106805 100644 --- a/src/methods/deltaV2/postTWAPDeltaOrder.ts +++ b/src/methods/deltaV2/postTWAPDeltaOrder.ts @@ -2,11 +2,9 @@ import type { Prettify } from 'ts-essentials'; import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { - DeltaAuction, - TWAPOnChainOrderType, -} from '../delta/helpers/types'; +import type { TWAPOnChainOrderType } from '../delta/helpers/types'; import type { DeltaOrderToPost } from './postDeltaOrder'; +import type { DeltaAuction } from './types'; export type PostTWAPDeltaOrderParams = Prettify< Omit< diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts index e0ac0af8b..0332ee1ae 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/deltaV2/types.ts @@ -1,9 +1,10 @@ +import type { Prettify } from 'ts-essentials'; import type { Address } from '../../types'; import type { TypedDataField } from '../common/orders/buildOrderData'; import type { Bridge, DeltaOrderType, - DeltaOrderUnion, + OnChainOrderMap, OnChainOrderType, } from '../delta/helpers/types'; @@ -120,7 +121,8 @@ export type BridgeRoute = { }; /* ------------------------------------------------------------------ */ -/* Orders v2 response shape (different from v1's DeltaAuction) */ +/* Orders v2 response shape: DeltaAuction, same generic shape as */ +/* v1's DeltaAuction but with v2 base fields. */ /* ------------------------------------------------------------------ */ /** @description Integrator-facing order status returned by v2 order endpoints. */ @@ -141,9 +143,6 @@ const DeltaOrderStatusMap = { export type DeltaOrderStatus = (typeof DeltaOrderStatusMap)[keyof typeof DeltaOrderStatusMap]; -/** @description `OnChainOrderType` plus the synthetic `FillableOrder` label, used when a Standard `Order` is `partiallyFillable`. */ -export type DeltaOnChainOrderTypeReported = OnChainOrderType | 'FillableOrder'; - /** @description Token side on an order. SELL provides an explicit `amount`; BUY provides expected/executed amounts. */ export type DeltaTokenSide = | { @@ -168,25 +167,35 @@ export type DeltaTransaction = { receivedAmount: string | null; }; -/** @description Order shape returned by GET /v2/orders, /v2/orders/:id, /v2/orders/hash/:hash. */ -export type DeltaOrderResponse = { +type DeltaAuctionBase = { id: string; status: DeltaOrderStatus; side: 'SELL' | 'BUY'; type: DeltaOrderType; - onChainOrderType: DeltaOnChainOrderTypeReported | null; input: DeltaTokenSide; output: DeltaTokenSide; owner: Address; beneficiary: Address; - orderHash: string | null; + orderHash: string; partner: string; - order: DeltaOrderUnion; transactions: DeltaTransaction[]; /** @description ISO datetime string. */ - createdAt: string | null; + createdAt: string; /** @description ISO datetime string. */ - updatedAt: string | null; + updatedAt: string; /** @description ISO datetime string. */ - expiresAt: string | null; + expiresAt: string; }; + +/** @description Order shape returned by GET /v2/orders, /v2/orders/:id, /v2/orders/hash/:hash. + * Generic over `onChainOrderType` like v1's `DeltaAuction`: the type distributes over the + * union so that `order` narrows to the matching family (`OnChainOrderMap[T]`). */ +export type DeltaAuction = + T extends T + ? Prettify< + DeltaAuctionBase & { + onChainOrderType: T; + order: OnChainOrderMap[T]; + } + > + : never; diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts index 100e94acf..442df95ea 100644 --- a/tests/deltaV2.test.ts +++ b/tests/deltaV2.test.ts @@ -331,8 +331,8 @@ describe('Delta v2: fetch methods', () => { }); test('getDeltaOrders returns the pagination envelope', async () => { - const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaOrderResponse; - const envelope: PaginatedResponse = { + const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaAuction; + const envelope: PaginatedResponse = { data: [order], total: 1, page: 1, @@ -367,7 +367,7 @@ describe('Delta v2: fetch methods', () => { }); test('getDeltaOrders by id / by hash use the v2 path', async () => { - const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaOrderResponse; + const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaAuction; const fetcher = makeFetcher(({ url }) => { if (url === `${API_URL}/delta/v2/orders/auction-1`) return order; if (url === `${API_URL}/delta/v2/orders/hash/0xhash`) return order; From e8e292fffff2528d5f484995bb76e541c6c13968 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 29 May 2026 14:05:11 +0300 Subject: [PATCH 45/52] run lint --- src/methods/delta/helpers/orders.ts | 6 ++-- src/methods/deltaV2/cancelDeltaOrder.ts | 5 +-- src/methods/deltaV2/getAgentsList.ts | 4 +-- src/methods/deltaV2/getDeltaOrders.ts | 5 +-- src/methods/deltaV2/index.ts | 44 +++++++++++------------ src/methods/deltaV2/postTWAPDeltaOrder.ts | 5 +-- 6 files changed, 27 insertions(+), 42 deletions(-) diff --git a/src/methods/delta/helpers/orders.ts b/src/methods/delta/helpers/orders.ts index 5c99bed85..f9cc026d8 100644 --- a/src/methods/delta/helpers/orders.ts +++ b/src/methods/delta/helpers/orders.ts @@ -450,7 +450,7 @@ type ExecutedDeltaAuctionProps = { * @description Checks whether an auction is fully executed. */ function isExecutedAuction< - T extends Pick, + T extends Pick >(auction: T): auction is T & ExecutedDeltaAuctionProps { if (auction.status !== 'EXECUTED') return false; @@ -486,7 +486,7 @@ type FailedDeltaAuctionProps = * @description Checks whether an auction is failed on source or destination chain. */ function isFailedAuction< - T extends Pick, + T extends Pick >(auction: T): auction is T & FailedDeltaAuctionProps { // already failed on srcChain, whether Order is crosschain or not if (failedAuctionStatusesSet.has(auction.status)) return true; @@ -551,7 +551,7 @@ function isPendingAuction>( * Orders in the middle of normal execution can also be considered partially executed if they have any transactions. */ function isPartiallyExecutedAuction< - T extends Pick, + T extends Pick >( auction: T ): auction is T & { transactions: NonEmptyArray } { diff --git a/src/methods/deltaV2/cancelDeltaOrder.ts b/src/methods/deltaV2/cancelDeltaOrder.ts index 1199a831a..babaf0534 100644 --- a/src/methods/deltaV2/cancelDeltaOrder.ts +++ b/src/methods/deltaV2/cancelDeltaOrder.ts @@ -89,10 +89,7 @@ export const constructCancelDeltaOrder = ( requestParams ); - return postCancelDeltaOrderRequest( - { orderIds, signature }, - requestParams - ); + return postCancelDeltaOrderRequest({ orderIds, signature }, requestParams); }; return { diff --git a/src/methods/deltaV2/getAgentsList.ts b/src/methods/deltaV2/getAgentsList.ts index 39c6db8c5..a18154e99 100644 --- a/src/methods/deltaV2/getAgentsList.ts +++ b/src/methods/deltaV2/getAgentsList.ts @@ -5,9 +5,7 @@ export type AgentList = string[]; type AgentsListResponse = AgentList; -type GetAgentsList = ( - requestParams?: RequestParameters -) => Promise; +type GetAgentsList = (requestParams?: RequestParameters) => Promise; export type GetAgentsListFunctions = { /** @description List agents available on the current chain. */ diff --git a/src/methods/deltaV2/getDeltaOrders.ts b/src/methods/deltaV2/getDeltaOrders.ts index 653ae7352..7e21a9513 100644 --- a/src/methods/deltaV2/getDeltaOrders.ts +++ b/src/methods/deltaV2/getDeltaOrders.ts @@ -6,10 +6,7 @@ import type { PaginatedResponse, RequestParameters, } from '../../types'; -import type { - DeltaOrderType, - OnChainOrderType, -} from '../delta/helpers/types'; +import type { DeltaOrderType, OnChainOrderType } from '../delta/helpers/types'; import type { DeltaOrderStatus, DeltaAuction } from './types'; type GetDeltaOrderById = ( diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 74bc8ba5d..94f0d5c24 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -2,21 +2,6 @@ import type { ConstructProviderFetchInput } from '../../types'; import type { OnChainOrderMap } from '../delta/helpers/types'; import type { DeltaAuction } from './types'; -// Re-export public surface so `import * as DeltaV2` carries everything. -export * from './types'; -export * from './buildDeltaOrder'; -export * from './buildExternalDeltaOrder'; -export * from './buildTWAPDeltaOrder'; -export * from './postDeltaOrder'; -export * from './postExternalDeltaOrder'; -export * from './postTWAPDeltaOrder'; -export * from './getDeltaPrice'; -export * from './getDeltaOrders'; -export * from './getBridgeRoutes'; -export * from './isTokenSupportedInDelta'; -export * from './cancelDeltaOrder'; -export * from './getAgentsList'; - // reused v1 modules import { GetDeltaContractFunctions, @@ -102,6 +87,21 @@ import { GetAgentsListFunctions, } from './getAgentsList'; +// Re-export public surface so `import * as DeltaV2` carries everything. +export * from './types'; +export * from './buildDeltaOrder'; +export * from './buildExternalDeltaOrder'; +export * from './buildTWAPDeltaOrder'; +export * from './postDeltaOrder'; +export * from './postExternalDeltaOrder'; +export * from './postTWAPDeltaOrder'; +export * from './getDeltaPrice'; +export * from './getDeltaOrders'; +export * from './getBridgeRoutes'; +export * from './isTokenSupportedInDelta'; +export * from './cancelDeltaOrder'; +export * from './getAgentsList'; + // ── Sign v2 ───────────────────────────────────────────────────────────────── type SignDeltaOrder = (builtOrder: BuiltDeltaOrder) => Promise; @@ -170,10 +170,9 @@ export const constructSubmitDeltaOrder = ( return { submitDeltaOrder }; }; -export type SubmitExternalDeltaOrderParams = - BuildExternalDeltaOrderParams & { - referrerAddress?: string; - } & Pick; +export type SubmitExternalDeltaOrderParams = BuildExternalDeltaOrderParams & { + referrerAddress?: string; +} & Pick; type SubmitExternalDeltaOrder = ( orderParams: SubmitExternalDeltaOrderParams @@ -186,8 +185,7 @@ export type SubmitExternalDeltaOrderFuncs = { export const constructSubmitExternalDeltaOrder = ( options: ConstructProviderFetchInput ): SubmitExternalDeltaOrderFuncs => { - const { buildExternalDeltaOrder } = - constructBuildExternalDeltaOrder(options); + const { buildExternalDeltaOrder } = constructBuildExternalDeltaOrder(options); const { signDeltaOrder } = constructSignDeltaOrder(options); const { postExternalDeltaOrder } = constructPostExternalDeltaOrder(options); @@ -232,9 +230,7 @@ export const constructSubmitTWAPDeltaOrder = ( const { signDeltaOrder } = constructSignDeltaOrder(options); const { postTWAPDeltaOrder } = constructPostTWAPDeltaOrder(options); - const submitTWAPDeltaOrder: SubmitTWAPDeltaOrder = async ( - orderParams - ) => { + const submitTWAPDeltaOrder: SubmitTWAPDeltaOrder = async (orderParams) => { const orderData = await buildTWAPDeltaOrder(orderParams); const signature = await signDeltaOrder(orderData); diff --git a/src/methods/deltaV2/postTWAPDeltaOrder.ts b/src/methods/deltaV2/postTWAPDeltaOrder.ts index 10b106805..7d950610a 100644 --- a/src/methods/deltaV2/postTWAPDeltaOrder.ts +++ b/src/methods/deltaV2/postTWAPDeltaOrder.ts @@ -33,10 +33,7 @@ export const constructPostTWAPDeltaOrder = ({ }: ConstructFetchInput): PostTWAPDeltaOrderFunctions => { const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - const postTWAPDeltaOrder: PostTWAPDeltaOrder = ( - _postData, - requestParams - ) => { + const postTWAPDeltaOrder: PostTWAPDeltaOrder = (_postData, requestParams) => { const { degenMode, ...postData } = _postData; const deltaOrderToPost: DeltaOrderToPost<'TWAPOrder' | 'TWAPBuyOrder'> = { ...postData, From bf28f4c068b82506a467498f302f15824d210ea3 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 29 May 2026 14:45:20 +0300 Subject: [PATCH 46/52] BuiltDeltaOrder/tighter type --- README.md | 4 +--- src/examples/deltaV2.ts | 8 ++------ src/methods/deltaV2/buildDeltaOrder.ts | 5 +++-- src/methods/deltaV2/buildExternalDeltaOrder.ts | 5 +++-- src/methods/deltaV2/buildTWAPDeltaOrder.ts | 7 ++++--- src/methods/deltaV2/index.ts | 9 +++------ src/methods/deltaV2/types.ts | 5 +++-- 7 files changed, 19 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 00855b9c0..b31733f05 100644 --- a/README.md +++ b/README.md @@ -537,9 +537,7 @@ const built = await simpleSDK.deltaV2.buildDeltaOrder({ const signature = await simpleSDK.deltaV2.signDeltaOrder(built); const deltaAuction = await simpleSDK.deltaV2.postDeltaOrder({ - order: built.toSign.value as Parameters< - typeof simpleSDK.deltaV2.postDeltaOrder - >[0]['order'], + order: built.toSign.value, signature, }); ``` diff --git a/src/examples/deltaV2.ts b/src/examples/deltaV2.ts index 3d03b7522..cf804ed89 100644 --- a/src/examples/deltaV2.ts +++ b/src/examples/deltaV2.ts @@ -100,9 +100,7 @@ async function manualDeltaV2Flow() { const deltaAuction = await deltaSDK.postDeltaOrder({ // partner: "..." // if available - order: builtOrder.toSign.value as Parameters< - typeof deltaSDK.postDeltaOrder - >[0]['order'], + order: builtOrder.toSign.value, signature, }); @@ -141,9 +139,7 @@ async function externalDeltaV2Flow() { const signature = await deltaSDK.signDeltaOrder(builtOrder); const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: builtOrder.toSign.value as Parameters< - typeof deltaSDK.postExternalDeltaOrder - >[0]['order'], + order: builtOrder.toSign.value, signature, }); diff --git a/src/methods/deltaV2/buildDeltaOrder.ts b/src/methods/deltaV2/buildDeltaOrder.ts index 14460cf5c..97f3f21a4 100644 --- a/src/methods/deltaV2/buildDeltaOrder.ts +++ b/src/methods/deltaV2/buildDeltaOrder.ts @@ -1,5 +1,6 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { DeltaAuctionOrder } from '../delta/helpers/types'; import type { BuiltDeltaOrder, DeltaRoute } from './types'; export type { BuiltDeltaOrder } from './types'; @@ -42,7 +43,7 @@ export type BuildDeltaOrderParams = { type BuildDeltaOrder = ( buildOrderParams: BuildDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type BuildDeltaOrderFunctions = { /** @description Build a Delta v2 order from a DeltaRoute via the server endpoint, ready to sign and post. */ @@ -56,7 +57,7 @@ export const constructBuildDeltaOrder = ( const buildUrl = `${apiURL}/delta/v2/orders/build` as const; const buildDeltaOrder: BuildDeltaOrder = async (params, requestParams) => - fetcher({ + fetcher>({ url: buildUrl, method: 'POST', data: { diff --git a/src/methods/deltaV2/buildExternalDeltaOrder.ts b/src/methods/deltaV2/buildExternalDeltaOrder.ts index b139355c0..db05c6b6e 100644 --- a/src/methods/deltaV2/buildExternalDeltaOrder.ts +++ b/src/methods/deltaV2/buildExternalDeltaOrder.ts @@ -1,5 +1,6 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { ExternalDeltaOrder } from '../delta/helpers/types'; import type { BuiltDeltaOrder, DeltaRoute } from './types'; export type { BuiltDeltaOrder } from './types'; @@ -46,7 +47,7 @@ export type BuildExternalDeltaOrderParams = { type BuildExternalDeltaOrder = ( buildOrderParams: BuildExternalDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type BuildExternalDeltaOrderFunctions = { /** @description Build a Delta v2 External Order from a DeltaRoute via the server endpoint, ready to sign and post. */ @@ -63,7 +64,7 @@ export const constructBuildExternalDeltaOrder = ( params, requestParams ) => - fetcher({ + fetcher>({ url: buildUrl, method: 'POST', data: { diff --git a/src/methods/deltaV2/buildTWAPDeltaOrder.ts b/src/methods/deltaV2/buildTWAPDeltaOrder.ts index 395746b16..453b0cc6a 100644 --- a/src/methods/deltaV2/buildTWAPDeltaOrder.ts +++ b/src/methods/deltaV2/buildTWAPDeltaOrder.ts @@ -1,5 +1,6 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; +import type { TWAPBuyDeltaOrder, TWAPDeltaOrder } from '../delta/helpers/types'; import type { BuiltDeltaOrder, DeltaRoute } from './types'; export type { BuiltDeltaOrder } from './types'; @@ -61,7 +62,7 @@ export type BuildTWAPDeltaOrderParams = type BuildTWAPDeltaOrder = ( buildOrderParams: BuildTWAPDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type BuildTWAPDeltaOrderFunctions = { /** @description Build a Delta v2 TWAP Order (sell or buy) from a DeltaRoute via the server endpoint, ready to sign and post. */ @@ -100,7 +101,7 @@ export const constructBuildTWAPDeltaOrder = ( }; if (params.onChainOrderType === 'TWAPOrder') { - return fetcher({ + return fetcher>({ url: buildUrl, method: 'POST', data: { @@ -113,7 +114,7 @@ export const constructBuildTWAPDeltaOrder = ( }); } - return fetcher({ + return fetcher>({ url: buildUrl, method: 'POST', data: { diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 94f0d5c24..296fff709 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -1,5 +1,4 @@ import type { ConstructProviderFetchInput } from '../../types'; -import type { OnChainOrderMap } from '../delta/helpers/types'; import type { DeltaAuction } from './types'; // reused v1 modules @@ -157,7 +156,7 @@ export const constructSubmitDeltaOrder = ( return postDeltaOrder({ signature, partner: orderParams.partner, - order: orderData.toSign.value as OnChainOrderMap['Order'], + order: orderData.toSign.value, partiallyFillable: orderParams.partiallyFillable, referrerAddress: orderParams.referrerAddress, type: orderParams.type, @@ -198,7 +197,7 @@ export const constructSubmitExternalDeltaOrder = ( return postExternalDeltaOrder({ signature, partner: orderParams.partner, - order: orderData.toSign.value as OnChainOrderMap['ExternalOrder'], + order: orderData.toSign.value, partiallyFillable: orderParams.partiallyFillable, referrerAddress: orderParams.referrerAddress, type: orderParams.type, @@ -237,9 +236,7 @@ export const constructSubmitTWAPDeltaOrder = ( return postTWAPDeltaOrder({ signature, partner: orderParams.partner, - order: orderData.toSign.value as - | OnChainOrderMap['TWAPOrder'] - | OnChainOrderMap['TWAPBuyOrder'], + order: orderData.toSign.value, onChainOrderType: orderParams.onChainOrderType, partiallyFillable: orderParams.partiallyFillable, referrerAddress: orderParams.referrerAddress, diff --git a/src/methods/deltaV2/types.ts b/src/methods/deltaV2/types.ts index 0332ee1ae..0f3980962 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/deltaV2/types.ts @@ -4,12 +4,13 @@ import type { TypedDataField } from '../common/orders/buildOrderData'; import type { Bridge, DeltaOrderType, + DeltaOrderUnion, OnChainOrderMap, OnChainOrderType, } from '../delta/helpers/types'; /** @description Response from POST /delta/v2/orders/build — EIP-712 typed data ready to sign. */ -export type BuiltDeltaOrder = { +export type BuiltDeltaOrder = { toSign: { domain: { name: string; @@ -20,7 +21,7 @@ export type BuiltDeltaOrder = { /** EIP-712 type definitions keyed by type name. */ types: Record; /** The on-chain order struct value to sign. */ - value: Record; + value: T; }; /** EIP-712 order hash. */ orderHash: string; From 072853b4ecb8e2d5c99e4f6686664971240da57c Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 29 May 2026 16:23:12 +0300 Subject: [PATCH 47/52] delta v2 order helpers --- CLAUDE.md | 15 ++ README.md | 16 ++ src/methods/deltaV2/helpers/orders.ts | 363 ++++++++++++++++++++++++++ src/methods/deltaV2/index.ts | 1 + 4 files changed, 395 insertions(+) create mode 100644 src/methods/deltaV2/helpers/orders.ts diff --git a/CLAUDE.md b/CLAUDE.md index 361ec8add..467f21d6c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -182,6 +182,7 @@ Symbol names below are as they appear **inside** the v2 folder (no V2 suffix). T | `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocols` | | `isTokenSupportedInDelta.ts` | `constructIsTokenSupportedInDelta` | GET `/v2/prices/is-token-supported` → `boolean` | | `getAgentsList.ts` | `constructGetAgentsList` | GET `/v2/agents/list/:chainId` → `string[]` | +| `helpers/orders.ts` | — (exports `OrderHelpers`) | v2 order/auction guards + getters. Reached as `DeltaV2.OrderHelpers`. See "V2 Helpers" below. | On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDeltaContract` are **reused from v1** — no duplication. Inside the v2 folder they're imported from `../delta/*`. @@ -205,6 +206,20 @@ Because v1 and v2 share unsuffixed names, the SDK assembly files import v2 eithe `PaginatedResponse` lives in `src/types.ts` (shared, still exported bare from the top of the package). +### V2 Helpers (`src/methods/deltaV2/helpers/orders.ts`) + +Exposed as `DeltaV2.OrderHelpers` — the v2 counterpart of v1's top-level `OrderHelpers`, with the same `{ checks, getters }` shape. Two distinct objects: top-level `OrderHelpers` (v1) and `DeltaV2.OrderHelpers` (v2). + +Because the on-chain order structs (`auction.order`) and the `onChainOrderType` union are **shared** between v1 and v2, the v2 file reuses v1's implementations directly for: +- **order-struct guards** — `isTWAPOrder`, `isTWAPSellOrder`, `isTWAPBuyOrder`, `isExternalOrder`, `isDeltaOrder`, `isProductiveOrder`, `isOrderCrosschain` +- **auction discriminant guards** — `isTWAPAuction`, `isTWAPSellAuction`, `isTWAPBuyAuction`, `isDeltaAuction`, `isExternalAuction`, `isProductiveAuction` +- **order-level getters** — `getOrderTokenAddresses`, `getSwapSideFromDeltaOrder`, `getSwapSideFromTwapOrderType`, `getExpectedTwapSrcAmount`, `getExpectedTwapDestAmount`, `getExpectedTwapOrderAmounts` + +What's **reimplemented for the v2 auction envelope** (v2's `status: DeltaOrderStatus`, `input`/`output: DeltaTokenSide`, flat `transactions: DeltaTransaction`, explicit `side`): +- **status / execution guards** — `isCompletedAuction` (v2's `COMPLETED`, replaces v1's `isExecutedAuction`/`EXECUTED`), `isFailedAuction` (`FAILED`/`EXPIRED`/`CANCELLED`/`REFUNDED`), `isCanceledAuction`, `isExpiredAuction`, `isPendingAuction` (`PENDING`/`AWAITING_SIGNATURE`/`ACTIVE`/`BRIDGING`), `isPartiallyExecutedAuction` +- **`isFillableAuction`** — new guard for `onChainOrderType === 'FillableOrder'` (treat alongside `isDeltaAuction`) +- **auction-level getters** — `getAuctionSwapSide` (just `auction.side`), `getAuctionSrcChainId`/`getAuctionDestChainId` (from `input`/`output.chainId`), `getAuctionTokenAddresses`, `getTransactionAmounts`, `getFilledPercent`, `getAuctionAmounts` (returns `{ expected, executed }` — note `executed`, matching the API, vs v1's `final`), and `getUnifiedDeltaOrderData` (returns the shared `UnifiedDeltaOrderData` shape). + ### `OnChainOrderType` note `'ProductiveOrder'` is part of `OnChainOrderType` and `OnChainOrderMap` — `DeltaAuction<'ProductiveOrder'>` (also exported as `DeltaAuctionProductive`) resolves to `ProductiveDeltaOrder`. The type is wired through the public surface, but **no build/sign/post helpers** exist for productive orders yet (`constructSubmit*` / `construct(Build|Sign|Post)*` cover only `Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`). Productive orders are read-only from the SDK's perspective — produced and managed by the server. Sides are inferred as `SELL` (productive orders carry no `OrderKind`). diff --git a/README.md b/README.md index b31733f05..dc2cac961 100644 --- a/README.md +++ b/README.md @@ -613,6 +613,22 @@ function describe(order: DeltaAuctionUnion) { } ``` +The top-level `OrderHelpers` (above) works with **v1** auctions. For **v2** auctions (`DeltaV2.DeltaAuction`, returned by `sdk.deltaV2.*` read/post methods) use `DeltaV2.OrderHelpers`, which has the same `{ checks, getters }` shape but reads the v2 auction envelope (`status: DeltaOrderStatus`, `input`/`output`, flat `transactions`, explicit `side`): + +```ts +import { DeltaV2 } from '@velora-dex/sdk'; + +const { checks, getters } = DeltaV2.OrderHelpers; + +if (checks.isCompletedAuction(auction)) { + const { expected, executed } = getters.getAuctionAmounts(auction); + // executed (not v1's `final`) — matches the API convention +} + +const unified = getters.getUnifiedDeltaOrderData(auction); +// { srcChainId, destChainId, srcToken, destToken, swapSide, filledPercent, amounts, ... } +``` + ------------ ### Market Swap handling diff --git a/src/methods/deltaV2/helpers/orders.ts b/src/methods/deltaV2/helpers/orders.ts new file mode 100644 index 000000000..e8b89def2 --- /dev/null +++ b/src/methods/deltaV2/helpers/orders.ts @@ -0,0 +1,363 @@ +import type { NonEmptyArray } from 'ts-essentials'; +import { OrderHelpers as DeltaV1OrderHelpers } from '../../delta/helpers/orders'; +import type { + SwapSideUnion, + UnifiedDeltaOrderData, +} from '../../delta/helpers/types'; +import type { + DeltaAuction, + DeltaOrderStatus, + DeltaTokenSide, + DeltaTransaction, +} from '../types'; + +/** + * v2 order helpers. + * + * The on-chain order structs (`auction.order`) are identical between v1 and v2 + * — they come from the same `OnChainOrderMap` — so every order-struct guard and + * order-level getter is reused directly from v1's `OrderHelpers`. Likewise the + * auction discriminant guards only look at `onChainOrderType` (same union in + * both versions), so those are reused too. + * + * What differs in v2 is the *auction* envelope: + * - `status` is the integrator-facing `DeltaOrderStatus` + * (PENDING/ACTIVE/COMPLETED/… — not v1's `DeltaAuctionStatus`), + * - amounts live on `input`/`output` (`DeltaTokenSide`) and `transactions` + * (`DeltaTransaction`) instead of v1's order/transaction shapes, + * - `side` is carried explicitly on the auction. + * + * Those pieces are reimplemented here against the v2 shapes. + */ + +const v1Checks = DeltaV1OrderHelpers.checks; +const v1Getters = DeltaV1OrderHelpers.getters; + +///// CHECKS ////// + +/** + * @description Checks whether an auction is fully executed (settled on every chain). + */ +function isCompletedAuction>( + auction: T +): auction is T & { status: 'COMPLETED' } { + return auction.status === 'COMPLETED'; +} + +const failedAuctionStatuses = [ + 'FAILED', + 'EXPIRED', + 'CANCELLED', + 'REFUNDED', +] as const; + +const failedAuctionStatusesSet = new Set( + failedAuctionStatuses +); + +/** + * @description Checks whether an auction is in a terminal failure state + * (failed, expired, cancelled, or refunded). + */ +function isFailedAuction>( + auction: T +): auction is T & { status: (typeof failedAuctionStatuses)[number] } { + return failedAuctionStatusesSet.has(auction.status); +} + +/** + * @description Checks whether an auction status is cancelled. + */ +function isCanceledAuction>( + auction: T +): auction is T & { status: 'CANCELLED' } { + return auction.status === 'CANCELLED'; +} + +/** + * @description Checks whether an auction status is expired. + */ +function isExpiredAuction>( + auction: T +): auction is T & { status: 'EXPIRED' } { + return auction.status === 'EXPIRED'; +} + +const pendingAuctionStatuses = [ + 'PENDING', + 'AWAITING_SIGNATURE', + 'ACTIVE', + 'BRIDGING', +] as const; + +const pendingAuctionStatusesSet = new Set( + pendingAuctionStatuses +); + +/** + * @description Checks whether an auction is still in flight (not yet settled + * and not failed): awaiting signature, pending, actively executing, or bridging. + */ +function isPendingAuction>( + auction: T +): auction is T & { status: (typeof pendingAuctionStatuses)[number] } { + return pendingAuctionStatusesSet.has(auction.status); +} + +/** + * @description Checks whether an auction is a Fillable auction. + * `FillableOrder` is the `onChainOrderType` the server reports for a + * `partiallyFillable` Standard order; it carries the same order struct as + * `Order`. Consumers that don't distinguish the two should treat + * `isDeltaAuction(a) || isFillableAuction(a)` as "is a standard order". + */ +function isFillableAuction>( + auction: T +): auction is T & { onChainOrderType: 'FillableOrder' } { + return auction.onChainOrderType === 'FillableOrder'; +} + +/** + * @description Checks whether an auction has been partially executed: + * it has at least one transaction and an overall filled percent strictly + * between 0 and 100. + */ +function isPartiallyExecutedAuction< + T extends Pick, +>( + auction: T +): auction is T & { transactions: NonEmptyArray } { + if (auction.transactions.length === 0) return false; + + const filledPercent = getFilledPercent(auction); + + return filledPercent > 0 && filledPercent < 100; +} + +const checks = { + // order-struct guards — order structs are shared with v1, reused as-is. + isTWAPOrder: v1Checks.isTWAPOrder, + isTWAPSellOrder: v1Checks.isTWAPSellOrder, + isTWAPBuyOrder: v1Checks.isTWAPBuyOrder, + isExternalOrder: v1Checks.isExternalOrder, + isDeltaOrder: v1Checks.isDeltaOrder, + isProductiveOrder: v1Checks.isProductiveOrder, + + // auction discriminant guards — `onChainOrderType` union is shared, reused as-is. + isTWAPAuction: v1Checks.isTWAPAuction, + isTWAPSellAuction: v1Checks.isTWAPSellAuction, + isTWAPBuyAuction: v1Checks.isTWAPBuyAuction, + isDeltaAuction: v1Checks.isDeltaAuction, + isExternalAuction: v1Checks.isExternalAuction, + isProductiveAuction: v1Checks.isProductiveAuction, + isFillableAuction, + + // status / execution guards — v2 status enum & transaction shape. + isCompletedAuction, + isFailedAuction, + isCanceledAuction, + isExpiredAuction, + isPendingAuction, + isPartiallyExecutedAuction, +}; + +///// GETTERS ////// + +/** + * @description Reads an amount off a v2 token side. A SELL input / BUY output + * carries an explicit `amount`; the opposite side carries + * `expectedAmount`/`executedAmount`. `prefer` chooses which to read on the + * expected/executed variant. + */ +function getTokenSideAmount( + side: DeltaTokenSide, + prefer: 'expected' | 'executed' +): string { + if ('amount' in side) return side.amount; + + const value = + prefer === 'executed' ? side.executedAmount : side.expectedAmount; + + return value ?? '0'; +} + +/** + * @description Returns the source chain id for the auction (the input side's chain). + */ +function getAuctionSrcChainId(auction: Pick): number { + return auction.input.chainId; +} + +/** + * @description Returns the destination chain id for the auction (the output side's chain). + * Equals the source chain id for same-chain orders. + */ +function getAuctionDestChainId(auction: Pick): number { + return auction.output.chainId; +} + +/** + * @description Returns the swap side for any auction. v2 carries `side` on the + * auction directly, so no order introspection is needed. + */ +function getAuctionSwapSide( + auction: Pick +): SwapSideUnion { + return auction.side; +} + +/** + * @description Returns source and destination token addresses for the auction, + * read from the input/output sides (already resolved to the dest-chain token + * for cross-chain orders). + */ +function getAuctionTokenAddresses( + auction: Pick +) { + return { + srcToken: auction.input.token, + destToken: auction.output.token, + }; +} + +/** + * @description Aggregates transaction amounts into total spent (src) and + * received (dest) values. + */ +function getTransactionAmounts(transactions: DeltaTransaction[]) { + const { srcAmount, destAmount } = transactions.reduce( + (acc, { spentAmount, receivedAmount }) => ({ + srcAmount: acc.srcAmount + BigInt(spentAmount ?? 0), + destAmount: acc.destAmount + BigInt(receivedAmount ?? 0), + }), + { srcAmount: 0n, destAmount: 0n } + ); + + return { + srcAmount: srcAmount.toString(), + destAmount: destAmount.toString(), + }; +} + +/** + * @description Calculates the overall filled percent (0–100) from the + * per-transaction `filledPercent` values. For TWAP orders each transaction is + * a slice (0–100 of that slice), so the slice values are averaged across + * `numSlices`; for single-fill orders the values sum directly. + */ +function getFilledPercent( + auction: Pick +): number { + if (auction.transactions.length === 0) return 0; + + const total = auction.transactions.reduce( + (acc, { filledPercent }) => acc + filledPercent, + 0 + ); + + if (checks.isTWAPOrder(auction.order) && auction.order.numSlices > 0) { + return total / auction.order.numSlices; + } + + return total; +} + +/** + * @description Returns expected amounts and, once the auction is completed, + * executed amounts. Executed amounts prefer the `executedAmount` baked onto the + * token sides and fall back to summing transactions. + */ +function getAuctionAmounts( + auction: Pick< + DeltaAuction, + 'status' | 'order' | 'input' | 'output' | 'transactions' + > +) { + const expected = { + srcAmount: getTokenSideAmount(auction.input, 'expected'), + destAmount: getTokenSideAmount(auction.output, 'expected'), + }; + + if (!isCompletedAuction(auction)) { + return { expected }; + } + + const txAmounts = getTransactionAmounts(auction.transactions); + + const executed = { + srcAmount: getExecutedAmount(auction.input, txAmounts.srcAmount), + destAmount: getExecutedAmount(auction.output, txAmounts.destAmount), + }; + + return { expected, executed }; +} + +/** + * @description Returns the executed amount of a token side when present, + * otherwise the provided fallback (typically summed from transactions). + */ +function getExecutedAmount(side: DeltaTokenSide, fallback: string): string { + if ('executedAmount' in side && side.executedAmount != null) { + return side.executedAmount; + } + + return fallback; +} + +/** + * @description Returns unified order data with normalized amounts, tokens, + * chain ids, and side — the v2 counterpart of v1's `getUnifiedDeltaOrderData`, + * built from the v2 auction envelope. + */ +function getUnifiedDeltaOrderData( + auction: DeltaAuction +): UnifiedDeltaOrderData { + const { srcToken, destToken } = getAuctionTokenAddresses(auction); + const { expected, executed } = getAuctionAmounts(auction); + + const srcChainId = getAuctionSrcChainId(auction); + const destChainId = getAuctionDestChainId(auction); + const swapSide = getAuctionSwapSide(auction); + const filledPercent = getFilledPercent(auction); + + return { + srcChainId, + destChainId, + srcAmount: executed?.srcAmount || expected.srcAmount, + destAmount: executed?.destAmount || expected.destAmount, + amounts: { + expected, + final: executed, + }, + srcToken, + destToken, + swapSide, + filledPercent, + }; +} + +const getters = { + getUnifiedDeltaOrderData, + + // auction-level getters — v2 envelope shape. + getAuctionTokenAddresses, + getAuctionSrcChainId, + getAuctionDestChainId, + getAuctionSwapSide, + getTransactionAmounts, + getAuctionAmounts, + getFilledPercent, + + // order-level getters — order structs are shared with v1, reused as-is. + getOrderTokenAddresses: v1Getters.getOrderTokenAddresses, + getSwapSideFromDeltaOrder: v1Getters.getSwapSideFromDeltaOrder, + getSwapSideFromTwapOrderType: v1Getters.getSwapSideFromTwapOrderType, + getExpectedTwapSrcAmount: v1Getters.getExpectedTwapSrcAmount, + getExpectedTwapDestAmount: v1Getters.getExpectedTwapDestAmount, + getExpectedTwapOrderAmounts: v1Getters.getExpectedTwapOrderAmounts, +}; + +export const OrderHelpers = { + checks, + getters, +}; diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts index 296fff709..65b517be9 100644 --- a/src/methods/deltaV2/index.ts +++ b/src/methods/deltaV2/index.ts @@ -100,6 +100,7 @@ export * from './getBridgeRoutes'; export * from './isTokenSupportedInDelta'; export * from './cancelDeltaOrder'; export * from './getAgentsList'; +export { OrderHelpers } from './helpers/orders'; // ── Sign v2 ───────────────────────────────────────────────────────────────── From 9cc1a1abfb8327bdd868d922705986f91d2515e5 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 29 May 2026 17:01:54 +0300 Subject: [PATCH 48/52] buildDeltaOrder/drop chainId param --- src/methods/deltaV2/buildDeltaOrder.ts | 3 +-- src/methods/deltaV2/buildExternalDeltaOrder.ts | 3 +-- src/methods/deltaV2/buildTWAPDeltaOrder.ts | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/methods/deltaV2/buildDeltaOrder.ts b/src/methods/deltaV2/buildDeltaOrder.ts index 97f3f21a4..487ddeabc 100644 --- a/src/methods/deltaV2/buildDeltaOrder.ts +++ b/src/methods/deltaV2/buildDeltaOrder.ts @@ -53,7 +53,7 @@ export type BuildDeltaOrderFunctions = { export const constructBuildDeltaOrder = ( options: ConstructFetchInput ): BuildDeltaOrderFunctions => { - const { apiURL = API_URL, chainId, fetcher } = options; + const { apiURL = API_URL, fetcher } = options; const buildUrl = `${apiURL}/delta/v2/orders/build` as const; const buildDeltaOrder: BuildDeltaOrder = async (params, requestParams) => @@ -61,7 +61,6 @@ export const constructBuildDeltaOrder = ( url: buildUrl, method: 'POST', data: { - chainId, side: params.side, route: params.route, owner: params.owner, diff --git a/src/methods/deltaV2/buildExternalDeltaOrder.ts b/src/methods/deltaV2/buildExternalDeltaOrder.ts index db05c6b6e..3b7e53c0d 100644 --- a/src/methods/deltaV2/buildExternalDeltaOrder.ts +++ b/src/methods/deltaV2/buildExternalDeltaOrder.ts @@ -57,7 +57,7 @@ export type BuildExternalDeltaOrderFunctions = { export const constructBuildExternalDeltaOrder = ( options: ConstructFetchInput ): BuildExternalDeltaOrderFunctions => { - const { apiURL = API_URL, chainId, fetcher } = options; + const { apiURL = API_URL, fetcher } = options; const buildUrl = `${apiURL}/delta/v2/orders/build` as const; const buildExternalDeltaOrder: BuildExternalDeltaOrder = async ( @@ -68,7 +68,6 @@ export const constructBuildExternalDeltaOrder = ( url: buildUrl, method: 'POST', data: { - chainId, side: params.side, route: params.route, owner: params.owner, diff --git a/src/methods/deltaV2/buildTWAPDeltaOrder.ts b/src/methods/deltaV2/buildTWAPDeltaOrder.ts index 453b0cc6a..adb6a23c9 100644 --- a/src/methods/deltaV2/buildTWAPDeltaOrder.ts +++ b/src/methods/deltaV2/buildTWAPDeltaOrder.ts @@ -72,7 +72,7 @@ export type BuildTWAPDeltaOrderFunctions = { export const constructBuildTWAPDeltaOrder = ( options: ConstructFetchInput ): BuildTWAPDeltaOrderFunctions => { - const { apiURL = API_URL, chainId, fetcher } = options; + const { apiURL = API_URL, fetcher } = options; const buildUrl = `${apiURL}/delta/v2/orders/build` as const; const buildTWAPDeltaOrder: BuildTWAPDeltaOrder = async ( @@ -80,7 +80,6 @@ export const constructBuildTWAPDeltaOrder = ( requestParams ) => { const commonBody = { - chainId, route: params.route, owner: params.owner, beneficiary: params.beneficiary, From f0d66799bddabac2aae4a29a1557a49b88bb6aec Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Fri, 29 May 2026 17:06:14 +0300 Subject: [PATCH 49/52] Release 9.5.4-dev.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cfd9cd44f..70cac6a4f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@velora-dex/sdk", - "version": "9.5.4-dev.1", + "version": "9.5.4-dev.2", "main": "dist/index.js", "module": "dist/sdk.esm.js", "typings": "dist/index.d.ts", From bbc6cfaf5e1245f0b3fe9063701fe40b59b3c3c6 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Tue, 2 Jun 2026 20:19:06 +0300 Subject: [PATCH 50/52] delta/drop v1, promote v2 to the sole delta API Remove the local-build Delta v1 surface and the unreleased DeltaV2 namespace; the v2 server-built implementation now backs sdk.delta.* and the bare top-level exports. Replace getBridgeInfo with getBridgeRoutes, and point getQuote at /v2/quote returning the v2 route-based DeltaPrice (overloads/modes unchanged). Migrate examples to the v2 flow. --- src/examples/delta.ts | 113 ++- src/examples/deltaV2.ts | 196 ----- src/examples/externalDelta.ts | 162 ----- src/examples/helpers/delta.ts | 26 +- src/examples/helpers/deltaV2.ts | 34 - src/examples/quote.ts | 97 +-- src/examples/simpleQuote.ts | 18 +- src/index.ts | 151 ++-- src/methods/delta/buildDeltaOrder.ts | 171 ++--- src/methods/delta/buildExternalDeltaOrder.ts | 147 ++-- src/methods/delta/buildTWAPDeltaOrder.ts | 192 ++--- src/methods/delta/cancelDeltaOrder.ts | 44 +- src/methods/delta/constants.ts | 11 - .../{deltaV2 => delta}/getAgentsList.ts | 0 src/methods/delta/getBridgeInfo.ts | 92 --- .../{deltaV2 => delta}/getBridgeRoutes.ts | 7 +- src/methods/delta/getDeltaOrders.ts | 97 +-- src/methods/delta/getDeltaPrice.ts | 154 +--- src/methods/delta/helpers/orders.ts | 673 +++++++++--------- src/methods/delta/helpers/types.ts | 155 ---- src/methods/delta/index.ts | 247 ++++--- src/methods/delta/isTokenSupportedInDelta.ts | 16 +- src/methods/delta/postDeltaOrder.ts | 13 +- src/methods/delta/postExternalDeltaOrder.ts | 4 +- src/methods/delta/postTWAPDeltaOrder.ts | 9 +- src/methods/delta/signDeltaOrder.ts | 35 - src/methods/delta/signExternalDeltaOrder.ts | 35 - src/methods/delta/signTWAPDeltaOrder.ts | 32 - src/methods/{deltaV2 => delta}/types.ts | 2 +- src/methods/deltaV2/buildDeltaOrder.ts | 86 --- .../deltaV2/buildExternalDeltaOrder.ts | 95 --- src/methods/deltaV2/buildTWAPDeltaOrder.ts | 131 ---- src/methods/deltaV2/cancelDeltaOrder.ts | 100 --- src/methods/deltaV2/getDeltaOrders.ts | 149 ---- src/methods/deltaV2/getDeltaPrice.ts | 108 --- src/methods/deltaV2/helpers/orders.ts | 363 ---------- src/methods/deltaV2/index.ts | 312 -------- .../deltaV2/isTokenSupportedInDelta.ts | 52 -- src/methods/deltaV2/postDeltaOrder.ts | 62 -- src/methods/deltaV2/postExternalDeltaOrder.ts | 45 -- src/methods/deltaV2/postTWAPDeltaOrder.ts | 58 -- src/methods/quote/getQuote.ts | 8 +- src/sdk/full.ts | 8 - src/sdk/simple.ts | 40 +- 44 files changed, 945 insertions(+), 3605 deletions(-) delete mode 100644 src/examples/deltaV2.ts delete mode 100644 src/examples/externalDelta.ts delete mode 100644 src/examples/helpers/deltaV2.ts delete mode 100644 src/methods/delta/constants.ts rename src/methods/{deltaV2 => delta}/getAgentsList.ts (100%) delete mode 100644 src/methods/delta/getBridgeInfo.ts rename src/methods/{deltaV2 => delta}/getBridgeRoutes.ts (95%) delete mode 100644 src/methods/delta/signDeltaOrder.ts delete mode 100644 src/methods/delta/signExternalDeltaOrder.ts delete mode 100644 src/methods/delta/signTWAPDeltaOrder.ts rename src/methods/{deltaV2 => delta}/types.ts (99%) delete mode 100644 src/methods/deltaV2/buildDeltaOrder.ts delete mode 100644 src/methods/deltaV2/buildExternalDeltaOrder.ts delete mode 100644 src/methods/deltaV2/buildTWAPDeltaOrder.ts delete mode 100644 src/methods/deltaV2/cancelDeltaOrder.ts delete mode 100644 src/methods/deltaV2/getDeltaOrders.ts delete mode 100644 src/methods/deltaV2/getDeltaPrice.ts delete mode 100644 src/methods/deltaV2/helpers/orders.ts delete mode 100644 src/methods/deltaV2/index.ts delete mode 100644 src/methods/deltaV2/isTokenSupportedInDelta.ts delete mode 100644 src/methods/deltaV2/postDeltaOrder.ts delete mode 100644 src/methods/deltaV2/postExternalDeltaOrder.ts delete mode 100644 src/methods/deltaV2/postTWAPDeltaOrder.ts diff --git a/src/examples/delta.ts b/src/examples/delta.ts index 208e4d948..3b371cfef 100644 --- a/src/examples/delta.ts +++ b/src/examples/delta.ts @@ -22,7 +22,6 @@ const contractCaller = constructEthersContractCaller( account ); -// type AdaptersFunctions & ApproveTokenFunctions const deltaSDK = constructPartialSDK( { chainId: 1, @@ -55,19 +54,18 @@ async function simpleDeltaFlow() { await tx.wait(); const deltaAuction = await deltaSDK.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // or pick from deltaPrice.alternatives + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - srcAmount: amount, - slippage: 50, // 50 bps = 0.5% slippage, destAmount auto-computed from deltaPrice + slippage: 50, // 50 bps = 0.5% slippage }); // poll if necessary startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); } + async function manualDeltaFlow() { const amount = '1000000000000'; // wei @@ -87,25 +85,112 @@ async function manualDeltaFlow() { const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); await tx.wait(); - const signableOrderData = await deltaSDK.buildDeltaOrder({ - deltaPrice, + // server-side build (returns EIP-712 typed data + orderHash) + const builtOrder = await deltaSDK.buildDeltaOrder({ + route: deltaPrice.route, // or pick from deltaPrice.alternatives + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - srcAmount: amount, - slippage: 50, // 50 bps = 0.5% slippage, destAmount auto-computed from deltaPrice + slippage: 50, // 50 bps = 0.5% slippage }); - const signature = await deltaSDK.signDeltaOrder(signableOrderData); + // one signer for every v2 order type (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) + const signature = await deltaSDK.signDeltaOrder(builtOrder); const deltaAuction = await deltaSDK.postDeltaOrder({ // partner: "..." // if available - order: signableOrderData.data, + order: builtOrder.toSign.value, signature, }); // poll if necessary startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); } + +// External orders forward execution to an integrator-provided handler contract. +// Same build/sign/post shape as standard orders, plus { handler, data }. +// See docs/EXTERNAL_ORDERS.md for handler-specific details (Aave collateral swap, etc.). +async function externalDeltaFlow() { + const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC + + const deltaPrice = await deltaSDK.getDeltaPrice({ + srcToken: USDC_TOKEN, + destToken: DAI_TOKEN, + amount, + userAddress: account, + srcDecimals: 6, + destDecimals: 18, + }); + + const HANDLER = '0xb4a2c36668cf8b19fe08f263e3685a5e16e82912'; // handler contract + const HANDLER_DATA = + '0x0000000000000000000000000000000000000000000000000000000000000000'; // handler-specific encoded bytes + + const builtOrder = await deltaSDK.buildExternalDeltaOrder({ + route: deltaPrice.route, + side: deltaPrice.side, + owner: account, + handler: HANDLER, + data: HANDLER_DATA, + slippage: 50, + }); + + const signature = await deltaSDK.signDeltaOrder(builtOrder); + + const deltaAuction = await deltaSDK.postExternalDeltaOrder({ + order: builtOrder.toSign.value, + signature, + }); + + startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); +} + +// TWAP sell splits a total srcAmount into N equal slices executed `interval` seconds apart. +// The price quote is fetched for a single slice; the server multiplies amounts by numSlices. +async function twapSellDeltaFlow() { + const numSlices = 4; + const totalSrcAmount = ethers.utils.parseUnits('100', 18).toString(); // 100 DAI total + const perSliceAmount = ( + BigInt(totalSrcAmount) / BigInt(numSlices) + ).toString(); + + // quote a single slice — route amounts must match floor(totalSrcAmount / numSlices) + const deltaPrice = await deltaSDK.getDeltaPrice({ + srcToken: DAI_TOKEN, + destToken: USDC_TOKEN, + amount: perSliceAmount, + userAddress: account, + srcDecimals: 18, + destDecimals: 6, + }); + + const tx = await deltaSDK.approveTokenForDelta(totalSrcAmount, DAI_TOKEN); + await tx.wait(); + + const deltaAuction = await deltaSDK.submitTWAPDeltaOrder({ + onChainOrderType: 'TWAPOrder', + route: deltaPrice.route, + owner: account, + totalSrcAmount, + numSlices, + interval: 300, // 5 minutes between slices (min 60) + slippage: 50, + }); + + startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); +} + +// Paginated list of a user's orders (returns a { data, total, page, limit, hasMore } envelope). +async function listUserOrders() { + const page1 = await deltaSDK.getDeltaOrders({ + userAddress: account, + page: 1, + limit: 50, + // status: ['ACTIVE', 'BRIDGING'], + // type: 'MARKET', + }); + + console.log('orders:', page1.data); + console.log('total:', page1.total, 'hasMore:', page1.hasMore); +} diff --git a/src/examples/deltaV2.ts b/src/examples/deltaV2.ts deleted file mode 100644 index cf804ed89..000000000 --- a/src/examples/deltaV2.ts +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import axios from 'axios'; -import { ethers, Wallet } from 'ethersV5'; -import { - constructPartialSDK, - constructEthersContractCaller, - constructAxiosFetcher, - DeltaV2, -} from '..'; -import { startStatusCheckV2 } from './helpers/deltaV2'; - -const fetcher = constructAxiosFetcher(axios); - -const provider = ethers.getDefaultProvider(1); -const signer = Wallet.createRandom().connect(provider); -const account = signer.address; -const contractCaller = constructEthersContractCaller( - { - ethersProviderOrSigner: provider, - EthersContract: ethers.Contract, - }, - account -); - -const deltaSDK = constructPartialSDK( - { - chainId: 1, - fetcher, - contractCaller, - }, - DeltaV2.constructAllDeltaOrdersHandlers -); - -const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f'; -const USDC_TOKEN = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; - -async function simpleDeltaV2Flow() { - const amount = '1000000000000'; // wei - - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - amount, - userAddress: account, - srcDecimals: 18, - destDecimals: 6, - // partner: "..." // if available - }); - - const DeltaContract = await deltaSDK.getDeltaContract(); - - // or sign a Permit1 or Permit2 TransferFrom for DeltaContract - const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); - await tx.wait(); - - const deltaAuction = await deltaSDK.submitDeltaOrder({ - route: deltaPrice.route, // or pick from deltaPrice.alternatives - side: deltaPrice.side, - owner: account, - // beneficiary: anotherAccount, // if need to send destToken to another account - // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - slippage: 50, // 50 bps = 0.5% slippage - }); - - // poll if necessary - startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} - -async function manualDeltaV2Flow() { - const amount = '1000000000000'; // wei - - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - amount, - userAddress: account, - srcDecimals: 18, - destDecimals: 6, - // partner: "..." // if available - }); - - const DeltaContract = await deltaSDK.getDeltaContract(); - - // or sign a Permit1 or Permit2 TransferFrom for DeltaContract - const tx = await deltaSDK.approveTokenForDelta(amount, DAI_TOKEN); - await tx.wait(); - - // server-side build (returns EIP-712 typed data + orderHash) - const builtOrder = await deltaSDK.buildDeltaOrder({ - route: deltaPrice.route, // or pick from deltaPrice.alternatives - side: deltaPrice.side, - owner: account, - // beneficiary: anotherAccount, // if need to send destToken to another account - // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - slippage: 50, // 50 bps = 0.5% slippage - }); - - // one signer for every v2 order type (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) - const signature = await deltaSDK.signDeltaOrder(builtOrder); - - const deltaAuction = await deltaSDK.postDeltaOrder({ - // partner: "..." // if available - order: builtOrder.toSign.value, - signature, - }); - - // poll if necessary - startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} - -// External orders forward execution to an integrator-provided handler contract. -// Same build/sign/post shape as standard orders, plus { handler, data }. -// See externalDelta.ts for handler-specific examples (Aave collateral swap, etc.). -async function externalDeltaV2Flow() { - const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC - - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: USDC_TOKEN, - destToken: DAI_TOKEN, - amount, - userAddress: account, - srcDecimals: 6, - destDecimals: 18, - }); - - const HANDLER = '0xb4a2c36668cf8b19fe08f263e3685a5e16e82912'; // handler contract - const HANDLER_DATA = - '0x0000000000000000000000000000000000000000000000000000000000000000'; // handler-specific encoded bytes - - const builtOrder = await deltaSDK.buildExternalDeltaOrder({ - route: deltaPrice.route, - side: deltaPrice.side, - owner: account, - handler: HANDLER, - data: HANDLER_DATA, - slippage: 50, - }); - - const signature = await deltaSDK.signDeltaOrder(builtOrder); - - const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: builtOrder.toSign.value, - signature, - }); - - startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} - -// TWAP sell splits a total srcAmount into N equal slices executed `interval` seconds apart. -// The price quote is fetched for a single slice; the server multiplies amounts by numSlices. -async function twapSellDeltaV2Flow() { - const numSlices = 4; - const totalSrcAmount = ethers.utils.parseUnits('100', 18).toString(); // 100 DAI total - const perSliceAmount = ( - BigInt(totalSrcAmount) / BigInt(numSlices) - ).toString(); - - // quote a single slice — route amounts must match floor(totalSrcAmount / numSlices) - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - amount: perSliceAmount, - userAddress: account, - srcDecimals: 18, - destDecimals: 6, - }); - - const tx = await deltaSDK.approveTokenForDelta(totalSrcAmount, DAI_TOKEN); - await tx.wait(); - - const deltaAuction = await deltaSDK.submitTWAPDeltaOrder({ - onChainOrderType: 'TWAPOrder', - route: deltaPrice.route, - owner: account, - totalSrcAmount, - numSlices, - interval: 300, // 5 minutes between slices (min 60) - slippage: 50, - }); - - startStatusCheckV2(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} - -// Paginated list of a user's orders (v2 returns a { results, pagination } envelope). -async function listUserOrders() { - const page1 = await deltaSDK.getDeltaOrders({ - userAddress: account, - page: 1, - limit: 50, - // status: ['ACTIVE', 'BRIDGING'], - // type: 'MARKET', - }); - - console.log('orders:', page1.data); - console.log('total:', page1.total, 'hasMore:', page1.hasMore); -} diff --git a/src/examples/externalDelta.ts b/src/examples/externalDelta.ts deleted file mode 100644 index 6144d5b4f..000000000 --- a/src/examples/externalDelta.ts +++ /dev/null @@ -1,162 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import axios from 'axios'; -import { ethers, Wallet } from 'ethersV5'; -import { - constructPartialSDK, - constructEthersContractCaller, - constructAxiosFetcher, - constructAllDeltaOrdersHandlers, - SwapSide, -} from '..'; -import { startStatusCheck } from './helpers/delta'; - -const fetcher = constructAxiosFetcher(axios); - -const provider = ethers.getDefaultProvider(1); // Ethereum -const signer = Wallet.createRandom().connect(provider); -const account = signer.address; -const contractCaller = constructEthersContractCaller( - { - ethersProviderOrSigner: signer, - EthersContract: ethers.Contract, - }, - account -); - -const deltaSDK = constructPartialSDK( - { - chainId: 1, // Ethereum - fetcher, - contractCaller, - }, - constructAllDeltaOrdersHandlers -); - -// Ethereum tokens -const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; -const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'; - -// Aave external handler on Ethereum (https://etherscan.io/address/0xb4a2c36668cf8b19fe08f263e3685a5e16e82912#code) -// The handler contract is provided by the integrator and must implement IExternalProtocolHandler. -// Different handlers serve different purposes and may have different prerequisites -// (e.g. token approvals, credit delegation, position setup). -const AAVE_HANDLER = '0xb4a2c36668cf8b19fe08f263e3685a5e16e82912'; - -// Aave-specific order types passed as `data` field. -// The `data` encoding is handler-specific — each handler defines its own format. -const AaveOrderTypes = { - COLLATERAL_SWAP: - '0x0000000000000000000000000000000000000000000000000000000000000000', - DEBT_SWAP: - '0x0000000000000000000000000000000000000000000000000000000000000001', - REPAY_WITH_COLLATERAL: - '0x0000000000000000000000000000000000000000000000000000000000000002', -}; - -// Aave Collateral Swap: swap one collateral asset for another (SELL side) -// Prerequisites: user must approve the source aToken to the handler -async function collateralSwapFlow() { - const amount = ethers.utils.parseUnits('1', 6).toString(); // 1 USDC - - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: USDC, - destToken: WETH, - amount, - userAddress: account, - srcDecimals: 6, - destDecimals: 18, - side: SwapSide.SELL, - }); - - const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ - deltaPrice, - owner: account, - handler: AAVE_HANDLER, - data: AaveOrderTypes.COLLATERAL_SWAP, - srcToken: USDC, - destToken: WETH, - srcAmount: amount, - slippage: 50, // 0.5% slippage in bps - }); - - const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); - - const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: signableOrderData.data, - signature, - }); - - startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} - -// Aave Debt Swap: swap one debt for another (BUY side) -// Prerequisites: user must grant borrowAllowance on the source variable debt token to the handler -async function debtSwapFlow() { - const debtAmount = ethers.utils.parseUnits('1', 6).toString(); // amount of debt to swap - - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: USDC, - destToken: WETH, - amount: debtAmount, - userAddress: account, - srcDecimals: 6, - destDecimals: 18, - side: SwapSide.BUY, - }); - - const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ - deltaPrice, - owner: account, - handler: AAVE_HANDLER, - data: AaveOrderTypes.DEBT_SWAP, - srcToken: USDC, - destToken: WETH, - destAmount: debtAmount, - slippage: 50, // 0.5% slippage in bps - }); - - const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); - - const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: signableOrderData.data, - signature, - }); - - startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} - -// Aave Repay with Collateral: use collateral to repay debt (BUY side) -// Prerequisites: user must approve the source aToken to the handler -async function repayWithCollateralFlow() { - const collateralAmount = ethers.utils.parseUnits('1', 6).toString(); - - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: USDC, - destToken: WETH, - amount: collateralAmount, - userAddress: account, - srcDecimals: 6, - destDecimals: 18, - side: SwapSide.BUY, - }); - - const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ - deltaPrice, - owner: account, - handler: AAVE_HANDLER, - data: AaveOrderTypes.REPAY_WITH_COLLATERAL, - srcToken: USDC, - destToken: WETH, - destAmount: collateralAmount, - slippage: 50, // 0.5% slippage in bps - }); - - const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); - - const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: signableOrderData.data, - signature, - }); - - startStatusCheck(() => deltaSDK.getDeltaOrderById(deltaAuction.id)); -} diff --git a/src/examples/helpers/delta.ts b/src/examples/helpers/delta.ts index fb04b0150..9b3b2b788 100644 --- a/src/examples/helpers/delta.ts +++ b/src/examples/helpers/delta.ts @@ -1,31 +1,19 @@ import { DeltaAuction } from '../..'; -function isExecutedDeltaAuction( - auction: DeltaAuction, - waitForCrosschain = true // only consider executed when destChain work is done -) { - if (auction.status !== 'EXECUTED') return false; - - // crosschain Order is executed on destChain if bridgeStatus is filled - if ( - waitForCrosschain && - auction.onChainOrderType === 'Order' && - auction.order.bridge.destinationChainId !== 0 - ) { - return auction.bridgeStatus === 'filled'; - } - - return true; +// v2 status COMPLETED already accounts for destChain bridge settlement +// (crosschain orders sit in BRIDGING until the destChain leg is done). +function isCompletedDeltaOrder(order: DeltaAuction) { + return order.status === 'COMPLETED'; } type GetDeltaOrderFn = () => Promise; function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderFn) { const intervalId = setInterval(async () => { - const auction = await getDeltaOrder(); - console.log('checks: ', auction); // Handle or log the fetched auction as needed + const order = await getDeltaOrder(); + console.log('checks: ', order); // Handle or log the fetched order as needed - if (isExecutedDeltaAuction(auction)) { + if (isCompletedDeltaOrder(order)) { clearInterval(intervalId); // Stop interval if completed console.log('Order completed'); } diff --git a/src/examples/helpers/deltaV2.ts b/src/examples/helpers/deltaV2.ts deleted file mode 100644 index 3b2bf6ba4..000000000 --- a/src/examples/helpers/deltaV2.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { DeltaV2 } from '../..'; - -// v2 status COMPLETED already accounts for destChain bridge settlement -// (crosschain orders sit in BRIDGING until the destChain leg is done). -function isCompletedDeltaV2Order(order: DeltaV2.DeltaAuction) { - return order.status === 'COMPLETED'; -} - -type GetDeltaOrderV2Fn = () => Promise; - -function fetchOrderPeriodically(getDeltaOrder: GetDeltaOrderV2Fn) { - const intervalId = setInterval(async () => { - const order = await getDeltaOrder(); - console.log('checks: ', order); // Handle or log the fetched order as needed - - if (isCompletedDeltaV2Order(order)) { - clearInterval(intervalId); // Stop interval if completed - console.log('Order completed'); - } - }, 3000); - console.log('Order Pending'); - // Return intervalId to enable clearing the interval if needed externally - return intervalId; -} - -export function startStatusCheckV2(getDeltaOrder: GetDeltaOrderV2Fn) { - const intervalId = fetchOrderPeriodically(getDeltaOrder); - const timeoutId = setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes - - return () => { - clearInterval(intervalId); - clearTimeout(timeoutId); - }; -} diff --git a/src/examples/quote.ts b/src/examples/quote.ts index d2d0a119f..c62de988e 100644 --- a/src/examples/quote.ts +++ b/src/examples/quote.ts @@ -40,74 +40,10 @@ const DAI_TOKEN = '0x6b175474e89094c44da98b954eedeac495271d0f'; const USDC_TOKEN = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; /** - * mode='delta' example + * mode='all' returns Delta pricing when possible, with Market price as a fallback. + * (mode='delta' and mode='market' request a single pricing source.) */ -async function deltaQuote() { - const amount = '1000000000000'; // wei - - const quote = await quoteSDK.getQuote({ - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - amount, - userAddress: account, - srcDecimals: 18, - destDecimals: 6, - mode: 'delta', - side: 'SELL', - // partner: "..." // if available - }); - - try { - const deltaPrice = quote.delta; - await handleDeltaQuote({ amount, deltaPrice }); - } catch (error) { - if (isFetcherError(error)) { - const data = error.response?.data; - console.log(`Delta Quote failed: ${data.errorType} - ${data.details}`); - } - } -} - -/** - * mode='market' example - */ -async function marketQuote() { - const amount = '1000000000000'; // wei - - const quote = await quoteSDK.getQuote({ - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - amount, - userAddress: account, - srcDecimals: 18, - destDecimals: 6, - mode: 'market', - side: 'SELL', - // partner: "..." // if available - }); - - const TokenTransferProxy = await quoteSDK.getSpender(); - - // or sign a Permit1 or Permit2 TransferFrom for TokenTransferProxy - const approveTxHash = quoteSDK.approveToken(amount, DAI_TOKEN); - - const txParams = await quoteSDK.buildTx({ - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - srcAmount: amount, - slippage: 250, // 2.5% - priceRoute: quote.market, - userAddress: account, - // partner: '...' // if available - }); - - const swapTx = await handleMarketQuote({ amount, priceRoute: quote.market }); -} - -/** - * mode='all' example - */ -async function allQuote() { +async function quoteExample() { const amount = '1000000000000'; // wei const quote = await quoteSDK.getQuote({ @@ -123,16 +59,14 @@ async function allQuote() { }); if ('delta' in quote) { - const deltaPrice = quote.delta; - await handleDeltaQuote({ amount, deltaPrice }); + // Delta path — quote.delta is the v2 DeltaPrice (route-based) + await handleDeltaQuote({ amount, deltaPrice: quote.delta }); } else { console.log( `Delta Quote failed: ${quote.fallbackReason.errorType} - ${quote.fallbackReason.details}` ); - const swapTx = await handleMarketQuote({ - amount, - priceRoute: quote.market, - }); + // settle against the current market price instead + await handleMarketQuote({ amount, priceRoute: quote.market }); } } @@ -151,23 +85,14 @@ async function handleDeltaQuote({ // or sign a Permit1 or Permit2 TransferFrom for DeltaContract await quoteSDK.approveTokenForDelta(amount, DAI_TOKEN); - const slippagePercent = 0.5; - const destAmountAfterSlippage = BigInt( - // get rid of exponential notation - - +(+deltaPrice.destAmount * (1 - slippagePercent / 100)).toFixed(0) - // get rid of decimals - ).toString(10); - + // v2 order building is server-side: pass the quoted route/side, no deltaPrice const deltaAuction = await quoteSDK.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // or pick from deltaPrice.alternatives + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + slippage: 50, // 50 bps = 0.5% slippage }); // poll if necessary diff --git a/src/examples/simpleQuote.ts b/src/examples/simpleQuote.ts index 322b1ab44..b74934884 100644 --- a/src/examples/simpleQuote.ts +++ b/src/examples/simpleQuote.ts @@ -39,6 +39,7 @@ async function allQuote() { }); if ('delta' in quote) { + // Delta path — quote.delta is the v2 DeltaPrice (route-based) const deltaPrice = quote.delta; const DeltaContract = await simpleSDK.delta.getDeltaContract(); @@ -49,23 +50,14 @@ async function allQuote() { DAI_TOKEN ); - const slippagePercent = 0.5; - const destAmountAfterSlippage = BigInt( - // get rid of exponential notation - - +(+deltaPrice.destAmount * (1 - slippagePercent / 100)).toFixed(0) - // get rid of decimals - ).toString(10); - + // v2 order building is server-side: pass the quoted route/side, no deltaPrice const deltaAuction = await simpleSDK.delta.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // or pick from deltaPrice.alternatives + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + slippage: 50, // 50 bps = 0.5% slippage }); // poll if necessary diff --git a/src/index.ts b/src/index.ts index 69774fdab..d44a7222e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -138,13 +138,13 @@ import type { PaginatedResponse, } from './types'; +// ── Delta ───────────────────────────────────────────────────────────────── +// Delta is v2 (server-built orders). The previous local-build v1 surface was +// removed; every Delta symbol below refers to the v2 implementation. + +// Shared on-chain order-struct types import type { DeltaAuctionOrder, - DeltaAuction, - DeltaAuctionStatus, - DeltaAuctionTransaction, - BridgeMetadata, - BridgeStatus, Bridge, ExternalDeltaOrder, ProductiveDeltaOrder, @@ -158,21 +158,31 @@ import type { DeltaAmountsSellSlippage, DeltaAmountsBuySlippage, DeltaAmountsExplicit, - DeltaAuctionDelta, - DeltaAuctionFillable, - DeltaAuctionTWAP, - DeltaAuctionTWAPBuy, - DeltaAuctionExternal, - DeltaAuctionProductive, DeltaOrderUnion, - DeltaAuctionUnion, UnifiedDeltaOrderData, } from './methods/delta/helpers/types'; +// v2 auction, price & route types +import type { + BuiltDeltaOrder, + DeltaAuction, + DeltaOrderStatus, + DeltaTokenSide, + DeltaTransaction, + DeltaPrice, + DeltaPriceToken, + DeltaTokenAmount, + BridgeTag, + DeltaRoute, + DeltaRouteStep, + DeltaRouteBridge, + DeltaRouteBridgeContractParams, + BridgeRoute, +} from './methods/delta/types'; + import { - BuildDeltaOrderDataParams, BuildDeltaOrderFunctions, + BuildDeltaOrderParams, constructBuildDeltaOrder, - SignableDeltaOrderData, } from './methods/delta/buildDeltaOrder'; import { constructPostDeltaOrder, @@ -183,7 +193,7 @@ import { import { constructSignDeltaOrder, SignDeltaOrderFunctions, -} from './methods/delta/signDeltaOrder'; +} from './methods/delta'; import { constructPreSignDeltaOrder, PreSignDeltaOrderFunctions, @@ -195,16 +205,11 @@ import { import { constructGetDeltaPrice, GetDeltaPriceFunctions, - DeltaPrice, - BridgePrice, - AvailableBridge, DeltaPriceParams, } from './methods/delta/getDeltaPrice'; import { constructGetDeltaOrders, GetDeltaOrdersFunctions, - DeltaOrderFilterByStatus, - DeltaOrderFromAPI, } from './methods/delta/getDeltaOrders'; import { ApproveTokenForDeltaFunctions, @@ -215,15 +220,19 @@ import { GetPartnerFeeFunctions, } from './methods/delta/getPartnerFee'; import { - constructGetBridgeInfo, - GetBridgeInfoFunctions, - BridgeInfo, + constructGetBridgeRoutes, + GetBridgeRoutesFunctions, BridgeProtocolResponse, -} from './methods/delta/getBridgeInfo'; +} from './methods/delta/getBridgeRoutes'; import { constructIsTokenSupportedInDelta, IsTokenSupportedInDeltaFunctions, } from './methods/delta/isTokenSupportedInDelta'; +import { + constructGetAgentsList, + GetAgentsListFunctions, + AgentList, +} from './methods/delta/getAgentsList'; import { constructBuildExternalDeltaOrder, @@ -231,10 +240,6 @@ import { BuildExternalDeltaOrderParams, } from './methods/delta/buildExternalDeltaOrder'; import type { SignableExternalOrderData } from './methods/delta/helpers/buildExternalOrderData'; -import { - constructSignExternalDeltaOrder, - SignExternalDeltaOrderFunctions, -} from './methods/delta/signExternalDeltaOrder'; import { constructPostExternalDeltaOrder, PostExternalDeltaOrderFunctions, @@ -247,16 +252,12 @@ import { import { BuildTWAPDeltaOrderParams, - BuildTWAPSellOrderParams, - BuildTWAPBuyOrderParams, + BuildTWAPSellDeltaOrderParams, + BuildTWAPBuyDeltaOrderParams, BuildTWAPDeltaOrderFunctions, constructBuildTWAPDeltaOrder, } from './methods/delta/buildTWAPDeltaOrder'; import type { SignableTWAPOrderData } from './methods/delta/helpers/buildTWAPOrderData'; -import { - constructSignTWAPDeltaOrder, - SignTWAPDeltaOrderFunctions, -} from './methods/delta/signTWAPDeltaOrder'; import { constructPostTWAPDeltaOrder, PostTWAPDeltaOrderFunctions, @@ -278,6 +279,9 @@ import { } from './methods/quote/getQuote'; import { CancelDeltaOrderFunctions, + CancelDeltaOrder, + SignCancelDeltaOrderRequest, + PostCancelDeltaOrderRequest, constructCancelDeltaOrder, } from './methods/delta/cancelDeltaOrder'; import { @@ -291,6 +295,7 @@ import { CancelDeltaOrderData, SignableCancelDeltaOrderData, } from './methods/delta/helpers/buildCancelDeltaOrderData'; +import { SignableDeltaOrderData } from './methods/delta/helpers/buildDeltaOrderData'; export { constructSwapSDK, SwapSDKMethods } from './methods/swap'; @@ -311,32 +316,6 @@ export { SubmitTWAPDeltaOrderParams, } from './methods/delta'; -// Delta v2 is exposed as a single namespace so it can ship alongside v1 without -// colliding at the top level. v2 source uses unsuffixed names internally -// (constructBuildDeltaOrder, BuiltDeltaOrder, DeltaPrice, ...); consumers reach -// them via `DeltaV2.constructBuildDeltaOrder` etc. -// -// Migration plan when deprecating v1 (breaking change): -// 1. Replace the bare `export { ... } from './methods/delta'` block above with -// `export * from './methods/deltaV2'` (or named re-exports of v2 symbols). -// Top-level `constructPostDeltaOrder` now resolves to v2. -// 2. Move v1 behind its own namespace for backcompat: -// `export * as DeltaV1 from './methods/delta'`. -// 3. Keep `export * as DeltaV2 from './methods/deltaV2'` as a redundant alias -// so code written against the v2 namespace today keeps compiling. -// 4. Mirror this on the bundled SDKs in sdk/full.ts and sdk/simple.ts: -// `sdk.delta.*` flips to v2 (use `constructAllDeltaOrdersHandlers` from -// './methods/deltaV2'), and add `sdk.deltaV1.*` for backcompat. -// -// Migration plan when dropping v1 entirely: -// - Delete the `DeltaV1` namespace export and `sdk.deltaV1` field. -// - Delete `src/methods/delta/`. -// - Delete the `DeltaV2` re-export alias (consumers can move to bare names). -// - The `methods/deltaV2/` folder can be renamed to `methods/delta/` (and the -// `/delta/v2/` URL prefix in the leaf modules updated if the server has by -// then collapsed v1 and v2 endpoints). -export * as DeltaV2 from './methods/deltaV2'; - export type { TransactionParams, BuildOptions, @@ -407,21 +386,20 @@ export { constructCancelDeltaOrder, constructDeltaTokenModule, constructApproveTokenForDelta, + constructGetAgentsList, // External Delta methods constructBuildExternalDeltaOrder, - constructSignExternalDeltaOrder, constructPostExternalDeltaOrder, constructPreSignExternalDeltaOrder, // TWAP Delta methods constructBuildTWAPDeltaOrder, - constructSignTWAPDeltaOrder, constructPostTWAPDeltaOrder, constructPreSignTWAPDeltaOrder, // Quote methods constructGetQuote, // different helpers constructGetPartnerFee, - constructGetBridgeInfo, + constructGetBridgeRoutes, constructIsTokenSupportedInDelta, constructEthersContractCaller, // same as constructEthersV5ContractCaller for backwards compatibility constructEthersV5ContractCaller, @@ -482,37 +460,33 @@ export type { BuildNFTOrderInput, BuildNFTOrderDataInput, NFTOrdersUserParams, - //types for Delta methods + // types for Delta methods DeltaPrice, - BridgePrice, DeltaPriceParams, + DeltaPriceToken, + DeltaTokenAmount, + DeltaRoute, + DeltaRouteStep, + DeltaRouteBridge, + DeltaRouteBridgeContractParams, + BridgeTag, + BridgeRoute, + BuiltDeltaOrder, DeltaAuctionOrder, DeltaAuction, - DeltaAuctionDelta, - DeltaAuctionFillable, - DeltaAuctionTWAP, - DeltaAuctionTWAPBuy, - DeltaAuctionExternal, - DeltaAuctionProductive, + DeltaOrderStatus, + DeltaTokenSide, + DeltaTransaction, DeltaOrderUnion, - DeltaAuctionUnion, UnifiedDeltaOrderData, - DeltaAuctionStatus, - DeltaAuctionTransaction, - DeltaOrderFilterByStatus, - DeltaOrderFromAPI, CancelDeltaOrderData, SignableCancelDeltaOrderData, + SignableDeltaOrderData, // bridge part of DeltaOrder - BridgeMetadata, - BridgeStatus, Bridge, - BridgeInfo, - AvailableBridge, BridgeProtocolResponse, - BuildDeltaOrderDataParams, BuildDeltaOrderFunctions, - SignableDeltaOrderData, + BuildDeltaOrderParams, DeltaOrderToPost, PostDeltaOrderFunctions, PostDeltaOrderParams, @@ -521,8 +495,14 @@ export type { GetDeltaContractFunctions, GetDeltaPriceFunctions, GetDeltaOrdersFunctions, + GetBridgeRoutesFunctions, + GetAgentsListFunctions, + AgentList, ApproveTokenForDeltaFunctions, CancelDeltaOrderFunctions, + CancelDeltaOrder, + SignCancelDeltaOrderRequest, + PostCancelDeltaOrderRequest, DeltaTokenModuleFunctions, CancelAndWithdrawDeltaOrderParams, DepositNativeAndPreSignParams, @@ -543,17 +523,15 @@ export type { SignableExternalOrderData, BuildExternalDeltaOrderParams, BuildExternalDeltaOrderFunctions, - SignExternalDeltaOrderFunctions, PostExternalDeltaOrderFunctions, PostExternalDeltaOrderParams, PreSignExternalDeltaOrderFunctions, // TWAP Delta types BuildTWAPDeltaOrderParams, - BuildTWAPSellOrderParams, - BuildTWAPBuyOrderParams, + BuildTWAPSellDeltaOrderParams, + BuildTWAPBuyDeltaOrderParams, BuildTWAPDeltaOrderFunctions, SignableTWAPOrderData, - SignTWAPDeltaOrderFunctions, PostTWAPDeltaOrderFunctions, PostTWAPDeltaOrderParams, PreSignTWAPDeltaOrderFunctions, @@ -570,7 +548,6 @@ export type { ConstructProviderFetchInput, // other types GetPartnerFeeFunctions, - GetBridgeInfoFunctions, IsTokenSupportedInDeltaFunctions, Token, Address, diff --git a/src/methods/delta/buildDeltaOrder.ts b/src/methods/delta/buildDeltaOrder.ts index 04f954604..1fbe493ee 100644 --- a/src/methods/delta/buildDeltaOrder.ts +++ b/src/methods/delta/buildDeltaOrder.ts @@ -1,133 +1,86 @@ +import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import { constructGetDeltaContract } from './getDeltaContract'; -import type { BridgePrice } from './getDeltaPrice'; -import { constructGetPartnerFee } from './getPartnerFee'; -import { - buildDeltaSignableOrderData, - type BuildDeltaOrderDataInput, - type SignableDeltaOrderData, -} from './helpers/buildDeltaOrderData'; -import type { DeltaAmountsWithSlippage } from './helpers/types'; -import { SwapSideToOrderKind } from './helpers/types'; -import { resolvePartnerFee, resolveAmounts } from './helpers/misc'; -import type { MarkOptional } from 'ts-essentials'; -export type { SignableDeltaOrderData } from './helpers/buildDeltaOrderData'; +import type { DeltaAuctionOrder } from './helpers/types'; +import type { BuiltDeltaOrder, DeltaRoute } from './types'; +export type { BuiltDeltaOrder } from './types'; -type BuildDeltaOrderDataParamsBase = { +export type BuildDeltaOrderParams = { /** @description The address of the order owner */ owner: string; - /** @description The address of the order beneficiary */ - beneficiary?: string; // beneficiary==owner if no transferTo - /** @description The address of the src token */ - srcToken: string; // lowercase - /** @description The address of the dest token. For Crosschain Order - destination token on the destination chain */ - destToken: string; // lowercase - /** @description The deadline for the order */ - deadline?: number; // seconds - /** @description The nonce of the order */ - nonce?: number | string; // can be random, can even be Date.now() - /** @description Optional permit signature for the src token https://developers.velora.xyz/api/velora-api/velora-delta-api/build-a-delta-order-to-sign#supported-permits-order#supported-permits */ - permit?: string; //can be "0x" - /** @description Partner string. */ + /** @description The address of the order beneficiary. Defaults to owner. */ + beneficiary?: string; + /** @description The deadline for the order (unix seconds) */ + deadline?: number; + /** @description The nonce of the order. Random if omitted. */ + nonce?: string; + /** @description Optional permit signature for the src token. Defaults to "0x". */ + permit?: string; + /** @description Partner string. Passed to the server to resolve partner fee details. */ partner?: string; - - /** @description Destination Chain ID for Crosschain Orders */ - destChainId?: number; - - /** @description price response received from /delta/prices (getDeltaPrice method) */ - deltaPrice: MarkOptional< - Pick< - BridgePrice, - | 'destAmount' - | 'partner' - | 'partnerFee' - | 'destToken' - | 'srcAmount' - | 'bridge' - >, - 'partner' | 'partnerFee' - >; - - /** @description partner fee in basis points (bps), 50bps=0.5% */ + /** @description Partner fee in basis points (bps), 50bps=0.5% */ partnerFeeBps?: number; - /** @description partner address */ + /** @description Partner address */ partnerAddress?: string; - /** @description take surplus */ + /** @description Take surplus flag */ partnerTakesSurplus?: boolean; - - /** @description A boolean indicating whether the surplus should be capped. True by default */ + /** @description Whether the surplus should be capped. True by default. */ capSurplus?: boolean; - /** @description Metadata for the order, hex string */ metadata?: string; + /** @description Designates the Order as partially fillable instead of fill-or-kill. Default false. */ + partiallyFillable?: boolean; + + /** @description DeltaRoute from getDeltaPrice — either price.route or any price.alternatives[i] */ + route: DeltaRoute; + /** @description Order side. SELL or BUY. */ + side: 'SELL' | 'BUY'; + /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ + slippage?: number; + /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ + limitAmount?: string; }; -export type BuildDeltaOrderDataParams = BuildDeltaOrderDataParamsBase & - DeltaAmountsWithSlippage; - type BuildDeltaOrder = ( - buildOrderParams: BuildDeltaOrderDataParams, + buildOrderParams: BuildDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type BuildDeltaOrderFunctions = { - /** @description Build Orders to be posted to Delta API for execution */ + /** @description Build a Delta v2 order from a DeltaRoute via the server endpoint, ready to sign and post. */ buildDeltaOrder: BuildDeltaOrder; }; export const constructBuildDeltaOrder = ( options: ConstructFetchInput ): BuildDeltaOrderFunctions => { - const { chainId } = options; - - // cached internally - const { getDeltaContract } = constructGetDeltaContract(options); - // cached internally for `partner` - const { getPartnerFee } = constructGetPartnerFee(options); - - const buildDeltaOrder: BuildDeltaOrder = async (options, requestParams) => { - const ParaswapDelta = await getDeltaContract(requestParams); - if (!ParaswapDelta) { - throw new Error(`Delta is not available on chain ${chainId}`); - } - - const { partnerAddress, partnerFeeBps, partnerTakesSurplus } = - await resolvePartnerFee(options, getPartnerFee, requestParams); - - const { srcAmount, destAmount, expectedAmount, swapSide } = - resolveAmounts(options); - - const input: BuildDeltaOrderDataInput = { - owner: options.owner, - beneficiary: options.beneficiary, - srcToken: options.srcToken, - // for some cases of WETH->ETH crosschain swaps, the destToken is changed to WETH or ETH, - // this is already reflected in deltaPrice - destToken: options.deltaPrice.destToken, - srcAmount, - destAmount, - expectedAmount, - deadline: options.deadline, - nonce: options.nonce?.toString(10), - permit: options.permit, - kind: SwapSideToOrderKind[swapSide], - metadata: options.metadata, - - chainId, - paraswapDeltaAddress: ParaswapDelta, - partnerAddress, - partnerTakesSurplus, - partnerFeeBps, - - capSurplus: options.capSurplus, - - bridge: options.deltaPrice.bridge, // ZERO_BRIDGE for same-chain Orders - }; - - return buildDeltaSignableOrderData(input); - }; - - return { - buildDeltaOrder, - }; + const { apiURL = API_URL, fetcher } = options; + const buildUrl = `${apiURL}/delta/v2/orders/build` as const; + + const buildDeltaOrder: BuildDeltaOrder = async (params, requestParams) => + fetcher>({ + url: buildUrl, + method: 'POST', + data: { + side: params.side, + route: params.route, + owner: params.owner, + beneficiary: params.beneficiary, + deadline: params.deadline, + nonce: params.nonce, + permit: params.permit, + slippage: params.slippage, + limitAmount: params.limitAmount, + metadata: params.metadata, + partiallyFillable: params.partiallyFillable, + partner: params.partner, + partnerAddress: params.partnerAddress, + partnerFeeBps: params.partnerFeeBps, + partnerTakesSurplus: params.partnerTakesSurplus, + capSurplus: params.capSurplus, + orderType: 'Order', + }, + requestParams, + }); + + return { buildDeltaOrder }; }; diff --git a/src/methods/delta/buildExternalDeltaOrder.ts b/src/methods/delta/buildExternalDeltaOrder.ts index 8fc31b260..fe79e186a 100644 --- a/src/methods/delta/buildExternalDeltaOrder.ts +++ b/src/methods/delta/buildExternalDeltaOrder.ts @@ -1,124 +1,95 @@ +import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import { constructGetDeltaContract } from './getDeltaContract'; -import type { DeltaPrice } from './getDeltaPrice'; -import { constructGetPartnerFee } from './getPartnerFee'; -import { - buildExternalOrderSignableData, - type BuildExternalOrderDataInput, - type SignableExternalOrderData, -} from './helpers/buildExternalOrderData'; -import type { DeltaAmountsWithSlippage } from './helpers/types'; -import { SwapSideToOrderKind } from './helpers/types'; -import type { MarkOptional } from 'ts-essentials'; -import { resolvePartnerFee, resolveAmounts } from './helpers/misc'; -export type { SignableExternalOrderData } from './helpers/buildExternalOrderData'; +import type { ExternalDeltaOrder } from './helpers/types'; +import type { BuiltDeltaOrder, DeltaRoute } from './types'; +export type { BuiltDeltaOrder } from './types'; -type BuildExternalDeltaOrderParamsBase = { +export type BuildExternalDeltaOrderParams = { /** @description The address of the order owner */ owner: string; /** @description The address of the external handler contract */ handler: string; /** @description Protocol-specific encoded bytes for the external handler */ data: string; - /** @description The address of the src token */ - srcToken: string; - /** @description The address of the dest token */ - destToken: string; - /** @description The deadline for the order */ + /** @description The address of the order beneficiary. Defaults to owner. */ + beneficiary?: string; + /** @description The deadline for the order (unix seconds) */ deadline?: number; - /** @description The nonce of the order */ - nonce?: number | string; - /** @description Optional permit signature for the src token */ + /** @description The nonce of the order. Random if omitted. */ + nonce?: string; + /** @description Optional permit signature for the src token. Defaults to "0x". */ permit?: string; - /** @description Partner string */ + /** @description Partner string. Passed to the server to resolve partner fee details. */ partner?: string; - /** @description partner fee in basis points (bps), 50bps=0.5% */ + /** @description Partner fee in basis points (bps), 50bps=0.5% */ partnerFeeBps?: number; - /** @description partner address */ + /** @description Partner address */ partnerAddress?: string; - /** @description take surplus */ + /** @description Take surplus flag */ partnerTakesSurplus?: boolean; - /** @description A boolean indicating whether the surplus should be capped. True by default */ + /** @description Whether the surplus should be capped. True by default. */ capSurplus?: boolean; /** @description Metadata for the order, hex string */ metadata?: string; + /** @description Designates the Order as partially fillable. Default false. */ + partiallyFillable?: boolean; - /** @description price response received from /delta/prices (getDeltaPrice method) */ - deltaPrice: MarkOptional< - Pick< - DeltaPrice, - 'destAmount' | 'partner' | 'partnerFee' | 'destToken' | 'srcAmount' - >, - 'partner' | 'partnerFee' - >; + /** @description DeltaRoute from getDeltaPrice */ + route: DeltaRoute; + /** @description Order side. SELL or BUY. */ + side: 'SELL' | 'BUY'; + /** @description Slippage in basis points (bps). Default 0. */ + slippage?: number; + /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ + limitAmount?: string; }; -export type BuildExternalDeltaOrderParams = BuildExternalDeltaOrderParamsBase & - DeltaAmountsWithSlippage; - type BuildExternalDeltaOrder = ( buildOrderParams: BuildExternalDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type BuildExternalDeltaOrderFunctions = { - /** @description Build External Orders to be posted to Delta API for execution */ + /** @description Build a Delta v2 External Order from a DeltaRoute via the server endpoint, ready to sign and post. */ buildExternalDeltaOrder: BuildExternalDeltaOrder; }; export const constructBuildExternalDeltaOrder = ( options: ConstructFetchInput ): BuildExternalDeltaOrderFunctions => { - const { chainId } = options; - - // cached internally - const { getDeltaContract } = constructGetDeltaContract(options); - // cached internally for `partner` - const { getPartnerFee } = constructGetPartnerFee(options); + const { apiURL = API_URL, fetcher } = options; + const buildUrl = `${apiURL}/delta/v2/orders/build` as const; const buildExternalDeltaOrder: BuildExternalDeltaOrder = async ( - options, + params, requestParams - ) => { - const ParaswapDelta = await getDeltaContract(requestParams); - if (!ParaswapDelta) { - throw new Error(`Delta is not available on chain ${chainId}`); - } - - const { partnerAddress, partnerFeeBps, partnerTakesSurplus } = - await resolvePartnerFee(options, getPartnerFee, requestParams); - - const { srcAmount, destAmount, expectedAmount, swapSide } = - resolveAmounts(options); - - const input: BuildExternalOrderDataInput = { - owner: options.owner, - handler: options.handler, - srcToken: options.srcToken, - destToken: options.deltaPrice.destToken, - srcAmount, - destAmount, - expectedAmount, - deadline: options.deadline, - nonce: options.nonce?.toString(10), - permit: options.permit, - kind: SwapSideToOrderKind[swapSide], - metadata: options.metadata, - data: options.data, - - chainId, - paraswapDeltaAddress: ParaswapDelta, - partnerAddress, - partnerTakesSurplus, - partnerFeeBps, - - capSurplus: options.capSurplus, - }; - - return buildExternalOrderSignableData(input); - }; + ) => + fetcher>({ + url: buildUrl, + method: 'POST', + data: { + side: params.side, + route: params.route, + owner: params.owner, + handler: params.handler, + data: params.data, + beneficiary: params.beneficiary, + deadline: params.deadline, + nonce: params.nonce, + permit: params.permit, + slippage: params.slippage, + limitAmount: params.limitAmount, + metadata: params.metadata, + partiallyFillable: params.partiallyFillable, + partner: params.partner, + partnerAddress: params.partnerAddress, + partnerFeeBps: params.partnerFeeBps, + partnerTakesSurplus: params.partnerTakesSurplus, + capSurplus: params.capSurplus, + orderType: 'ExternalOrder', + }, + requestParams, + }); - return { - buildExternalDeltaOrder, - }; + return { buildExternalDeltaOrder }; }; diff --git a/src/methods/delta/buildTWAPDeltaOrder.ts b/src/methods/delta/buildTWAPDeltaOrder.ts index d7ed8b1a9..ac17f037a 100644 --- a/src/methods/delta/buildTWAPDeltaOrder.ts +++ b/src/methods/delta/buildTWAPDeltaOrder.ts @@ -1,187 +1,131 @@ +import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import { DEFAULT_BRIDGE } from './constants'; -import { constructGetDeltaContract } from './getDeltaContract'; -import type { BridgePrice } from './getDeltaPrice'; -import { constructGetPartnerFee } from './getPartnerFee'; -import { - buildTWAPSignableOrderData, - TWAPOrderCommonInput, - type BuildTWAPOrderDataInput, - type SignableTWAPOrderData, -} from './helpers/buildTWAPOrderData'; -import { applySlippage, resolvePartnerFee } from './helpers/misc'; -import type { MarkOptional } from 'ts-essentials'; -export type { SignableTWAPOrderData } from './helpers/buildTWAPOrderData'; +import type { TWAPBuyDeltaOrder, TWAPDeltaOrder } from './helpers/types'; +import type { BuiltDeltaOrder, DeltaRoute } from './types'; +export type { BuiltDeltaOrder } from './types'; -type BuildTWAPDeltaOrderParamsBase = { +type BuildTWAPDeltaOrderBase = { /** @description The address of the order owner */ owner: string; - /** @description The address of the order beneficiary */ + /** @description The address of the order beneficiary. Defaults to owner. */ beneficiary?: string; - /** @description The address of the src token */ - srcToken: string; - /** @description The address of the dest token. For Crosschain Order - destination token on the destination chain */ - destToken: string; - /** @description The deadline for the order */ + /** @description The deadline for the order (unix seconds) */ deadline?: number; - /** @description The nonce of the order */ - nonce?: number | string; - /** @description Optional permit signature for the src token */ + /** @description The nonce of the order. Random if omitted. */ + nonce?: string; + /** @description Optional permit signature for the src token. Defaults to "0x". */ permit?: string; - /** @description Partner string */ + /** @description Partner string. Passed to the server to resolve partner fee details. */ partner?: string; - /** @description Destination Chain ID for Crosschain Orders */ - destChainId?: number; /** @description Seconds between slice executions (min 60) */ interval: number; /** @description Number of slices (min 2) */ numSlices: number; - /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5% */ + /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ slippage?: number; - - /** @description price response received from /delta/prices (getDeltaPrice method) for a single slice */ - deltaPrice: MarkOptional< - Pick< - BridgePrice, - | 'destAmount' - | 'partner' - | 'partnerFee' - | 'destToken' - | 'srcAmount' - | 'bridge' - >, - 'partner' | 'partnerFee' - >; - - /** @description partner fee in basis points (bps), 50bps=0.5% */ + /** @description DeltaRoute from getDeltaPrice for a single slice */ + route: DeltaRoute; + /** @description Partner fee in basis points (bps) */ partnerFeeBps?: number; - /** @description partner address */ + /** @description Partner address */ partnerAddress?: string; - /** @description take surplus */ + /** @description Take surplus flag */ partnerTakesSurplus?: boolean; - /** @description A boolean indicating whether the surplus should be capped. True by default */ + /** @description Whether the surplus should be capped. True by default. */ capSurplus?: boolean; /** @description Metadata for the order, hex string */ metadata?: string; + /** @description Designates the Order as partially fillable. Default false. */ + partiallyFillable?: boolean; + /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount for each slice */ + limitAmount?: string; }; -export type BuildTWAPSellOrderParams = BuildTWAPDeltaOrderParamsBase & { - /** @description Must be "TWAPOrder" for sell orders */ +export type BuildTWAPSellDeltaOrderParams = BuildTWAPDeltaOrderBase & { onChainOrderType: 'TWAPOrder'; - /** @description Total source token amount across all slices */ + /** @description Total source token amount across all slices. route.origin.input.amount must equal floor(totalSrcAmount / numSlices). */ totalSrcAmount: string; }; -export type BuildTWAPBuyOrderParams = BuildTWAPDeltaOrderParamsBase & { - /** @description Must be "TWAPBuyOrder" for buy orders */ +export type BuildTWAPBuyDeltaOrderParams = BuildTWAPDeltaOrderBase & { onChainOrderType: 'TWAPBuyOrder'; - /** @description Total destination token amount to buy across all slices */ + /** @description Total destination token amount to buy across all slices. route.origin.output.amount must equal floor(totalDestAmount / numSlices). */ totalDestAmount: string; - /** @description Maximum source token amount willing to spend */ + /** @description Maximum source token amount willing to spend across all slices. */ maxSrcAmount: string; }; export type BuildTWAPDeltaOrderParams = - | BuildTWAPSellOrderParams - | BuildTWAPBuyOrderParams; + | BuildTWAPSellDeltaOrderParams + | BuildTWAPBuyDeltaOrderParams; type BuildTWAPDeltaOrder = ( buildOrderParams: BuildTWAPDeltaOrderParams, requestParams?: RequestParameters -) => Promise; +) => Promise>; export type BuildTWAPDeltaOrderFunctions = { - /** @description Build TWAP Orders (sell or buy) to be posted to Delta API for execution */ + /** @description Build a Delta v2 TWAP Order (sell or buy) from a DeltaRoute via the server endpoint, ready to sign and post. */ buildTWAPDeltaOrder: BuildTWAPDeltaOrder; }; export const constructBuildTWAPDeltaOrder = ( options: ConstructFetchInput ): BuildTWAPDeltaOrderFunctions => { - const { chainId } = options; - - const { getDeltaContract } = constructGetDeltaContract(options); - const { getPartnerFee } = constructGetPartnerFee(options); + const { apiURL = API_URL, fetcher } = options; + const buildUrl = `${apiURL}/delta/v2/orders/build` as const; const buildTWAPDeltaOrder: BuildTWAPDeltaOrder = async ( params, requestParams ) => { - const ParaswapDelta = await getDeltaContract(requestParams); - if (!ParaswapDelta) { - throw new Error(`Delta is not available on chain ${chainId}`); - } - - const { partnerAddress, partnerFeeBps, partnerTakesSurplus } = - await resolvePartnerFee(params, getPartnerFee, requestParams); - - const commonInput: TWAPOrderCommonInput = { + const commonBody = { + route: params.route, owner: params.owner, beneficiary: params.beneficiary, - srcToken: params.srcToken, - destToken: params.deltaPrice.destToken, deadline: params.deadline, - nonce: params.nonce?.toString(10), + nonce: params.nonce, permit: params.permit, + slippage: params.slippage, + limitAmount: params.limitAmount, metadata: params.metadata, + partiallyFillable: params.partiallyFillable, + partner: params.partner, + partnerAddress: params.partnerAddress, + partnerFeeBps: params.partnerFeeBps, + partnerTakesSurplus: params.partnerTakesSurplus, + capSurplus: params.capSurplus, interval: params.interval, numSlices: params.numSlices, - bridge: { - ...params.deltaPrice.bridge, - // TWAP child orders get their bridge data at execution time - protocolData: DEFAULT_BRIDGE.protocolData, - }, - - chainId, - paraswapDeltaAddress: ParaswapDelta, - partnerAddress, - partnerTakesSurplus, - partnerFeeBps, - capSurplus: params.capSurplus, }; - let input: BuildTWAPOrderDataInput; - if (params.onChainOrderType === 'TWAPOrder') { - const slippage = params.slippage ?? 0; - const destAmountPerSlice = - slippage > 0 - ? applySlippage({ - amount: params.deltaPrice.destAmount, - slippageBps: slippage, - increase: false, - }) - : params.deltaPrice.destAmount; - - input = { - ...commonInput, - onChainOrderType: 'TWAPOrder', - destAmountPerSlice, - totalSrcAmount: params.totalSrcAmount, - }; - } else { - const slippage = params.slippage ?? 0; - const maxSrcAmount = - slippage > 0 - ? applySlippage({ - amount: params.maxSrcAmount, - slippageBps: slippage, - increase: true, - }) - : params.maxSrcAmount; - - input = { - ...commonInput, - onChainOrderType: 'TWAPBuyOrder', - totalDestAmount: params.totalDestAmount, - maxSrcAmount, - }; + return fetcher>({ + url: buildUrl, + method: 'POST', + data: { + ...commonBody, + side: 'SELL', + orderType: 'TWAPOrder', + totalSrcAmount: params.totalSrcAmount, + }, + requestParams, + }); } - return buildTWAPSignableOrderData(input); + return fetcher>({ + url: buildUrl, + method: 'POST', + data: { + ...commonBody, + side: 'BUY', + orderType: 'TWAPBuyOrder', + totalDestAmount: params.totalDestAmount, + maxSrcAmount: params.maxSrcAmount, + }, + requestParams, + }); }; - return { - buildTWAPDeltaOrder, - }; + return { buildTWAPDeltaOrder }; }; diff --git a/src/methods/delta/cancelDeltaOrder.ts b/src/methods/delta/cancelDeltaOrder.ts index 20ca8de6b..29835be72 100644 --- a/src/methods/delta/cancelDeltaOrder.ts +++ b/src/methods/delta/cancelDeltaOrder.ts @@ -6,7 +6,7 @@ import type { import { constructGetDeltaContract } from './getDeltaContract'; import { buildCancelDeltaOrderSignableData, - CancelDeltaOrderData, + type CancelDeltaOrderData, } from './helpers/buildCancelDeltaOrderData'; type SuccessResponse = { success: true }; @@ -32,10 +32,10 @@ export type CancelDeltaOrder = ( ) => Promise; export type CancelDeltaOrderFunctions = { - signCancelLimitDeltaOrderRequest: SignCancelDeltaOrderRequest; - postCancelLimitDeltaOrderRequest: PostCancelDeltaOrderRequest; - /** @description Cancel a Limit Delta order */ - cancelLimitDeltaOrders: CancelDeltaOrder; + signCancelDeltaOrderRequest: SignCancelDeltaOrderRequest; + postCancelDeltaOrderRequest: PostCancelDeltaOrderRequest; + /** @description Cancel one or more Delta orders via the v2 endpoint */ + cancelDeltaOrders: CancelDeltaOrder; }; export const constructCancelDeltaOrder = ( @@ -46,10 +46,9 @@ export const constructCancelDeltaOrder = ( ): CancelDeltaOrderFunctions => { const apiURL = options.apiURL ?? API_URL; - // cached internally const { getDeltaContract } = constructGetDeltaContract(options); - const signCancelLimitDeltaOrderRequest: SignCancelDeltaOrderRequest = async ( + const signCancelDeltaOrderRequest: SignCancelDeltaOrderRequest = async ( params, requestParams ) => { @@ -63,50 +62,39 @@ export const constructCancelDeltaOrder = ( paraswapDeltaAddress: ParaswapDelta, chainId: options.chainId, }); - const signature = await options.contractCaller.signTypedDataCall(typedData); - return signature; + return options.contractCaller.signTypedDataCall(typedData); }; - const postCancelLimitDeltaOrderRequest: PostCancelDeltaOrderRequest = async ( + const postCancelDeltaOrderRequest: PostCancelDeltaOrderRequest = async ( params, requestParams ) => { - const cancelUrl = `${apiURL}/delta/orders/cancel` as const; + const cancelUrl = `${apiURL}/delta/v2/orders/cancel` as const; - const res = await options.fetcher({ + return options.fetcher({ url: cancelUrl, method: 'POST', data: params, requestParams, }); - - return res; }; - const cancelLimitDeltaOrders: CancelDeltaOrder = async ( + const cancelDeltaOrders: CancelDeltaOrder = async ( { orderIds }, requestParams ) => { - const signature = await signCancelLimitDeltaOrderRequest( + const signature = await signCancelDeltaOrderRequest( { orderIds }, requestParams ); - const res = await postCancelLimitDeltaOrderRequest( - { - orderIds, - signature, - }, - requestParams - ); - - return res; + return postCancelDeltaOrderRequest({ orderIds, signature }, requestParams); }; return { - signCancelLimitDeltaOrderRequest, - postCancelLimitDeltaOrderRequest, - cancelLimitDeltaOrders, + signCancelDeltaOrderRequest, + postCancelDeltaOrderRequest, + cancelDeltaOrders, }; }; diff --git a/src/methods/delta/constants.ts b/src/methods/delta/constants.ts deleted file mode 100644 index bc22e0e0e..000000000 --- a/src/methods/delta/constants.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ZERO_ADDRESS } from '../common/orders/buildOrderData'; -import { Bridge } from './helpers/types'; - -// for same-chain Orders, all 0 params -export const DEFAULT_BRIDGE = { - protocolSelector: '0x00000000', // 4 bytes - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', -} as const satisfies Bridge; diff --git a/src/methods/deltaV2/getAgentsList.ts b/src/methods/delta/getAgentsList.ts similarity index 100% rename from src/methods/deltaV2/getAgentsList.ts rename to src/methods/delta/getAgentsList.ts diff --git a/src/methods/delta/getBridgeInfo.ts b/src/methods/delta/getBridgeInfo.ts deleted file mode 100644 index b3d33981f..000000000 --- a/src/methods/delta/getBridgeInfo.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { API_URL } from '../../constants'; -import { constructSearchString } from '../../helpers/misc'; -import type { - Address, - ConstructFetchInput, - RequestParameters, -} from '../../types'; - -// srcChainId -> destChainId -> outputToken[] -// output Tokens that are supported for a srcChainId -> destChainId pair -export type BridgeInfo = Record>; -type BridgeInfoResponse = { supportedTokens: BridgeInfo }; - -type GetBridgeInfoParams = { - /** @description Include tokens that can be swapped on destChain after bridge. Default is true. */ - allowBridgeAndSwap?: boolean; - /** @description Include only the specified bridges. Default is all bridges. */ - bridges?: string[]; -}; - -type BridgeInfoQuery = { - allowBridgeAndSwap?: boolean; - bridges?: string; -}; - -type GetBridgeInfo = ( - params?: GetBridgeInfoParams, - requestParams?: RequestParameters -) => Promise; - -export type BridgeProtocolResponse = { - protocol: string; - displayName: string; - icon: string; -}; - -type BridgeProtocolsResponse = { - bridgeProtocols: BridgeProtocolResponse[]; -}; - -type GetBridgeProtocols = ( - requestParams?: RequestParameters -) => Promise; - -export type GetBridgeInfoFunctions = { - getBridgeInfo: GetBridgeInfo; - getBridgeProtocols: GetBridgeProtocols; -}; - -export const constructGetBridgeInfo = ({ - apiURL = API_URL, - fetcher, -}: ConstructFetchInput): GetBridgeInfoFunctions => { - const deltaBridgeUrl = `${apiURL}/delta/prices` as const; - - const getBridgeInfo: GetBridgeInfo = async (params = {}, requestParams) => { - const { allowBridgeAndSwap, bridges } = params; - const bridgesString = bridges ? bridges.join(',') : undefined; - - const search = constructSearchString({ - allowBridgeAndSwap, - bridges: bridgesString, - }); - - const fetchURL = `${deltaBridgeUrl}/bridge-info${search}` as const; - - const data = await fetcher({ - url: fetchURL, - method: 'GET', - requestParams, - }); - - return data.supportedTokens; - }; - - const getBridgeProtocols: GetBridgeProtocols = async (requestParams) => { - const fetchURL = `${deltaBridgeUrl}/bridge-protocols` as const; - - const data = await fetcher({ - url: fetchURL, - method: 'GET', - requestParams, - }); - - return data.bridgeProtocols; - }; - - return { - getBridgeInfo, - getBridgeProtocols, - }; -}; diff --git a/src/methods/deltaV2/getBridgeRoutes.ts b/src/methods/delta/getBridgeRoutes.ts similarity index 95% rename from src/methods/deltaV2/getBridgeRoutes.ts rename to src/methods/delta/getBridgeRoutes.ts index 6ae9f12f5..32b2dbf47 100644 --- a/src/methods/deltaV2/getBridgeRoutes.ts +++ b/src/methods/delta/getBridgeRoutes.ts @@ -1,9 +1,14 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { BridgeProtocolResponse } from '../delta/getBridgeInfo'; import type { BridgeRoute } from './types'; +export type BridgeProtocolResponse = { + protocol: string; + displayName: string; + icon: string; +}; + type GetBridgeRoutesParams = { /** @description Include tokens that can be swapped on destChain after bridge. Default is true. */ allowBridgeAndSwap?: boolean; diff --git a/src/methods/delta/getDeltaOrders.ts b/src/methods/delta/getDeltaOrders.ts index 26bebd142..d5f25dd97 100644 --- a/src/methods/delta/getDeltaOrders.ts +++ b/src/methods/delta/getDeltaOrders.ts @@ -3,25 +3,11 @@ import { constructSearchString } from '../../helpers/misc'; import type { Address, ConstructFetchInput, + PaginatedResponse, RequestParameters, } from '../../types'; -import type { - DeltaAuction, - DeltaAuctionStatus, - DeltaOrderType, - OnChainOrderMap, -} from './helpers/types'; - -/** @deprecated Use DeltaAuction directly */ -export type DeltaOrderFromAPI = DeltaAuction; - -export type DeltaOrderFilterByStatus = - | DeltaAuctionStatus - | 'INSUFFICIENT_BALANCE' - | 'INSUFFICIENT_ALLOWANCE' - | 'INVALIDATED' - | 'ACTIVE' - | 'INACTIVE'; +import type { DeltaOrderType, OnChainOrderType } from './helpers/types'; +import type { DeltaOrderStatus, DeltaAuction } from './types'; type GetDeltaOrderById = ( orderId: string, @@ -33,44 +19,32 @@ type GetDeltaOrderByHash = ( requestParams?: RequestParameters ) => Promise; -type OrdersFilter = { - /** @description Order.owner to fetch Delta Order for */ +type OrdersFilter = { + /** @description `order.owner` to fetch Delta Orders for. */ userAddress: Address; - /** @description Pagination option, page. Default 1 */ + /** @description Pagination option. Default 1. */ page?: number; - /** @description Pagination option, limit. Default 100 */ + /** @description Pagination option. Default 100, max 1000. */ limit?: number; - /** @description Filter by chainId, without this filter, orders from all chains are returned */ + /** @description Filter by chainId. Omitted = orders across all chains. */ chainId?: number[]; - /** - * @description - * Filter by any known DeltaAuctionStatus and some custom statuses: - * - **INSUFFICIENT_BALANCE** — returned as SUSPENDED from API - * - **INSUFFICIENT_ALLOWANCE** — returned as SUSPENDED from API - * - **INVALIDATED** — returned as FAILED from API - * - **ACTIVE** — All orders with NOT_STARTED, RUNNING, EXECUTING, CANCELLING or SUSPENDED statuses. - * - **INACTIVE** — All orders with EXECUTED, FAILED, EXPIRED, CANCELLED or INVALIDATED statuses. - */ - status?: DeltaOrderFilterByStatus[]; - /** @description Filter by type. MARKET, LIMIT. Orders with both types are returned if not specified */ + /** @description Filter by integrator-facing status. */ + status?: DeltaOrderStatus[]; + /** @description Filter by order type. MARKET or LIMIT. */ type?: DeltaOrderType; - /** @description Filter by on-chain order type. Order, ExternalOrder. Orders of all types are returned if not specified */ - onChainOrderType?: T; + /** @description Filter by on-chain order type. */ + onChainOrderType?: OnChainOrderType; }; + type OrderFiltersQuery = Omit & { chainId?: string; status?: string; }; -type GetDeltaOrders = { - ( - options: OrdersFilter & { onChainOrderType: T }, - requestParams?: RequestParameters - ): Promise[]>; - (options: OrdersFilter, requestParams?: RequestParameters): Promise< - DeltaAuction[] - >; -}; +type GetDeltaOrders = ( + options: OrdersFilter, + requestParams?: RequestParameters +) => Promise>; type GetRequiredBalanceParams = { userAddress: Address; @@ -80,13 +54,17 @@ type GetRequiredBalanceParams = { type GetRequiredBalance = ( userParams: GetRequiredBalanceParams, requestParams?: RequestParameters -) => Promise>; // token -> balance in Limit Orders +) => Promise>; // token -> required balance across open Delta orders export type GetDeltaOrdersFunctions = { + /** @description Fetch a single order by its UUID. */ getDeltaOrderById: GetDeltaOrderById; + /** @description Fetch a single order by its EIP-712 order hash. */ getDeltaOrderByHash: GetDeltaOrderByHash; + /** @description List Delta orders with the v2 pagination envelope. */ getDeltaOrders: GetDeltaOrders; - getRequiredBalanceForDeltaLimitOrders: GetRequiredBalance; + /** @description Required balance per token across the user's open Delta v2 orders. Pass `tokenAddress` to narrow the result to a single token. */ + getRequiredBalanceForDeltaOrders: GetRequiredBalance; }; export const constructGetDeltaOrders = ({ @@ -94,21 +72,18 @@ export const constructGetDeltaOrders = ({ fetcher, chainId, }: ConstructFetchInput): GetDeltaOrdersFunctions => { - const baseUrl = `${apiURL}/delta/orders` as const; + const baseUrl = `${apiURL}/delta/v2/orders` as const; const getDeltaOrderById: GetDeltaOrderById = async ( orderId, requestParams ) => { const fetchURL = `${baseUrl}/${orderId}` as const; - - const order = await fetcher({ + return fetcher({ url: fetchURL, method: 'GET', requestParams, }); - - return order; }; const getDeltaOrderByHash: GetDeltaOrderByHash = async ( @@ -116,22 +91,14 @@ export const constructGetDeltaOrders = ({ requestParams ) => { const fetchURL = `${baseUrl}/hash/${orderHash}` as const; - - const order = await fetcher({ + return fetcher({ url: fetchURL, method: 'GET', requestParams, }); - - return order; }; - const getDeltaOrders: GetDeltaOrders = async < - T extends keyof OnChainOrderMap = keyof OnChainOrderMap - >( - options: OrdersFilter, - requestParams?: RequestParameters - ) => { + const getDeltaOrders: GetDeltaOrders = async (options, requestParams) => { const chainIdString = options.chainId?.join(','); const statusString = options.status?.join(','); @@ -147,16 +114,14 @@ export const constructGetDeltaOrders = ({ const fetchURL = `${baseUrl}${search}` as const; - const orders = await fetcher[]>({ + return fetcher>({ url: fetchURL, method: 'GET', requestParams, }); - - return orders; }; - const getRequiredBalanceForDeltaLimitOrders: GetRequiredBalance = async ( + const getRequiredBalanceForDeltaOrders: GetRequiredBalance = async ( userParams, requestParams ) => { @@ -179,6 +144,6 @@ export const constructGetDeltaOrders = ({ getDeltaOrderById, getDeltaOrderByHash, getDeltaOrders, - getRequiredBalanceForDeltaLimitOrders, + getRequiredBalanceForDeltaOrders, }; }; diff --git a/src/methods/delta/getDeltaPrice.ts b/src/methods/delta/getDeltaPrice.ts index 7f6d7a7ee..6ca39cb6e 100644 --- a/src/methods/delta/getDeltaPrice.ts +++ b/src/methods/delta/getDeltaPrice.ts @@ -1,5 +1,3 @@ -import { Prettify } from 'viem'; -import { Bridge } from '../..'; import { API_URL, SwapSide } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { @@ -7,14 +5,14 @@ import type { EnumerateLiteral, RequestParameters, } from '../../types'; -import { BridgePriceInfo } from './helpers/types'; +import type { DeltaPrice } from './types'; type SwapSideUnion = EnumerateLiteral; export type DeltaPriceParams = { /** @description Source Token Address */ srcToken: string; - /** @description Destination Token Address */ + /** @description Destination Token Address. For Crosschain Orders, the destination token on the destination chain */ destToken: string; /** @description srcToken amount in wei */ amount: string; @@ -25,16 +23,16 @@ export type DeltaPriceParams = { /** @description User's Wallet Address */ userAddress?: string; /** @description Beneficiary Address */ - beneficiary?: string; // beneficiary==owner if no transferTo + beneficiary?: string; /** @description Partner string. */ partner?: string; - /** @description Used together with `partner` if provided. Represented in basis points, 50bps=0.5% */ + /** @description Partner fee in basis points (bps), 50bps=0.5% */ partnerFeeBps?: number; /** @description Destination Chain ID for Crosschain Orders */ destChainId?: number; /** @description SELL or BUY, default is SELL */ side?: SwapSideUnion; - /** @description In %. It's a way to bypass the API price impact check (default = 15%) */ + /** @description In %. Bypasses the API price impact check (default = 15%) */ maxImpact?: number; maxUSDImpact?: number; @@ -52,101 +50,20 @@ type DeltaPriceQueryOptions = Omit< DeltaPriceParams, 'includeAgents' | 'excludeAgents' | 'includeBridges' | 'excludeBridges' > & { - chainId: number; // will return error from API on unsupported chains + chainId: number; includeAgents?: string; excludeAgents?: string; includeBridges?: string; excludeBridges?: string; }; -export type DeltaPrice = { - srcToken: string; - destToken: string; - srcAmount: string; - /** @description Available for BUY side */ - srcAmountBeforeFee?: string; - destAmount: string; - /** @description Available for SELL side */ - destAmountBeforeFee?: string; - /** @description amount of the final outcome token */ - receivedDestAmount: string; - receivedDestUSD: string; - /** @description Available for SELL side */ - receivedDestAmountBeforeFee?: string; - /** @description Available for SELL side */ - receivedDestUSDBeforeFee?: string; - gasCost: string; - gasCostBeforeFee: string; - gasCostUSD: string; - gasCostUSDBeforeFee: string; - srcUSD: string; - /** @description Available for BUY side */ - srcUSDBeforeFee?: string; - destUSD: string; - /** @description Available for SELL side */ - destUSDBeforeFee?: string; - partner: string; - partnerFee: number; // in % - hmac: string; - bridge: Bridge; // for single-chain DeltaPrice, it's DEFAULT_BRIDGE -}; - -type AvailableBridgePrice = Pick< - DeltaPrice, - | 'srcAmount' - | 'srcAmountBeforeFee' // Available for BUY side - | 'srcUSD' - | 'srcUSDBeforeFee' // Available for BUY side - | 'destToken' - | 'destAmount' - | 'destAmountBeforeFee' // Available for SELL side - | 'destUSD' - | 'destUSDBeforeFee' // Available for SELL side - | 'gasCostUSD' - | 'gasCost' - | 'gasCostUSDBeforeFee' - | 'gasCostBeforeFee' - | 'receivedDestAmount' - | 'receivedDestAmountBeforeFee' - | 'receivedDestUSD' - | 'receivedDestUSDBeforeFee' ->; - -export type AvailableBridge = Prettify< - AvailableBridgePrice & Pick ->; - -export type BridgePrice = Omit & { - // destAmountAfterBridge: string; // became bridgeInfo.destAmountAfterBridge - // destUSDAfterBridge: string; // became bridgeInfo.destUSDAfterBridge - // bridgeFee: string; // became bridgeInfo.fees[0].amount - // bridgeFeeUSD: string; // became bridgeInfo.fees[0].amountInUSD - // poolAddress: string; - bridge: Bridge; - bridgeInfo: BridgePriceInfo; - availableBridges: AvailableBridge[]; -}; - -type DeltaPriceResponse = { - price: DeltaPrice | BridgePrice; - deltaAddress: string; -}; - -interface GetDeltaPrice { - ( - options: DeltaPriceParams & { destChainId: number }, - requestParams?: RequestParameters - ): Promise; - ( - options: DeltaPriceParams & { destChainId?: undefined }, - requestParams?: RequestParameters - ): Promise; - (options: DeltaPriceParams, requestParams?: RequestParameters): Promise< - DeltaPrice | BridgePrice - >; -} +type GetDeltaPrice = ( + options: DeltaPriceParams, + requestParams?: RequestParameters +) => Promise; export type GetDeltaPriceFunctions = { + /** @description Fetch a v2 price quote (route-based response). */ getDeltaPrice: GetDeltaPrice; }; @@ -155,24 +72,9 @@ export const constructGetDeltaPrice = ({ chainId, fetcher, }: ConstructFetchInput): GetDeltaPriceFunctions => { - const pricesUrl = `${apiURL}/delta/prices` as const; + const pricesUrl = `${apiURL}/delta/v2/prices` as const; - async function getDeltaPrice( - options: DeltaPriceParams & { destChainId: number }, - requestParams?: RequestParameters - ): Promise; - async function getDeltaPrice( - options: DeltaPriceParams & { destChainId?: undefined }, - requestParams?: RequestParameters - ): Promise; - async function getDeltaPrice( - options: DeltaPriceParams, - requestParams?: RequestParameters - ): Promise; - async function getDeltaPrice( - options: DeltaPriceParams, - requestParams?: RequestParameters - ): Promise { + const getDeltaPrice: GetDeltaPrice = async (options, requestParams) => { const { includeAgents, excludeAgents, @@ -180,41 +82,27 @@ export const constructGetDeltaPrice = ({ excludeBridges, ...rest } = options; - const includeAgentsString = includeAgents - ? includeAgents.join(',') - : undefined; - const excludeAgentsString = excludeAgents - ? excludeAgents.join(',') - : undefined; - const includeBridgesString = includeBridges - ? includeBridges.join(',') - : undefined; - const excludeBridgesString = excludeBridges - ? excludeBridges.join(',') - : undefined; const search = constructSearchString({ ...rest, chainId, side: options.side ?? SwapSide.SELL, - includeAgents: includeAgentsString, - excludeAgents: excludeAgentsString, - includeBridges: includeBridgesString, - excludeBridges: excludeBridgesString, + includeAgents: includeAgents?.join(','), + excludeAgents: excludeAgents?.join(','), + includeBridges: includeBridges?.join(','), + excludeBridges: excludeBridges?.join(','), }); const fetchURL = `${pricesUrl}${search}` as const; - const data = await fetcher({ + const data = await fetcher({ url: fetchURL, method: 'GET', requestParams, }); - return data.price; - } - - return { - getDeltaPrice, + return data; }; + + return { getDeltaPrice }; }; diff --git a/src/methods/delta/helpers/orders.ts b/src/methods/delta/helpers/orders.ts index 927307f23..7443f7750 100644 --- a/src/methods/delta/helpers/orders.ts +++ b/src/methods/delta/helpers/orders.ts @@ -1,13 +1,7 @@ import type { NonEmptyArray, Prettify } from 'ts-essentials'; import { Bridge, - DeltaAuction, DeltaAuctionOrder, - DeltaAuctionStatus, - DeltaAuctionTransaction, - DeltaAuctionTWAP, - DeltaAuctionTWAPBuy, - DeltaOrderUnion, ExternalDeltaOrder, OnChainOrderType, OrderKind, @@ -15,10 +9,32 @@ import { SwapSideUnion, TWAPBuyDeltaOrder, TWAPDeltaOrder, + DeltaOrderUnion, UnifiedDeltaOrderData, } from './types'; +import type { + DeltaAuction, + DeltaOrderStatus, + DeltaTokenSide, + DeltaTransaction, +} from '../types'; + +/** + * Delta order helpers. + * + * The on-chain order structs (`auction.order`) and the `onChainOrderType` union + * are shared across all order families, so the order-struct guards, auction + * discriminant guards, and order-level getters operate purely on those shapes. + * + * The *auction* envelope is the integrator-facing v2 shape: + * - `status` is the integrator-facing `DeltaOrderStatus` + * (PENDING/ACTIVE/COMPLETED/…), + * - amounts live on `input`/`output` (`DeltaTokenSide`) and `transactions` + * (`DeltaTransaction`), + * - `side` is carried explicitly on the auction. + */ -///// CHECKS ////// +///// CHECKS — order structs ////// /** * @description Checks whether an order is a TWAP Sell or TWAP Buy order. @@ -39,6 +55,7 @@ function isTWAPSellOrder(order: DeltaOrderUnion): order is TWAPDeltaOrder { typeof order.totalSrcAmount === 'string' ); } + /** * @description Checks whether an order is a TWAP Buy order. */ @@ -76,6 +93,8 @@ function isProductiveOrder( return 'strategy' in order && typeof order.strategy === 'string'; } +///// CHECKS — auction discriminants ////// + /** * @description Checks whether an auction is a TWAP auction. */ @@ -130,29 +149,189 @@ function isProductiveAuction(auction: { return auction.onChainOrderType === 'ProductiveOrder'; } +/** + * @description Checks whether an auction is a Fillable auction. + * `FillableOrder` is the `onChainOrderType` the server reports for a + * `partiallyFillable` Standard order; it carries the same order struct as + * `Order`. Consumers that don't distinguish the two should treat + * `isDeltaAuction(a) || isFillableAuction(a)` as "is a standard order". + */ +function isFillableAuction>( + auction: T +): auction is T & { onChainOrderType: 'FillableOrder' } { + return auction.onChainOrderType === 'FillableOrder'; +} + +///// CHECKS — status / execution (v2 envelope) ////// + +/** + * @description Checks whether an auction is fully executed (settled on every chain). + */ +function isCompletedAuction>( + auction: T +): auction is T & { status: 'COMPLETED' } { + return auction.status === 'COMPLETED'; +} + +const failedAuctionStatuses = [ + 'FAILED', + 'EXPIRED', + 'CANCELLED', + 'REFUNDED', +] as const; + +const failedAuctionStatusesSet = new Set( + failedAuctionStatuses +); + +/** + * @description Checks whether an auction is in a terminal failure state + * (failed, expired, cancelled, or refunded). + */ +function isFailedAuction>( + auction: T +): auction is T & { status: (typeof failedAuctionStatuses)[number] } { + return failedAuctionStatusesSet.has(auction.status); +} + +/** + * @description Checks whether an auction status is cancelled. + */ +function isCanceledAuction>( + auction: T +): auction is T & { status: 'CANCELLED' } { + return auction.status === 'CANCELLED'; +} + +/** + * @description Checks whether an auction status is expired. + */ +function isExpiredAuction>( + auction: T +): auction is T & { status: 'EXPIRED' } { + return auction.status === 'EXPIRED'; +} + +const pendingAuctionStatuses = [ + 'PENDING', + 'AWAITING_SIGNATURE', + 'ACTIVE', + 'BRIDGING', +] as const; + +const pendingAuctionStatusesSet = new Set( + pendingAuctionStatuses +); + +/** + * @description Checks whether an auction is still in flight (not yet settled + * and not failed): awaiting signature, pending, actively executing, or bridging. + */ +function isPendingAuction>( + auction: T +): auction is T & { status: (typeof pendingAuctionStatuses)[number] } { + return pendingAuctionStatusesSet.has(auction.status); +} + +/** + * @description Checks whether an auction has been partially executed: + * it has at least one transaction and an overall filled percent strictly + * between 0 and 100. + */ +function isPartiallyExecutedAuction< + T extends Pick +>( + auction: T +): auction is T & { transactions: NonEmptyArray } { + if (auction.transactions.length === 0) return false; + + const filledPercent = getFilledPercent(auction); + + return filledPercent > 0 && filledPercent < 100; +} + +/** + * @description Checks whether an order includes valid cross-chain bridge details. + */ +function isOrderCrosschain( + order: T +): order is Prettify & { bridge: Bridge }> { + return ( + 'bridge' in order && !!order.bridge && order.bridge.destinationChainId !== 0 + ); +} + const checks = { + // order-struct guards isTWAPOrder, isTWAPSellOrder, isTWAPBuyOrder, isExternalOrder, isDeltaOrder, isProductiveOrder, + isOrderCrosschain, + + // auction discriminant guards isTWAPAuction, isTWAPSellAuction, isTWAPBuyAuction, isDeltaAuction, isExternalAuction, isProductiveAuction, - isOrderCrosschain, - isExecutedAuction, - isPartiallyExecutedAuction, + isFillableAuction, + + // status / execution guards (v2 envelope) + isCompletedAuction, isFailedAuction, isCanceledAuction, isExpiredAuction, isPendingAuction, + isPartiallyExecutedAuction, }; -///// GETTERS ////// +///// GETTERS — order structs ////// + +const OrderKindToSwapSide = { + [OrderKind.Sell]: 'SELL', + [OrderKind.Buy]: 'BUY', +} as const; + +/** + * @description Returns swap side from a Delta or External order kind. + */ +function getSwapSideFromDeltaOrder( + order: DeltaAuctionOrder | ExternalDeltaOrder +): SwapSideUnion { + return OrderKindToSwapSide[order.kind]; +} + +const TwapTypeToSwapSide = { + TWAPOrder: 'SELL', + TWAPBuyOrder: 'BUY', +} as const; + +/** + * @description Returns swap side from TWAP on-chain order type. + */ +function getSwapSideFromTwapOrderType( + onChainOrderType: 'TWAPOrder' | 'TWAPBuyOrder' +): SwapSideUnion { + return TwapTypeToSwapSide[onChainOrderType]; +} + +/** + * @description Returns source and destination token addresses for an order. + */ +function getOrderTokenAddresses(order: DeltaAuction['order']) { + const srcToken = order.srcToken; + const destToken = isOrderCrosschain(order) + ? order.bridge.outputToken + : order.destToken; + return { + srcToken, + destToken, + }; +} /** * @description Returns the expected source amount for a TWAP order. @@ -201,177 +380,88 @@ function getExpectedTwapOrderAmounts( return { srcAmount, destAmount }; } -/** - * @description Returns expected and, when available, final amounts for a TWAP auction. - */ -function getTwapAuctionAmounts( - twapAuction: - | Pick - | Pick -) { - const isExecuted = isExecutedAuction(twapAuction); +function scaleByFactor(amount: bigint, scalingFactor: number): bigint { + if (!amount) return 0n; - const expected = getExpectedTwapOrderAmounts(twapAuction.order); - if (isExecuted) { - const final = getTransactionAmounts(twapAuction.transactions); - return { - final, - expected, - minimal: expected, // TWAP orders don't have more detailed amounts - }; - } - return { - expected, - minimal: expected, // TWAP orders don't have more detailed amounts - }; -} + if (scalingFactor === 0) return amount; -const getters = { - getUnifiedDeltaOrderData, - getExpectedTwapSrcAmount, - getExpectedTwapDestAmount, - getExpectedTwapOrderAmounts, - getTwapAuctionAmounts, - getAuctionDestChainId, - getSwapSideFromDeltaOrder, - getSwapSideFromTwapOrderType, - getAuctionSwapSide, - getOrderTokenAddresses, - getTransactionAmounts, - getAuctionAmounts, - getFilledPercent, -}; + const base = 10n; -export const OrderHelpers = { - checks, - getters, -}; + return scalingFactor < 0 + ? amount / base ** BigInt(-scalingFactor) + : amount * base ** BigInt(scalingFactor); +} -// -------------------- Auction Unified Data -------------------- +///// GETTERS — auction envelope (v2) ////// /** - * @description Returns the destination chain id for the auction. + * @description Reads an amount off a v2 token side. A SELL input / BUY output + * carries an explicit `amount`; the opposite side carries + * `expectedAmount`/`executedAmount`. `prefer` chooses which to read on the + * expected/executed variant. */ -function getAuctionDestChainId({ - order, - chainId, -}: Pick) { - return isOrderCrosschain(order) ? order.bridge.destinationChainId : chainId; -} +function getTokenSideAmount( + side: DeltaTokenSide, + prefer: 'expected' | 'executed' +): string { + if ('amount' in side) return side.amount; -const OrderKindToSwapSide = { - [OrderKind.Sell]: 'SELL', - [OrderKind.Buy]: 'BUY', -} as const; + const value = + prefer === 'executed' ? side.executedAmount : side.expectedAmount; -/** - * @description Returns swap side from a Delta or External order kind. - */ -function getSwapSideFromDeltaOrder( - order: DeltaAuctionOrder | ExternalDeltaOrder -): SwapSideUnion { - return OrderKindToSwapSide[order.kind]; + return value ?? '0'; } -const TwapTypeToSwapSide = { - TWAPOrder: 'SELL', - TWAPBuyOrder: 'BUY', -} as const; - /** - * @description Returns swap side from TWAP on-chain order type. + * @description Returns the source chain id for the auction (the input side's chain). */ -function getSwapSideFromTwapOrderType( - onChainOrderType: 'TWAPOrder' | 'TWAPBuyOrder' -): SwapSideUnion { - return TwapTypeToSwapSide[onChainOrderType]; +function getAuctionSrcChainId(auction: Pick): number { + return auction.input.chainId; } /** - * @description Returns swap side for any auction type. + * @description Returns the destination chain id for the auction (the output side's chain). + * Equals the source chain id for same-chain orders. */ -function getAuctionSwapSide(auction: DeltaAuction): SwapSideUnion { - if (isTWAPAuction(auction)) { - // TWAP orders have onChainOrderType instead of kind - return getSwapSideFromTwapOrderType(auction.onChainOrderType); - } - if (isProductiveAuction(auction)) { - // ProductiveOrders don't carry an explicit OrderKind; treated as SELL. - return 'SELL'; - } - return getSwapSideFromDeltaOrder(auction.order); +function getAuctionDestChainId(auction: Pick): number { + return auction.output.chainId; } /** - * @description Returns unified order data with normalized amounts, tokens, and side. + * @description Returns the swap side for any auction. The auction carries `side` + * directly, so no order introspection is needed. */ -function getUnifiedDeltaOrderData( - auction: DeltaAuction -): UnifiedDeltaOrderData { - const { order, chainId } = auction; - - const { srcToken, destToken } = getOrderTokenAddresses(order); - const { expected, final, minimal } = getAuctionAmounts(auction); - - const srcChainId = chainId; - const destChainId = getAuctionDestChainId({ order, chainId }); - - const swapSide = getAuctionSwapSide(auction); - - const filledPercent = getFilledPercent(auction); - - return { - srcChainId, - destChainId, - srcAmount: final?.srcAmount || expected.srcAmount, - destAmount: final?.destAmount || expected.destAmount, - amounts: { - expected, - final, - minimal, - }, - srcToken, - destToken, - swapSide, - filledPercent, - }; +function getAuctionSwapSide( + auction: Pick +): SwapSideUnion { + return auction.side; } /** - * @description Returns source and destination token addresses for an order. + * @description Returns source and destination token addresses for the auction, + * read from the input/output sides (already resolved to the dest-chain token + * for cross-chain orders). */ -function getOrderTokenAddresses(order: DeltaAuction['order']) { - const srcToken = order.srcToken; - const destToken = isOrderCrosschain(order) - ? order.bridge.outputToken - : order.destToken; +function getAuctionTokenAddresses( + auction: Pick +) { return { - srcToken, - destToken, + srcToken: auction.input.token, + destToken: auction.output.token, }; } /** - * @description Aggregates transaction amounts into total source and destination values. + * @description Aggregates transaction amounts into total spent (src) and + * received (dest) values. */ -function getTransactionAmounts(transactions: DeltaAuctionTransaction[]) { +function getTransactionAmounts(transactions: DeltaTransaction[]) { const { srcAmount, destAmount } = transactions.reduce( - (acc, { spentAmount, receivedAmount, bridgeMetadata }) => { - return { - srcAmount: acc.srcAmount + BigInt(spentAmount), - destAmount: - acc.destAmount + - BigInt( - bridgeMetadata?.outputAmount - ? bridgeMetadata.outputAmount - : receivedAmount - ), - }; - }, - { - srcAmount: 0n, - destAmount: 0n, - } + (acc, { spentAmount, receivedAmount }) => ({ + srcAmount: acc.srcAmount + BigInt(spentAmount ?? 0), + destAmount: acc.destAmount + BigInt(receivedAmount ?? 0), + }), + { srcAmount: 0n, destAmount: 0n } ); return { @@ -381,224 +471,125 @@ function getTransactionAmounts(transactions: DeltaAuctionTransaction[]) { } /** - * @description Returns expected and, when available, final amounts for an auction. + * @description Calculates the overall filled percent (0–100) from the + * per-transaction `filledPercent` values. For TWAP orders each transaction is + * a slice (0–100 of that slice), so the slice values are averaged across + * `numSlices`; for single-fill orders the values sum directly. */ -function getAuctionAmounts(auction: DeltaAuction) { - const isTwap = checks.isTWAPAuction(auction); - if (isTwap) { - return getTwapAuctionAmounts(auction); - } - - let expected = { - srcAmount: auction.order.srcAmount, - // defensive fallback in case Order shape changes or legacy Orders don't have all fields - destAmount: auction.order.expectedAmount || auction.order.destAmount, - }; - - let minimal = { - srcAmount: auction.order.srcAmount, - destAmount: auction.order.destAmount, - }; +function getFilledPercent( + auction: Pick +): number { + if (auction.transactions.length === 0) return 0; - const order = auction.order; + const total = auction.transactions.reduce( + (acc, { filledPercent }) => acc + filledPercent, + 0 + ); - if (isOrderCrosschain(order)) { - expected = { - srcAmount: expected.srcAmount, - destAmount: scaleByFactor( - BigInt(expected.destAmount), - order.bridge.scalingFactor - ).toString(), - }; - - minimal = { - srcAmount: minimal.srcAmount, - destAmount: scaleByFactor( - BigInt(minimal.destAmount), - order.bridge.scalingFactor - ).toString(), - }; + if (isTWAPOrder(auction.order) && auction.order.numSlices > 0) { + return total / auction.order.numSlices; } - const isExecuted = isExecutedAuction(auction); - if (isExecuted) { - const final = getTransactionAmounts(auction.transactions); - return { - final, - expected, - minimal, - }; - } - return { - expected, - minimal, - }; + return total; } /** - * @description Checks whether an order includes valid cross-chain bridge details. + * @description Returns the executed amount of a token side when present, + * otherwise the provided fallback (typically summed from transactions). */ -function isOrderCrosschain( - order: T - // Extract == never -): order is Prettify & { bridge: Bridge }> { - return ( - 'bridge' in order && !!order.bridge && order.bridge.destinationChainId !== 0 - ); -} - -function scaleByFactor(amount: bigint, scalingFactor: number): bigint { - if (!amount) return 0n; - - if (scalingFactor === 0) return amount; - - const base = 10n; +function getExecutedAmount(side: DeltaTokenSide, fallback: string): string { + if ('executedAmount' in side && side.executedAmount != null) { + return side.executedAmount; + } - return scalingFactor < 0 - ? amount / base ** BigInt(-scalingFactor) - : amount * base ** BigInt(scalingFactor); + return fallback; } -type ExecutedDeltaAuctionProps = { - status: 'EXECUTED'; - transactions: NonEmptyArray; -}; - /** - * @description Checks whether an auction is fully executed. + * @description Returns expected amounts and, once the auction is completed, + * executed amounts. Executed amounts prefer the `executedAmount` baked onto the + * token sides and fall back to summing transactions. */ -function isExecutedAuction< - T extends Pick ->(auction: T): auction is T & ExecutedDeltaAuctionProps { - if (auction.status !== 'EXECUTED') return false; +function getAuctionAmounts( + auction: Pick< + DeltaAuction, + 'status' | 'order' | 'input' | 'output' | 'transactions' + > +) { + const expected = { + srcAmount: getTokenSideAmount(auction.input, 'expected'), + destAmount: getTokenSideAmount(auction.output, 'expected'), + }; - if (isOrderCrosschain(auction.order)) { - const filledPercent = getFilledPercent(auction); - return filledPercent === 100; + if (!isCompletedAuction(auction)) { + return { expected }; } - return true; -} - -const failedAuctionStatuses = [ - 'FAILED', - 'EXPIRED', - 'CANCELLED', - 'REFUNDED', -] as const; - -const failedAuctionStatusesSet = new Set( - failedAuctionStatuses -); - -type FailedDeltaAuctionProps = - | { - status: (typeof failedAuctionStatuses)[number]; - } - | { - status: 'EXECUTED'; // srcChain tx succeeded - bridgeStatus: 'expired' | 'refunded'; // destChain tx failed or relayer didn't deliver - }; - -/** - * @description Checks whether an auction is failed on source or destination chain. - */ -function isFailedAuction< - T extends Pick ->(auction: T): auction is T & FailedDeltaAuctionProps { - // already failed on srcChain, whether Order is crosschain or not - if (failedAuctionStatusesSet.has(auction.status)) return true; - - // crosschain Order is executed on srcChain, but failed on destChain - if (auction.status === 'EXECUTED' && isOrderCrosschain(auction.order)) { - return ( - auction.bridgeStatus === 'expired' || auction.bridgeStatus === 'refunded' - ); - } + const txAmounts = getTransactionAmounts(auction.transactions); - return false; -} + const executed = { + srcAmount: getExecutedAmount(auction.input, txAmounts.srcAmount), + destAmount: getExecutedAmount(auction.output, txAmounts.destAmount), + }; -/** - * @description Checks whether an auction status is cancelled. - */ -function isCanceledAuction>( - auction: T -): auction is T & { - status: 'CANCELLED'; -} { - return auction.status === 'CANCELLED'; + return { expected, executed }; } /** - * @description Checks whether an auction status is expired. + * @description Returns unified order data with normalized amounts, tokens, + * chain ids, and side, built from the auction envelope. */ -function isExpiredAuction>( - auction: T -): auction is T & { - status: 'EXPIRED'; -} { - return auction.status === 'EXPIRED'; -} +function getUnifiedDeltaOrderData( + auction: DeltaAuction +): UnifiedDeltaOrderData { + const { srcToken, destToken } = getAuctionTokenAddresses(auction); + const { expected, executed } = getAuctionAmounts(auction); -const pendingAuctionStatuses = [ - 'NOT_STARTED', - 'AWAITING_PRE_SIGNATURE', - 'RUNNING', - 'EXECUTING', -] as const; + const srcChainId = getAuctionSrcChainId(auction); + const destChainId = getAuctionDestChainId(auction); + const swapSide = getAuctionSwapSide(auction); + const filledPercent = getFilledPercent(auction); -const pendingAuctionStatusesSet = new Set( - pendingAuctionStatuses -); -/** - * @description Checks whether an auction status is in pending execution states. - */ -function isPendingAuction>( - auction: T -): auction is T & { - status: (typeof pendingAuctionStatuses)[number]; -} { - return pendingAuctionStatusesSet.has(auction.status); + return { + srcChainId, + destChainId, + srcAmount: executed?.srcAmount || expected.srcAmount, + destAmount: executed?.destAmount || expected.destAmount, + amounts: { + expected, + // No separate "minimal" amount in the v2 envelope; mirrors expected. + minimal: expected, + final: executed, + }, + srcToken, + destToken, + swapSide, + filledPercent, + }; } -/** - * @description Auction can be cancelled in the middle of execution, - * or crosschain-TWAP slices may not all be bridged, - * or order can be suspended if it runs out of user balance/allowance. - * Orders in the middle of normal execution can also be considered partially executed if they have any transactions. - */ -function isPartiallyExecutedAuction< - T extends Pick ->( - auction: T -): auction is T & { transactions: NonEmptyArray } { - if (auction.transactions.length === 0) return false; - - const filledPercent = getFilledPercent(auction); +const getters = { + getUnifiedDeltaOrderData, - return filledPercent > 0 && filledPercent < 100; -} + // auction-level getters — v2 envelope shape. + getAuctionTokenAddresses, + getAuctionSrcChainId, + getAuctionDestChainId, + getAuctionSwapSide, + getTransactionAmounts, + getAuctionAmounts, + getFilledPercent, -/** - * @description Calculates filled percentage from auction transaction filled bps values. - */ -function getFilledPercent( - auction: Pick -): number { - const completeTransactions = !isOrderCrosschain(auction.order) - ? auction.transactions - : auction.transactions.filter( - (transaction) => transaction.bridgeStatus === 'filled' - ); - - const filledPercentBps = completeTransactions.reduce( - (acc, { filledPercent }) => { - return acc + filledPercent; - }, - 0 - ); + // order-level getters — order structs shared across families. + getOrderTokenAddresses, + getSwapSideFromDeltaOrder, + getSwapSideFromTwapOrderType, + getExpectedTwapSrcAmount, + getExpectedTwapDestAmount, + getExpectedTwapOrderAmounts, +}; - const filledPercent = filledPercentBps / 100; - return filledPercent; -} +export const OrderHelpers = { + checks, + getters, +}; diff --git a/src/methods/delta/helpers/types.ts b/src/methods/delta/helpers/types.ts index a42cdfdf5..6ae8913f5 100644 --- a/src/methods/delta/helpers/types.ts +++ b/src/methods/delta/helpers/types.ts @@ -1,6 +1,5 @@ import type { EnumerateLiteral } from '../../../types'; import { SwapSide } from '../../../constants'; -import { Prettify } from 'ts-essentials'; export type SwapSideUnion = EnumerateLiteral; @@ -200,52 +199,6 @@ export type TWAPBuyDeltaOrder = TWAPDeltaOrderBase & { maxSrcAmount: string; // wei }; -export type DeltaAuctionStatus = - | 'NOT_STARTED' - | 'AWAITING_PRE_SIGNATURE' - | 'RUNNING' - | 'EXECUTING' - | 'EXECUTED' - | 'FAILED' - | 'EXPIRED' - | 'CANCELLED' - | 'CANCELLING' - | 'SUSPENDED' - | 'REFUNDED'; - -export type DeltaAuctionTransaction = { - id: string; - hash: string; - orderId: string; - bidId: string | null; - blockNumber: number; - blockHash: string; - blockTimestamp: string | null; // ISO string, null for older Orders - gasUsed: bigint; - gasPrice: bigint; - blobGasUsed: bigint; - blobGasPrice: bigint; - index: number; - status: number; - from: string; - to: string; - receivedAmount: string; - receivedAmountUSD: number; - spentAmount: string; - spentAmountUSD: number; - filledPercent: number; // in base points - protocolFee: string; - partnerFee: string; - agent: string; - auctionId: string; - - // transactgion.bridge* fields = null for single-chain orders - bridgeMetadata: BridgeMetadata | null; - bridgeStatus: BridgeStatus | null; - bridgeProtocol: string | null; - bridgeOverride: Pick | null; -}; - export type OnChainOrderMap = { Order: DeltaAuctionOrder; FillableOrder: DeltaAuctionOrder; @@ -255,96 +208,8 @@ export type OnChainOrderMap = { ProductiveOrder: ProductiveDeltaOrder; }; -type BaseBridgeAuctionFields = Pick< - DeltaAuctionBase, - 'bridgeMetadata' | 'bridgeStatus' ->; - -type BridgeAuctionFiledsMap = { - Order: BaseBridgeAuctionFields; - FillableOrder: BaseBridgeAuctionFields; - ExternalOrder: BaseBridgeAuctionFields; - TWAPOrder: Record; - TWAPBuyOrder: Record; - ProductiveOrder: BaseBridgeAuctionFields; -}; - -type DeltaAuctionBase = { - id: string; - deltaVersion: string; // 1.0 or 2.0 currently - user: string; - status: DeltaAuctionStatus; - orderHash: string | null; // not available on old Orders only - transactions: DeltaAuctionTransaction[]; - chainId: number; - partner: string; - referrerAddress: string | null; - expiresAt: string; - createdAt: string; - updatedAt: string; - partiallyFillable: boolean; - - excludeAgents: string[] | null; - includeAgents: string[] | null; - - // bridge* fields = null for single-chain orders and all TWAP orders - bridgeMetadata: BridgeMetadata | null; - bridgeStatus: BridgeStatus | null; - - type: DeltaOrderType; -}; - -export type DeltaAuction = - T extends T - ? Prettify< - DeltaAuctionBase & { - onChainOrderType: T; - order: OnChainOrderMap[T]; - } & BridgeAuctionFiledsMap[T] - > - : never; - -export type DeltaAuctionDelta = DeltaAuction<'Order'>; -export type DeltaAuctionFillable = DeltaAuction<'FillableOrder'>; -export type DeltaAuctionExternal = DeltaAuction<'ExternalOrder'>; -export type DeltaAuctionTWAP = DeltaAuction<'TWAPOrder'>; -export type DeltaAuctionTWAPBuy = DeltaAuction<'TWAPBuyOrder'>; -export type DeltaAuctionProductive = DeltaAuction<'ProductiveOrder'>; - -export type DeltaAuctionUnion = - | DeltaAuctionDelta - | DeltaAuctionFillable - | DeltaAuctionExternal - | DeltaAuctionTWAP - | DeltaAuctionTWAPBuy - | DeltaAuctionProductive; - export type DeltaOrderUnion = OnChainOrderMap[keyof OnChainOrderMap]; -export type BridgeMetadata = { - /** @description Field is present after bridge is executed. - * The actual amount received from the bridge, which may differ - * from the expectedOutputAmount due to bridge slippage or other factors. - * */ - outputAmount?: string; - /** @description Field is present iff: order was built via POST /v2/orders/build, - * the route is cross-chain (route.bridge !== null and not an external handler), - * and the order is posted before the per-order cache entry expires. - */ - expectedOutputAmount?: string; - /** @description The cross-chain deadline. If deadline passes, the bridgeStatus would be expired */ - fillDeadline?: number; // available for Across protocol - /** @description The deposit id */ - depositId?: number; // available for Across protocol - /** @description The transaction hash on the destination chain that fulfilled the order. When bridgeStatus='filled' */ - fillTx?: string; - /** @description The transaction hash on the source chain that refunded the deposit. When bridgeStatus='refunded' */ - depositRefundTxHash?: string; -}; - -// refunded is basically failed -export type BridgeStatus = 'pending' | 'filled' | 'expired' | 'refunded'; - export type OnChainOrderType = keyof OnChainOrderMap; export type TWAPOnChainOrderType = 'TWAPOrder' | 'TWAPBuyOrder'; @@ -352,26 +217,6 @@ export type TWAPOnChainOrderType = 'TWAPOrder' | 'TWAPBuyOrder'; /** @description Order kind: MARKET (immediate) vs LIMIT (rate-pegged). */ export type DeltaOrderType = 'MARKET' | 'LIMIT'; -//// available on BridgePrice //// - -type BridgeQuoteFee = { - feeToken: string; - amount: string; - amountInSrcToken: string; - amountInUSD: string; -}; - -export type BridgePriceInfo = { - protocolName: string; - destAmountAfterBridge: string; - destUSDAfterBridge: string; - fees: BridgeQuoteFee[]; - estimatedTimeMs: number; - fastest: boolean; - bestReturn: boolean; - recommended: boolean; -}; - export type UnifiedDeltaOrderData = { /** @description amounts at the start of Order execution and after Order execution. May differ from each other */ amounts: { diff --git a/src/methods/delta/index.ts b/src/methods/delta/index.ts index dd0a1452f..4b56c7ba3 100644 --- a/src/methods/delta/index.ts +++ b/src/methods/delta/index.ts @@ -1,31 +1,11 @@ import type { ConstructProviderFetchInput } from '../../types'; -import type { DeltaAuction } from './helpers/types'; -import { - BuildDeltaOrderDataParams, - BuildDeltaOrderFunctions, - constructBuildDeltaOrder, -} from './buildDeltaOrder'; -import { - constructPostDeltaOrder, - DeltaOrderToPost, - PostDeltaOrderFunctions, -} from './postDeltaOrder'; -import { - constructSignDeltaOrder, - SignDeltaOrderFunctions, -} from './signDeltaOrder'; +import type { DeltaAuction } from './types'; + +// reused v1 modules import { GetDeltaContractFunctions, constructGetDeltaContract, } from './getDeltaContract'; -import { - constructGetDeltaPrice, - GetDeltaPriceFunctions, -} from './getDeltaPrice'; -import { - constructGetDeltaOrders, - GetDeltaOrdersFunctions, -} from './getDeltaOrders'; import { constructGetPartnerFee, GetPartnerFeeFunctions, @@ -34,64 +14,122 @@ import { ApproveTokenForDeltaFunctions, constructApproveTokenForDelta, } from './approveForDelta'; -import { - constructGetBridgeInfo, - GetBridgeInfoFunctions, -} from './getBridgeInfo'; -import { - constructIsTokenSupportedInDelta, - IsTokenSupportedInDeltaFunctions, -} from './isTokenSupportedInDelta'; -import { - CancelDeltaOrderFunctions, - constructCancelDeltaOrder, -} from './cancelDeltaOrder'; import { constructPreSignDeltaOrder, PreSignDeltaOrderFunctions, } from './preSignDeltaOrder'; +import { + constructPreSignExternalDeltaOrder, + PreSignExternalDeltaOrderFunctions, +} from './preSignExternalDeltaOrder'; +import { + constructPreSignTWAPDeltaOrder, + PreSignTWAPDeltaOrderFunctions, +} from './preSignTWAPDeltaOrder'; import { DeltaTokenModuleFunctions, constructDeltaTokenModule, } from './deltaTokenModule'; + +// new v2 modules +import { + BuildDeltaOrderFunctions, + BuildDeltaOrderParams, + BuiltDeltaOrder, + constructBuildDeltaOrder, +} from './buildDeltaOrder'; import { - BuildExternalDeltaOrderParams, BuildExternalDeltaOrderFunctions, + BuildExternalDeltaOrderParams, constructBuildExternalDeltaOrder, } from './buildExternalDeltaOrder'; import { - constructSignExternalDeltaOrder, - SignExternalDeltaOrderFunctions, -} from './signExternalDeltaOrder'; -import { - constructPostExternalDeltaOrder, - PostExternalDeltaOrderFunctions, -} from './postExternalDeltaOrder'; -import { - constructPreSignExternalDeltaOrder, - PreSignExternalDeltaOrderFunctions, -} from './preSignExternalDeltaOrder'; -import { - BuildTWAPDeltaOrderParams, BuildTWAPDeltaOrderFunctions, + BuildTWAPDeltaOrderParams, constructBuildTWAPDeltaOrder, } from './buildTWAPDeltaOrder'; import { - constructSignTWAPDeltaOrder, - SignTWAPDeltaOrderFunctions, -} from './signTWAPDeltaOrder'; + constructPostDeltaOrder, + DeltaOrderToPost, + PostDeltaOrderFunctions, +} from './postDeltaOrder'; +import { + constructPostExternalDeltaOrder, + PostExternalDeltaOrderFunctions, +} from './postExternalDeltaOrder'; import { constructPostTWAPDeltaOrder, PostTWAPDeltaOrderFunctions, } from './postTWAPDeltaOrder'; import { - constructPreSignTWAPDeltaOrder, - PreSignTWAPDeltaOrderFunctions, -} from './preSignTWAPDeltaOrder'; + constructGetDeltaPrice, + GetDeltaPriceFunctions, +} from './getDeltaPrice'; +import { + constructGetDeltaOrders, + GetDeltaOrdersFunctions, +} from './getDeltaOrders'; +import { + constructGetBridgeRoutes, + GetBridgeRoutesFunctions, +} from './getBridgeRoutes'; +import { + constructIsTokenSupportedInDelta, + IsTokenSupportedInDeltaFunctions, +} from './isTokenSupportedInDelta'; +import { + CancelDeltaOrderFunctions, + constructCancelDeltaOrder, +} from './cancelDeltaOrder'; +import { + constructGetAgentsList, + GetAgentsListFunctions, +} from './getAgentsList'; + +// Re-export the public surface so consumers can reach every leaf module. +export * from './types'; +export * from './buildDeltaOrder'; +export * from './buildExternalDeltaOrder'; +export * from './buildTWAPDeltaOrder'; +export * from './postDeltaOrder'; +export * from './postExternalDeltaOrder'; +export * from './postTWAPDeltaOrder'; +export * from './getDeltaPrice'; +export * from './getDeltaOrders'; +export * from './getBridgeRoutes'; +export * from './isTokenSupportedInDelta'; +export * from './cancelDeltaOrder'; +export * from './getAgentsList'; +export { OrderHelpers } from './helpers/orders'; + +// ── Sign v2 ───────────────────────────────────────────────────────────────── + +type SignDeltaOrder = (builtOrder: BuiltDeltaOrder) => Promise; + +export type SignDeltaOrderFunctions = { + /** @description Sign a BuiltDeltaOrder (any order type) using EIP-712 typed data. */ + signDeltaOrder: SignDeltaOrder; +}; -export type SubmitDeltaOrderParams = BuildDeltaOrderDataParams & { - /** @description designates the Order as being able to be partially filled, as opposed to fill-or-kill */ - partiallyFillable?: boolean; +export const constructSignDeltaOrder = ( + options: Pick< + ConstructProviderFetchInput, + 'contractCaller' + > +): SignDeltaOrderFunctions => { + const signDeltaOrder: SignDeltaOrder = async (builtOrder) => { + return options.contractCaller.signTypedDataCall({ + types: builtOrder.toSign.types, + domain: builtOrder.toSign.domain, + data: builtOrder.toSign.value, + }); + }; + return { signDeltaOrder }; +}; + +// ── Submit orchestrators ───────────────────────────────────────────────────── + +export type SubmitDeltaOrderParams = BuildDeltaOrderParams & { /** @description Referrer address */ referrerAddress?: string; degenMode?: boolean; @@ -109,7 +147,6 @@ export const constructSubmitDeltaOrder = ( options: ConstructProviderFetchInput ): SubmitDeltaOrderFuncs => { const { buildDeltaOrder } = constructBuildDeltaOrder(options); - // in the normal submitOrderFlow preSign tx is not involved const { signDeltaOrder } = constructSignDeltaOrder(options); const { postDeltaOrder } = constructPostDeltaOrder(options); @@ -117,10 +154,10 @@ export const constructSubmitDeltaOrder = ( const orderData = await buildDeltaOrder(orderParams); const signature = await signDeltaOrder(orderData); - const response = await postDeltaOrder({ + return postDeltaOrder({ signature, partner: orderParams.partner, - order: orderData.data, + order: orderData.toSign.value, partiallyFillable: orderParams.partiallyFillable, referrerAddress: orderParams.referrerAddress, type: orderParams.type, @@ -128,17 +165,12 @@ export const constructSubmitDeltaOrder = ( excludeAgents: orderParams.excludeAgents, degenMode: orderParams.degenMode, }); - - return response; }; return { submitDeltaOrder }; }; export type SubmitExternalDeltaOrderParams = BuildExternalDeltaOrderParams & { - /** @description designates the Order as being able to be partially filled, as opposed to fill-or-kill */ - partiallyFillable?: boolean; - /** @description Referrer address */ referrerAddress?: string; } & Pick; @@ -154,36 +186,31 @@ export const constructSubmitExternalDeltaOrder = ( options: ConstructProviderFetchInput ): SubmitExternalDeltaOrderFuncs => { const { buildExternalDeltaOrder } = constructBuildExternalDeltaOrder(options); - const { signExternalDeltaOrder } = constructSignExternalDeltaOrder(options); + const { signDeltaOrder } = constructSignDeltaOrder(options); const { postExternalDeltaOrder } = constructPostExternalDeltaOrder(options); const submitExternalDeltaOrder: SubmitExternalDeltaOrder = async ( orderParams ) => { const orderData = await buildExternalDeltaOrder(orderParams); - const signature = await signExternalDeltaOrder(orderData); + const signature = await signDeltaOrder(orderData); - const response = await postExternalDeltaOrder({ + return postExternalDeltaOrder({ signature, partner: orderParams.partner, - order: orderData.data, + order: orderData.toSign.value, partiallyFillable: orderParams.partiallyFillable, referrerAddress: orderParams.referrerAddress, type: orderParams.type, includeAgents: orderParams.includeAgents, excludeAgents: orderParams.excludeAgents, }); - - return response; }; return { submitExternalDeltaOrder }; }; export type SubmitTWAPDeltaOrderParams = BuildTWAPDeltaOrderParams & { - /** @description designates the Order as being able to be partially filled, as opposed to fill-or-kill */ - partiallyFillable?: boolean; - /** @description Referrer address */ referrerAddress?: string; degenMode?: boolean; } & Pick; @@ -200,17 +227,17 @@ export const constructSubmitTWAPDeltaOrder = ( options: ConstructProviderFetchInput ): SubmitTWAPDeltaOrderFuncs => { const { buildTWAPDeltaOrder } = constructBuildTWAPDeltaOrder(options); - const { signTWAPDeltaOrder } = constructSignTWAPDeltaOrder(options); + const { signDeltaOrder } = constructSignDeltaOrder(options); const { postTWAPDeltaOrder } = constructPostTWAPDeltaOrder(options); const submitTWAPDeltaOrder: SubmitTWAPDeltaOrder = async (orderParams) => { const orderData = await buildTWAPDeltaOrder(orderParams); - const signature = await signTWAPDeltaOrder(orderData); + const signature = await signDeltaOrder(orderData); - const response = await postTWAPDeltaOrder({ + return postTWAPDeltaOrder({ signature, partner: orderParams.partner, - order: orderData.data, + order: orderData.toSign.value, onChainOrderType: orderParams.onChainOrderType, partiallyFillable: orderParams.partiallyFillable, referrerAddress: orderParams.referrerAddress, @@ -219,39 +246,38 @@ export const constructSubmitTWAPDeltaOrder = ( excludeAgents: orderParams.excludeAgents, degenMode: orderParams.degenMode, }); - - return response; }; return { submitTWAPDeltaOrder }; }; -export type DeltaOrderHandlers = SubmitDeltaOrderFuncs & - ApproveTokenForDeltaFunctions & - BuildDeltaOrderFunctions & - GetDeltaOrdersFunctions & - GetDeltaPriceFunctions & - GetDeltaContractFunctions & - GetPartnerFeeFunctions & - GetBridgeInfoFunctions & - IsTokenSupportedInDeltaFunctions & - PostDeltaOrderFunctions & - SignDeltaOrderFunctions & - PreSignDeltaOrderFunctions & - CancelDeltaOrderFunctions & - DeltaTokenModuleFunctions & +// ── Handler bundle ─────────────────────────────────────────────────────────── + +export type DeltaOrderHandlers = SubmitDeltaOrderFuncs & SubmitExternalDeltaOrderFuncs & - BuildExternalDeltaOrderFunctions & - SignExternalDeltaOrderFunctions & - PostExternalDeltaOrderFunctions & - PreSignExternalDeltaOrderFunctions & SubmitTWAPDeltaOrderFuncs & + BuildDeltaOrderFunctions & + BuildExternalDeltaOrderFunctions & BuildTWAPDeltaOrderFunctions & - SignTWAPDeltaOrderFunctions & + PostDeltaOrderFunctions & + PostExternalDeltaOrderFunctions & PostTWAPDeltaOrderFunctions & - PreSignTWAPDeltaOrderFunctions; + SignDeltaOrderFunctions & + PreSignDeltaOrderFunctions & + PreSignExternalDeltaOrderFunctions & + PreSignTWAPDeltaOrderFunctions & + GetDeltaPriceFunctions & + GetDeltaOrdersFunctions & + GetBridgeRoutesFunctions & + IsTokenSupportedInDeltaFunctions & + GetAgentsListFunctions & + GetDeltaContractFunctions & + GetPartnerFeeFunctions & + ApproveTokenForDeltaFunctions & + DeltaTokenModuleFunctions & + CancelDeltaOrderFunctions; -/** @description construct SDK with every Delta Order-related method, fetching from API and Order signing */ +/** @description Construct an SDK bundle exposing every Delta v2 method (queries, build/sign/post, on-chain helpers). */ export const constructAllDeltaOrdersHandlers = ( options: ConstructProviderFetchInput< TxResponse, @@ -263,15 +289,17 @@ export const constructAllDeltaOrdersHandlers = ( const deltaPrice = constructGetDeltaPrice(options); const partnerFee = constructGetPartnerFee(options); - const bridgeInfo = constructGetBridgeInfo(options); + const bridgeRoutes = constructGetBridgeRoutes(options); const isTokenSupportedInDelta = constructIsTokenSupportedInDelta(options); + const agentsList = constructGetAgentsList(options); const approveTokenForDelta = constructApproveTokenForDelta(options); - const deltaOrdersSubmit = constructSubmitDeltaOrder(options); + // single signer for every order family + const deltaOrdersSign = constructSignDeltaOrder(options); + const deltaOrdersSubmit = constructSubmitDeltaOrder(options); const deltaOrdersBuild = constructBuildDeltaOrder(options); - const deltaOrdersSign = constructSignDeltaOrder(options); const deltaOrdersPreSign = constructPreSignDeltaOrder(options); const deltaOrdersPost = constructPostDeltaOrder(options); @@ -281,14 +309,12 @@ export const constructAllDeltaOrdersHandlers = ( const externalDeltaOrdersSubmit = constructSubmitExternalDeltaOrder(options); const externalDeltaOrdersBuild = constructBuildExternalDeltaOrder(options); - const externalDeltaOrdersSign = constructSignExternalDeltaOrder(options); const externalDeltaOrdersPost = constructPostExternalDeltaOrder(options); const externalDeltaOrdersPreSign = constructPreSignExternalDeltaOrder(options); const twapDeltaOrdersSubmit = constructSubmitTWAPDeltaOrder(options); const twapDeltaOrdersBuild = constructBuildTWAPDeltaOrder(options); - const twapDeltaOrdersSign = constructSignTWAPDeltaOrder(options); const twapDeltaOrdersPost = constructPostTWAPDeltaOrder(options); const twapDeltaOrdersPreSign = constructPreSignTWAPDeltaOrder(options); @@ -297,24 +323,23 @@ export const constructAllDeltaOrdersHandlers = ( ...deltaOrdersContractGetter, ...deltaPrice, ...partnerFee, - ...bridgeInfo, + ...bridgeRoutes, ...isTokenSupportedInDelta, + ...agentsList, ...approveTokenForDelta, + ...deltaOrdersSign, ...deltaOrdersSubmit, ...deltaOrdersBuild, - ...deltaOrdersSign, ...deltaOrdersPreSign, ...deltaOrdersPost, ...deltaOrdersCancel, ...deltaTokenModule, ...externalDeltaOrdersSubmit, ...externalDeltaOrdersBuild, - ...externalDeltaOrdersSign, ...externalDeltaOrdersPost, ...externalDeltaOrdersPreSign, ...twapDeltaOrdersSubmit, ...twapDeltaOrdersBuild, - ...twapDeltaOrdersSign, ...twapDeltaOrdersPost, ...twapDeltaOrdersPreSign, }; diff --git a/src/methods/delta/isTokenSupportedInDelta.ts b/src/methods/delta/isTokenSupportedInDelta.ts index c0ae668ed..ee14a94df 100644 --- a/src/methods/delta/isTokenSupportedInDelta.ts +++ b/src/methods/delta/isTokenSupportedInDelta.ts @@ -6,8 +6,8 @@ import type { RequestParameters, } from '../../types'; -type TokenSupportedInDeltaResponse = { supported: boolean }; -type IsTokenSupportedInDeltaQueryOptions = { +type TokenSupportedResponse = { supported: boolean }; +type IsTokenSupportedQuery = { token: Address; chainId: number; }; @@ -26,20 +26,20 @@ export const constructIsTokenSupportedInDelta = ({ chainId, fetcher, }: ConstructFetchInput): IsTokenSupportedInDeltaFunctions => { - const bridgeInfoUrl = `${apiURL}/delta/prices/is-token-supported` as const; + const baseUrl = `${apiURL}/delta/v2/prices/is-token-supported` as const; const isTokenSupportedInDelta: IsTokenSupportedInDelta = async ( token, requestParams ) => { - const search = constructSearchString({ + const search = constructSearchString({ token, chainId, }); - const fetchURL = `${bridgeInfoUrl}/${search}` as const; + const fetchURL = `${baseUrl}/${search}` as const; - const data = await fetcher({ + const data = await fetcher({ url: fetchURL, method: 'GET', requestParams, @@ -48,7 +48,5 @@ export const constructIsTokenSupportedInDelta = ({ return data.supported; }; - return { - isTokenSupportedInDelta, - }; + return { isTokenSupportedInDelta }; }; diff --git a/src/methods/delta/postDeltaOrder.ts b/src/methods/delta/postDeltaOrder.ts index b5c7fa8ac..f494de4db 100644 --- a/src/methods/delta/postDeltaOrder.ts +++ b/src/methods/delta/postDeltaOrder.ts @@ -1,11 +1,8 @@ import { API_URL } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { - DeltaAuction, - DeltaOrderType, - OnChainOrderMap, -} from './helpers/types'; +import type { DeltaOrderType, OnChainOrderMap } from './helpers/types'; +import type { DeltaAuction } from './types'; export type DeltaOrderToPost = { /** @description Partner string */ @@ -16,12 +13,10 @@ export type DeltaOrderToPost = { /** @description Signature of the order from order.owner address. EOA signatures must be submitted in ERC-2098 Compact Representation. */ signature: string; chainId: number; - /** @description designates the Order as being able to partially filled, as opposed to fill-or-kill */ + /** @description Designates the Order as being able to be partially filled, as opposed to fill-or-kill */ partiallyFillable?: boolean; - /** @description Type of the order. MARKET or LIMIT. Default is MARKET */ type?: DeltaOrderType; - includeAgents?: string[]; excludeAgents?: string[]; }; @@ -44,7 +39,7 @@ export const constructPostDeltaOrder = ({ chainId, fetcher, }: ConstructFetchInput): PostDeltaOrderFunctions => { - const postOrderUrl = `${apiURL}/delta/orders` as const; + const postOrderUrl = `${apiURL}/delta/v2/orders` as const; const postDeltaOrder: PostDeltaOrder = (_postData, requestParams) => { const { degenMode, ...postData } = _postData; diff --git a/src/methods/delta/postExternalDeltaOrder.ts b/src/methods/delta/postExternalDeltaOrder.ts index e3257d6d2..90b4455cd 100644 --- a/src/methods/delta/postExternalDeltaOrder.ts +++ b/src/methods/delta/postExternalDeltaOrder.ts @@ -1,7 +1,7 @@ import { API_URL } from '../../constants'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaAuction } from './helpers/types'; import type { DeltaOrderToPost } from './postDeltaOrder'; +import type { DeltaAuction } from './types'; export type PostExternalDeltaOrderParams = Omit< DeltaOrderToPost<'ExternalOrder'>, @@ -22,7 +22,7 @@ export const constructPostExternalDeltaOrder = ({ chainId, fetcher, }: ConstructFetchInput): PostExternalDeltaOrderFunctions => { - const postOrderUrl = `${apiURL}/delta/orders` as const; + const postOrderUrl = `${apiURL}/delta/v2/orders` as const; const postExternalDeltaOrder: PostExternalDeltaOrder = ( postData, diff --git a/src/methods/delta/postTWAPDeltaOrder.ts b/src/methods/delta/postTWAPDeltaOrder.ts index 0fce7555b..31cc4ddc2 100644 --- a/src/methods/delta/postTWAPDeltaOrder.ts +++ b/src/methods/delta/postTWAPDeltaOrder.ts @@ -1,9 +1,10 @@ -import { Prettify } from 'ts-essentials'; +import type { Prettify } from 'ts-essentials'; import { API_URL } from '../../constants'; +import { constructSearchString } from '../../helpers/misc'; import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaAuction, TWAPOnChainOrderType } from './helpers/types'; +import type { TWAPOnChainOrderType } from './helpers/types'; import type { DeltaOrderToPost } from './postDeltaOrder'; -import { constructSearchString } from '../../helpers/misc'; +import type { DeltaAuction } from './types'; export type PostTWAPDeltaOrderParams = Prettify< Omit< @@ -30,7 +31,7 @@ export const constructPostTWAPDeltaOrder = ({ chainId, fetcher, }: ConstructFetchInput): PostTWAPDeltaOrderFunctions => { - const postOrderUrl = `${apiURL}/delta/orders` as const; + const postOrderUrl = `${apiURL}/delta/v2/orders` as const; const postTWAPDeltaOrder: PostTWAPDeltaOrder = (_postData, requestParams) => { const { degenMode, ...postData } = _postData; diff --git a/src/methods/delta/signDeltaOrder.ts b/src/methods/delta/signDeltaOrder.ts deleted file mode 100644 index cd13fea1d..000000000 --- a/src/methods/delta/signDeltaOrder.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { ConstructProviderFetchInput } from '../../types'; -import { SignableDeltaOrderData } from './helpers/buildDeltaOrderData'; -import { sanitizeDeltaOrderData } from './helpers/misc'; - -type SignDeltaOrder = ( - signableOrderData: SignableDeltaOrderData -) => Promise; - -export type SignDeltaOrderFunctions = { - signDeltaOrder: SignDeltaOrder; -}; - -// returns whatever `contractCaller` returns -// to allow for better versatility -export const constructSignDeltaOrder = ( - options: Pick< - ConstructProviderFetchInput, - 'contractCaller' - > -): SignDeltaOrderFunctions => { - const signDeltaOrder: SignDeltaOrder = async (typedData) => { - // types allow to pass OrderData & extra_stuff, but tx will break like that - const typedDataOnly: SignableDeltaOrderData = { - ...typedData, - data: sanitizeDeltaOrderData(typedData.data), - }; - const signature = await options.contractCaller.signTypedDataCall( - typedDataOnly - ); - - return signature; - }; - - return { signDeltaOrder }; -}; diff --git a/src/methods/delta/signExternalDeltaOrder.ts b/src/methods/delta/signExternalDeltaOrder.ts deleted file mode 100644 index 2fc4d6e11..000000000 --- a/src/methods/delta/signExternalDeltaOrder.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { ConstructProviderFetchInput } from '../../types'; -import { SignableExternalOrderData } from './helpers/buildExternalOrderData'; -import { sanitizeExternalOrderData } from './helpers/misc'; - -type SignExternalDeltaOrder = ( - signableOrderData: SignableExternalOrderData -) => Promise; - -export type SignExternalDeltaOrderFunctions = { - signExternalDeltaOrder: SignExternalDeltaOrder; -}; - -// returns whatever `contractCaller` returns -// to allow for better versatility -export const constructSignExternalDeltaOrder = ( - options: Pick< - ConstructProviderFetchInput, - 'contractCaller' - > -): SignExternalDeltaOrderFunctions => { - const signExternalDeltaOrder: SignExternalDeltaOrder = async (typedData) => { - // types allow to pass OrderData & extra_stuff, but tx will break like that - const typedDataOnly: SignableExternalOrderData = { - ...typedData, - data: sanitizeExternalOrderData(typedData.data), - }; - const signature = await options.contractCaller.signTypedDataCall( - typedDataOnly - ); - - return signature; - }; - - return { signExternalDeltaOrder }; -}; diff --git a/src/methods/delta/signTWAPDeltaOrder.ts b/src/methods/delta/signTWAPDeltaOrder.ts deleted file mode 100644 index 736491c79..000000000 --- a/src/methods/delta/signTWAPDeltaOrder.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { ConstructProviderFetchInput } from '../../types'; -import { SignableTWAPOrderData } from './helpers/buildTWAPOrderData'; -import { sanitizeTWAPOrderData } from './helpers/misc'; - -type SignTWAPDeltaOrder = ( - signableOrderData: SignableTWAPOrderData -) => Promise; - -export type SignTWAPDeltaOrderFunctions = { - signTWAPDeltaOrder: SignTWAPDeltaOrder; -}; - -export const constructSignTWAPDeltaOrder = ( - options: Pick< - ConstructProviderFetchInput, - 'contractCaller' - > -): SignTWAPDeltaOrderFunctions => { - const signTWAPDeltaOrder: SignTWAPDeltaOrder = async (typedData) => { - const typedDataOnly = { - ...typedData, - data: sanitizeTWAPOrderData(typedData.data), - } as SignableTWAPOrderData; - const signature = await options.contractCaller.signTypedDataCall( - typedDataOnly - ); - - return signature; - }; - - return { signTWAPDeltaOrder }; -}; diff --git a/src/methods/deltaV2/types.ts b/src/methods/delta/types.ts similarity index 99% rename from src/methods/deltaV2/types.ts rename to src/methods/delta/types.ts index 0f3980962..f172d6260 100644 --- a/src/methods/deltaV2/types.ts +++ b/src/methods/delta/types.ts @@ -7,7 +7,7 @@ import type { DeltaOrderUnion, OnChainOrderMap, OnChainOrderType, -} from '../delta/helpers/types'; +} from './helpers/types'; /** @description Response from POST /delta/v2/orders/build — EIP-712 typed data ready to sign. */ export type BuiltDeltaOrder = { diff --git a/src/methods/deltaV2/buildDeltaOrder.ts b/src/methods/deltaV2/buildDeltaOrder.ts deleted file mode 100644 index 487ddeabc..000000000 --- a/src/methods/deltaV2/buildDeltaOrder.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { API_URL } from '../../constants'; -import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaAuctionOrder } from '../delta/helpers/types'; -import type { BuiltDeltaOrder, DeltaRoute } from './types'; -export type { BuiltDeltaOrder } from './types'; - -export type BuildDeltaOrderParams = { - /** @description The address of the order owner */ - owner: string; - /** @description The address of the order beneficiary. Defaults to owner. */ - beneficiary?: string; - /** @description The deadline for the order (unix seconds) */ - deadline?: number; - /** @description The nonce of the order. Random if omitted. */ - nonce?: string; - /** @description Optional permit signature for the src token. Defaults to "0x". */ - permit?: string; - /** @description Partner string. Passed to the server to resolve partner fee details. */ - partner?: string; - /** @description Partner fee in basis points (bps), 50bps=0.5% */ - partnerFeeBps?: number; - /** @description Partner address */ - partnerAddress?: string; - /** @description Take surplus flag */ - partnerTakesSurplus?: boolean; - /** @description Whether the surplus should be capped. True by default. */ - capSurplus?: boolean; - /** @description Metadata for the order, hex string */ - metadata?: string; - /** @description Designates the Order as partially fillable instead of fill-or-kill. Default false. */ - partiallyFillable?: boolean; - - /** @description DeltaRoute from getDeltaPrice — either price.route or any price.alternatives[i] */ - route: DeltaRoute; - /** @description Order side. SELL or BUY. */ - side: 'SELL' | 'BUY'; - /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ - slippage?: number; - /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ - limitAmount?: string; -}; - -type BuildDeltaOrder = ( - buildOrderParams: BuildDeltaOrderParams, - requestParams?: RequestParameters -) => Promise>; - -export type BuildDeltaOrderFunctions = { - /** @description Build a Delta v2 order from a DeltaRoute via the server endpoint, ready to sign and post. */ - buildDeltaOrder: BuildDeltaOrder; -}; - -export const constructBuildDeltaOrder = ( - options: ConstructFetchInput -): BuildDeltaOrderFunctions => { - const { apiURL = API_URL, fetcher } = options; - const buildUrl = `${apiURL}/delta/v2/orders/build` as const; - - const buildDeltaOrder: BuildDeltaOrder = async (params, requestParams) => - fetcher>({ - url: buildUrl, - method: 'POST', - data: { - side: params.side, - route: params.route, - owner: params.owner, - beneficiary: params.beneficiary, - deadline: params.deadline, - nonce: params.nonce, - permit: params.permit, - slippage: params.slippage, - limitAmount: params.limitAmount, - metadata: params.metadata, - partiallyFillable: params.partiallyFillable, - partner: params.partner, - partnerAddress: params.partnerAddress, - partnerFeeBps: params.partnerFeeBps, - partnerTakesSurplus: params.partnerTakesSurplus, - capSurplus: params.capSurplus, - orderType: 'Order', - }, - requestParams, - }); - - return { buildDeltaOrder }; -}; diff --git a/src/methods/deltaV2/buildExternalDeltaOrder.ts b/src/methods/deltaV2/buildExternalDeltaOrder.ts deleted file mode 100644 index 3b7e53c0d..000000000 --- a/src/methods/deltaV2/buildExternalDeltaOrder.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { API_URL } from '../../constants'; -import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { ExternalDeltaOrder } from '../delta/helpers/types'; -import type { BuiltDeltaOrder, DeltaRoute } from './types'; -export type { BuiltDeltaOrder } from './types'; - -export type BuildExternalDeltaOrderParams = { - /** @description The address of the order owner */ - owner: string; - /** @description The address of the external handler contract */ - handler: string; - /** @description Protocol-specific encoded bytes for the external handler */ - data: string; - /** @description The address of the order beneficiary. Defaults to owner. */ - beneficiary?: string; - /** @description The deadline for the order (unix seconds) */ - deadline?: number; - /** @description The nonce of the order. Random if omitted. */ - nonce?: string; - /** @description Optional permit signature for the src token. Defaults to "0x". */ - permit?: string; - /** @description Partner string. Passed to the server to resolve partner fee details. */ - partner?: string; - /** @description Partner fee in basis points (bps), 50bps=0.5% */ - partnerFeeBps?: number; - /** @description Partner address */ - partnerAddress?: string; - /** @description Take surplus flag */ - partnerTakesSurplus?: boolean; - /** @description Whether the surplus should be capped. True by default. */ - capSurplus?: boolean; - /** @description Metadata for the order, hex string */ - metadata?: string; - /** @description Designates the Order as partially fillable. Default false. */ - partiallyFillable?: boolean; - - /** @description DeltaRoute from getDeltaPrice */ - route: DeltaRoute; - /** @description Order side. SELL or BUY. */ - side: 'SELL' | 'BUY'; - /** @description Slippage in basis points (bps). Default 0. */ - slippage?: number; - /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount */ - limitAmount?: string; -}; - -type BuildExternalDeltaOrder = ( - buildOrderParams: BuildExternalDeltaOrderParams, - requestParams?: RequestParameters -) => Promise>; - -export type BuildExternalDeltaOrderFunctions = { - /** @description Build a Delta v2 External Order from a DeltaRoute via the server endpoint, ready to sign and post. */ - buildExternalDeltaOrder: BuildExternalDeltaOrder; -}; - -export const constructBuildExternalDeltaOrder = ( - options: ConstructFetchInput -): BuildExternalDeltaOrderFunctions => { - const { apiURL = API_URL, fetcher } = options; - const buildUrl = `${apiURL}/delta/v2/orders/build` as const; - - const buildExternalDeltaOrder: BuildExternalDeltaOrder = async ( - params, - requestParams - ) => - fetcher>({ - url: buildUrl, - method: 'POST', - data: { - side: params.side, - route: params.route, - owner: params.owner, - handler: params.handler, - data: params.data, - beneficiary: params.beneficiary, - deadline: params.deadline, - nonce: params.nonce, - permit: params.permit, - slippage: params.slippage, - limitAmount: params.limitAmount, - metadata: params.metadata, - partiallyFillable: params.partiallyFillable, - partner: params.partner, - partnerAddress: params.partnerAddress, - partnerFeeBps: params.partnerFeeBps, - partnerTakesSurplus: params.partnerTakesSurplus, - capSurplus: params.capSurplus, - orderType: 'ExternalOrder', - }, - requestParams, - }); - - return { buildExternalDeltaOrder }; -}; diff --git a/src/methods/deltaV2/buildTWAPDeltaOrder.ts b/src/methods/deltaV2/buildTWAPDeltaOrder.ts deleted file mode 100644 index adb6a23c9..000000000 --- a/src/methods/deltaV2/buildTWAPDeltaOrder.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { API_URL } from '../../constants'; -import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { TWAPBuyDeltaOrder, TWAPDeltaOrder } from '../delta/helpers/types'; -import type { BuiltDeltaOrder, DeltaRoute } from './types'; -export type { BuiltDeltaOrder } from './types'; - -type BuildTWAPDeltaOrderBase = { - /** @description The address of the order owner */ - owner: string; - /** @description The address of the order beneficiary. Defaults to owner. */ - beneficiary?: string; - /** @description The deadline for the order (unix seconds) */ - deadline?: number; - /** @description The nonce of the order. Random if omitted. */ - nonce?: string; - /** @description Optional permit signature for the src token. Defaults to "0x". */ - permit?: string; - /** @description Partner string. Passed to the server to resolve partner fee details. */ - partner?: string; - /** @description Seconds between slice executions (min 60) */ - interval: number; - /** @description Number of slices (min 2) */ - numSlices: number; - /** @description Slippage in basis points (bps). 10000 = 100%, 50 = 0.5%. Default 0. */ - slippage?: number; - /** @description DeltaRoute from getDeltaPrice for a single slice */ - route: DeltaRoute; - /** @description Partner fee in basis points (bps) */ - partnerFeeBps?: number; - /** @description Partner address */ - partnerAddress?: string; - /** @description Take surplus flag */ - partnerTakesSurplus?: boolean; - /** @description Whether the surplus should be capped. True by default. */ - capSurplus?: boolean; - /** @description Metadata for the order, hex string */ - metadata?: string; - /** @description Designates the Order as partially fillable. Default false. */ - partiallyFillable?: boolean; - /** @description If passed, the server will use this as SELL destAmount (as BUY srcAmount) and expectedAmount for each slice */ - limitAmount?: string; -}; - -export type BuildTWAPSellDeltaOrderParams = BuildTWAPDeltaOrderBase & { - onChainOrderType: 'TWAPOrder'; - /** @description Total source token amount across all slices. route.origin.input.amount must equal floor(totalSrcAmount / numSlices). */ - totalSrcAmount: string; -}; - -export type BuildTWAPBuyDeltaOrderParams = BuildTWAPDeltaOrderBase & { - onChainOrderType: 'TWAPBuyOrder'; - /** @description Total destination token amount to buy across all slices. route.origin.output.amount must equal floor(totalDestAmount / numSlices). */ - totalDestAmount: string; - /** @description Maximum source token amount willing to spend across all slices. */ - maxSrcAmount: string; -}; - -export type BuildTWAPDeltaOrderParams = - | BuildTWAPSellDeltaOrderParams - | BuildTWAPBuyDeltaOrderParams; - -type BuildTWAPDeltaOrder = ( - buildOrderParams: BuildTWAPDeltaOrderParams, - requestParams?: RequestParameters -) => Promise>; - -export type BuildTWAPDeltaOrderFunctions = { - /** @description Build a Delta v2 TWAP Order (sell or buy) from a DeltaRoute via the server endpoint, ready to sign and post. */ - buildTWAPDeltaOrder: BuildTWAPDeltaOrder; -}; - -export const constructBuildTWAPDeltaOrder = ( - options: ConstructFetchInput -): BuildTWAPDeltaOrderFunctions => { - const { apiURL = API_URL, fetcher } = options; - const buildUrl = `${apiURL}/delta/v2/orders/build` as const; - - const buildTWAPDeltaOrder: BuildTWAPDeltaOrder = async ( - params, - requestParams - ) => { - const commonBody = { - route: params.route, - owner: params.owner, - beneficiary: params.beneficiary, - deadline: params.deadline, - nonce: params.nonce, - permit: params.permit, - slippage: params.slippage, - limitAmount: params.limitAmount, - metadata: params.metadata, - partiallyFillable: params.partiallyFillable, - partner: params.partner, - partnerAddress: params.partnerAddress, - partnerFeeBps: params.partnerFeeBps, - partnerTakesSurplus: params.partnerTakesSurplus, - capSurplus: params.capSurplus, - interval: params.interval, - numSlices: params.numSlices, - }; - - if (params.onChainOrderType === 'TWAPOrder') { - return fetcher>({ - url: buildUrl, - method: 'POST', - data: { - ...commonBody, - side: 'SELL', - orderType: 'TWAPOrder', - totalSrcAmount: params.totalSrcAmount, - }, - requestParams, - }); - } - - return fetcher>({ - url: buildUrl, - method: 'POST', - data: { - ...commonBody, - side: 'BUY', - orderType: 'TWAPBuyOrder', - totalDestAmount: params.totalDestAmount, - maxSrcAmount: params.maxSrcAmount, - }, - requestParams, - }); - }; - - return { buildTWAPDeltaOrder }; -}; diff --git a/src/methods/deltaV2/cancelDeltaOrder.ts b/src/methods/deltaV2/cancelDeltaOrder.ts deleted file mode 100644 index babaf0534..000000000 --- a/src/methods/deltaV2/cancelDeltaOrder.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { API_URL } from '../../constants'; -import type { - ConstructProviderFetchInput, - RequestParameters, -} from '../../types'; -import { constructGetDeltaContract } from '../delta/getDeltaContract'; -import { - buildCancelDeltaOrderSignableData, - type CancelDeltaOrderData, -} from '../delta/helpers/buildCancelDeltaOrderData'; - -type SuccessResponse = { success: true }; - -type CancelDeltaOrderRequestParams = { - orderIds: string[]; - signature: string; -}; - -export type SignCancelDeltaOrderRequest = ( - params: CancelDeltaOrderData, - requestParams?: RequestParameters -) => Promise; - -export type PostCancelDeltaOrderRequest = ( - params: CancelDeltaOrderRequestParams, - requestParams?: RequestParameters -) => Promise; - -export type CancelDeltaOrder = ( - params: CancelDeltaOrderData, - requestParams?: RequestParameters -) => Promise; - -export type CancelDeltaOrderFunctions = { - signCancelDeltaOrderRequest: SignCancelDeltaOrderRequest; - postCancelDeltaOrderRequest: PostCancelDeltaOrderRequest; - /** @description Cancel one or more Delta orders via the v2 endpoint */ - cancelDeltaOrders: CancelDeltaOrder; -}; - -export const constructCancelDeltaOrder = ( - options: Pick< - ConstructProviderFetchInput, - 'contractCaller' | 'fetcher' | 'apiURL' | 'chainId' - > -): CancelDeltaOrderFunctions => { - const apiURL = options.apiURL ?? API_URL; - - const { getDeltaContract } = constructGetDeltaContract(options); - - const signCancelDeltaOrderRequest: SignCancelDeltaOrderRequest = async ( - params, - requestParams - ) => { - const ParaswapDelta = await getDeltaContract(requestParams); - if (!ParaswapDelta) { - throw new Error(`Delta is not available on chain ${options.chainId}`); - } - - const typedData = buildCancelDeltaOrderSignableData({ - orderInput: params, - paraswapDeltaAddress: ParaswapDelta, - chainId: options.chainId, - }); - - return options.contractCaller.signTypedDataCall(typedData); - }; - - const postCancelDeltaOrderRequest: PostCancelDeltaOrderRequest = async ( - params, - requestParams - ) => { - const cancelUrl = `${apiURL}/delta/v2/orders/cancel` as const; - - return options.fetcher({ - url: cancelUrl, - method: 'POST', - data: params, - requestParams, - }); - }; - - const cancelDeltaOrders: CancelDeltaOrder = async ( - { orderIds }, - requestParams - ) => { - const signature = await signCancelDeltaOrderRequest( - { orderIds }, - requestParams - ); - - return postCancelDeltaOrderRequest({ orderIds, signature }, requestParams); - }; - - return { - signCancelDeltaOrderRequest, - postCancelDeltaOrderRequest, - cancelDeltaOrders, - }; -}; diff --git a/src/methods/deltaV2/getDeltaOrders.ts b/src/methods/deltaV2/getDeltaOrders.ts deleted file mode 100644 index 7e21a9513..000000000 --- a/src/methods/deltaV2/getDeltaOrders.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { API_URL } from '../../constants'; -import { constructSearchString } from '../../helpers/misc'; -import type { - Address, - ConstructFetchInput, - PaginatedResponse, - RequestParameters, -} from '../../types'; -import type { DeltaOrderType, OnChainOrderType } from '../delta/helpers/types'; -import type { DeltaOrderStatus, DeltaAuction } from './types'; - -type GetDeltaOrderById = ( - orderId: string, - requestParams?: RequestParameters -) => Promise; - -type GetDeltaOrderByHash = ( - orderHash: string, - requestParams?: RequestParameters -) => Promise; - -type OrdersFilter = { - /** @description `order.owner` to fetch Delta Orders for. */ - userAddress: Address; - /** @description Pagination option. Default 1. */ - page?: number; - /** @description Pagination option. Default 100, max 1000. */ - limit?: number; - /** @description Filter by chainId. Omitted = orders across all chains. */ - chainId?: number[]; - /** @description Filter by integrator-facing status. */ - status?: DeltaOrderStatus[]; - /** @description Filter by order type. MARKET or LIMIT. */ - type?: DeltaOrderType; - /** @description Filter by on-chain order type. */ - onChainOrderType?: OnChainOrderType; -}; - -type OrderFiltersQuery = Omit & { - chainId?: string; - status?: string; -}; - -type GetDeltaOrders = ( - options: OrdersFilter, - requestParams?: RequestParameters -) => Promise>; - -type GetRequiredBalanceParams = { - userAddress: Address; - tokenAddress?: Address; -}; - -type GetRequiredBalance = ( - userParams: GetRequiredBalanceParams, - requestParams?: RequestParameters -) => Promise>; // token -> required balance across open Delta orders - -export type GetDeltaOrdersFunctions = { - /** @description Fetch a single order by its UUID. */ - getDeltaOrderById: GetDeltaOrderById; - /** @description Fetch a single order by its EIP-712 order hash. */ - getDeltaOrderByHash: GetDeltaOrderByHash; - /** @description List Delta orders with the v2 pagination envelope. */ - getDeltaOrders: GetDeltaOrders; - /** @description Required balance per token across the user's open Delta v2 orders. Pass `tokenAddress` to narrow the result to a single token. */ - getRequiredBalanceForDeltaOrders: GetRequiredBalance; -}; - -export const constructGetDeltaOrders = ({ - apiURL = API_URL, - fetcher, - chainId, -}: ConstructFetchInput): GetDeltaOrdersFunctions => { - const baseUrl = `${apiURL}/delta/v2/orders` as const; - - const getDeltaOrderById: GetDeltaOrderById = async ( - orderId, - requestParams - ) => { - const fetchURL = `${baseUrl}/${orderId}` as const; - return fetcher({ - url: fetchURL, - method: 'GET', - requestParams, - }); - }; - - const getDeltaOrderByHash: GetDeltaOrderByHash = async ( - orderHash, - requestParams - ) => { - const fetchURL = `${baseUrl}/hash/${orderHash}` as const; - return fetcher({ - url: fetchURL, - method: 'GET', - requestParams, - }); - }; - - const getDeltaOrders: GetDeltaOrders = async (options, requestParams) => { - const chainIdString = options.chainId?.join(','); - const statusString = options.status?.join(','); - - const search = constructSearchString({ - userAddress: options.userAddress, - page: options.page, - limit: options.limit, - type: options.type, - onChainOrderType: options.onChainOrderType, - chainId: chainIdString, - status: statusString, - }); - - const fetchURL = `${baseUrl}${search}` as const; - - return fetcher>({ - url: fetchURL, - method: 'GET', - requestParams, - }); - }; - - const getRequiredBalanceForDeltaOrders: GetRequiredBalance = async ( - userParams, - requestParams - ) => { - const userURL = - `${baseUrl}/fillablebalance/${chainId}/${userParams.userAddress}` as const; - const fetchURL = userParams.tokenAddress - ? (`${userURL}/${userParams.tokenAddress}` as const) - : userURL; - - const response = await fetcher>({ - url: fetchURL, - method: 'GET', - requestParams, - }); - - return response; - }; - - return { - getDeltaOrderById, - getDeltaOrderByHash, - getDeltaOrders, - getRequiredBalanceForDeltaOrders, - }; -}; diff --git a/src/methods/deltaV2/getDeltaPrice.ts b/src/methods/deltaV2/getDeltaPrice.ts deleted file mode 100644 index 6ca39cb6e..000000000 --- a/src/methods/deltaV2/getDeltaPrice.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { API_URL, SwapSide } from '../../constants'; -import { constructSearchString } from '../../helpers/misc'; -import type { - ConstructFetchInput, - EnumerateLiteral, - RequestParameters, -} from '../../types'; -import type { DeltaPrice } from './types'; - -type SwapSideUnion = EnumerateLiteral; - -export type DeltaPriceParams = { - /** @description Source Token Address */ - srcToken: string; - /** @description Destination Token Address. For Crosschain Orders, the destination token on the destination chain */ - destToken: string; - /** @description srcToken amount in wei */ - amount: string; - /** @description Source Token Decimals */ - srcDecimals: number; - /** @description Destination Token Decimals */ - destDecimals: number; - /** @description User's Wallet Address */ - userAddress?: string; - /** @description Beneficiary Address */ - beneficiary?: string; - /** @description Partner string. */ - partner?: string; - /** @description Partner fee in basis points (bps), 50bps=0.5% */ - partnerFeeBps?: number; - /** @description Destination Chain ID for Crosschain Orders */ - destChainId?: number; - /** @description SELL or BUY, default is SELL */ - side?: SwapSideUnion; - /** @description In %. Bypasses the API price impact check (default = 15%) */ - maxImpact?: number; - maxUSDImpact?: number; - - includeAgents?: string[]; - excludeAgents?: string[]; - includeBridges?: string[]; - excludeBridges?: string[]; - - /** @description Allow swap on destChain after bridge. Default is true. */ - allowBridgeAndSwap?: boolean; - degenMode?: boolean; -}; - -type DeltaPriceQueryOptions = Omit< - DeltaPriceParams, - 'includeAgents' | 'excludeAgents' | 'includeBridges' | 'excludeBridges' -> & { - chainId: number; - includeAgents?: string; - excludeAgents?: string; - includeBridges?: string; - excludeBridges?: string; -}; - -type GetDeltaPrice = ( - options: DeltaPriceParams, - requestParams?: RequestParameters -) => Promise; - -export type GetDeltaPriceFunctions = { - /** @description Fetch a v2 price quote (route-based response). */ - getDeltaPrice: GetDeltaPrice; -}; - -export const constructGetDeltaPrice = ({ - apiURL = API_URL, - chainId, - fetcher, -}: ConstructFetchInput): GetDeltaPriceFunctions => { - const pricesUrl = `${apiURL}/delta/v2/prices` as const; - - const getDeltaPrice: GetDeltaPrice = async (options, requestParams) => { - const { - includeAgents, - excludeAgents, - includeBridges, - excludeBridges, - ...rest - } = options; - - const search = constructSearchString({ - ...rest, - chainId, - side: options.side ?? SwapSide.SELL, - includeAgents: includeAgents?.join(','), - excludeAgents: excludeAgents?.join(','), - includeBridges: includeBridges?.join(','), - excludeBridges: excludeBridges?.join(','), - }); - - const fetchURL = `${pricesUrl}${search}` as const; - - const data = await fetcher({ - url: fetchURL, - method: 'GET', - requestParams, - }); - - return data; - }; - - return { getDeltaPrice }; -}; diff --git a/src/methods/deltaV2/helpers/orders.ts b/src/methods/deltaV2/helpers/orders.ts deleted file mode 100644 index e8b89def2..000000000 --- a/src/methods/deltaV2/helpers/orders.ts +++ /dev/null @@ -1,363 +0,0 @@ -import type { NonEmptyArray } from 'ts-essentials'; -import { OrderHelpers as DeltaV1OrderHelpers } from '../../delta/helpers/orders'; -import type { - SwapSideUnion, - UnifiedDeltaOrderData, -} from '../../delta/helpers/types'; -import type { - DeltaAuction, - DeltaOrderStatus, - DeltaTokenSide, - DeltaTransaction, -} from '../types'; - -/** - * v2 order helpers. - * - * The on-chain order structs (`auction.order`) are identical between v1 and v2 - * — they come from the same `OnChainOrderMap` — so every order-struct guard and - * order-level getter is reused directly from v1's `OrderHelpers`. Likewise the - * auction discriminant guards only look at `onChainOrderType` (same union in - * both versions), so those are reused too. - * - * What differs in v2 is the *auction* envelope: - * - `status` is the integrator-facing `DeltaOrderStatus` - * (PENDING/ACTIVE/COMPLETED/… — not v1's `DeltaAuctionStatus`), - * - amounts live on `input`/`output` (`DeltaTokenSide`) and `transactions` - * (`DeltaTransaction`) instead of v1's order/transaction shapes, - * - `side` is carried explicitly on the auction. - * - * Those pieces are reimplemented here against the v2 shapes. - */ - -const v1Checks = DeltaV1OrderHelpers.checks; -const v1Getters = DeltaV1OrderHelpers.getters; - -///// CHECKS ////// - -/** - * @description Checks whether an auction is fully executed (settled on every chain). - */ -function isCompletedAuction>( - auction: T -): auction is T & { status: 'COMPLETED' } { - return auction.status === 'COMPLETED'; -} - -const failedAuctionStatuses = [ - 'FAILED', - 'EXPIRED', - 'CANCELLED', - 'REFUNDED', -] as const; - -const failedAuctionStatusesSet = new Set( - failedAuctionStatuses -); - -/** - * @description Checks whether an auction is in a terminal failure state - * (failed, expired, cancelled, or refunded). - */ -function isFailedAuction>( - auction: T -): auction is T & { status: (typeof failedAuctionStatuses)[number] } { - return failedAuctionStatusesSet.has(auction.status); -} - -/** - * @description Checks whether an auction status is cancelled. - */ -function isCanceledAuction>( - auction: T -): auction is T & { status: 'CANCELLED' } { - return auction.status === 'CANCELLED'; -} - -/** - * @description Checks whether an auction status is expired. - */ -function isExpiredAuction>( - auction: T -): auction is T & { status: 'EXPIRED' } { - return auction.status === 'EXPIRED'; -} - -const pendingAuctionStatuses = [ - 'PENDING', - 'AWAITING_SIGNATURE', - 'ACTIVE', - 'BRIDGING', -] as const; - -const pendingAuctionStatusesSet = new Set( - pendingAuctionStatuses -); - -/** - * @description Checks whether an auction is still in flight (not yet settled - * and not failed): awaiting signature, pending, actively executing, or bridging. - */ -function isPendingAuction>( - auction: T -): auction is T & { status: (typeof pendingAuctionStatuses)[number] } { - return pendingAuctionStatusesSet.has(auction.status); -} - -/** - * @description Checks whether an auction is a Fillable auction. - * `FillableOrder` is the `onChainOrderType` the server reports for a - * `partiallyFillable` Standard order; it carries the same order struct as - * `Order`. Consumers that don't distinguish the two should treat - * `isDeltaAuction(a) || isFillableAuction(a)` as "is a standard order". - */ -function isFillableAuction>( - auction: T -): auction is T & { onChainOrderType: 'FillableOrder' } { - return auction.onChainOrderType === 'FillableOrder'; -} - -/** - * @description Checks whether an auction has been partially executed: - * it has at least one transaction and an overall filled percent strictly - * between 0 and 100. - */ -function isPartiallyExecutedAuction< - T extends Pick, ->( - auction: T -): auction is T & { transactions: NonEmptyArray } { - if (auction.transactions.length === 0) return false; - - const filledPercent = getFilledPercent(auction); - - return filledPercent > 0 && filledPercent < 100; -} - -const checks = { - // order-struct guards — order structs are shared with v1, reused as-is. - isTWAPOrder: v1Checks.isTWAPOrder, - isTWAPSellOrder: v1Checks.isTWAPSellOrder, - isTWAPBuyOrder: v1Checks.isTWAPBuyOrder, - isExternalOrder: v1Checks.isExternalOrder, - isDeltaOrder: v1Checks.isDeltaOrder, - isProductiveOrder: v1Checks.isProductiveOrder, - - // auction discriminant guards — `onChainOrderType` union is shared, reused as-is. - isTWAPAuction: v1Checks.isTWAPAuction, - isTWAPSellAuction: v1Checks.isTWAPSellAuction, - isTWAPBuyAuction: v1Checks.isTWAPBuyAuction, - isDeltaAuction: v1Checks.isDeltaAuction, - isExternalAuction: v1Checks.isExternalAuction, - isProductiveAuction: v1Checks.isProductiveAuction, - isFillableAuction, - - // status / execution guards — v2 status enum & transaction shape. - isCompletedAuction, - isFailedAuction, - isCanceledAuction, - isExpiredAuction, - isPendingAuction, - isPartiallyExecutedAuction, -}; - -///// GETTERS ////// - -/** - * @description Reads an amount off a v2 token side. A SELL input / BUY output - * carries an explicit `amount`; the opposite side carries - * `expectedAmount`/`executedAmount`. `prefer` chooses which to read on the - * expected/executed variant. - */ -function getTokenSideAmount( - side: DeltaTokenSide, - prefer: 'expected' | 'executed' -): string { - if ('amount' in side) return side.amount; - - const value = - prefer === 'executed' ? side.executedAmount : side.expectedAmount; - - return value ?? '0'; -} - -/** - * @description Returns the source chain id for the auction (the input side's chain). - */ -function getAuctionSrcChainId(auction: Pick): number { - return auction.input.chainId; -} - -/** - * @description Returns the destination chain id for the auction (the output side's chain). - * Equals the source chain id for same-chain orders. - */ -function getAuctionDestChainId(auction: Pick): number { - return auction.output.chainId; -} - -/** - * @description Returns the swap side for any auction. v2 carries `side` on the - * auction directly, so no order introspection is needed. - */ -function getAuctionSwapSide( - auction: Pick -): SwapSideUnion { - return auction.side; -} - -/** - * @description Returns source and destination token addresses for the auction, - * read from the input/output sides (already resolved to the dest-chain token - * for cross-chain orders). - */ -function getAuctionTokenAddresses( - auction: Pick -) { - return { - srcToken: auction.input.token, - destToken: auction.output.token, - }; -} - -/** - * @description Aggregates transaction amounts into total spent (src) and - * received (dest) values. - */ -function getTransactionAmounts(transactions: DeltaTransaction[]) { - const { srcAmount, destAmount } = transactions.reduce( - (acc, { spentAmount, receivedAmount }) => ({ - srcAmount: acc.srcAmount + BigInt(spentAmount ?? 0), - destAmount: acc.destAmount + BigInt(receivedAmount ?? 0), - }), - { srcAmount: 0n, destAmount: 0n } - ); - - return { - srcAmount: srcAmount.toString(), - destAmount: destAmount.toString(), - }; -} - -/** - * @description Calculates the overall filled percent (0–100) from the - * per-transaction `filledPercent` values. For TWAP orders each transaction is - * a slice (0–100 of that slice), so the slice values are averaged across - * `numSlices`; for single-fill orders the values sum directly. - */ -function getFilledPercent( - auction: Pick -): number { - if (auction.transactions.length === 0) return 0; - - const total = auction.transactions.reduce( - (acc, { filledPercent }) => acc + filledPercent, - 0 - ); - - if (checks.isTWAPOrder(auction.order) && auction.order.numSlices > 0) { - return total / auction.order.numSlices; - } - - return total; -} - -/** - * @description Returns expected amounts and, once the auction is completed, - * executed amounts. Executed amounts prefer the `executedAmount` baked onto the - * token sides and fall back to summing transactions. - */ -function getAuctionAmounts( - auction: Pick< - DeltaAuction, - 'status' | 'order' | 'input' | 'output' | 'transactions' - > -) { - const expected = { - srcAmount: getTokenSideAmount(auction.input, 'expected'), - destAmount: getTokenSideAmount(auction.output, 'expected'), - }; - - if (!isCompletedAuction(auction)) { - return { expected }; - } - - const txAmounts = getTransactionAmounts(auction.transactions); - - const executed = { - srcAmount: getExecutedAmount(auction.input, txAmounts.srcAmount), - destAmount: getExecutedAmount(auction.output, txAmounts.destAmount), - }; - - return { expected, executed }; -} - -/** - * @description Returns the executed amount of a token side when present, - * otherwise the provided fallback (typically summed from transactions). - */ -function getExecutedAmount(side: DeltaTokenSide, fallback: string): string { - if ('executedAmount' in side && side.executedAmount != null) { - return side.executedAmount; - } - - return fallback; -} - -/** - * @description Returns unified order data with normalized amounts, tokens, - * chain ids, and side — the v2 counterpart of v1's `getUnifiedDeltaOrderData`, - * built from the v2 auction envelope. - */ -function getUnifiedDeltaOrderData( - auction: DeltaAuction -): UnifiedDeltaOrderData { - const { srcToken, destToken } = getAuctionTokenAddresses(auction); - const { expected, executed } = getAuctionAmounts(auction); - - const srcChainId = getAuctionSrcChainId(auction); - const destChainId = getAuctionDestChainId(auction); - const swapSide = getAuctionSwapSide(auction); - const filledPercent = getFilledPercent(auction); - - return { - srcChainId, - destChainId, - srcAmount: executed?.srcAmount || expected.srcAmount, - destAmount: executed?.destAmount || expected.destAmount, - amounts: { - expected, - final: executed, - }, - srcToken, - destToken, - swapSide, - filledPercent, - }; -} - -const getters = { - getUnifiedDeltaOrderData, - - // auction-level getters — v2 envelope shape. - getAuctionTokenAddresses, - getAuctionSrcChainId, - getAuctionDestChainId, - getAuctionSwapSide, - getTransactionAmounts, - getAuctionAmounts, - getFilledPercent, - - // order-level getters — order structs are shared with v1, reused as-is. - getOrderTokenAddresses: v1Getters.getOrderTokenAddresses, - getSwapSideFromDeltaOrder: v1Getters.getSwapSideFromDeltaOrder, - getSwapSideFromTwapOrderType: v1Getters.getSwapSideFromTwapOrderType, - getExpectedTwapSrcAmount: v1Getters.getExpectedTwapSrcAmount, - getExpectedTwapDestAmount: v1Getters.getExpectedTwapDestAmount, - getExpectedTwapOrderAmounts: v1Getters.getExpectedTwapOrderAmounts, -}; - -export const OrderHelpers = { - checks, - getters, -}; diff --git a/src/methods/deltaV2/index.ts b/src/methods/deltaV2/index.ts deleted file mode 100644 index 65b517be9..000000000 --- a/src/methods/deltaV2/index.ts +++ /dev/null @@ -1,312 +0,0 @@ -import type { ConstructProviderFetchInput } from '../../types'; -import type { DeltaAuction } from './types'; - -// reused v1 modules -import { - GetDeltaContractFunctions, - constructGetDeltaContract, -} from '../delta/getDeltaContract'; -import { - constructGetPartnerFee, - GetPartnerFeeFunctions, -} from '../delta/getPartnerFee'; -import { - ApproveTokenForDeltaFunctions, - constructApproveTokenForDelta, -} from '../delta/approveForDelta'; -import { - constructPreSignDeltaOrder, - PreSignDeltaOrderFunctions, -} from '../delta/preSignDeltaOrder'; -import { - constructPreSignExternalDeltaOrder, - PreSignExternalDeltaOrderFunctions, -} from '../delta/preSignExternalDeltaOrder'; -import { - constructPreSignTWAPDeltaOrder, - PreSignTWAPDeltaOrderFunctions, -} from '../delta/preSignTWAPDeltaOrder'; -import { - DeltaTokenModuleFunctions, - constructDeltaTokenModule, -} from '../delta/deltaTokenModule'; - -// new v2 modules -import { - BuildDeltaOrderFunctions, - BuildDeltaOrderParams, - BuiltDeltaOrder, - constructBuildDeltaOrder, -} from './buildDeltaOrder'; -import { - BuildExternalDeltaOrderFunctions, - BuildExternalDeltaOrderParams, - constructBuildExternalDeltaOrder, -} from './buildExternalDeltaOrder'; -import { - BuildTWAPDeltaOrderFunctions, - BuildTWAPDeltaOrderParams, - constructBuildTWAPDeltaOrder, -} from './buildTWAPDeltaOrder'; -import { - constructPostDeltaOrder, - DeltaOrderToPost, - PostDeltaOrderFunctions, -} from './postDeltaOrder'; -import { - constructPostExternalDeltaOrder, - PostExternalDeltaOrderFunctions, -} from './postExternalDeltaOrder'; -import { - constructPostTWAPDeltaOrder, - PostTWAPDeltaOrderFunctions, -} from './postTWAPDeltaOrder'; -import { - constructGetDeltaPrice, - GetDeltaPriceFunctions, -} from './getDeltaPrice'; -import { - constructGetDeltaOrders, - GetDeltaOrdersFunctions, -} from './getDeltaOrders'; -import { - constructGetBridgeRoutes, - GetBridgeRoutesFunctions, -} from './getBridgeRoutes'; -import { - constructIsTokenSupportedInDelta, - IsTokenSupportedInDeltaFunctions, -} from './isTokenSupportedInDelta'; -import { - CancelDeltaOrderFunctions, - constructCancelDeltaOrder, -} from './cancelDeltaOrder'; -import { - constructGetAgentsList, - GetAgentsListFunctions, -} from './getAgentsList'; - -// Re-export public surface so `import * as DeltaV2` carries everything. -export * from './types'; -export * from './buildDeltaOrder'; -export * from './buildExternalDeltaOrder'; -export * from './buildTWAPDeltaOrder'; -export * from './postDeltaOrder'; -export * from './postExternalDeltaOrder'; -export * from './postTWAPDeltaOrder'; -export * from './getDeltaPrice'; -export * from './getDeltaOrders'; -export * from './getBridgeRoutes'; -export * from './isTokenSupportedInDelta'; -export * from './cancelDeltaOrder'; -export * from './getAgentsList'; -export { OrderHelpers } from './helpers/orders'; - -// ── Sign v2 ───────────────────────────────────────────────────────────────── - -type SignDeltaOrder = (builtOrder: BuiltDeltaOrder) => Promise; - -export type SignDeltaOrderFunctions = { - /** @description Sign a BuiltDeltaOrder (any order type) using EIP-712 typed data. */ - signDeltaOrder: SignDeltaOrder; -}; - -export const constructSignDeltaOrder = ( - options: Pick< - ConstructProviderFetchInput, - 'contractCaller' - > -): SignDeltaOrderFunctions => { - const signDeltaOrder: SignDeltaOrder = async (builtOrder) => { - return options.contractCaller.signTypedDataCall({ - types: builtOrder.toSign.types, - domain: builtOrder.toSign.domain, - data: builtOrder.toSign.value, - }); - }; - return { signDeltaOrder }; -}; - -// ── Submit orchestrators ───────────────────────────────────────────────────── - -export type SubmitDeltaOrderParams = BuildDeltaOrderParams & { - /** @description Referrer address */ - referrerAddress?: string; - degenMode?: boolean; -} & Pick; - -type SubmitDeltaOrder = ( - orderParams: SubmitDeltaOrderParams -) => Promise>; - -export type SubmitDeltaOrderFuncs = { - submitDeltaOrder: SubmitDeltaOrder; -}; - -export const constructSubmitDeltaOrder = ( - options: ConstructProviderFetchInput -): SubmitDeltaOrderFuncs => { - const { buildDeltaOrder } = constructBuildDeltaOrder(options); - const { signDeltaOrder } = constructSignDeltaOrder(options); - const { postDeltaOrder } = constructPostDeltaOrder(options); - - const submitDeltaOrder: SubmitDeltaOrder = async (orderParams) => { - const orderData = await buildDeltaOrder(orderParams); - const signature = await signDeltaOrder(orderData); - - return postDeltaOrder({ - signature, - partner: orderParams.partner, - order: orderData.toSign.value, - partiallyFillable: orderParams.partiallyFillable, - referrerAddress: orderParams.referrerAddress, - type: orderParams.type, - includeAgents: orderParams.includeAgents, - excludeAgents: orderParams.excludeAgents, - degenMode: orderParams.degenMode, - }); - }; - - return { submitDeltaOrder }; -}; - -export type SubmitExternalDeltaOrderParams = BuildExternalDeltaOrderParams & { - referrerAddress?: string; -} & Pick; - -type SubmitExternalDeltaOrder = ( - orderParams: SubmitExternalDeltaOrderParams -) => Promise>; - -export type SubmitExternalDeltaOrderFuncs = { - submitExternalDeltaOrder: SubmitExternalDeltaOrder; -}; - -export const constructSubmitExternalDeltaOrder = ( - options: ConstructProviderFetchInput -): SubmitExternalDeltaOrderFuncs => { - const { buildExternalDeltaOrder } = constructBuildExternalDeltaOrder(options); - const { signDeltaOrder } = constructSignDeltaOrder(options); - const { postExternalDeltaOrder } = constructPostExternalDeltaOrder(options); - - const submitExternalDeltaOrder: SubmitExternalDeltaOrder = async ( - orderParams - ) => { - const orderData = await buildExternalDeltaOrder(orderParams); - const signature = await signDeltaOrder(orderData); - - return postExternalDeltaOrder({ - signature, - partner: orderParams.partner, - order: orderData.toSign.value, - partiallyFillable: orderParams.partiallyFillable, - referrerAddress: orderParams.referrerAddress, - type: orderParams.type, - includeAgents: orderParams.includeAgents, - excludeAgents: orderParams.excludeAgents, - }); - }; - - return { submitExternalDeltaOrder }; -}; - -export type SubmitTWAPDeltaOrderParams = BuildTWAPDeltaOrderParams & { - referrerAddress?: string; - degenMode?: boolean; -} & Pick; - -type SubmitTWAPDeltaOrder = ( - orderParams: SubmitTWAPDeltaOrderParams -) => Promise | DeltaAuction<'TWAPBuyOrder'>>; - -export type SubmitTWAPDeltaOrderFuncs = { - submitTWAPDeltaOrder: SubmitTWAPDeltaOrder; -}; - -export const constructSubmitTWAPDeltaOrder = ( - options: ConstructProviderFetchInput -): SubmitTWAPDeltaOrderFuncs => { - const { buildTWAPDeltaOrder } = constructBuildTWAPDeltaOrder(options); - const { signDeltaOrder } = constructSignDeltaOrder(options); - const { postTWAPDeltaOrder } = constructPostTWAPDeltaOrder(options); - - const submitTWAPDeltaOrder: SubmitTWAPDeltaOrder = async (orderParams) => { - const orderData = await buildTWAPDeltaOrder(orderParams); - const signature = await signDeltaOrder(orderData); - - return postTWAPDeltaOrder({ - signature, - partner: orderParams.partner, - order: orderData.toSign.value, - onChainOrderType: orderParams.onChainOrderType, - partiallyFillable: orderParams.partiallyFillable, - referrerAddress: orderParams.referrerAddress, - type: orderParams.type, - includeAgents: orderParams.includeAgents, - excludeAgents: orderParams.excludeAgents, - degenMode: orderParams.degenMode, - }); - }; - - return { submitTWAPDeltaOrder }; -}; - -// ── Handler bundle ─────────────────────────────────────────────────────────── - -export type DeltaOrderHandlers = SubmitDeltaOrderFuncs & - SubmitExternalDeltaOrderFuncs & - SubmitTWAPDeltaOrderFuncs & - BuildDeltaOrderFunctions & - BuildExternalDeltaOrderFunctions & - BuildTWAPDeltaOrderFunctions & - PostDeltaOrderFunctions & - PostExternalDeltaOrderFunctions & - PostTWAPDeltaOrderFunctions & - SignDeltaOrderFunctions & - PreSignDeltaOrderFunctions & - PreSignExternalDeltaOrderFunctions & - PreSignTWAPDeltaOrderFunctions & - GetDeltaPriceFunctions & - GetDeltaOrdersFunctions & - GetBridgeRoutesFunctions & - IsTokenSupportedInDeltaFunctions & - GetAgentsListFunctions & - GetDeltaContractFunctions & - GetPartnerFeeFunctions & - ApproveTokenForDeltaFunctions & - DeltaTokenModuleFunctions & - CancelDeltaOrderFunctions; - -/** @description Construct an SDK bundle exposing every Delta v2 method (queries, build/sign/post, on-chain helpers). */ -export const constructAllDeltaOrdersHandlers = ( - options: ConstructProviderFetchInput< - TxResponse, - 'signTypedDataCall' | 'transactCall' - > -): DeltaOrderHandlers => { - return { - ...constructSubmitDeltaOrder(options), - ...constructSubmitExternalDeltaOrder(options), - ...constructSubmitTWAPDeltaOrder(options), - ...constructBuildDeltaOrder(options), - ...constructBuildExternalDeltaOrder(options), - ...constructBuildTWAPDeltaOrder(options), - ...constructPostDeltaOrder(options), - ...constructPostExternalDeltaOrder(options), - ...constructPostTWAPDeltaOrder(options), - ...constructSignDeltaOrder(options), - ...constructPreSignDeltaOrder(options), - ...constructPreSignExternalDeltaOrder(options), - ...constructPreSignTWAPDeltaOrder(options), - ...constructGetDeltaPrice(options), - ...constructGetDeltaOrders(options), - ...constructGetBridgeRoutes(options), - ...constructIsTokenSupportedInDelta(options), - ...constructGetAgentsList(options), - ...constructGetDeltaContract(options), - ...constructGetPartnerFee(options), - ...constructApproveTokenForDelta(options), - ...constructDeltaTokenModule(options), - ...constructCancelDeltaOrder(options), - }; -}; diff --git a/src/methods/deltaV2/isTokenSupportedInDelta.ts b/src/methods/deltaV2/isTokenSupportedInDelta.ts deleted file mode 100644 index ee14a94df..000000000 --- a/src/methods/deltaV2/isTokenSupportedInDelta.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { API_URL } from '../../constants'; -import { constructSearchString } from '../../helpers/misc'; -import type { - Address, - ConstructFetchInput, - RequestParameters, -} from '../../types'; - -type TokenSupportedResponse = { supported: boolean }; -type IsTokenSupportedQuery = { - token: Address; - chainId: number; -}; - -type IsTokenSupportedInDelta = ( - token: Address, - requestParams?: RequestParameters -) => Promise; - -export type IsTokenSupportedInDeltaFunctions = { - isTokenSupportedInDelta: IsTokenSupportedInDelta; -}; - -export const constructIsTokenSupportedInDelta = ({ - apiURL = API_URL, - chainId, - fetcher, -}: ConstructFetchInput): IsTokenSupportedInDeltaFunctions => { - const baseUrl = `${apiURL}/delta/v2/prices/is-token-supported` as const; - - const isTokenSupportedInDelta: IsTokenSupportedInDelta = async ( - token, - requestParams - ) => { - const search = constructSearchString({ - token, - chainId, - }); - - const fetchURL = `${baseUrl}/${search}` as const; - - const data = await fetcher({ - url: fetchURL, - method: 'GET', - requestParams, - }); - - return data.supported; - }; - - return { isTokenSupportedInDelta }; -}; diff --git a/src/methods/deltaV2/postDeltaOrder.ts b/src/methods/deltaV2/postDeltaOrder.ts deleted file mode 100644 index e1e54f3f4..000000000 --- a/src/methods/deltaV2/postDeltaOrder.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { API_URL } from '../../constants'; -import { constructSearchString } from '../../helpers/misc'; -import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaOrderType, OnChainOrderMap } from '../delta/helpers/types'; -import type { DeltaAuction } from './types'; - -export type DeltaOrderToPost = { - /** @description Partner string */ - partner?: string; - /** @description Referrer address */ - referrerAddress?: string; - order: OnChainOrderMap[T]; - /** @description Signature of the order from order.owner address. EOA signatures must be submitted in ERC-2098 Compact Representation. */ - signature: string; - chainId: number; - /** @description Designates the Order as being able to be partially filled, as opposed to fill-or-kill */ - partiallyFillable?: boolean; - /** @description Type of the order. MARKET or LIMIT. Default is MARKET */ - type?: DeltaOrderType; - includeAgents?: string[]; - excludeAgents?: string[]; -}; - -export type PostDeltaOrderParams = Omit & { - degenMode?: boolean; -}; - -type PostDeltaOrder = ( - postData: PostDeltaOrderParams, - requestParams?: RequestParameters -) => Promise>; - -export type PostDeltaOrderFunctions = { - postDeltaOrder: PostDeltaOrder; -}; - -export const constructPostDeltaOrder = ({ - apiURL = API_URL, - chainId, - fetcher, -}: ConstructFetchInput): PostDeltaOrderFunctions => { - const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - - const postDeltaOrder: PostDeltaOrder = (_postData, requestParams) => { - const { degenMode, ...postData } = _postData; - const deltaOrderToPost: DeltaOrderToPost = { ...postData, chainId }; - - const search = constructSearchString<{ degenMode?: boolean }>({ - degenMode, - }); - const fetchURL = `${postOrderUrl}${search}` as const; - - return fetcher>({ - url: fetchURL, - method: 'POST', - data: deltaOrderToPost, - requestParams, - }); - }; - - return { postDeltaOrder }; -}; diff --git a/src/methods/deltaV2/postExternalDeltaOrder.ts b/src/methods/deltaV2/postExternalDeltaOrder.ts deleted file mode 100644 index 90b4455cd..000000000 --- a/src/methods/deltaV2/postExternalDeltaOrder.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { API_URL } from '../../constants'; -import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { DeltaOrderToPost } from './postDeltaOrder'; -import type { DeltaAuction } from './types'; - -export type PostExternalDeltaOrderParams = Omit< - DeltaOrderToPost<'ExternalOrder'>, - 'chainId' ->; - -type PostExternalDeltaOrder = ( - postData: PostExternalDeltaOrderParams, - requestParams?: RequestParameters -) => Promise>; - -export type PostExternalDeltaOrderFunctions = { - postExternalDeltaOrder: PostExternalDeltaOrder; -}; - -export const constructPostExternalDeltaOrder = ({ - apiURL = API_URL, - chainId, - fetcher, -}: ConstructFetchInput): PostExternalDeltaOrderFunctions => { - const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - - const postExternalDeltaOrder: PostExternalDeltaOrder = ( - postData, - requestParams - ) => { - const deltaOrderToPost: DeltaOrderToPost<'ExternalOrder'> = { - ...postData, - chainId, - }; - - return fetcher>({ - url: postOrderUrl, - method: 'POST', - data: deltaOrderToPost, - requestParams, - }); - }; - - return { postExternalDeltaOrder }; -}; diff --git a/src/methods/deltaV2/postTWAPDeltaOrder.ts b/src/methods/deltaV2/postTWAPDeltaOrder.ts deleted file mode 100644 index 7d950610a..000000000 --- a/src/methods/deltaV2/postTWAPDeltaOrder.ts +++ /dev/null @@ -1,58 +0,0 @@ -import type { Prettify } from 'ts-essentials'; -import { API_URL } from '../../constants'; -import { constructSearchString } from '../../helpers/misc'; -import type { ConstructFetchInput, RequestParameters } from '../../types'; -import type { TWAPOnChainOrderType } from '../delta/helpers/types'; -import type { DeltaOrderToPost } from './postDeltaOrder'; -import type { DeltaAuction } from './types'; - -export type PostTWAPDeltaOrderParams = Prettify< - Omit< - DeltaOrderToPost<'TWAPOrder'> | DeltaOrderToPost<'TWAPBuyOrder'>, - 'chainId' - > & { - /** @description Must be "TWAPOrder" or "TWAPBuyOrder" */ - onChainOrderType: TWAPOnChainOrderType; - degenMode?: boolean; - } ->; - -type PostTWAPDeltaOrder = ( - postData: PostTWAPDeltaOrderParams, - requestParams?: RequestParameters -) => Promise | DeltaAuction<'TWAPBuyOrder'>>; - -export type PostTWAPDeltaOrderFunctions = { - postTWAPDeltaOrder: PostTWAPDeltaOrder; -}; - -export const constructPostTWAPDeltaOrder = ({ - apiURL = API_URL, - chainId, - fetcher, -}: ConstructFetchInput): PostTWAPDeltaOrderFunctions => { - const postOrderUrl = `${apiURL}/delta/v2/orders` as const; - - const postTWAPDeltaOrder: PostTWAPDeltaOrder = (_postData, requestParams) => { - const { degenMode, ...postData } = _postData; - const deltaOrderToPost: DeltaOrderToPost<'TWAPOrder' | 'TWAPBuyOrder'> = { - ...postData, - chainId, - }; - - const search = constructSearchString<{ degenMode?: boolean }>({ - degenMode, - }); - - const fetchURL = `${postOrderUrl}${search}` as const; - - return fetcher | DeltaAuction<'TWAPBuyOrder'>>({ - url: fetchURL, - method: 'POST', - data: deltaOrderToPost, - requestParams, - }); - }; - - return { postTWAPDeltaOrder }; -}; diff --git a/src/methods/quote/getQuote.ts b/src/methods/quote/getQuote.ts index 9299f6f80..4cac17fb0 100644 --- a/src/methods/quote/getQuote.ts +++ b/src/methods/quote/getQuote.ts @@ -1,6 +1,6 @@ import { API_URL, SwapSide } from '../../constants'; import { constructSearchString } from '../../helpers/misc'; -import type { BridgePrice, DeltaPrice } from '../delta/getDeltaPrice'; +import type { DeltaPrice } from '../delta/types'; import type { ConstructFetchInput, EnumerateLiteral, @@ -58,12 +58,12 @@ export type QuoteWithDeltaPrice = { }; export type QuoteWithBridgePrice = { - delta: BridgePrice; + delta: DeltaPrice; deltaAddress: string; }; export type QuoteWithDeltaPriceAndBridgePrice = { - delta: DeltaPrice | BridgePrice; + delta: DeltaPrice; deltaAddress: string; }; @@ -123,7 +123,7 @@ export const constructGetQuote = ({ chainId, fetcher, }: ConstructFetchInput): GetQuoteFunctions => { - const pricesUrl = `${apiURL}/quote` as const; + const pricesUrl = `${apiURL}/v2/quote` as const; function getQuote( options: QuoteParams<'delta'> & { destChainId?: undefined }, diff --git a/src/sdk/full.ts b/src/sdk/full.ts index e134ed757..e6d2dde54 100644 --- a/src/sdk/full.ts +++ b/src/sdk/full.ts @@ -12,10 +12,6 @@ import { constructAllDeltaOrdersHandlers, DeltaOrderHandlers, } from '../methods/delta'; -import { - constructAllDeltaOrdersHandlers as constructAllDeltaV2OrdersHandlers, - DeltaOrderHandlers as DeltaV2OrderHandlers, -} from '../methods/deltaV2'; import { constructGetQuote, GetQuoteFunctions, @@ -30,7 +26,6 @@ export type AllSDKMethods = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; - deltaV2: DeltaV2OrderHandlers; quote: GetQuoteFunctions; } & Required; @@ -46,8 +41,6 @@ export const constructFullSDK = ( constructAllNFTOrdersHandlers(config); const delta: DeltaOrderHandlers = constructAllDeltaOrdersHandlers(config); - const deltaV2: DeltaV2OrderHandlers = - constructAllDeltaV2OrdersHandlers(config); const quote = constructGetQuote(config); return { @@ -55,7 +48,6 @@ export const constructFullSDK = ( limitOrders, nftOrders, delta, - deltaV2, quote, apiURL: config.apiURL ?? API_URL, chainId: config.chainId, diff --git a/src/sdk/simple.ts b/src/sdk/simple.ts index 3d8ecaea8..5b24f859c 100644 --- a/src/sdk/simple.ts +++ b/src/sdk/simple.ts @@ -129,16 +129,14 @@ import { GetQuoteFunctions, } from '../methods/quote/getQuote'; import { - constructGetBridgeInfo, - GetBridgeInfoFunctions, -} from '../methods/delta/getBridgeInfo'; + constructGetBridgeRoutes, + GetBridgeRoutesFunctions, +} from '../methods/delta/getBridgeRoutes'; import { constructIsTokenSupportedInDelta, IsTokenSupportedInDeltaFunctions, } from '../methods/delta/isTokenSupportedInDelta'; -import * as DeltaV2 from '../methods/deltaV2'; - export type SwapFetchMethods = GetBalancesFunctions & GetTokensFunctions & GetSpenderFunctions & @@ -166,19 +164,10 @@ export type DeltaFetchMethods = BuildDeltaOrderFunctions & GetDeltaPriceFunctions & GetDeltaContractFunctions & GetPartnerFeeFunctions & - GetBridgeInfoFunctions & + GetBridgeRoutesFunctions & IsTokenSupportedInDeltaFunctions & PostDeltaOrderFunctions; -export type DeltaV2FetchMethods = DeltaV2.BuildDeltaOrderFunctions & - DeltaV2.GetDeltaOrdersFunctions & - DeltaV2.GetDeltaPriceFunctions & - GetDeltaContractFunctions & - GetPartnerFeeFunctions & - DeltaV2.GetBridgeRoutesFunctions & - DeltaV2.IsTokenSupportedInDeltaFunctions & - DeltaV2.PostDeltaOrderFunctions; - export type SimpleFetchSDK = { swap: SwapFetchMethods; /** @deprecated Limit Orders are deprecated and will be removed in a future version. */ @@ -186,7 +175,6 @@ export type SimpleFetchSDK = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrdersFetchMethods; delta: DeltaFetchMethods; - deltaV2: DeltaV2FetchMethods; quote: QuoteFetchMethods; } & Required; @@ -199,7 +187,6 @@ export type SimpleSDK = { /** @deprecated NFT Orders are deprecated and will be removed in a future version. */ nftOrders: NFTOrderHandlers; delta: DeltaOrderHandlers; - deltaV2: DeltaV2.DeltaOrderHandlers; quote: QuoteFetchMethods; } & Required; @@ -307,22 +294,10 @@ export function constructSimpleSDK( constructGetDeltaPrice, constructGetDeltaContract, constructGetPartnerFee, - constructGetBridgeInfo, + constructGetBridgeRoutes, constructIsTokenSupportedInDelta ); - const deltaV2 = constructPartialSDK( - config, - DeltaV2.constructBuildDeltaOrder, - DeltaV2.constructPostDeltaOrder, - DeltaV2.constructGetDeltaOrders, - DeltaV2.constructGetDeltaPrice, - constructGetDeltaContract, - constructGetPartnerFee, - DeltaV2.constructGetBridgeRoutes, - DeltaV2.constructIsTokenSupportedInDelta - ); - const quote = constructPartialSDK(config, constructGetQuote); return { @@ -330,7 +305,6 @@ export function constructSimpleSDK( limitOrders, nftOrders, delta, - deltaV2, quote, apiURL: options.apiURL ?? API_URL, chainId: options.chainId, @@ -359,9 +333,6 @@ export function constructSimpleSDK( const delta: DeltaOrderHandlers = constructAllDeltaOrdersHandlers(config); - const deltaV2: DeltaV2.DeltaOrderHandlers = - DeltaV2.constructAllDeltaOrdersHandlers(config); - const quote = constructGetQuote(config); return { @@ -369,7 +340,6 @@ export function constructSimpleSDK( limitOrders, nftOrders, delta, - deltaV2, quote, apiURL: options.apiURL ?? API_URL, chainId: options.chainId, From 482d41121dcd65fea3a6a62e69dd96c5de848dac Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Tue, 2 Jun 2026 20:19:16 +0300 Subject: [PATCH 51/52] tests/migrate delta and quote suites to v2 --- tests/__snapshots__/delta.test.ts.snap | 517 ------- tests/delta.test.ts | 1884 +++++++++++------------- tests/deltaV2.test.ts | 1002 ------------- tests/quote.test.ts | 164 +-- 4 files changed, 911 insertions(+), 2656 deletions(-) delete mode 100644 tests/__snapshots__/delta.test.ts.snap delete mode 100644 tests/deltaV2.test.ts diff --git a/tests/__snapshots__/delta.test.ts.snap b/tests/__snapshots__/delta.test.ts.snap deleted file mode 100644 index f4cb106b0..000000000 --- a/tests/__snapshots__/delta.test.ts.snap +++ /dev/null @@ -1,517 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Delta:methods Build Delta Order 1`] = ` -{ - "data": { - "beneficiary": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "deadline": NaN, - "destAmount": "3147447403157656698880", - "destToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "expectedAmount": "3163263721766488892666", - "kind": 0, - "metadata": "0x", - "nonce": "dynamic_number", - "owner": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "partnerAndFee": "512", - "permit": "0x", - "srcAmount": "1000000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - }, - "domain": { - "chainId": 1, - "name": "Portikus", - "verifyingContract": "0x0000000000bbf5c5fd284e657f01bd000933c96d", - "version": "2.0.0", - }, - "types": { - "Bridge": [ - { - "name": "protocolSelector", - "type": "bytes4", - }, - { - "name": "destinationChainId", - "type": "uint256", - }, - { - "name": "outputToken", - "type": "address", - }, - { - "name": "scalingFactor", - "type": "int8", - }, - { - "name": "protocolData", - "type": "bytes", - }, - ], - "Order": [ - { - "name": "owner", - "type": "address", - }, - { - "name": "beneficiary", - "type": "address", - }, - { - "name": "srcToken", - "type": "address", - }, - { - "name": "destToken", - "type": "address", - }, - { - "name": "srcAmount", - "type": "uint256", - }, - { - "name": "destAmount", - "type": "uint256", - }, - { - "name": "expectedAmount", - "type": "uint256", - }, - { - "name": "deadline", - "type": "uint256", - }, - { - "name": "kind", - "type": "uint8", - }, - { - "name": "nonce", - "type": "uint256", - }, - { - "name": "partnerAndFee", - "type": "uint256", - }, - { - "name": "permit", - "type": "bytes", - }, - { - "name": "metadata", - "type": "bytes", - }, - { - "name": "bridge", - "type": "Bridge", - }, - ], - }, -} -`; - -exports[`Delta:methods Get Delta Order by Id and Hash 1`] = ` -{ - "bridgeMetadata": null, - "bridgeStatus": null, - "chainId": 1, - "createdAt": "2025-04-18T14:04:43.806Z", - "deltaVersion": "2.0", - "excludeAgents": null, - "expiresAt": "2025-04-18T15:03:33.000Z", - "id": "7ec0dc82-98ad-4501-9f46-03e31e51098f", - "includeAgents": null, - "onChainOrderType": "Order", - "order": { - "beneficiary": "0x0ddc793680ff4f5793849c8c6992be1695cbe72a", - "bridge": { - "destinationChainId": 0, - "maxRelayerFee": "0", - "multiCallHandler": "0x0000000000000000000000000000000000000000", - "outputToken": "0x0000000000000000000000000000000000000000", - }, - "deadline": 1744988613, - "destAmount": "15614735", - "destToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - "expectedAmount": "15693202", - "expectedDestAmount": "15693202", - "nonce": "1744985033868", - "owner": "0x0ddc793680ff4f5793849c8c6992be1695cbe72a", - "partnerAndFee": "0", - "permit": "0x0000000000000000000000000000000000000000000000000000000000000011b7130d8420811c9f39ed0393c106255bae4619e2ad0d41ca8bbf81a91b257a89dd67bca7d8a48faba04f51dd84f4e587865e7f5c9c92858663bfb4eb809e4c26", - "srcAmount": "10000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - }, - "orderHash": "0xce14e79ba90ba85c52f3e7308d00dd8978827d8d3c2249252222cc324121d02a", - "partiallyFillable": false, - "partner": "paraswap.io-local", - "referrerAddress": null, - "status": "EXECUTED", - "transactions": [ - { - "agent": "laita", - "bidId": "787bdca0-bd2e-4cfb-ad6c-9a8a84d90a76", - "blobGasPrice": 0, - "blobGasUsed": 0, - "blockHash": "0x9b66830ee3ae02a604309099227303bc3e73a672e58cffd0685a8c3f7152ff51", - "blockNumber": 22296365, - "blockTimestamp": null, - "bridgeMetadata": null, - "bridgeOverride": null, - "bridgeProtocol": null, - "bridgeStatus": null, - "filledPercent": 10000, - "from": "0x2e5ef37ade8afb712b8be858fec7389fe32857e2", - "gasPrice": 471068591, - "gasUsed": 313190, - "hash": "0x1f955f47482a8deeb5763613448a7d737ca3b3583dc9ab0c8665329ad93a2f32", - "id": "483394ee-1f2d-47f4-bc3d-e050b6645495", - "index": 73, - "orderId": "7ec0dc82-98ad-4501-9f46-03e31e51098f", - "partnerFee": "0", - "protocolFee": "26193", - "receivedAmount": "15719395", - "receivedAmountUSD": 15.72, - "spentAmount": "10000000000000000", - "spentAmountUSD": 15.9, - "status": 1, - "to": "0x0000000000bbf5c5fd284e657f01bd000933c96d", - }, - ], - "type": "MARKET", - "updatedAt": "2025-04-18T14:05:13.519Z", - "user": "0x0ddc793680ff4f5793849c8c6992be1695cbe72a", -} -`; - -exports[`Delta:methods Get Delta Orders for user 1`] = ` -[ - { - "bridgeMetadata": null, - "bridgeStatus": null, - "chainId": 1, - "createdAt": "2024-10-10T16:18:04.727Z", - "deltaVersion": "1.0", - "excludeAgents": null, - "expiresAt": "2024-10-10T17:17:47.000Z", - "id": "8515cce6-c7c6-486b-9f1e-5702f204edd6", - "includeAgents": null, - "onChainOrderType": "Order", - "order": { - "beneficiary": "0x76176c2971300217e9f48e3dd4e40591500b96ff", - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "deadline": 1728580667, - "destAmount": "11302885800000000000", - "destToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "expectedAmount": "11302885800000000000", - "nonce": 1728577074265, - "owner": "0x76176c2971300217e9f48e3dd4e40591500b96ff", - "permit": "0x00000000000000000000000076176c2971300217e9f48e3dd4e40591500b96ff00000000000000000000000036ff475499e928590659d5b8aa3a34330a583fd900000000000000000000000000000000000000000000000000000000019d278900000000000000000000000000000000000000000000000000000000670bf2ae000000000000000000000000000000000000000000000000000000000000001bf548be9f97f37f0b2ab285bba67c8fdab99c3a08b0fdc0a910267988485535945df93e27958867f1d479c7b7783e98ba586629407e44f8d5c5d4115a7298dca9", - "srcAmount": "27076489", - "srcToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - }, - "orderHash": "0x5cd9f334b7b72943588af160e3fa8a46c894f89a3ce38967079713bf38af8128", - "partiallyFillable": false, - "partner": "delta-paraswap.io-local", - "referrerAddress": null, - "status": "EXECUTED", - "transactions": [ - { - "agent": "laita", - "bidId": null, - "blobGasPrice": 0, - "blobGasUsed": 0, - "blockHash": "0x21425d0c3625d5e55061ba2fd8ce91621dbee52c7d2846b76dd897d3438a6893", - "blockNumber": 20936359, - "blockTimestamp": null, - "bridgeMetadata": null, - "bridgeOverride": null, - "bridgeProtocol": null, - "bridgeStatus": null, - "filledPercent": 10000, - "from": "0x2e5eF37Ade8afb712B8Be858fEc7389Fe32857e2", - "gasPrice": 23525770029, - "gasUsed": 597540, - "hash": "0x3e5040d187288848ca57e4423d60fd31922b6db7fe636580d96200b03a8a8d8f", - "id": "c729ff7b-ffc8-4c85-88d8-41f4f26668eb", - "index": 57, - "orderId": "8515cce6-c7c6-486b-9f1e-5702f204edd6", - "partnerFee": "0", - "protocolFee": "0", - "receivedAmount": "17225367867506356154", - "receivedAmountUSD": 17.22, - "spentAmount": "27076489", - "spentAmountUSD": 27.06, - "status": 1, - "to": "0x1D7405DF25FD2fe80390DA3A696dcFd5120cA9Ce", - }, - ], - "type": "MARKET", - "updatedAt": "2024-10-10T16:18:51.447Z", - "user": "0x76176c2971300217e9f48e3dd4e40591500b96ff", - }, - { - "bridgeMetadata": null, - "bridgeStatus": null, - "chainId": 1, - "createdAt": "2024-10-09T16:52:18.826Z", - "deltaVersion": "1.0", - "excludeAgents": null, - "expiresAt": "2024-10-09T17:52:08.000Z", - "id": "7696f983-4f0d-4bb0-b591-61957abf74de", - "includeAgents": null, - "onChainOrderType": "Order", - "order": { - "beneficiary": "0x76176c2971300217e9f48e3dd4e40591500b96ff", - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "deadline": 1728496328, - "destAmount": "736681085000000000000", - "destToken": "0xcafe001067cdef266afb7eb5a286dcfd277f3de5", - "expectedAmount": "736681085000000000000", - "nonce": 1728492729603, - "owner": "0x76176c2971300217e9f48e3dd4e40591500b96ff", - "permit": "0x", - "srcAmount": "21000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - }, - "orderHash": "0x07b46a39e260d90f1be2575b1fffb7c905eacd0f9e36ad2f3a45f14b921b8a60", - "partiallyFillable": false, - "partner": "delta-paraswap.io-local", - "referrerAddress": null, - "status": "EXECUTED", - "transactions": [ - { - "agent": "laita", - "bidId": null, - "blobGasPrice": 0, - "blobGasUsed": 0, - "blockHash": "0x58dbd72e843c1224e8113694b8b4a37e29657f0d52634c0f3f89835a3c7a7187", - "blockNumber": 20929352, - "blockTimestamp": null, - "bridgeMetadata": null, - "bridgeOverride": null, - "bridgeProtocol": null, - "bridgeStatus": null, - "filledPercent": 10000, - "from": "0x2e5eF37Ade8afb712B8Be858fEc7389Fe32857e2", - "gasPrice": 47757958240, - "gasUsed": 224182, - "hash": "0x6d5fa34f4723283dc32496acb8b8faf4bb9e713e3a9d43152ebef7d842c59700", - "id": "0531cfdf-0732-4757-8a46-3886487eeedd", - "index": 188, - "orderId": "7696f983-4f0d-4bb0-b591-61957abf74de", - "partnerFee": "0", - "protocolFee": "0", - "receivedAmount": "1635237633557152096036", - "receivedAmountUSD": 22.77, - "spentAmount": "21000000000000000", - "spentAmountUSD": 51.08, - "status": 1, - "to": "0x1D7405DF25FD2fe80390DA3A696dcFd5120cA9Ce", - }, - ], - "type": "MARKET", - "updatedAt": "2024-10-09T16:52:37.585Z", - "user": "0x76176c2971300217e9f48e3dd4e40591500b96ff", - }, -] -`; - -exports[`Delta:methods Get Delta Price 1`] = ` -{ - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestAmountBeforeFee": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "receivedDestUSDBeforeFee": "dynamic_number", - "srcAmount": "1000000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "srcUSD": "dynamic_number", -} -`; - -exports[`Delta:methods Get Delta Price Crosschain Get Delta Price Crosschain/destToken=ETH 1`] = ` -{ - "availableBridges": [], - "bridge": { - "destinationChainId": 10, - "outputToken": "dynamic_hash", - "protocolData": "dynamic_string", - "protocolSelector": "dynamic_string", - "scalingFactor": NaN, - }, - "bridgeInfo": { - "bestReturn": true, - "destAmountAfterBridge": "dynamic_number", - "destUSDAfterBridge": "dynamic_number", - "estimatedTimeMs": NaN, - "fastest": true, - "fees": [], - "protocolName": "dynamic_string", - "recommended": true, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestAmountBeforeFee": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "receivedDestUSDBeforeFee": "dynamic_number", - "srcAmount": "1000000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "srcUSD": "dynamic_number", -} -`; - -exports[`Delta:methods Get Delta Price Crosschain Get Delta Price Crosschain/destToken=WETH 1`] = ` -{ - "availableBridges": [], - "bridge": { - "destinationChainId": 10, - "outputToken": "0x4200000000000000000000000000000000000006", - "protocolData": "dynamic_string", - "protocolSelector": "dynamic_string", - "scalingFactor": NaN, - }, - "bridgeInfo": { - "bestReturn": true, - "destAmountAfterBridge": "dynamic_number", - "destUSDAfterBridge": "dynamic_number", - "estimatedTimeMs": NaN, - "fastest": true, - "fees": [], - "protocolName": "dynamic_string", - "recommended": true, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestAmountBeforeFee": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "receivedDestUSDBeforeFee": "dynamic_number", - "srcAmount": "1000000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "srcUSD": "dynamic_number", -} -`; - -exports[`Delta:methods Get Delta Price Crosschain Get Delta Price Crosschain/destToken=random 1`] = ` -{ - "availableBridges": [], - "bridge": { - "destinationChainId": 10, - "outputToken": "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", - "protocolData": "dynamic_string", - "protocolSelector": "dynamic_string", - "scalingFactor": NaN, - }, - "bridgeInfo": { - "bestReturn": true, - "destAmountAfterBridge": "dynamic_number", - "destUSDAfterBridge": "dynamic_number", - "estimatedTimeMs": NaN, - "fastest": true, - "fees": [], - "protocolName": "dynamic_string", - "recommended": true, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "dynamic_address", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestAmountBeforeFee": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "receivedDestUSDBeforeFee": "dynamic_number", - "srcAmount": "1000000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - "srcUSD": "dynamic_number", -} -`; - -exports[`Delta:methods Submit(=build+sign+post) Delta Order 1`] = ` -{ - "beneficiary": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "deadline": NaN, - "destAmount": "3147447403157656698880", - "destToken": "0x6b175474e89094c44da98b954eedeac495271d0f", - "expectedAmount": "3163263721766488892666", - "kind": 0, - "metadata": "0x", - "nonce": "dynamic_number", - "owner": "0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9", - "partnerAndFee": "512", - "permit": "0x", - "srcAmount": "1000000000000000000", - "srcToken": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", -} -`; diff --git a/tests/delta.test.ts b/tests/delta.test.ts index ee25fa81c..7c7c792fc 100644 --- a/tests/delta.test.ts +++ b/tests/delta.test.ts @@ -1,1132 +1,1022 @@ import * as dotenv from 'dotenv'; -import Web3 from 'web3'; -import { ethers } from 'ethersV5'; -import { ethers as ethersV6 } from 'ethers'; import fetch from 'isomorphic-unfetch'; import { - constructEthersV5ContractCaller, - constructEthersV6ContractCaller, - constructFetchFetcher, constructPartialSDK, - constructWeb3ContractCaller, + constructFetchFetcher, constructGetDeltaContract, + constructGetPartnerFee, + constructAllDeltaOrdersHandlers, + constructBuildDeltaOrder, + constructBuildExternalDeltaOrder, + constructBuildTWAPDeltaOrder, + constructCancelDeltaOrder, + constructGetAgentsList, + constructGetBridgeRoutes, constructGetDeltaOrders, constructGetDeltaPrice, - constructBuildDeltaOrder, - constructApproveTokenForDelta, - constructSignDeltaOrder, - constructViemContractCaller, - constructGetPartnerFee, - SignableDeltaOrderData, - DeltaPrice, + constructIsTokenSupportedInDelta, constructPostDeltaOrder, + constructPostExternalDeltaOrder, + constructPostTWAPDeltaOrder, constructSubmitDeltaOrder, - PostDeltaOrderParams, + PaginatedResponse, FetcherFunction, - constructCancelDeltaOrder, - constructPreSignDeltaOrder, - GetDeltaContractFunctions, - constructGetBridgeInfo, - BridgeInfo, } from '../src'; -import BigNumber from 'bignumber.js'; +import type { ContractCallerFunctions, TxHash } from '../src/types'; +import type { + DeltaAuction, + DeltaPrice, + DeltaRoute, + BuiltDeltaOrder, + BridgeRoute, +} from '../src/methods/delta/types'; -import erc20abi from './abi/ERC20.json'; +dotenv.config(); -import { assert } from 'ts-essentials'; -import { HardhatProvider } from './helpers/hardhat'; -import { privateKeyToAccount } from 'viem/accounts'; -import { - Address, - createWalletClient, - custom, - Hash, - Hex, - publicActions, - verifyTypedData, -} from 'viem'; -import { hardhat } from 'viem/chains'; -import { ZERO_ADDRESS } from '../src/methods/common/orders/buildOrderData'; -import { - BridgePriceInfo, - DeltaAuctionOrder, -} from '../src/methods/delta/helpers/types'; +const PARASWAP_DELTA = '0x1111111111111111111111111111111111111111'; +const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; +const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f'; +const USDC_ARB = '0xaf88d065e77c8cc2239327c5edb3a432268e5831'; +const OWNER = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9'; +const API_URL = 'https://api.test.invalid'; +const FAKE_SIGNATURE = '0x' + 'ab'.repeat(64); + +type FetchSpy = jest.Mock, Parameters>; + +function buildPriceFixture( + overrides: Partial = {} +): DeltaPrice { + const srcInput = { + token: { chainId: 1, address: WETH }, + amount: '1000000000000000000', + amountUSD: '3000', + }; + const destOutput = { + token: { chainId: 1, address: DAI }, + amount: '2950000000000000000000', + amountUSD: '2950', + }; -dotenv.config(); + const route: DeltaRoute = { + origin: { input: srcInput, output: destOutput }, + destination: { input: destOutput, output: destOutput }, + bridge: null, + fees: { + gas: { + token: { + chainId: 1, + address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', + }, + amount: '500000', + amountUSD: '0.5', + }, + bridge: [], + }, + }; -jest.setTimeout(30 * 1000); + return { + id: 'price-id-1', + side: 'SELL', + inputToken: { chainId: 1, address: WETH }, + outputToken: { chainId: 1, address: DAI }, + route, + partner: { name: 'sdk-test', feePercent: 0 }, + spender: PARASWAP_DELTA, + alternatives: [], + ...overrides, + }; +} -const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; -const DAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; - -const chainId = 1; -const srcToken = WETH; -const destToken = DAI; -const srcAmount = (1 * 1e18).toString(); //The source amount multiplied by its decimals - -const TEST_MNEMONIC = - 'radar blur cabbage chef fix engine embark joy scheme fiction master release'; -//0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9 -const wallet = ethers.Wallet.fromMnemonic(TEST_MNEMONIC); -const walletV6 = ethersV6.HDNodeWallet.fromPhrase(TEST_MNEMONIC); - -const web3provider = new Web3(HardhatProvider as any); - -const ethersProvider = new ethers.providers.Web3Provider( - HardhatProvider as any -); - -const ethersV6Provider = new ethersV6.BrowserProvider(HardhatProvider); -const signerV6 = walletV6.connect(ethersV6Provider); - -const fetchFetcher = constructFetchFetcher(fetch); - -const signer = wallet.connect(ethersProvider); -const senderAddress = signer.address; - -const viemWalletClient = createWalletClient({ - // either walletClient needs to have account set at creation - // or provider must own the account (for testing can `await viemTestClient.impersonateAccount({ address: senderAddress });`) - // to be able to sign transactions - account: privateKeyToAccount(wallet.privateKey as Hex), - chain: { ...hardhat, id: chainId }, - transport: custom(HardhatProvider), -}).extend(publicActions); - -const ethersV5ContractCaller = constructEthersV5ContractCaller( - { - ethersProviderOrSigner: signer, - EthersContract: ethers.Contract, - }, - senderAddress -); - -const ethersV6ContractCaller = constructEthersV6ContractCaller( - { - ethersV6ProviderOrSigner: signerV6, - EthersV6Contract: ethersV6.Contract, - }, - senderAddress -); - -const web3ContractCaller = constructWeb3ContractCaller( - web3provider, - senderAddress -); - -const viemContractCaller = constructViemContractCaller( - viemWalletClient, - senderAddress -); - -describe('Delta:methods', () => { - const deltaSDK = constructPartialSDK( - { +function buildCrosschainRoute(): DeltaRoute { + const srcInput = { + token: { chainId: 1, address: WETH }, + amount: '1000000000000000000', + amountUSD: '3000', + }; + const srcOutputIntermediate = { + token: { chainId: 1, - fetcher: fetchFetcher, - contractCaller: ethersV5ContractCaller, - apiURL: process.env.API_URL, + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', }, - constructGetDeltaContract, - constructGetDeltaOrders, - constructGetDeltaPrice, - constructBuildDeltaOrder, - constructApproveTokenForDelta, - constructGetPartnerFee, - constructGetBridgeInfo - ); - - describe('Bridge methods', () => { - function flattenAllBridgeInfoTokens(bridgeInfo: BridgeInfo): string[] { - return Object.values(bridgeInfo).flatMap((chainMap) => - Object.values(chainMap).flat() - ); - } - test('Get Bridge Info', async () => { - const bridgeInfo = await deltaSDK.getBridgeInfo(); - expect(Object.keys(bridgeInfo)).toEqual( - // allow for more chains to be added in the future - expect.arrayContaining(['1', '10', '56', '130', '137', '8453', '42161']) - ); + amount: '2980000000', + amountUSD: '2980', + }; + const destInput = { + token: { chainId: 42161, address: USDC_ARB }, + amount: '2978000000', + amountUSD: '2978', + }; + const destOutput = { + token: { chainId: 42161, address: USDC_ARB }, + amount: '2978000000', + amountUSD: '2978', + }; - const defaultNumOfTokens = flattenAllBridgeInfoTokens(bridgeInfo).length; + return { + origin: { input: srcInput, output: srcOutputIntermediate }, + destination: { input: destInput, output: destOutput }, + bridge: { + protocol: 'Across', + tags: ['recommended', 'fastest'], + estimatedTimeMs: 90_000, + contractParams: { + protocolSelector: '0xdeadbeef', + outputToken: USDC_ARB, + scalingFactor: -12, + protocolData: '0xabcd', + }, + }, + fees: { + gas: { + token: { chainId: 1, address: WETH }, + amount: '7000000000000000', + amountUSD: '21', + }, + bridge: [ + { + token: { chainId: 42161, address: USDC_ARB }, + amount: '200000', + amountUSD: '0.2', + }, + ], + }, + }; +} - const bridgeInfoDIsallowedBridgeAndSwap = await deltaSDK.getBridgeInfo({ - allowBridgeAndSwap: false, - }); +/** Minimal BuiltDeltaOrder fixture representing a server-built order. */ +function buildBuiltOrderFixture( + value: Record = {}, + orderHash = '0xdeadbeef1234' +): BuiltDeltaOrder { + return { + toSign: { + domain: { + name: 'Portikus', + version: '2.0.0', + chainId: 1, + verifyingContract: PARASWAP_DELTA, + }, + types: { + Order: [ + { name: 'owner', type: 'address' }, + { name: 'beneficiary', type: 'address' }, + { name: 'srcToken', type: 'address' }, + { name: 'destToken', type: 'address' }, + { name: 'srcAmount', type: 'uint256' }, + { name: 'destAmount', type: 'uint256' }, + { name: 'expectedAmount', type: 'uint256' }, + { name: 'deadline', type: 'uint256' }, + { name: 'kind', type: 'uint8' }, + { name: 'nonce', type: 'uint256' }, + { name: 'partnerAndFee', type: 'uint256' }, + { name: 'permit', type: 'bytes' }, + { name: 'metadata', type: 'bytes' }, + { name: 'bridge', type: 'Bridge' }, + ], + Bridge: [ + { name: 'protocolSelector', type: 'bytes4' }, + { name: 'destinationChainId', type: 'uint256' }, + { name: 'outputToken', type: 'address' }, + { name: 'scalingFactor', type: 'int8' }, + { name: 'protocolData', type: 'bytes' }, + ], + }, + value: { + owner: OWNER, + beneficiary: OWNER, + srcToken: WETH, + destToken: DAI, + srcAmount: '1000000000000000000', + destAmount: '2950000000000000000000', + expectedAmount: '2950000000000000000000', + deadline: 9999999999, + kind: 0, + nonce: '12345', + permit: '0x', + partnerAndFee: '0', + metadata: '0x', + bridge: { + protocolSelector: '0x00000000', + destinationChainId: 0, + outputToken: '0x0000000000000000000000000000000000000000', + scalingFactor: 0, + protocolData: '0x', + }, + ...value, + }, + }, + orderHash, + }; +} - expect(Object.keys(bridgeInfoDIsallowedBridgeAndSwap)).toEqual( - Object.keys(bridgeInfo) +function makeMockContractCaller(): ContractCallerFunctions { + return { + staticCall: jest.fn(async () => { + throw new Error( + 'staticCall should not be invoked in v2 fetch-only tests' ); - const disallowedNumOfTokens = flattenAllBridgeInfoTokens( - bridgeInfoDIsallowedBridgeAndSwap - ).length; + }), + transactCall: jest.fn(async () => '0xfeedface' as TxHash), + signTypedDataCall: jest.fn(async () => FAKE_SIGNATURE), + }; +} - // fewer tokens are available when bridge and swap (swap on destChain after bridge) is not allowed - expect(disallowedNumOfTokens).toBeLessThan(defaultNumOfTokens); +function makeFetcher(handler: (params: any) => any): FetchSpy { + return jest.fn(async (params) => handler(params)) as FetchSpy; +} + +describe('Delta: fetch methods', () => { + test('getDeltaPrice hits /delta/v2/prices and returns DeltaPrice', async () => { + const fixture = buildPriceFixture(); + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url.startsWith(`${API_URL}/delta/v2/prices?`)).toBe(true); + expect(url).toContain(`srcToken=${WETH}`); + expect(url).toContain(`destToken=${DAI}`); + expect(url).toContain('amount=1000000000000000000'); + expect(url).toContain('chainId=1'); + expect(url).toContain('side=SELL'); + return fixture; }); - test('Get Bridge Protocols', async () => { - const bridgeProtocols = await deltaSDK.getBridgeProtocols(); - const expectedToInclude = [ - { - displayName: 'Across', - icon: expect.any(String), - protocol: 'Across', - }, - { - displayName: 'Relay', - icon: expect.any(String), - protocol: 'Relay', - }, - ]; - expect(bridgeProtocols).toEqual( - // allow for more bridges to be added in the future - expect.arrayContaining(expectedToInclude) - ); + const { getDeltaPrice } = constructGetDeltaPrice({ + apiURL: API_URL, + chainId: 1, + fetcher, }); - }); - test('Get Delta Price', async () => { - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: srcToken, - destToken: destToken, - amount: srcAmount, - userAddress: senderAddress, + const price = await getDeltaPrice({ + srcToken: WETH, + destToken: DAI, + amount: '1000000000000000000', srcDecimals: 18, destDecimals: 18, }); - const staticDeltaPrice: typeof deltaPrice = { - ...deltaPrice, - partnerFee: NaN, // dynamic number - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - receivedDestAmountBeforeFee: 'dynamic_number', - receivedDestUSDBeforeFee: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', - hmac: 'dynamic_string', - }; + expect(price).toEqual(fixture); + expect(price.route.origin.input.amount).toBe('1000000000000000000'); + expect(price.route.bridge).toBeNull(); + expect(fetcher).toHaveBeenCalledTimes(1); + }); - expect(staticDeltaPrice).toMatchSnapshot(); + test('getDeltaPrice passes destChainId for cross-chain', async () => { + const fixture = buildPriceFixture({ + route: buildCrosschainRoute(), + outputToken: { chainId: 42161, address: USDC_ARB }, + }); + const fetcher = makeFetcher(({ url }) => { + expect(url).toContain('destChainId=42161'); + return fixture; + }); + + const { getDeltaPrice } = constructGetDeltaPrice({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const price = await getDeltaPrice({ + srcToken: WETH, + destToken: USDC_ARB, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 6, + destChainId: 42161, + }); + + expect(price.route.bridge?.protocol).toBe('Across'); + expect(price.route.destination.input.token.chainId).toBe(42161); }); - describe('Get Delta Price Crosschain', () => { - const destChainId = 10; - const ETH = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; - const WETH_ON_OPTIMISM = '0x4200000000000000000000000000000000000006'; - // const DAI_TOKEN_ON_ETHEREUM = '0x6B175474E89094C44Da98b954EedeAC495271d0F'; - const DAI_TOKEN_ON_OPTIMISM = '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1'; + test('getBridgeRoutes hits /delta/v2/prices/bridge-routes and unwraps `routes`', async () => { + const routes: BridgeRoute[] = [ + { srcChainId: 1, destChainId: 42161, tokens: [USDC_ARB] }, + { srcChainId: 1, destChainId: 10, tokens: [DAI] }, + ]; + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url).toBe(`${API_URL}/delta/v2/prices/bridge-routes`); + return { routes }; + }); - test('Get Delta Price Crosschain/destToken=random', async () => { - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: WETH, - destToken: DAI_TOKEN_ON_OPTIMISM, - amount: srcAmount, - userAddress: senderAddress, - srcDecimals: 18, - destDecimals: 18, - destChainId, - }); - - const staticDeltaPrice: typeof deltaPrice = { - ...deltaPrice, - partnerFee: NaN, // dynamic number - destToken: 'dynamic_address', // will no longer match DAI_TOKEN_ON_ETHEREUM if bridge is Relay - bridge: { - ...deltaPrice.bridge, - protocolData: 'dynamic_string', - protocolSelector: 'dynamic_string', - scalingFactor: NaN, // dynamic number - }, - bridgeInfo: { - ...deltaPrice.bridgeInfo, - bestReturn: true, - destAmountAfterBridge: 'dynamic_number', - destUSDAfterBridge: 'dynamic_number', - estimatedTimeMs: NaN, // dynamic number - fastest: true, - fees: [], // dynamic array - protocolName: 'dynamic_string' as BridgePriceInfo['protocolName'], - recommended: true, - }, - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - receivedDestAmountBeforeFee: 'dynamic_number', - receivedDestUSDBeforeFee: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', - hmac: 'dynamic_string', - availableBridges: [], // dynamic array of bridge variants - }; - - // will no longer be true if swap is through Relay - // expect(deltaPrice.destToken).toEqual(DAI_TOKEN_ON_ETHEREUM.toLowerCase()); - expect(staticDeltaPrice).toMatchSnapshot(); - expect(deltaPrice.bridge.destinationChainId).toEqual(destChainId); - expect(deltaPrice.bridge.outputToken).toEqual( - DAI_TOKEN_ON_OPTIMISM.toLowerCase() - ); + const { getBridgeRoutes } = constructGetBridgeRoutes({ + apiURL: API_URL, + chainId: 1, + fetcher, }); - test('Get Delta Price Crosschain/destToken=WETH', async () => { - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: WETH, - destToken: WETH_ON_OPTIMISM, - amount: srcAmount, - userAddress: senderAddress, - srcDecimals: 18, - destDecimals: 18, - destChainId, - }); - - const staticDeltaPrice: typeof deltaPrice = { - ...deltaPrice, - partnerFee: NaN, // dynamic number - bridge: { - ...deltaPrice.bridge, - protocolData: 'dynamic_string', - protocolSelector: 'dynamic_string', - scalingFactor: NaN, // dynamic number - }, - bridgeInfo: { - ...deltaPrice.bridgeInfo, - bestReturn: true, - destAmountAfterBridge: 'dynamic_number', - destUSDAfterBridge: 'dynamic_number', - estimatedTimeMs: NaN, // dynamic number - fastest: true, - fees: [], // dynamic array - protocolName: 'dynamic_string' as BridgePriceInfo['protocolName'], - recommended: true, - }, - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - receivedDestAmountBeforeFee: 'dynamic_number', - receivedDestUSDBeforeFee: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', - hmac: 'dynamic_string', - availableBridges: [], // dynamic array of bridge variants - }; - - expect(staticDeltaPrice).toMatchSnapshot(); - expect(deltaPrice.bridge.destinationChainId).toEqual(destChainId); - expect(deltaPrice.bridge.outputToken).toEqual( - WETH_ON_OPTIMISM.toLowerCase() - ); + expect(await getBridgeRoutes()).toEqual(routes); + }); + + test('getBridgeRoutes passes filter params', async () => { + const fetcher = makeFetcher(({ url }) => { + expect(url).toContain('allowBridgeAndSwap=false'); + expect(url).toContain('bridges=Across%2CRelay'); + return { routes: [] }; }); - test('Get Delta Price Crosschain/destToken=ETH', async () => { - const deltaPrice = await deltaSDK.getDeltaPrice({ - srcToken: WETH, - destToken: ETH, - amount: srcAmount, - userAddress: senderAddress, - srcDecimals: 18, - destDecimals: 18, - destChainId, - }); - - const staticDeltaPrice: typeof deltaPrice = { - ...deltaPrice, - partnerFee: NaN, // dynamic number - bridge: { - ...deltaPrice.bridge, - outputToken: 'dynamic_hash', // WETH or ETH depending on bridge used - protocolData: 'dynamic_string', - protocolSelector: 'dynamic_string', - scalingFactor: NaN, // dynamic number - }, - bridgeInfo: { - ...deltaPrice.bridgeInfo, - bestReturn: true, - destAmountAfterBridge: 'dynamic_number', - destUSDAfterBridge: 'dynamic_number', - estimatedTimeMs: NaN, // dynamic number - fastest: true, - fees: [], // dynamic array - protocolName: 'dynamic_string' as BridgePriceInfo['protocolName'], - recommended: true, - }, - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - receivedDestAmountBeforeFee: 'dynamic_number', - receivedDestUSDBeforeFee: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', - hmac: 'dynamic_string', - availableBridges: [], // dynamic array of bridge variants - }; - - expect(staticDeltaPrice).toMatchSnapshot(); - expect(deltaPrice.bridge.destinationChainId).toEqual(destChainId); - // bridge.outputToken = WETH|ETH for destToken=ETH|WETH on destChain depending on bridge used; - // wrap/unwrap logic is determined by bridge.multiCallHandler presence - expect([WETH_ON_OPTIMISM.toLowerCase(), ETH.toLowerCase()]).toContain( - deltaPrice.bridge.outputToken - ); + const { getBridgeRoutes } = constructGetBridgeRoutes({ + apiURL: API_URL, + chainId: 1, + fetcher, }); + + expect( + await getBridgeRoutes({ + allowBridgeAndSwap: false, + bridges: ['Across', 'Relay'], + }) + ).toEqual([]); }); - test('Get Delta Contract', async () => { - const deltaContract = await deltaSDK.getDeltaContract(); - expect(deltaContract).toMatchInlineSnapshot( - `"0x0000000000bbf5c5fd284e657f01bd000933c96d"` - ); + test('isTokenSupportedInDelta unwraps `supported`', async () => { + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect( + url.startsWith(`${API_URL}/delta/v2/prices/is-token-supported/?`) + ).toBe(true); + expect(url).toContain(`token=${WETH}`); + expect(url).toContain('chainId=1'); + return { supported: true }; + }); + + const { isTokenSupportedInDelta } = constructIsTokenSupportedInDelta({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + expect(await isTokenSupportedInDelta(WETH)).toBe(true); }); - test('Approve Token For Delta', async () => { - const deltaContract = await deltaSDK.getDeltaContract(); - assert(deltaContract, 'Delta contract not found'); + test('getDeltaOrders returns the pagination envelope', async () => { + const order = { id: 'auction-1' } as unknown as DeltaAuction; + const envelope: PaginatedResponse = { + data: [order], + total: 1, + page: 1, + limit: 100, + hasMore: false, + }; - const allowanceBefore = await getTokenAllowance({ - tokenAddress: DAI, - owner: senderAddress, - spender: deltaContract, + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url.startsWith(`${API_URL}/delta/v2/orders?`)).toBe(true); + expect(url).toContain(`userAddress=${OWNER}`); + expect(url).toContain('page=2'); + expect(url).toContain('limit=10'); + return envelope; + }); + + const { getDeltaOrders } = constructGetDeltaOrders({ + apiURL: API_URL, + chainId: 1, + fetcher, }); - expect(allowanceBefore.toString()).toEqual('0'); + const result = await getDeltaOrders({ + userAddress: OWNER, + page: 2, + limit: 10, + }); - const amount = '1000000000000000000'; // 1 DAI - const tx = await deltaSDK.approveTokenForDelta(amount, DAI); - expect(tx).toBeDefined(); - await tx.wait(); + expect(result).toEqual(envelope); + expect(result.hasMore).toBe(false); + expect(result.data).toHaveLength(1); + }); - const allowanceAfter = await getTokenAllowance({ - tokenAddress: DAI, - owner: senderAddress, - spender: deltaContract, + test('getDeltaOrders by id / by hash use the v2 path', async () => { + const order = { id: 'auction-1' } as unknown as DeltaAuction; + const fetcher = makeFetcher(({ url }) => { + if (url === `${API_URL}/delta/v2/orders/auction-1`) return order; + if (url === `${API_URL}/delta/v2/orders/hash/0xhash`) return order; + throw new Error(`unexpected URL ${url}`); }); - expect(allowanceAfter.toString()).toEqual(amount); + const { getDeltaOrderById, getDeltaOrderByHash } = + constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); + + expect(await getDeltaOrderById('auction-1')).toBe(order); + expect(await getDeltaOrderByHash('0xhash')).toBe(order); }); - test('Get Delta Orders for user', async () => { - const userWithOrders = '0x76176C2971300217E9f48E3dD4e40591500b96Ff'; + test('getRequiredBalanceForDeltaOrders hits /delta/v2/orders/fillablebalance/:chainId/:userAddress', async () => { + const required = { + [WETH]: '500000000000000000', + [DAI]: '1500000000000000000000', + }; + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url).toBe( + `${API_URL}/delta/v2/orders/fillablebalance/1/${OWNER}` + ); + return required; + }); - const deltaOrders = await deltaSDK.getDeltaOrders({ - userAddress: userWithOrders, + const { getRequiredBalanceForDeltaOrders } = + constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); + + expect( + await getRequiredBalanceForDeltaOrders({ userAddress: OWNER }) + ).toEqual(required); + }); + + test('getRequiredBalanceForDeltaOrders narrows the URL when tokenAddress is passed', async () => { + const fetcher = makeFetcher(({ url }) => { + expect(url).toBe( + `${API_URL}/delta/v2/orders/fillablebalance/1/${OWNER}/${WETH}` + ); + return { [WETH]: '500000000000000000' }; }); - // Orders that we know the user had in the past - const staticSliceOfPastOrders = deltaOrders.slice(-2); // first 2 orders historically - expect(staticSliceOfPastOrders).toMatchSnapshot(); + const { getRequiredBalanceForDeltaOrders } = + constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); + + const balance = await getRequiredBalanceForDeltaOrders({ + userAddress: OWNER, + tokenAddress: WETH, + }); + expect(balance[WETH]).toBe('500000000000000000'); }); - test('Get Delta Order by Id and Hash', async () => { - const orderId = '7ec0dc82-98ad-4501-9f46-03e31e51098f'; - const deltaOrder = await deltaSDK.getDeltaOrderById(orderId); - expect(deltaOrder).toMatchSnapshot(); - expect(deltaOrder).toBeDefined(); - assert( - deltaOrder?.orderHash, - "Delta order not found or doesn't have orderHash" - ); + test('getAgentsList hits /delta/v2/agents/list/:chainId and returns agent names', async () => { + const agents = ['agent-a', 'agent-b']; + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('GET'); + expect(url).toBe(`${API_URL}/delta/v2/agents/list/42161`); + return agents; // server returns string[] directly + }); - const orderByHash = await deltaSDK.getDeltaOrderByHash( - deltaOrder.orderHash - ); - expect(orderByHash).toEqual(deltaOrder); + const { getAgentsList } = constructGetAgentsList({ + apiURL: API_URL, + chainId: 42161, + fetcher, + }); + + expect(await getAgentsList()).toEqual(agents); }); +}); - test('Get PartnerFee', async () => { - const partnerFee = await deltaSDK.getPartnerFee({ partner: 'paraswap.io' }); - expect(partnerFee).toMatchInlineSnapshot(` - { - "partnerAddress": "0xc85f5d432b7fa25287c7e0cb88139a1a4c37f565", - "partnerFee": 0.15, - "takeSurplus": false, - } - `); +describe('Delta: build (server-side via POST /v2/orders/build)', () => { + test('buildDeltaOrder POSTs to /delta/v2/orders/build with correct body', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, method, data }) => { + expect(method).toBe('POST'); + expect(url).toBe(`${API_URL}/delta/v2/orders/build`); + postedBody = data; + return builtFixture; + }); + + const { buildDeltaOrder } = constructBuildDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const route = buildPriceFixture().route; + const result = await buildDeltaOrder({ + owner: OWNER, + route, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(result).toEqual(builtFixture); + // build endpoint derives the chain from the route — no chainId in the body + expect(postedBody.chainId).toBeUndefined(); + expect(postedBody.side).toBe('SELL'); + expect(postedBody.owner).toBe(OWNER); + expect(postedBody.route).toBe(route); + expect(postedBody.slippage).toBeUndefined(); + expect(postedBody.orderType).toBe('Order'); }); - test('Build Delta Order', async () => { - const sampleDeltaPrice: DeltaPrice = { - destAmount: '3163263721766488892666', - destAmountBeforeFee: '3194635547945152526200', - receivedDestAmount: '3163263721766488892666', - destToken: '0x6b175474e89094c44da98b954eedeac495271d0f', - destUSD: '3166.4269854931', - receivedDestUSD: '3166.4269854931', - destUSDBeforeFee: '3197.8301834931', - gasCost: '347788', - gasCostBeforeFee: '124240', - gasCostUSD: '31.403198', - gasCostUSDBeforeFee: '11.218137', - partner: 'anon', - partnerFee: 0, - srcAmount: '1000000000000000000', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - srcUSD: '3191.5500000000', - hmac: '1234aeb', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', - }, - }; + test('buildDeltaOrder passes slippage to server for SELL', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; - const slippagePercent = 0.5; - const destAmountAfterSlippage = decreaseBySlippage( - sampleDeltaPrice.destAmount, - slippagePercent - ); + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); - const amount = '1000000000000000000'; // 1 DAI + const { buildDeltaOrder } = constructBuildDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); - const signableOrderData = await deltaSDK.buildDeltaOrder({ - deltaPrice: sampleDeltaPrice, - owner: senderAddress, - // beneficiary: anotherAccount, // if need to send destToken to another account - // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: WETH, - destToken: DAI, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount - partnerAddress: ZERO_ADDRESS, + await buildDeltaOrder({ + owner: OWNER, + route: buildPriceFixture().route, + side: 'SELL', + slippage: 100, + partnerAddress: '0x0000000000000000000000000000000000000000', }); - const staticSignableOrderData: typeof signableOrderData = { - ...signableOrderData, - data: { - ...signableOrderData.data, - deadline: NaN, // dynamic number - nonce: 'dynamic_number', - }, - }; - // for ZERO partnerAddress capSurplus (true) shifted (<< 9) = 512 - expect(signableOrderData.data.partnerAndFee).toEqual((1 << 9).toString()); - expect(staticSignableOrderData).toMatchSnapshot(); + // slippage is forwarded to server; server applies it to destAmount + expect(postedBody.slippage).toBe(100); + expect(postedBody.side).toBe('SELL'); }); - test('Build Delta Order with slippage (SELL)', async () => { - const sampleDeltaPrice: DeltaPrice = { - destAmount: '3163263721766488892666', - destAmountBeforeFee: '3194635547945152526200', - receivedDestAmount: '3163263721766488892666', - destToken: '0x6b175474e89094c44da98b954eedeac495271d0f', - destUSD: '3166.4269854931', - receivedDestUSD: '3166.4269854931', - destUSDBeforeFee: '3197.8301834931', - gasCost: '347788', - gasCostBeforeFee: '124240', - gasCostUSD: '31.403198', - gasCostUSDBeforeFee: '11.218137', - partner: 'anon', - partnerFee: 0, - srcAmount: '1000000000000000000', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - srcUSD: '3191.5500000000', - hmac: '1234aeb', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', - }, - }; + test('buildDeltaOrder passes slippage to server for BUY', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; - const slippageBps = 50; // 50 bps = 0.5% - const BPS_BASE = BigInt(10_000); - const expectedDestAmount = ( - (BigInt(sampleDeltaPrice.destAmount) * (BPS_BASE - BigInt(slippageBps))) / - BPS_BASE - ).toString(10); + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); - const amount = '1000000000000000000'; + const { buildDeltaOrder } = constructBuildDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); - const signableOrderData = await deltaSDK.buildDeltaOrder({ - deltaPrice: sampleDeltaPrice, - owner: senderAddress, - srcToken: WETH, - destToken: DAI, - srcAmount: amount, - slippage: slippageBps, - partnerAddress: ZERO_ADDRESS, + await buildDeltaOrder({ + owner: OWNER, + route: buildPriceFixture().route, + side: 'BUY', + slippage: 100, + partnerAddress: '0x0000000000000000000000000000000000000000', }); - expect(signableOrderData.data.srcAmount).toEqual(amount); - expect(signableOrderData.data.destAmount).toEqual(expectedDestAmount); + expect(postedBody.slippage).toBe(100); + expect(postedBody.side).toBe('BUY'); }); - test('Build Delta Order with slippage (BUY)', async () => { - const sampleDeltaPrice: DeltaPrice = { - destAmount: '3163263721766488892666', - destAmountBeforeFee: '3194635547945152526200', - receivedDestAmount: '3163263721766488892666', - destToken: '0x6b175474e89094c44da98b954eedeac495271d0f', - destUSD: '3166.4269854931', - receivedDestUSD: '3166.4269854931', - destUSDBeforeFee: '3197.8301834931', - gasCost: '347788', - gasCostBeforeFee: '124240', - gasCostUSD: '31.403198', - gasCostUSDBeforeFee: '11.218137', - partner: 'anon', - partnerFee: 0, - srcAmount: '1000000000000000000', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - srcUSD: '3191.5500000000', - hmac: '1234aeb', + test('buildDeltaOrder passes cross-chain route as-is; server injects destinationChainId', async () => { + const ccRoute = buildCrosschainRoute(); + const builtFixture = buildBuiltOrderFixture({ + srcToken: WETH, + destToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', + protocolSelector: '0xdeadbeef', + destinationChainId: 42161, + outputToken: USDC_ARB, + scalingFactor: -12, + protocolData: '0xabcd', }, - }; + }); + let postedBody: any; - const slippageBps = 50; // 50 bps = 0.5% - const destAmount = '3163263721766488892666'; + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); - const BPS_BASE = BigInt(10_000); - const expectedSrcAmount = ( - (BigInt(sampleDeltaPrice.srcAmount) * (BPS_BASE + BigInt(slippageBps))) / - BPS_BASE - ).toString(10); + const { buildDeltaOrder } = constructBuildDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); - const signableOrderData = await deltaSDK.buildDeltaOrder({ - deltaPrice: sampleDeltaPrice, - owner: senderAddress, - srcToken: WETH, - destToken: DAI, - destAmount, - slippage: slippageBps, - side: 'BUY', - partnerAddress: ZERO_ADDRESS, + const result = await buildDeltaOrder({ + owner: OWNER, + route: ccRoute, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', }); - expect(signableOrderData.data.destAmount).toEqual(destAmount); - expect(signableOrderData.data.srcAmount).toEqual(expectedSrcAmount); + // route is forwarded as-is; bridge in route.contractParams has no destinationChainId + expect(postedBody.route).toBe(ccRoute); + // the server (fixture) fills in destinationChainId + expect(result.toSign.value.bridge).toMatchObject({ + protocolSelector: '0xdeadbeef', + destinationChainId: 42161, + }); }); - let signature = ''; + test('buildExternalDeltaOrder sends orderType ExternalOrder with handler/data', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; - test.each([ - ['ethersV5', ethersV5ContractCaller], - ['ethersV6', ethersV6ContractCaller], - ['web3', web3ContractCaller], - ['viem', viemContractCaller], - ])('sign Delta Order with %s', async (_libName, contractCaller) => { - const sdk = constructPartialSDK( - { - chainId: 1, - fetcher: fetchFetcher, - contractCaller, - apiURL: process.env.API_URL, - }, - constructSignDeltaOrder + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildExternalDeltaOrder } = constructBuildExternalDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); + + const route = buildPriceFixture().route; + await buildExternalDeltaOrder({ + owner: OWNER, + handler: '0x2222222222222222222222222222222222222222', + data: '0xdeadbeef', + route, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postedBody.orderType).toBe('ExternalOrder'); + expect(postedBody.handler).toBe( + '0x2222222222222222222222222222222222222222' ); + expect(postedBody.data).toBe('0xdeadbeef'); + expect(postedBody.route).toBe(route); + }); - const sampleOrder: SignableDeltaOrderData = { - data: { - beneficiary: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9', - deadline: 1731328853, - destAmount: '3147447403157656698880', - destToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F', - expectedAmount: '3163263721766488892666', - nonce: '1731325253703', - owner: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9', - partnerAndFee: '0', - permit: '0x', - srcAmount: '1000000000000000000', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - kind: 0, - metadata: '0x', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', - }, - }, - domain: { - chainId: 1, - name: 'Portikus', - verifyingContract: '0x0000000000bbf5c5fd284e657f01bd000933c96d', - version: '2.0.0', - }, - types: { - Order: [ - { - name: 'owner', - type: 'address', - }, - { - name: 'beneficiary', - type: 'address', - }, - { - name: 'srcToken', - type: 'address', - }, - { - name: 'destToken', - type: 'address', - }, - { - name: 'srcAmount', - type: 'uint256', - }, - { - name: 'destAmount', - type: 'uint256', - }, - { - name: 'expectedAmount', - type: 'uint256', - }, - { - name: 'deadline', - type: 'uint256', - }, - { - name: 'kind', - type: 'uint8', - }, - { - name: 'nonce', - type: 'uint256', - }, - { - name: 'partnerAndFee', - type: 'uint256', - }, - { - name: 'permit', - type: 'bytes', - }, - { - name: 'metadata', - type: 'bytes', - }, - { - name: 'bridge', - type: 'Bridge', - }, - ], - Bridge: [ - { - name: 'protocolSelector', - type: 'bytes4', - }, - { - name: 'destinationChainId', - type: 'uint256', - }, - { - name: 'outputToken', - type: 'address', - }, - { - name: 'scalingFactor', - type: 'int8', - }, - { - name: 'protocolData', - type: 'bytes', - }, - ], - }, - }; + test('buildTWAPDeltaOrder (sell) sends TWAPOrder body; slippage forwarded to server', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); + + const { buildTWAPDeltaOrder } = constructBuildTWAPDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); - const deltaOrderSignature = await sdk.signDeltaOrder(sampleOrder); - if (!signature) signature = deltaOrderSignature; - // signatures match between libraries - expect(deltaOrderSignature).toEqual(signature); + const route = buildPriceFixture().route; + await buildTWAPDeltaOrder({ + owner: OWNER, + onChainOrderType: 'TWAPOrder', + route, + totalSrcAmount: '5000000000000000000', + interval: 300, + numSlices: 5, + slippage: 50, + partnerAddress: '0x0000000000000000000000000000000000000000', + }); + + expect(postedBody.orderType).toBe('TWAPOrder'); + expect(postedBody.interval).toBe(300); + expect(postedBody.numSlices).toBe(5); + expect(postedBody.totalSrcAmount).toBe('5000000000000000000'); + expect(postedBody.slippage).toBe(50); // server applies slippage to destAmountPerSlice + expect(postedBody.side).toBe('SELL'); }); - let cancelSignature = ''; + test('buildTWAPDeltaOrder (buy) forwards slippage and maxSrcAmount to server', async () => { + const builtFixture = buildBuiltOrderFixture(); + let postedBody: any; + + const fetcher = makeFetcher(({ url, data }) => { + if (url === `${API_URL}/delta/v2/orders/build`) { + postedBody = data; + return builtFixture; + } + throw new Error(`unexpected ${url}`); + }); - const sampleOrderId = '7ec0dc82-98ad-4501-9f46-03e31e51098f'; + const { buildTWAPDeltaOrder } = constructBuildTWAPDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); - test.each([ - ['ethersV5', ethersV5ContractCaller], - ['ethersV6', ethersV6ContractCaller], - ['web3', web3ContractCaller], - ['viem', viemContractCaller], - ])( - 'sign Cancel Delta Order Request with %s', - async (_libName, contractCaller) => { - const sdk = constructPartialSDK( - { - chainId: 1, - fetcher: fetchFetcher, - contractCaller, - apiURL: process.env.API_URL, - }, - constructCancelDeltaOrder - ); + const route = buildPriceFixture().route; + await buildTWAPDeltaOrder({ + owner: OWNER, + onChainOrderType: 'TWAPBuyOrder', + route, + totalDestAmount: '5000000000000000000', + maxSrcAmount: '1000000000000000000', + interval: 300, + numSlices: 5, + slippage: 100, + partnerAddress: '0x0000000000000000000000000000000000000000', + }); - const deltaCancelSignature = await sdk.signCancelLimitDeltaOrderRequest({ - orderIds: [sampleOrderId], - }); + expect(postedBody.orderType).toBe('TWAPBuyOrder'); + expect(postedBody.side).toBe('BUY'); + expect(postedBody.maxSrcAmount).toBe('1000000000000000000'); + expect(postedBody.slippage).toBe(100); + }); +}); - const valid = await verifySignedCancelRequest({ - orderId: sampleOrderId, - signature: deltaCancelSignature, - address: senderAddress, - chainId: sdk.chainId, - }); +describe('Delta: submit (build → sign → post)', () => { + test('submitDeltaOrder posts to /delta/v2/orders with signed order', async () => { + const builtFixture = buildBuiltOrderFixture(); + let posted: any; + let postUrl = ''; - expect(valid).toBe(true); + const fetcher = makeFetcher(({ url, method, data }) => { + if (method === 'POST' && url === `${API_URL}/delta/v2/orders/build`) { + return builtFixture; + } + if (method === 'POST' && url.startsWith(`${API_URL}/delta/v2/orders`)) { + postUrl = url; + posted = data; + return { + id: 'auction-99', + order: data.order, + onChainOrderType: 'Order', + } as unknown as DeltaAuction<'Order'>; + } + throw new Error(`unexpected request ${method} ${url}`); + }); - if (!cancelSignature) cancelSignature = deltaCancelSignature; - // signatures match between libraries - expect(deltaCancelSignature).toEqual(cancelSignature); - } - ); + const { submitDeltaOrder } = constructSubmitDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + contractCaller: makeMockContractCaller(), + }); - const dummyFetcher: FetcherFunction = (params) => { - // intercept POST requests - if (params.method === 'POST') { - return params as any; - } + const response = await submitDeltaOrder({ + owner: OWNER, + route: buildPriceFixture().route, + side: 'SELL', + partnerAddress: '0x0000000000000000000000000000000000000000', + }); - return fetchFetcher(params); - }; + expect(postUrl.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); + expect(posted.signature).toBe(FAKE_SIGNATURE); + expect(posted.chainId).toBe(1); + // order comes from builtFixture.toSign.value + expect(posted.order.owner).toBe(OWNER); + expect(posted.order.srcToken).toBe(WETH); + expect(posted.order.destToken).toBe(DAI); + expect(response.id).toBe('auction-99'); + }); - const mockFetch = jest.fn(dummyFetcher); + test('postDeltaOrder forwards degenMode as a query param', async () => { + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('POST'); + expect(url).toContain('degenMode=true'); + return { id: 'x' } as unknown as DeltaAuction<'Order'>; + }); - const dummySDK = constructPartialSDK( - { + const { postDeltaOrder } = constructPostDeltaOrder({ + apiURL: API_URL, chainId: 1, - fetcher: mockFetch as FetcherFunction, - contractCaller: ethersV5ContractCaller, - apiURL: process.env.API_URL, - }, - constructPostDeltaOrder, - constructSubmitDeltaOrder - ); - - test('Post Delta Order', async () => { - const sampleOrderData: SignableDeltaOrderData['data'] = { - beneficiary: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9', - deadline: NaN, // dynamic number - destAmount: '3147447403157656698880', - destToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F', - expectedAmount: '3163263721766488892666', - nonce: 'dynamic_number', - owner: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9', - partnerAndFee: '0', - permit: '0x', - srcAmount: '1000000000000000000', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - kind: 0, - metadata: '0x', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', - }, - }; + fetcher, + }); - const sampleSignature = '0x1234....'; + expect( + await postDeltaOrder({ + signature: FAKE_SIGNATURE, + order: {} as any, + degenMode: true, + }) + ).toEqual({ id: 'x' }); + }); - const input = { - order: sampleOrderData, - signature: sampleSignature, - }; + test('postExternalDeltaOrder sends to /delta/v2/orders', async () => { + const fetcher = makeFetcher(({ url, method }) => { + expect(method).toBe('POST'); + expect(url).toBe(`${API_URL}/delta/v2/orders`); + return { id: 'ext-1' } as unknown as DeltaAuction<'ExternalOrder'>; + }); - await dummySDK.postDeltaOrder(input); + const { postExternalDeltaOrder } = constructPostExternalDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + }); - expect(mockFetch).toHaveBeenLastCalledWith({ - data: { ...input, chainId: dummySDK.chainId }, - method: 'POST', - url: `${dummySDK.apiURL}/delta/orders`, + expect( + await postExternalDeltaOrder({ + signature: FAKE_SIGNATURE, + order: {} as any, + }) + ).toEqual({ id: 'ext-1' }); + }); + + test('postTWAPDeltaOrder sends to /delta/v2/orders with onChainOrderType', async () => { + const fetcher = makeFetcher(({ url, method, data }) => { + expect(method).toBe('POST'); + expect(url.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); + expect(data.onChainOrderType).toBe('TWAPOrder'); + return { id: 'twap-1' } as unknown as DeltaAuction<'TWAPOrder'>; + }); + + const { postTWAPDeltaOrder } = constructPostTWAPDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, }); + + expect( + await postTWAPDeltaOrder({ + signature: FAKE_SIGNATURE, + order: {} as any, + onChainOrderType: 'TWAPOrder', + }) + ).toEqual({ id: 'twap-1' }); }); +}); - test('Submit(=build+sign+post) Delta Order', async () => { - const sampleDeltaPrice: DeltaPrice = { - destAmount: '3163263721766488892666', - destAmountBeforeFee: '3194635547945152526200', - receivedDestAmount: '3163263721766488892666', - destToken: '0x6b175474e89094c44da98b954eedeac495271d0f', - destUSD: '3166.4269854931', - receivedDestUSD: '3166.4269854931', - destUSDBeforeFee: '3197.8301834931', - gasCost: '347788', - gasCostBeforeFee: '124240', - gasCostUSD: '31.403198', - gasCostUSDBeforeFee: '11.218137', - partner: 'anon', - partnerFee: 0, - srcAmount: '1000000000000000000', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - srcUSD: '3191.5500000000', - hmac: '1234aeb', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', - }, - }; +describe('Delta: cancel', () => { + test('cancelDeltaOrders signs then posts to /delta/v2/orders/cancel', async () => { + let postedTo = ''; + let postedBody: any; + + const fetcher = makeFetcher(({ url, method, data }) => { + const adapter = url.includes('/adapters/contracts') + ? { + AugustusSwapper: '0x', + TokenTransferProxy: '0x', + AugustusRFQ: '0x', + Executors: {}, + ParaswapDelta: '0x1111111111111111111111111111111111111111', + } + : undefined; + if (adapter) return adapter; + if (method === 'POST') { + postedTo = url; + postedBody = data; + return { success: true }; + } + throw new Error('unexpected'); + }); - const slippagePercent = 0.5; - const destAmountAfterSlippage = decreaseBySlippage( - sampleDeltaPrice.destAmount, - slippagePercent - ); + const { cancelDeltaOrders } = constructCancelDeltaOrder({ + apiURL: API_URL, + chainId: 1, + fetcher, + contractCaller: makeMockContractCaller(), + }); - const amount = '1000000000000000000'; // 1 DAI + const result = await cancelDeltaOrders({ + orderIds: ['a', 'b'], + }); - const input = { - deltaPrice: sampleDeltaPrice, - owner: senderAddress, - // beneficiary: anotherAccount, // if need to send destToken to another account - // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: WETH, - destToken: DAI, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount - partnerAddress: ZERO_ADDRESS, - }; + expect(result).toEqual({ success: true }); + expect(postedTo).toBe(`${API_URL}/delta/v2/orders/cancel`); + expect(postedBody.orderIds).toEqual(['a', 'b']); + expect(postedBody.signature).toBe(FAKE_SIGNATURE); + }); +}); - await dummySDK.submitDeltaOrder(input); +describe('Delta: live API contract', () => { + jest.setTimeout(30_000); - const callArgs = mockFetch.mock.lastCall?.[0]; - assert(callArgs, 'No fetch call was made'); - assert('data' in callArgs, 'No data was sent in the fetch call'); - const { order, signature } = callArgs.data as PostDeltaOrderParams; + const LIVE_API = process.env.API_URL; + const fetchFetcher = constructFetchFetcher(fetch); - expect(signature).toBeDefined(); + test('GET /delta/v2/prices (same-chain) matches DeltaPrice shape', async () => { + const { getDeltaPrice } = constructGetDeltaPrice({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, + }); - const staticSignedOrderData: SignableDeltaOrderData['data'] = { - ...order, - deadline: NaN, // dynamic number - nonce: 'dynamic_number', - }; + const price = await getDeltaPrice({ + srcToken: WETH, + destToken: DAI, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 18, + side: 'SELL', + }); - // for ZERO partnerAddress capSurplus (true) shifted (<< 9) = 512 - expect(order.partnerAndFee).toEqual((1 << 9).toString()); - expect(staticSignedOrderData).toMatchSnapshot(); + expect(price.side).toBe('SELL'); + expect(price.inputToken.chainId).toBe(1); + expect(price.outputToken.chainId).toBe(1); + expect(typeof price.id).toBe('string'); + expect(typeof price.spender).toBe('string'); + expect(price.route.origin.input.token.address.toLowerCase()).toBe(WETH); + expect(typeof price.route.origin.input.amount).toBe('string'); + expect(typeof price.route.origin.input.amountUSD).toBe('string'); + // same-chain: bridge is null + expect(price.route.bridge).toBeNull(); + // fees.gas is a single DeltaTokenAmount, fees.bridge is an array + expect(typeof price.route.fees.gas.amount).toBe('string'); + expect(Array.isArray(price.route.fees.bridge)).toBe(true); }); - describe('PreSign Delta Order', () => { - const sdk = constructPartialSDK( - { - chainId: 1, - fetcher: fetchFetcher, - contractCaller: viemContractCaller, - apiURL: process.env.API_URL, - }, - constructPreSignDeltaOrder, - constructGetDeltaContract - ); + test('GET /delta/v2/prices (cross-chain) returns DeltaRoute with bridge.contractParams (no destinationChainId)', async () => { + const { getDeltaPrice } = constructGetDeltaPrice({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, + }); - const sampleOrder: DeltaAuctionOrder = { - owner: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9', - beneficiary: '0xaC39b311DCEb2A4b2f5d8461c1cdaF756F4F7Ae9', - srcToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', - destToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F', - srcAmount: '1000000000000000000', - destAmount: '3147447403157656698880', - expectedAmount: '3163263721766488892666', - kind: 0, - metadata: '0x', - deadline: 1731328853, - nonce: '1731325253703', - permit: '0x', - partnerAndFee: '0', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: ZERO_ADDRESS, - scalingFactor: 0, - protocolData: '0x', - }, - }; + const price = await getDeltaPrice({ + srcToken: WETH, + destToken: USDC_ARB, + amount: '1000000000000000000', + srcDecimals: 18, + destDecimals: 6, + destChainId: 42161, + side: 'SELL', + }); - test('hash Delta Order', async () => { - const orderHash = await sdk.hashDeltaOrder(sampleOrder); - expect(orderHash).toMatchInlineSnapshot( - `"0x4e68492d838e64c329ecdba51d32cb088088445ca62b1d5c4edf5a2ab80b586d"` + expect(price.outputToken.chainId).toBe(42161); + expect(price.route.destination.input.token.chainId).toBe(42161); + expect(price.route.bridge).not.toBeNull(); + if (price.route.bridge) { + expect(typeof price.route.bridge.protocol).toBe('string'); + expect(Array.isArray(price.route.bridge.tags)).toBe(true); + expect(typeof price.route.bridge.contractParams.protocolSelector).toBe( + 'string' + ); + expect(typeof price.route.bridge.contractParams.outputToken).toBe( + 'string' + ); + // destinationChainId is NOT present on the wire — the SDK injects it at build time + expect('destinationChainId' in price.route.bridge.contractParams).toBe( + false ); + } + }); + + test('GET /delta/v2/prices/bridge-routes returns flat array', async () => { + const { getBridgeRoutes } = constructGetBridgeRoutes({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, }); - test('PreSign Delta Order', async () => { - const sampleOrderHash = - '0x4e68492d838e64c329ecdba51d32cb088088445ca62b1d5c4edf5a2ab80b586d'; - const txHash = await sdk.setDeltaOrderPreSignature(sampleOrderHash); - await viemWalletClient.waitForTransactionReceipt({ hash: txHash }); + const routes = await getBridgeRoutes(); + expect(Array.isArray(routes)).toBe(true); + expect(routes.length).toBeGreaterThan(0); + const first = routes[0]!; + expect(typeof first.srcChainId).toBe('number'); + expect(typeof first.destChainId).toBe('number'); + expect(Array.isArray(first.tokens)).toBe(true); + }); - const isPreSigned = await checkIfOrderHashPreSigned({ - orderHash: sampleOrderHash, - owner: senderAddress, - sdk, - }); - expect(isPreSigned).toBe(true); + test('GET /delta/v2/prices/bridge-protocols returns protocols', async () => { + const { getBridgeProtocols } = constructGetBridgeRoutes({ + apiURL: LIVE_API, + chainId: 1, + fetcher: fetchFetcher, }); + + const protocols = await getBridgeProtocols(); + expect(protocols.length).toBeGreaterThan(0); + expect(protocols.some((p) => p.protocol === 'Across')).toBe(true); }); }); -function getTokenAllowance({ - tokenAddress, - owner, - spender, -}: { - tokenAddress: string; - owner: string; - spender: string; -}): Promise { - const contract = new ethers.Contract(tokenAddress, erc20abi, signer); - return contract.allowance(owner, spender); -} - -function decreaseBySlippage(amount: string, slippagePercent: number): string { - const amountAfterSlippage = BigInt( - +(+amount * (1 - slippagePercent / 100)).toFixed(0) - ).toString(10); - - return amountAfterSlippage; -} +describe('Delta: SDK wiring', () => { + test('constructAllDeltaOrdersHandlers exposes all v2 methods', () => { + const sdk = constructAllDeltaOrdersHandlers({ + apiURL: API_URL, + chainId: 1, + fetcher: makeFetcher(() => ({})), + contractCaller: makeMockContractCaller(), + }); -type VerifySignedCancelRequestInput = { - orderId: string; - signature: string; - address: string; - chainId: number; -}; - -async function verifySignedCancelRequest({ - orderId, - signature, - address, -}: VerifySignedCancelRequestInput): Promise { - const ParaswapDelta = await constructGetDeltaContract({ - chainId, - fetcher: fetchFetcher, - }).getDeltaContract(); - - assert(ParaswapDelta, 'ParaswapDelta is not defined'); - - const valid = await verifyTypedData({ - address: address as Address, - domain: { - name: 'Portikus', - version: '2.0.0', - chainId, - verifyingContract: ParaswapDelta as Address, - }, - types: { - OrderCancellations: [{ name: 'orderIds', type: 'string[]' }], - }, - primaryType: 'OrderCancellations', - message: { - orderIds: [orderId], - }, - signature: signature as Hex, + expect(typeof sdk.getDeltaPrice).toBe('function'); + expect(typeof sdk.getDeltaOrders).toBe('function'); + expect(typeof sdk.getRequiredBalanceForDeltaOrders).toBe('function'); + expect(typeof sdk.getBridgeRoutes).toBe('function'); + expect(typeof sdk.buildDeltaOrder).toBe('function'); + expect(typeof sdk.postDeltaOrder).toBe('function'); + expect(typeof sdk.submitDeltaOrder).toBe('function'); + expect(typeof sdk.submitExternalDeltaOrder).toBe('function'); + expect(typeof sdk.submitTWAPDeltaOrder).toBe('function'); + expect(typeof sdk.cancelDeltaOrders).toBe('function'); + expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); + expect(typeof sdk.getAgentsList).toBe('function'); + // reused v1 utilities + expect(typeof sdk.getDeltaContract).toBe('function'); + expect(typeof sdk.getPartnerFee).toBe('function'); + expect(typeof sdk.approveTokenForDelta).toBe('function'); + // v2 sign function (replaces v1 sign in deltaV2 namespace) + expect(typeof sdk.signDeltaOrder).toBe('function'); }); - return valid; -} + test('constructPartialSDK accepts v2 constructors individually', () => { + const fetcher = makeFetcher(() => ({})); + const sdk = constructPartialSDK( + { apiURL: API_URL, chainId: 1, fetcher }, + constructBuildDeltaOrder, + constructPostDeltaOrder, + constructGetDeltaOrders, + constructGetDeltaPrice, + constructGetDeltaContract, + constructGetPartnerFee, + constructGetBridgeRoutes, + constructIsTokenSupportedInDelta + ); -const PreSignatureModuleAbi = [ - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'orderHash', - type: 'bytes32', - }, - ], - name: 'isPreSigned', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'orderHash', - type: 'bytes32', - }, - { - internalType: 'bool', - name: 'preSigned', - type: 'bool', - }, - ], - name: 'setPreSignature', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, -] as const; - -type CheckIfOrderHashPreSignedInput = { - orderHash: string; - owner: string; - sdk: GetDeltaContractFunctions; -}; - -async function checkIfOrderHashPreSigned({ - orderHash, - owner, - sdk, -}: CheckIfOrderHashPreSignedInput): Promise { - const ParaswapDelta = await sdk.getDeltaContract(); - - assert(ParaswapDelta, 'ParaswapDelta is not available'); - - const isPreSigned = await viemWalletClient.readContract({ - address: ParaswapDelta as Address, - abi: PreSignatureModuleAbi, - functionName: 'isPreSigned', - args: [owner as Address, orderHash as Hash], + expect(typeof sdk.getDeltaPrice).toBe('function'); + expect(typeof sdk.getBridgeRoutes).toBe('function'); + expect(typeof sdk.getDeltaOrders).toBe('function'); + expect(typeof sdk.getRequiredBalanceForDeltaOrders).toBe('function'); + expect(typeof sdk.buildDeltaOrder).toBe('function'); + expect(typeof sdk.postDeltaOrder).toBe('function'); + expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); }); - return isPreSigned; -} +}); diff --git a/tests/deltaV2.test.ts b/tests/deltaV2.test.ts deleted file mode 100644 index 442df95ea..000000000 --- a/tests/deltaV2.test.ts +++ /dev/null @@ -1,1002 +0,0 @@ -import * as dotenv from 'dotenv'; -import fetch from 'isomorphic-unfetch'; -import { - constructPartialSDK, - constructFetchFetcher, - constructGetDeltaContract, - constructGetPartnerFee, - DeltaV2, - PaginatedResponse, - FetcherFunction, -} from '../src'; -import type { ContractCallerFunctions, TxHash } from '../src/types'; -import type { DeltaAuction } from '../src/methods/delta/helpers/types'; - -dotenv.config(); - -const PARASWAP_DELTA = '0x1111111111111111111111111111111111111111'; -const WETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'; -const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f'; -const USDC_ARB = '0xaf88d065e77c8cc2239327c5edb3a432268e5831'; -const OWNER = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9'; -const API_URL = 'https://api.test.invalid'; -const FAKE_SIGNATURE = '0x' + 'ab'.repeat(64); - -type FetchSpy = jest.Mock, Parameters>; - -function buildPriceFixture( - overrides: Partial = {} -): DeltaV2.DeltaPrice { - const srcInput = { - token: { chainId: 1, address: WETH }, - amount: '1000000000000000000', - amountUSD: '3000', - }; - const destOutput = { - token: { chainId: 1, address: DAI }, - amount: '2950000000000000000000', - amountUSD: '2950', - }; - - const route: DeltaV2.DeltaRoute = { - origin: { input: srcInput, output: destOutput }, - destination: { input: destOutput, output: destOutput }, - bridge: null, - fees: { - gas: { - token: { - chainId: 1, - address: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee', - }, - amount: '500000', - amountUSD: '0.5', - }, - bridge: [], - }, - }; - - return { - id: 'price-id-1', - side: 'SELL', - inputToken: { chainId: 1, address: WETH }, - outputToken: { chainId: 1, address: DAI }, - route, - partner: { name: 'sdk-test', feePercent: 0 }, - spender: PARASWAP_DELTA, - alternatives: [], - ...overrides, - }; -} - -function buildCrosschainRoute(): DeltaV2.DeltaRoute { - const srcInput = { - token: { chainId: 1, address: WETH }, - amount: '1000000000000000000', - amountUSD: '3000', - }; - const srcOutputIntermediate = { - token: { - chainId: 1, - address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', - }, - amount: '2980000000', - amountUSD: '2980', - }; - const destInput = { - token: { chainId: 42161, address: USDC_ARB }, - amount: '2978000000', - amountUSD: '2978', - }; - const destOutput = { - token: { chainId: 42161, address: USDC_ARB }, - amount: '2978000000', - amountUSD: '2978', - }; - - return { - origin: { input: srcInput, output: srcOutputIntermediate }, - destination: { input: destInput, output: destOutput }, - bridge: { - protocol: 'Across', - tags: ['recommended', 'fastest'], - estimatedTimeMs: 90_000, - contractParams: { - protocolSelector: '0xdeadbeef', - outputToken: USDC_ARB, - scalingFactor: -12, - protocolData: '0xabcd', - }, - }, - fees: { - gas: { - token: { chainId: 1, address: WETH }, - amount: '7000000000000000', - amountUSD: '21', - }, - bridge: [ - { - token: { chainId: 42161, address: USDC_ARB }, - amount: '200000', - amountUSD: '0.2', - }, - ], - }, - }; -} - -/** Minimal BuiltDeltaOrder fixture representing a server-built order. */ -function buildBuiltOrderFixture( - value: Record = {}, - orderHash = '0xdeadbeef1234' -): DeltaV2.BuiltDeltaOrder { - return { - toSign: { - domain: { - name: 'Portikus', - version: '2.0.0', - chainId: 1, - verifyingContract: PARASWAP_DELTA, - }, - types: { - Order: [ - { name: 'owner', type: 'address' }, - { name: 'beneficiary', type: 'address' }, - { name: 'srcToken', type: 'address' }, - { name: 'destToken', type: 'address' }, - { name: 'srcAmount', type: 'uint256' }, - { name: 'destAmount', type: 'uint256' }, - { name: 'expectedAmount', type: 'uint256' }, - { name: 'deadline', type: 'uint256' }, - { name: 'kind', type: 'uint8' }, - { name: 'nonce', type: 'uint256' }, - { name: 'partnerAndFee', type: 'uint256' }, - { name: 'permit', type: 'bytes' }, - { name: 'metadata', type: 'bytes' }, - { name: 'bridge', type: 'Bridge' }, - ], - Bridge: [ - { name: 'protocolSelector', type: 'bytes4' }, - { name: 'destinationChainId', type: 'uint256' }, - { name: 'outputToken', type: 'address' }, - { name: 'scalingFactor', type: 'int8' }, - { name: 'protocolData', type: 'bytes' }, - ], - }, - value: { - owner: OWNER, - beneficiary: OWNER, - srcToken: WETH, - destToken: DAI, - srcAmount: '1000000000000000000', - destAmount: '2950000000000000000000', - expectedAmount: '2950000000000000000000', - deadline: 9999999999, - kind: 0, - nonce: '12345', - permit: '0x', - partnerAndFee: '0', - metadata: '0x', - bridge: { - protocolSelector: '0x00000000', - destinationChainId: 0, - outputToken: '0x0000000000000000000000000000000000000000', - scalingFactor: 0, - protocolData: '0x', - }, - ...value, - }, - }, - orderHash, - }; -} - -function makeMockContractCaller(): ContractCallerFunctions { - return { - staticCall: jest.fn(async () => { - throw new Error( - 'staticCall should not be invoked in v2 fetch-only tests' - ); - }), - transactCall: jest.fn(async () => '0xfeedface' as TxHash), - signTypedDataCall: jest.fn(async () => FAKE_SIGNATURE), - }; -} - -function makeFetcher(handler: (params: any) => any): FetchSpy { - return jest.fn(async (params) => handler(params)) as FetchSpy; -} - -describe('Delta v2: fetch methods', () => { - test('getDeltaPrice hits /delta/v2/prices and returns DeltaPrice', async () => { - const fixture = buildPriceFixture(); - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('GET'); - expect(url.startsWith(`${API_URL}/delta/v2/prices?`)).toBe(true); - expect(url).toContain(`srcToken=${WETH}`); - expect(url).toContain(`destToken=${DAI}`); - expect(url).toContain('amount=1000000000000000000'); - expect(url).toContain('chainId=1'); - expect(url).toContain('side=SELL'); - return fixture; - }); - - const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const price = await getDeltaPrice({ - srcToken: WETH, - destToken: DAI, - amount: '1000000000000000000', - srcDecimals: 18, - destDecimals: 18, - }); - - expect(price).toEqual(fixture); - expect(price.route.origin.input.amount).toBe('1000000000000000000'); - expect(price.route.bridge).toBeNull(); - expect(fetcher).toHaveBeenCalledTimes(1); - }); - - test('getDeltaPrice passes destChainId for cross-chain', async () => { - const fixture = buildPriceFixture({ - route: buildCrosschainRoute(), - outputToken: { chainId: 42161, address: USDC_ARB }, - }); - const fetcher = makeFetcher(({ url }) => { - expect(url).toContain('destChainId=42161'); - return fixture; - }); - - const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const price = await getDeltaPrice({ - srcToken: WETH, - destToken: USDC_ARB, - amount: '1000000000000000000', - srcDecimals: 18, - destDecimals: 6, - destChainId: 42161, - }); - - expect(price.route.bridge?.protocol).toBe('Across'); - expect(price.route.destination.input.token.chainId).toBe(42161); - }); - - test('getBridgeRoutes hits /delta/v2/prices/bridge-routes and unwraps `routes`', async () => { - const routes: DeltaV2.BridgeRoute[] = [ - { srcChainId: 1, destChainId: 42161, tokens: [USDC_ARB] }, - { srcChainId: 1, destChainId: 10, tokens: [DAI] }, - ]; - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('GET'); - expect(url).toBe(`${API_URL}/delta/v2/prices/bridge-routes`); - return { routes }; - }); - - const { getBridgeRoutes } = DeltaV2.constructGetBridgeRoutes({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - expect(await getBridgeRoutes()).toEqual(routes); - }); - - test('getBridgeRoutes passes filter params', async () => { - const fetcher = makeFetcher(({ url }) => { - expect(url).toContain('allowBridgeAndSwap=false'); - expect(url).toContain('bridges=Across%2CRelay'); - return { routes: [] }; - }); - - const { getBridgeRoutes } = DeltaV2.constructGetBridgeRoutes({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - expect( - await getBridgeRoutes({ - allowBridgeAndSwap: false, - bridges: ['Across', 'Relay'], - }) - ).toEqual([]); - }); - - test('isTokenSupportedInDelta unwraps `supported`', async () => { - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('GET'); - expect( - url.startsWith(`${API_URL}/delta/v2/prices/is-token-supported/?`) - ).toBe(true); - expect(url).toContain(`token=${WETH}`); - expect(url).toContain('chainId=1'); - return { supported: true }; - }); - - const { isTokenSupportedInDelta } = DeltaV2.constructIsTokenSupportedInDelta({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - expect(await isTokenSupportedInDelta(WETH)).toBe(true); - }); - - test('getDeltaOrders returns the pagination envelope', async () => { - const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaAuction; - const envelope: PaginatedResponse = { - data: [order], - total: 1, - page: 1, - limit: 100, - hasMore: false, - }; - - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('GET'); - expect(url.startsWith(`${API_URL}/delta/v2/orders?`)).toBe(true); - expect(url).toContain(`userAddress=${OWNER}`); - expect(url).toContain('page=2'); - expect(url).toContain('limit=10'); - return envelope; - }); - - const { getDeltaOrders } = DeltaV2.constructGetDeltaOrders({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const result = await getDeltaOrders({ - userAddress: OWNER, - page: 2, - limit: 10, - }); - - expect(result).toEqual(envelope); - expect(result.hasMore).toBe(false); - expect(result.data).toHaveLength(1); - }); - - test('getDeltaOrders by id / by hash use the v2 path', async () => { - const order = { id: 'auction-1' } as unknown as DeltaV2.DeltaAuction; - const fetcher = makeFetcher(({ url }) => { - if (url === `${API_URL}/delta/v2/orders/auction-1`) return order; - if (url === `${API_URL}/delta/v2/orders/hash/0xhash`) return order; - throw new Error(`unexpected URL ${url}`); - }); - - const { getDeltaOrderById, getDeltaOrderByHash } = - DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); - - expect(await getDeltaOrderById('auction-1')).toBe(order); - expect(await getDeltaOrderByHash('0xhash')).toBe(order); - }); - - test('getRequiredBalanceForDeltaOrders hits /delta/v2/orders/fillablebalance/:chainId/:userAddress', async () => { - const required = { - [WETH]: '500000000000000000', - [DAI]: '1500000000000000000000', - }; - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('GET'); - expect(url).toBe( - `${API_URL}/delta/v2/orders/fillablebalance/1/${OWNER}` - ); - return required; - }); - - const { getRequiredBalanceForDeltaOrders } = - DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); - - expect( - await getRequiredBalanceForDeltaOrders({ userAddress: OWNER }) - ).toEqual(required); - }); - - test('getRequiredBalanceForDeltaOrders narrows the URL when tokenAddress is passed', async () => { - const fetcher = makeFetcher(({ url }) => { - expect(url).toBe( - `${API_URL}/delta/v2/orders/fillablebalance/1/${OWNER}/${WETH}` - ); - return { [WETH]: '500000000000000000' }; - }); - - const { getRequiredBalanceForDeltaOrders } = - DeltaV2.constructGetDeltaOrders({ apiURL: API_URL, chainId: 1, fetcher }); - - const balance = await getRequiredBalanceForDeltaOrders({ - userAddress: OWNER, - tokenAddress: WETH, - }); - expect(balance[WETH]).toBe('500000000000000000'); - }); - - test('getAgentsList hits /delta/v2/agents/list/:chainId and returns agent names', async () => { - const agents = ['agent-a', 'agent-b']; - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('GET'); - expect(url).toBe(`${API_URL}/delta/v2/agents/list/42161`); - return agents; // server returns string[] directly - }); - - const { getAgentsList } = DeltaV2.constructGetAgentsList({ - apiURL: API_URL, - chainId: 42161, - fetcher, - }); - - expect(await getAgentsList()).toEqual(agents); - }); -}); - -describe('Delta v2: build (server-side via POST /v2/orders/build)', () => { - test('buildDeltaOrder POSTs to /delta/v2/orders/build with correct body', async () => { - const builtFixture = buildBuiltOrderFixture(); - let postedBody: any; - - const fetcher = makeFetcher(({ url, method, data }) => { - expect(method).toBe('POST'); - expect(url).toBe(`${API_URL}/delta/v2/orders/build`); - postedBody = data; - return builtFixture; - }); - - const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const route = buildPriceFixture().route; - const result = await buildDeltaOrder({ - owner: OWNER, - route, - side: 'SELL', - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - expect(result).toEqual(builtFixture); - expect(postedBody.chainId).toBe(1); - expect(postedBody.side).toBe('SELL'); - expect(postedBody.owner).toBe(OWNER); - expect(postedBody.route).toBe(route); - expect(postedBody.slippage).toBeUndefined(); - expect(postedBody.orderType).toBe('Order'); - }); - - test('buildDeltaOrder passes slippage to server for SELL', async () => { - const builtFixture = buildBuiltOrderFixture(); - let postedBody: any; - - const fetcher = makeFetcher(({ url, data }) => { - if (url === `${API_URL}/delta/v2/orders/build`) { - postedBody = data; - return builtFixture; - } - throw new Error(`unexpected ${url}`); - }); - - const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - await buildDeltaOrder({ - owner: OWNER, - route: buildPriceFixture().route, - side: 'SELL', - slippage: 100, - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - // slippage is forwarded to server; server applies it to destAmount - expect(postedBody.slippage).toBe(100); - expect(postedBody.side).toBe('SELL'); - }); - - test('buildDeltaOrder passes slippage to server for BUY', async () => { - const builtFixture = buildBuiltOrderFixture(); - let postedBody: any; - - const fetcher = makeFetcher(({ url, data }) => { - if (url === `${API_URL}/delta/v2/orders/build`) { - postedBody = data; - return builtFixture; - } - throw new Error(`unexpected ${url}`); - }); - - const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - await buildDeltaOrder({ - owner: OWNER, - route: buildPriceFixture().route, - side: 'BUY', - slippage: 100, - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - expect(postedBody.slippage).toBe(100); - expect(postedBody.side).toBe('BUY'); - }); - - test('buildDeltaOrder passes cross-chain route as-is; server injects destinationChainId', async () => { - const ccRoute = buildCrosschainRoute(); - const builtFixture = buildBuiltOrderFixture({ - srcToken: WETH, - destToken: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', - bridge: { - protocolSelector: '0xdeadbeef', - destinationChainId: 42161, - outputToken: USDC_ARB, - scalingFactor: -12, - protocolData: '0xabcd', - }, - }); - let postedBody: any; - - const fetcher = makeFetcher(({ url, data }) => { - if (url === `${API_URL}/delta/v2/orders/build`) { - postedBody = data; - return builtFixture; - } - throw new Error(`unexpected ${url}`); - }); - - const { buildDeltaOrder } = DeltaV2.constructBuildDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const result = await buildDeltaOrder({ - owner: OWNER, - route: ccRoute, - side: 'SELL', - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - // route is forwarded as-is; bridge in route.contractParams has no destinationChainId - expect(postedBody.route).toBe(ccRoute); - // the server (fixture) fills in destinationChainId - expect(result.toSign.value.bridge).toMatchObject({ - protocolSelector: '0xdeadbeef', - destinationChainId: 42161, - }); - }); - - test('buildExternalDeltaOrder sends orderType ExternalOrder with handler/data', async () => { - const builtFixture = buildBuiltOrderFixture(); - let postedBody: any; - - const fetcher = makeFetcher(({ url, data }) => { - if (url === `${API_URL}/delta/v2/orders/build`) { - postedBody = data; - return builtFixture; - } - throw new Error(`unexpected ${url}`); - }); - - const { buildExternalDeltaOrder } = DeltaV2.constructBuildExternalDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const route = buildPriceFixture().route; - await buildExternalDeltaOrder({ - owner: OWNER, - handler: '0x2222222222222222222222222222222222222222', - data: '0xdeadbeef', - route, - side: 'SELL', - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - expect(postedBody.orderType).toBe('ExternalOrder'); - expect(postedBody.handler).toBe( - '0x2222222222222222222222222222222222222222' - ); - expect(postedBody.data).toBe('0xdeadbeef'); - expect(postedBody.route).toBe(route); - }); - - test('buildTWAPDeltaOrder (sell) sends TWAPOrder body; slippage forwarded to server', async () => { - const builtFixture = buildBuiltOrderFixture(); - let postedBody: any; - - const fetcher = makeFetcher(({ url, data }) => { - if (url === `${API_URL}/delta/v2/orders/build`) { - postedBody = data; - return builtFixture; - } - throw new Error(`unexpected ${url}`); - }); - - const { buildTWAPDeltaOrder } = DeltaV2.constructBuildTWAPDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const route = buildPriceFixture().route; - await buildTWAPDeltaOrder({ - owner: OWNER, - onChainOrderType: 'TWAPOrder', - route, - totalSrcAmount: '5000000000000000000', - interval: 300, - numSlices: 5, - slippage: 50, - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - expect(postedBody.orderType).toBe('TWAPOrder'); - expect(postedBody.interval).toBe(300); - expect(postedBody.numSlices).toBe(5); - expect(postedBody.totalSrcAmount).toBe('5000000000000000000'); - expect(postedBody.slippage).toBe(50); // server applies slippage to destAmountPerSlice - expect(postedBody.side).toBe('SELL'); - }); - - test('buildTWAPDeltaOrder (buy) forwards slippage and maxSrcAmount to server', async () => { - const builtFixture = buildBuiltOrderFixture(); - let postedBody: any; - - const fetcher = makeFetcher(({ url, data }) => { - if (url === `${API_URL}/delta/v2/orders/build`) { - postedBody = data; - return builtFixture; - } - throw new Error(`unexpected ${url}`); - }); - - const { buildTWAPDeltaOrder } = DeltaV2.constructBuildTWAPDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - const route = buildPriceFixture().route; - await buildTWAPDeltaOrder({ - owner: OWNER, - onChainOrderType: 'TWAPBuyOrder', - route, - totalDestAmount: '5000000000000000000', - maxSrcAmount: '1000000000000000000', - interval: 300, - numSlices: 5, - slippage: 100, - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - expect(postedBody.orderType).toBe('TWAPBuyOrder'); - expect(postedBody.side).toBe('BUY'); - expect(postedBody.maxSrcAmount).toBe('1000000000000000000'); - expect(postedBody.slippage).toBe(100); - }); -}); - -describe('Delta v2: submit (build → sign → post)', () => { - test('submitDeltaOrder posts to /delta/v2/orders with signed order', async () => { - const builtFixture = buildBuiltOrderFixture(); - let posted: any; - let postUrl = ''; - - const fetcher = makeFetcher(({ url, method, data }) => { - if (method === 'POST' && url === `${API_URL}/delta/v2/orders/build`) { - return builtFixture; - } - if (method === 'POST' && url.startsWith(`${API_URL}/delta/v2/orders`)) { - postUrl = url; - posted = data; - return { - id: 'auction-99', - order: data.order, - onChainOrderType: 'Order', - } as unknown as DeltaAuction<'Order'>; - } - throw new Error(`unexpected request ${method} ${url}`); - }); - - const { submitDeltaOrder } = DeltaV2.constructSubmitDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - contractCaller: makeMockContractCaller(), - }); - - const response = await submitDeltaOrder({ - owner: OWNER, - route: buildPriceFixture().route, - side: 'SELL', - partnerAddress: '0x0000000000000000000000000000000000000000', - }); - - expect(postUrl.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); - expect(posted.signature).toBe(FAKE_SIGNATURE); - expect(posted.chainId).toBe(1); - // order comes from builtFixture.toSign.value - expect(posted.order.owner).toBe(OWNER); - expect(posted.order.srcToken).toBe(WETH); - expect(posted.order.destToken).toBe(DAI); - expect(response.id).toBe('auction-99'); - }); - - test('postDeltaOrder forwards degenMode as a query param', async () => { - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('POST'); - expect(url).toContain('degenMode=true'); - return { id: 'x' } as unknown as DeltaAuction<'Order'>; - }); - - const { postDeltaOrder } = DeltaV2.constructPostDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - expect( - await postDeltaOrder({ - signature: FAKE_SIGNATURE, - order: {} as any, - degenMode: true, - }) - ).toEqual({ id: 'x' }); - }); - - test('postExternalDeltaOrder sends to /delta/v2/orders', async () => { - const fetcher = makeFetcher(({ url, method }) => { - expect(method).toBe('POST'); - expect(url).toBe(`${API_URL}/delta/v2/orders`); - return { id: 'ext-1' } as unknown as DeltaAuction<'ExternalOrder'>; - }); - - const { postExternalDeltaOrder } = DeltaV2.constructPostExternalDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - expect( - await postExternalDeltaOrder({ - signature: FAKE_SIGNATURE, - order: {} as any, - }) - ).toEqual({ id: 'ext-1' }); - }); - - test('postTWAPDeltaOrder sends to /delta/v2/orders with onChainOrderType', async () => { - const fetcher = makeFetcher(({ url, method, data }) => { - expect(method).toBe('POST'); - expect(url.startsWith(`${API_URL}/delta/v2/orders`)).toBe(true); - expect(data.onChainOrderType).toBe('TWAPOrder'); - return { id: 'twap-1' } as unknown as DeltaAuction<'TWAPOrder'>; - }); - - const { postTWAPDeltaOrder } = DeltaV2.constructPostTWAPDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - }); - - expect( - await postTWAPDeltaOrder({ - signature: FAKE_SIGNATURE, - order: {} as any, - onChainOrderType: 'TWAPOrder', - }) - ).toEqual({ id: 'twap-1' }); - }); -}); - -describe('Delta v2: cancel', () => { - test('cancelDeltaOrders signs then posts to /delta/v2/orders/cancel', async () => { - let postedTo = ''; - let postedBody: any; - - const fetcher = makeFetcher(({ url, method, data }) => { - const adapter = url.includes('/adapters/contracts') - ? { - AugustusSwapper: '0x', - TokenTransferProxy: '0x', - AugustusRFQ: '0x', - Executors: {}, - ParaswapDelta: '0x1111111111111111111111111111111111111111', - } - : undefined; - if (adapter) return adapter; - if (method === 'POST') { - postedTo = url; - postedBody = data; - return { success: true }; - } - throw new Error('unexpected'); - }); - - const { cancelDeltaOrders } = DeltaV2.constructCancelDeltaOrder({ - apiURL: API_URL, - chainId: 1, - fetcher, - contractCaller: makeMockContractCaller(), - }); - - const result = await cancelDeltaOrders({ - orderIds: ['a', 'b'], - }); - - expect(result).toEqual({ success: true }); - expect(postedTo).toBe(`${API_URL}/delta/v2/orders/cancel`); - expect(postedBody.orderIds).toEqual(['a', 'b']); - expect(postedBody.signature).toBe(FAKE_SIGNATURE); - }); -}); - -describe('Delta v2: live API contract', () => { - jest.setTimeout(30_000); - - const LIVE_API = process.env.API_URL; - const fetchFetcher = constructFetchFetcher(fetch); - - test('GET /delta/v2/prices (same-chain) matches DeltaPrice shape', async () => { - const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ - apiURL: LIVE_API, - chainId: 1, - fetcher: fetchFetcher, - }); - - const price = await getDeltaPrice({ - srcToken: WETH, - destToken: DAI, - amount: '1000000000000000000', - srcDecimals: 18, - destDecimals: 18, - side: 'SELL', - }); - - expect(price.side).toBe('SELL'); - expect(price.inputToken.chainId).toBe(1); - expect(price.outputToken.chainId).toBe(1); - expect(typeof price.id).toBe('string'); - expect(typeof price.spender).toBe('string'); - expect(price.route.origin.input.token.address.toLowerCase()).toBe(WETH); - expect(typeof price.route.origin.input.amount).toBe('string'); - expect(typeof price.route.origin.input.amountUSD).toBe('string'); - // same-chain: bridge is null - expect(price.route.bridge).toBeNull(); - // fees.gas is a single DeltaTokenAmount, fees.bridge is an array - expect(typeof price.route.fees.gas.amount).toBe('string'); - expect(Array.isArray(price.route.fees.bridge)).toBe(true); - }); - - test('GET /delta/v2/prices (cross-chain) returns DeltaRoute with bridge.contractParams (no destinationChainId)', async () => { - const { getDeltaPrice } = DeltaV2.constructGetDeltaPrice({ - apiURL: LIVE_API, - chainId: 1, - fetcher: fetchFetcher, - }); - - const price = await getDeltaPrice({ - srcToken: WETH, - destToken: USDC_ARB, - amount: '1000000000000000000', - srcDecimals: 18, - destDecimals: 6, - destChainId: 42161, - side: 'SELL', - }); - - expect(price.outputToken.chainId).toBe(42161); - expect(price.route.destination.input.token.chainId).toBe(42161); - expect(price.route.bridge).not.toBeNull(); - if (price.route.bridge) { - expect(typeof price.route.bridge.protocol).toBe('string'); - expect(Array.isArray(price.route.bridge.tags)).toBe(true); - expect(typeof price.route.bridge.contractParams.protocolSelector).toBe( - 'string' - ); - expect(typeof price.route.bridge.contractParams.outputToken).toBe( - 'string' - ); - // destinationChainId is NOT present on the wire — the SDK injects it at build time - expect('destinationChainId' in price.route.bridge.contractParams).toBe( - false - ); - } - }); - - test('GET /delta/v2/prices/bridge-routes returns flat array', async () => { - const { getBridgeRoutes } = DeltaV2.constructGetBridgeRoutes({ - apiURL: LIVE_API, - chainId: 1, - fetcher: fetchFetcher, - }); - - const routes = await getBridgeRoutes(); - expect(Array.isArray(routes)).toBe(true); - expect(routes.length).toBeGreaterThan(0); - const first = routes[0]!; - expect(typeof first.srcChainId).toBe('number'); - expect(typeof first.destChainId).toBe('number'); - expect(Array.isArray(first.tokens)).toBe(true); - }); - - test('GET /delta/v2/prices/bridge-protocols returns protocols', async () => { - const { getBridgeProtocols } = DeltaV2.constructGetBridgeRoutes({ - apiURL: LIVE_API, - chainId: 1, - fetcher: fetchFetcher, - }); - - const protocols = await getBridgeProtocols(); - expect(protocols.length).toBeGreaterThan(0); - expect(protocols.some((p) => p.protocol === 'Across')).toBe(true); - }); -}); - -describe('Delta v2: SDK wiring', () => { - test('constructAllDeltaOrdersHandlers exposes all v2 methods', () => { - const sdk = DeltaV2.constructAllDeltaOrdersHandlers({ - apiURL: API_URL, - chainId: 1, - fetcher: makeFetcher(() => ({})), - contractCaller: makeMockContractCaller(), - }); - - expect(typeof sdk.getDeltaPrice).toBe('function'); - expect(typeof sdk.getDeltaOrders).toBe('function'); - expect(typeof sdk.getRequiredBalanceForDeltaOrders).toBe('function'); - expect(typeof sdk.getBridgeRoutes).toBe('function'); - expect(typeof sdk.buildDeltaOrder).toBe('function'); - expect(typeof sdk.postDeltaOrder).toBe('function'); - expect(typeof sdk.submitDeltaOrder).toBe('function'); - expect(typeof sdk.submitExternalDeltaOrder).toBe('function'); - expect(typeof sdk.submitTWAPDeltaOrder).toBe('function'); - expect(typeof sdk.cancelDeltaOrders).toBe('function'); - expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); - expect(typeof sdk.getAgentsList).toBe('function'); - // reused v1 utilities - expect(typeof sdk.getDeltaContract).toBe('function'); - expect(typeof sdk.getPartnerFee).toBe('function'); - expect(typeof sdk.approveTokenForDelta).toBe('function'); - // v2 sign function (replaces v1 sign in deltaV2 namespace) - expect(typeof sdk.signDeltaOrder).toBe('function'); - }); - - test('constructPartialSDK accepts v2 constructors individually', () => { - const fetcher = makeFetcher(() => ({})); - const sdk = constructPartialSDK( - { apiURL: API_URL, chainId: 1, fetcher }, - DeltaV2.constructBuildDeltaOrder, - DeltaV2.constructPostDeltaOrder, - DeltaV2.constructGetDeltaOrders, - DeltaV2.constructGetDeltaPrice, - constructGetDeltaContract, - constructGetPartnerFee, - DeltaV2.constructGetBridgeRoutes, - DeltaV2.constructIsTokenSupportedInDelta - ); - - expect(typeof sdk.getDeltaPrice).toBe('function'); - expect(typeof sdk.getBridgeRoutes).toBe('function'); - expect(typeof sdk.getDeltaOrders).toBe('function'); - expect(typeof sdk.getRequiredBalanceForDeltaOrders).toBe('function'); - expect(typeof sdk.buildDeltaOrder).toBe('function'); - expect(typeof sdk.postDeltaOrder).toBe('function'); - expect(typeof sdk.isTokenSupportedInDelta).toBe('function'); - }); -}); diff --git a/tests/quote.test.ts b/tests/quote.test.ts index 5e9157796..8292e861b 100644 --- a/tests/quote.test.ts +++ b/tests/quote.test.ts @@ -49,53 +49,16 @@ describe('Quote:methods', () => { const staticDeltaPrice: typeof quote.delta = { ...quote.delta, - partnerFee: NaN, // dynamic number, can change slightly depending on API config - hmac: 'dynamic_string', - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - receivedDestAmountBeforeFee: 'dynamic_number', - receivedDestUSDBeforeFee: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', + id: 'dynamic_string', + // route + alternatives carry the dynamic amounts/USD/gas fields in v2; + // stabilized wholesale so the inline snapshot below regenerates cleanly. + route: 'dynamic_route' as unknown as typeof quote.delta.route, + alternatives: + 'dynamic_alternatives' as unknown as typeof quote.delta.alternatives, + partner: { name: quote.delta.partner.name, feePercent: NaN }, }; - expect(staticDeltaPrice).toMatchInlineSnapshot(` - { - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestAmountBeforeFee": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "receivedDestUSDBeforeFee": "dynamic_number", - "srcAmount": "100000000000", - "srcToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - "srcUSD": "dynamic_number", - } - `); + expect(staticDeltaPrice).toMatchInlineSnapshot(); }); test('Fail Quote for delta for small amounts', async () => { @@ -147,58 +110,16 @@ describe('Quote:methods', () => { const staticDeltaPrice: typeof quote.delta = { ...quote.delta, - partnerFee: NaN, // dynamic number - hmac: 'dynamic_string', - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', - srcAmount: 'dynamic_number', - srcAmountBeforeFee: 'dynamic_number', - srcUSDBeforeFee: 'dynamic_number', + id: 'dynamic_string', + // route + alternatives carry the dynamic amounts/USD/gas fields in v2; + // stabilized wholesale so the inline snapshot below regenerates cleanly. + route: 'dynamic_route' as unknown as typeof quote.delta.route, + alternatives: + 'dynamic_alternatives' as unknown as typeof quote.delta.alternatives, + partner: { name: quote.delta.partner.name, feePercent: NaN }, }; - // only SELL side has receivedDestAmountBeforeFee and receivedDestUSDBeforeFee - expect('receivedDestAmountBeforeFee' in quote.delta).toBeFalsy(); - expect('receivedDestUSDBeforeFee' in quote.delta).toBeFalsy(); - - expect(staticDeltaPrice).toMatchInlineSnapshot(` - { - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "srcAmount": "dynamic_number", - "srcAmountBeforeFee": "dynamic_number", - "srcToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - "srcUSD": "dynamic_number", - "srcUSDBeforeFee": "dynamic_number", - } - `); + expect(staticDeltaPrice).toMatchInlineSnapshot(); }); test('Get Quote for market', async () => { @@ -258,53 +179,16 @@ describe('Quote:methods', () => { const staticDeltaPrice: typeof quote.delta = { ...quote.delta, - partnerFee: NaN, // dynamic number, can change slightly depending on API config - hmac: 'dynamic_string', - destAmount: 'dynamic_number', - destAmountBeforeFee: 'dynamic_number', - srcUSD: 'dynamic_number', - destUSD: 'dynamic_number', - destUSDBeforeFee: 'dynamic_number', - receivedDestAmount: 'dynamic_number', - receivedDestUSD: 'dynamic_number', - receivedDestAmountBeforeFee: 'dynamic_number', - receivedDestUSDBeforeFee: 'dynamic_number', - gasCost: 'dynamic_number', - gasCostBeforeFee: 'dynamic_number', - gasCostUSD: 'dynamic_number', - gasCostUSDBeforeFee: 'dynamic_number', + id: 'dynamic_string', + // route + alternatives carry the dynamic amounts/USD/gas fields in v2; + // stabilized wholesale so the inline snapshot below regenerates cleanly. + route: 'dynamic_route' as unknown as typeof quote.delta.route, + alternatives: + 'dynamic_alternatives' as unknown as typeof quote.delta.alternatives, + partner: { name: quote.delta.partner.name, feePercent: NaN }, }; - expect(staticDeltaPrice).toMatchInlineSnapshot(` - { - "bridge": { - "destinationChainId": 0, - "outputToken": "0x0000000000000000000000000000000000000000", - "protocolData": "0x", - "protocolSelector": "0x00000000", - "scalingFactor": 0, - }, - "destAmount": "dynamic_number", - "destAmountBeforeFee": "dynamic_number", - "destToken": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", - "destUSD": "dynamic_number", - "destUSDBeforeFee": "dynamic_number", - "gasCost": "dynamic_number", - "gasCostBeforeFee": "dynamic_number", - "gasCostUSD": "dynamic_number", - "gasCostUSDBeforeFee": "dynamic_number", - "hmac": "dynamic_string", - "partner": "anon", - "partnerFee": NaN, - "receivedDestAmount": "dynamic_number", - "receivedDestAmountBeforeFee": "dynamic_number", - "receivedDestUSD": "dynamic_number", - "receivedDestUSDBeforeFee": "dynamic_number", - "srcAmount": "100000000000", - "srcToken": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - "srcUSD": "dynamic_number", - } - `); + expect(staticDeltaPrice).toMatchInlineSnapshot(); }); test('Get Fallback Market Quote for all', async () => { From 43af8f1dbb703f56f3dff0f11f32fea170371ac6 Mon Sep 17 00:00:00 2001 From: andriy-shymkiv Date: Tue, 2 Jun 2026 20:19:16 +0300 Subject: [PATCH 52/52] docs/migrate to delta v2 --- CLAUDE.md | 200 ++++++++----------------- README.md | 315 +++++++++++----------------------------- docs/DELTA.md | 140 ++++++------------ docs/EXTERNAL_ORDERS.md | 80 +++++----- 4 files changed, 224 insertions(+), 511 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 467f21d6c..5817340d8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -33,7 +33,7 @@ Three ways to construct the SDK: `constructSimpleSDK` accepts `{ axios }`, `{ fetch }`, or `{ fetcher }` for the network layer, and optionally `{ ethersProviderOrSigner | ethersV6ProviderOrSigner | viemClient | web3, account }` for signing/transacting. -`constructFullSDK` exposes namespaced methods: `sdk.delta.*` (v1), `sdk.deltaV2.*` (v2), `sdk.swap.*`, etc. +`constructFullSDK` exposes namespaced methods: `sdk.delta.*`, `sdk.swap.*`, `sdk.quote.*`, etc. ## Provider Adapters (`src/helpers/providers/`) @@ -45,12 +45,11 @@ Each file exports `constructContractCaller(provider, account)` → `ContractCall ## Module Structure (`src/methods/`) -- `delta/` — Core feature: Delta auction orders v1 (see detail below) -- `deltaV2/` — Delta v2: server-side order building, route-based pricing, paginated orders (see detail below) +- `delta/` — Core feature: Delta auction orders (server-side order building, route-based pricing, paginated orders; see detail below) - `swap/` — Token swap: rates, transaction building, approvals, balances - `limitOrders/` — **Deprecated.** EIP-712 signed limit orders - `nftOrders/` — **Deprecated.** EIP-712 signed NFT orders -- `quote/` — Unified quote endpoint +- `quote/` — Unified `/v2/quote` endpoint (mode-selectable Delta v2 price / market / fallback) ## Composable Constructor Pattern @@ -59,7 +58,7 @@ Every feature module exports a `constructXxx(options) => XxxFunctions` factory: - `D` selects required caller methods: `'transactCall'` | `'signTypedDataCall'` | both - Generic `` = transaction response type (e.g., `TxHash`, `ethers.ContractTransaction`) - Non-generic constructors use `any` (for API-only flows that don't return tx responses) -- All Delta constructors are combined in `constructAllDeltaOrdersHandlers` in `src/methods/delta/index.ts` +- All Delta constructors are combined in `constructAllDeltaOrdersHandlers` in `src/methods/delta/index.ts`. **Convention:** bind each `constructXxx(options)` call to a named local (`const deltaPrice = constructGetDeltaPrice(options)`), then spread those locals into the returned object — don't spread the constructor calls inline. (Matches `constructAllLimitOrdersHandlers`.) ## Key Patterns @@ -76,155 +75,81 @@ Every feature module exports a `constructXxx(options) => XxxFunctions` factory: ## Delta Module (`src/methods/delta/`) -Four order families with build/sign/post/preSign constructors, plus a read-only Productive family: +Delta is the SDK's core feature: server-built, on-chain auction orders. Exposed as `sdk.delta.*` and via bare top-level exports. -| Family | `onChainOrderType` | Order type | Build input key | -|--------|-------------------|-----------|-----------------| -| Standard | `'Order'` | `DeltaAuctionOrder` | `buildDeltaOrder` | -| External | `'ExternalOrder'` | `ExternalDeltaOrder` | `buildExternalDeltaOrder` (has `handler` field instead of `bridge`) | -| TWAP Sell | `'TWAPOrder'` | `TWAPDeltaOrder` | `buildTWAPDeltaOrder` | -| TWAP Buy | `'TWAPBuyOrder'` | `TWAPBuyDeltaOrder` | `buildTWAPDeltaOrder` | -| Productive | `'ProductiveOrder'` | `ProductiveDeltaOrder` | _read-only_ — no SDK builder (server-produced) | +> **History.** Delta was once a **v1** with local EIP-712 order building and per-family sign functions. It was replaced (breaking) by the server-built **v2** described here — `sdk.delta.*` *is* v2, with a single set of bare top-level exports. All Delta URLs use the `/delta/v2/...` prefix. -`'FillableOrder'` is also a key in `OnChainOrderMap`/`OnChainOrderType`, mapping to the same `DeltaAuctionOrder` shape as `'Order'`. It is not a separate buildable family — it's the `onChainOrderType` the server reports when a Standard order is `partiallyFillable`. Built/signed/posted exactly as a Standard `Order`; only surfaces (read-only) on the way back through the read paths. +Order building is **server-side**: `POST /delta/v2/orders/build` returns a `BuiltDeltaOrder { toSign, orderHash }`; a single `signDeltaOrder(builtOrder)` signs every family; `post*` submits the signed order. Partner fee is passed as raw params (`partner`, `partnerFeeBps`) to the server rather than resolved locally. Reads are paginated (`PaginatedResponse`), price is route-based. -The first four families have four files each: `build*`, `sign*`, `post*`, `preSign*`. High-level orchestrators (`constructSubmitDeltaOrder`, `constructSubmitExternalDeltaOrder`, `constructSubmitTWAPDeltaOrder`) in `index.ts` wrap build→sign→post. Productive orders surface only through the read paths (`getDeltaOrders*` / `getDeltaOrderById*` / `DeltaAuctionUnion`). +### Order families + +All built via `POST /delta/v2/orders/build` with an `orderType` field: + +| Family | `orderType` / `onChainOrderType` | Build params | Build fn | +|--------|-------------------|-----------|----------| +| Standard | `'Order'` | `BuildDeltaOrderParams` | `buildDeltaOrder` | +| External | `'ExternalOrder'` | `BuildExternalDeltaOrderParams` (adds `handler`, `data`) | `buildExternalDeltaOrder` | +| TWAP Sell | `'TWAPOrder'` | `BuildTWAPSellDeltaOrderParams` | `buildTWAPDeltaOrder` | +| TWAP Buy | `'TWAPBuyOrder'` | `BuildTWAPBuyDeltaOrderParams` | `buildTWAPDeltaOrder` | +| Productive | `'ProductiveOrder'` | _read-only_ — no SDK builder (server-produced) | — | + +`'FillableOrder'` is also a key in `OnChainOrderMap`/`OnChainOrderType`, mapping to the same `DeltaAuctionOrder` shape as `'Order'`. It is not a separate buildable family — it's the `onChainOrderType` the server reports when a Standard order is `partiallyFillable`. Only surfaces (read-only) on the way back through the read paths. + +Submit orchestrators (`constructSubmitDeltaOrder`, `constructSubmitExternalDeltaOrder`, `constructSubmitTWAPDeltaOrder`) in `index.ts` wrap build→sign→post. Productive orders surface only through the read paths (`getDeltaOrders*` / `getDeltaOrderById*`). ### Key Files -| File | Constructor | Purpose | Generic? | Pattern | -|------|-------------|---------|----------|---------| -| `index.ts` | `constructSubmitDeltaOrder`, `constructAllDeltaOrdersHandlers` | Composite: orchestrates all modules, defines `DeltaOrderHandlers` | `submitDelta`: No, `allHandlers`: `` | Composite | -| `buildDeltaOrder.ts` | `constructBuildDeltaOrder` | Build `SignableDeltaOrderData` from params (fetches contract + partner fee, then local computation) | No | API fetch + local | -| `signDeltaOrder.ts` | `constructSignDeltaOrder` | EIP-712 sign order via `signTypedDataCall` → returns signature `string` | No (`any`) | `signTypedDataCall` | -| `postDeltaOrder.ts` | `constructPostDeltaOrder` | POST signed order to API → `DeltaOrderApiResponse` | No | `fetcher` POST | -| `getDeltaPrice.ts` | `constructGetDeltaPrice` | Fetch quote/price from API. Overloaded: returns `DeltaPrice` (same-chain) or `BridgePrice` (cross-chain when `destChainId` present) | No | `fetcher` GET | -| `getDeltaOrders.ts` | `constructGetDeltaOrders` | Query orders from API: `getDeltaOrderById`, `getDeltaOrderByHash`, `getDeltaOrders` (list), `getRequiredBalanceForDeltaLimitOrders` | No | `fetcher` GET | -| `getDeltaContract.ts` | `constructGetDeltaContract` | Resolve ParaswapDelta contract address from contracts endpoint | No | `fetcher` GET | -| `approveForDelta.ts` | `constructApproveTokenForDelta` | ERC-20 `approve` with ParaswapDelta as spender (delegates to `approveTokenMethodFactory`) | `` | `transactCall` | -| `preSignDeltaOrder.ts` | `constructPreSignDeltaOrder` | On-chain `setPreSignature` + order hashing helpers (`hashDeltaOrderTypedData`, `hashDeltaOrder`, `preSignDeltaOrder`) | `` | `transactCall` | -| `cancelDeltaOrder.ts` | `constructCancelDeltaOrder` | API cancel: `signCancelLimitDeltaOrderRequest` → `postCancelLimitDeltaOrderRequest` → `cancelLimitDeltaOrders` (orchestrator) | No (`any`) | `signTypedDataCall` + `fetcher` POST | -| `deltaTokenModule.ts` | `constructDeltaTokenModule` | On-chain `cancelAndWithdrawDeltaOrder`, `withdrawDeltaNative`, `depositNativeAndPreSign`, `depositNativeAndPreSignDeltaOrder` | `` | `transactCall` | -| `getPartnerFee.ts` | `constructGetPartnerFee` | Fetch partner fee info (internally cached per partner in a `Map`) | No | `fetcher` GET | -| `getBridgeInfo.ts` | `constructGetBridgeInfo` | `getBridgeInfo` (supported routes) + `getBridgeProtocols` | No | `fetcher` GET | -| `isTokenSupportedInDelta.ts` | `constructIsTokenSupportedInDelta` | Check if a token is supported → `boolean` | No | `fetcher` GET | -| `constants.ts` | — | `DEFAULT_BRIDGE` constant (all-zero values for same-chain orders) | — | — | +| File | Constructor | Purpose | Generic? | +|------|-------------|---------|----------| +| `index.ts` | `constructAllDeltaOrdersHandlers`, `constructSubmit{Delta,External,TWAP}Order`, `constructSignDeltaOrder` | Composite: orchestrates all modules, defines `DeltaOrderHandlers`, hosts the single `signDeltaOrder` (signs any `BuiltDeltaOrder`), re-exports every leaf module | `allHandlers`: `` | +| `buildDeltaOrder.ts` | `constructBuildDeltaOrder` | POST `/v2/orders/build` → `BuiltDeltaOrder` | No | +| `buildExternalDeltaOrder.ts` | `constructBuildExternalDeltaOrder` | Same, `orderType: 'ExternalOrder'` | No | +| `buildTWAPDeltaOrder.ts` | `constructBuildTWAPDeltaOrder` | Same, `orderType: 'TWAPOrder'` / `'TWAPBuyOrder'` | No | +| `postDeltaOrder.ts` / `postExternalDeltaOrder.ts` / `postTWAPDeltaOrder.ts` | `constructPost*DeltaOrder` | POST `/v2/orders` → `DeltaAuction` | No | +| `getDeltaPrice.ts` | `constructGetDeltaPrice` | GET `/delta/v2/prices` → `DeltaPrice` (route-based: `route` + `alternatives`; cross-chain handled in-route via `destChainId`) | No | +| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash`, `getRequiredBalanceForDeltaOrders`. Reads return `DeltaAuction`. | No | +| `cancelDeltaOrder.ts` | `constructCancelDeltaOrder` | `signCancelDeltaOrderRequest` → `postCancelDeltaOrderRequest` → `cancelDeltaOrders` (orchestrator). POST `/v2/orders/cancel`. | No (`any`) | +| `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocols` | No | +| `isTokenSupportedInDelta.ts` | `constructIsTokenSupportedInDelta` | GET `/v2/prices/is-token-supported` → `boolean` | No | +| `getAgentsList.ts` | `constructGetAgentsList` | GET `/v2/agents/list/:chainId` → `string[]` | No | +| `getDeltaContract.ts` | `constructGetDeltaContract` | Resolve ParaswapDelta contract address | No | +| `getPartnerFee.ts` | `constructGetPartnerFee` | Fetch partner fee info (cached per partner in a `Map`) | No | +| `approveForDelta.ts` | `constructApproveTokenForDelta` | ERC-20 `approve` with ParaswapDelta as spender | `` | +| `preSignDeltaOrder.ts` / `preSignExternalDeltaOrder.ts` / `preSignTWAPDeltaOrder.ts` | `constructPreSign*DeltaOrder` | On-chain `setPreSignature` + order hashing helpers (`produceDeltaOrderHash`, etc.) | `` | +| `deltaTokenModule.ts` | `constructDeltaTokenModule` | On-chain `cancelAndWithdrawDeltaOrder`, `withdrawDeltaNative`, `depositNativeAndPreSign`, `depositNativeAndPreSignDeltaOrder` | `` | + +The on-chain modules (`preSign*`, `deltaTokenModule`, `approveForDelta`) and the local EIP-712 hashing helpers (`helpers/build*OrderData`, `helpers/misc`) are retained from the original delta module — they back the on-chain flows (pre-signing, native deposit, cancel-and-withdraw) that complement server-side building. + +### Types + +- **`src/methods/delta/types.ts`** (v2 surface) — `BuiltDeltaOrder`, `DeltaPrice` (+ `DeltaRoute` / `DeltaRouteStep` / `DeltaRouteBridge` / `DeltaRouteBridgeContractParams`, `DeltaPriceToken`, `DeltaTokenAmount`, `BridgeTag`, `BridgeRoute`), `DeltaAuction` (the envelope returned by **every** read/post — `status: DeltaOrderStatus`, `input`/`output: DeltaTokenSide`, flat `transactions: DeltaTransaction`, explicit `side`; generic over `onChainOrderType`, narrowing `order` to `OnChainOrderMap[T]`), `DeltaOrderStatus`, `DeltaTokenSide`, `DeltaTransaction`. +- **`src/methods/delta/helpers/types.ts`** (shared on-chain order structs) — `DeltaAuctionOrder`, `ExternalDeltaOrder`, `TWAPDeltaOrder`, `TWAPBuyDeltaOrder`, `ProductiveDeltaOrder`, `Bridge`, `OnChainOrderMap` (Standard/Fillable/External/TWAP Sell/TWAP Buy/Productive), `OnChainOrderType`, `TWAPOnChainOrderType`, `DeltaOrderUnion`, `DeltaOrderType` (`'MARKET' | 'LIMIT'`), `DeltaAmounts*`, `UnifiedDeltaOrderData`, `OrderKind` / `SwapSideToOrderKind`. +- `PaginatedResponse` lives in `src/types.ts`. ### Delta Helpers (`src/methods/delta/helpers/`) -- `types.ts` — `DeltaAuctionOrder`, `ExternalDeltaOrder`, `ProductiveDeltaOrder`, `TWAPDeltaOrder`, `TWAPBuyDeltaOrder`, `Bridge`, `DeltaAuction`, `OnChainOrderMap` (Standard/External/TWAP Sell/TWAP Buy/Productive families, plus the `FillableOrder` variant of Standard), `DeltaAuctionStatus`, `BridgeMetadata`, `BridgeStatus`, `OnChainOrderType`, `DeltaOrderType` (`'MARKET' | 'LIMIT'`, shared by v1 & v2), `DeltaAuctionUnion` (= `DeltaAuctionDelta | DeltaAuctionFillable | DeltaAuctionExternal | DeltaAuctionTWAP | DeltaAuctionTWAPBuy | DeltaAuctionProductive`) -- `buildDeltaOrderData.ts` — `buildDeltaSignableOrderData`, `produceDeltaOrderTypedData`, `SignableDeltaOrderData`, `BuildDeltaOrderDataInput`, `DELTA_DEFAULT_EXPIRY` -- `buildCancelDeltaOrderData.ts` — `buildCancelDeltaOrderSignableData`, `SignableCancelDeltaOrderData`, `CancelDeltaOrderData` -- `buildTWAPOrderData.ts` — `buildTWAPSignableOrderData`, `SignableTWAPOrderData`, `BuildTWAPOrderDataInput` -- `buildExternalOrderData.ts` — `buildExternalSignableOrderData`, `SignableExternalOrderData` -- `misc.ts` — `sanitizeDeltaOrderData` (strips extra fields before signing/hashing), `applySlippage`, `resolvePartnerFee` -- `orders.ts` — `OrderHelpers` namespace with `.checks` (type guards: `isDeltaOrder`, `isTWAPOrder`, `isExternalOrder`, `isOrderCrosschain`, `isExecutedAuction`, etc.) and `.getters` (`getUnifiedDeltaOrderData`, `getAuctionAmounts`, `getTwapAuctionAmounts`, `getFilledPercent`, etc.) -- `abi.ts` — shared ABI fragments +- `types.ts` — shared order-struct types (above). +- `buildDeltaOrderData.ts` / `buildExternalOrderData.ts` / `buildTWAPOrderData.ts` — local EIP-712 typed-data builders + `produceDeltaOrderTypedData`, `SignableDeltaOrderData` / `SignableExternalOrderData` / `SignableTWAPOrderData`, `DELTA_DEFAULT_EXPIRY` (consumed by `preSign*` / `deltaTokenModule`). +- `buildCancelDeltaOrderData.ts` — `SignableCancelDeltaOrderData`, `CancelDeltaOrderData`. +- `misc.ts` — `sanitizeDeltaOrderData` (strips extra fields before signing/hashing), `applySlippage`, `resolvePartnerFee`, `producePartnerAndFee`. +- `orders.ts` — single `OrderHelpers` object `{ checks, getters }` (no v1/v2 split): + - `checks`: order-struct guards (`isDeltaOrder`, `isExternalOrder`, `isTWAPOrder` / `isTWAPSellOrder` / `isTWAPBuyOrder`, `isProductiveOrder`, `isOrderCrosschain`); auction discriminants (`isDeltaAuction`, `isExternalAuction`, `isTWAPAuction` / `isTWAPSellAuction` / `isTWAPBuyAuction`, `isProductiveAuction`, `isFillableAuction`); status guards over the v2 envelope (`isCompletedAuction`, `isFailedAuction`, `isCanceledAuction`, `isExpiredAuction`, `isPendingAuction`, `isPartiallyExecutedAuction`). + - `getters`: `getUnifiedDeltaOrderData`, `getAuctionAmounts` (`{ expected, executed }`), `getAuctionTokenAddresses`, `getAuctionSrcChainId` / `getAuctionDestChainId`, `getAuctionSwapSide` (reads `auction.side`), `getTransactionAmounts`, `getFilledPercent`; plus order-level `getOrderTokenAddresses`, `getSwapSideFromDeltaOrder`, `getSwapSideFromTwapOrderType`, `getExpectedTwapSrcAmount` / `getExpectedTwapDestAmount` / `getExpectedTwapOrderAmounts`. +- `abi.ts` — shared ABI fragments. ### Core Types (`src/`) - `types.ts` — `ConstructProviderFetchInput`, `ContractCallerFunctions`, `TxSendOverrides`, `PaginatedResponse` - `helpers/misc.ts` — `ExtractAbiMethodNames` - `sdk/partial.ts` — `constructPartialSDK`, `InferWithTxResponse` type tuple -## Delta V2 Module (`src/methods/deltaV2/`) - -Exposed as `sdk.deltaV2.*` on the full/simple SDK, and as the **`DeltaV2` namespace** at the top of the package. Ships alongside v1 (non-breaking). All URLs use the `/delta/v2/...` prefix. - -### Public access pattern — the `DeltaV2` namespace - -`src/index.ts` re-exports the v2 surface as `export * as DeltaV2 from './methods/deltaV2'`. Inside the v2 folder, symbols use unsuffixed names (`constructBuildDeltaOrder`, `BuiltDeltaOrder`, `DeltaPrice`, …); consumers reach them as `DeltaV2.X`. This avoids top-level collisions with v1 (which also exports `DeltaPrice`, `constructBuildDeltaOrder`, etc.) while letting the v2 source live under the canonical names it will eventually inherit. - -```ts -import { DeltaV2 } from '@velora-dex/sdk'; - -// runtime: DeltaV2.constructBuildDeltaOrder, DeltaV2.constructAllDeltaOrdersHandlers, ... -// types: DeltaV2.DeltaPrice, DeltaV2.BuiltDeltaOrder, DeltaV2.DeltaRoute, ... -``` - -`import type { DeltaV2 } from '@velora-dex/sdk'` works the same way for type-only consumers (no runtime cost). Types live *inside* the namespace — destructuring at the import site (`const { DeltaPrice } = DeltaV2`) does not bring the type; alias via `type DeltaPrice = DeltaV2.DeltaPrice;` instead. - -The migration story (1) v1 bare + DeltaV2 namespace, (2) flip to v2 bare + DeltaV1 backcompat, (3) drop v1 — is documented inline in [src/index.ts](src/index.ts) above the `export * as DeltaV2` line. - -### Key differences from v1 - -| Concern | v1 | v2 | -|---------|----|----| -| Order building | Local EIP-712 computation | `POST /delta/v2/orders/build` → returns `DeltaV2.BuiltDeltaOrder { toSign, orderHash }` | -| Signing | Family-specific sign functions | Single `signDeltaOrder(builtOrder)` for all order types | -| Price response | `DeltaPrice` / `BridgePrice` overload | `DeltaV2.DeltaPrice` with `route: DeltaRoute` and `alternatives: DeltaRoute[]` | -| Order list | Flat array | `PaginatedResponse` envelope | -| Partner fee | Resolved locally via `getPartnerFee` | Passed as raw params to server (`partner`, `partnerAddress`, `partnerFeeBps`) | - -### Order families - -Same three families as v1, all built via `POST /delta/v2/orders/build` with an `orderType` field: - -| Family | `orderType` | Build params type (under `DeltaV2.*`) | -|--------|-------------|-------------------| -| Standard | `'Order'` | `BuildDeltaOrderParams` | -| External | `'ExternalOrder'` | `BuildExternalDeltaOrderParams` (adds `handler`, `data`) | -| TWAP Sell | `'TWAPOrder'` | `BuildTWAPSellDeltaOrderParams` | -| TWAP Buy | `'TWAPBuyOrder'` | `BuildTWAPBuyDeltaOrderParams` | - -### Key files - -Symbol names below are as they appear **inside** the v2 folder (no V2 suffix). Through the namespace they are `DeltaV2.constructBuildDeltaOrder`, etc. - -| File | Constructor | Purpose | -|------|-------------|---------| -| `index.ts` | `constructAllDeltaOrdersHandlers`, `constructSubmitDeltaOrder` etc. | Composite: orchestrates all v2 modules, defines `DeltaOrderHandlers`. Submit orchestrators wrap build→sign→post. Re-exports every leaf module so `import * as DeltaV2` carries the full surface. | -| `buildDeltaOrder.ts` | `constructBuildDeltaOrder` | POST to `/v2/orders/build` → `BuiltDeltaOrder` | -| `buildExternalDeltaOrder.ts` | `constructBuildExternalDeltaOrder` | Same, `orderType: 'ExternalOrder'` | -| `buildTWAPDeltaOrder.ts` | `constructBuildTWAPDeltaOrder` | Same, `orderType: 'TWAPOrder'` or `'TWAPBuyOrder'` | -| `getDeltaPrice.ts` | `constructGetDeltaPrice` | GET `/v2/prices` → `DeltaPrice` | -| `getDeltaOrders.ts` | `constructGetDeltaOrders` | `getDeltaOrders` (paginated list), `getDeltaOrderById`, `getDeltaOrderByHash`, `getRequiredBalanceForDeltaOrders` (mirrors v1's `getRequiredBalanceForDeltaLimitOrders` under `/delta/v2/orders/fillablebalance/...`). Read endpoints return the v2 `DeltaAuction` (= `DeltaV2.DeltaAuction`). | -| `postDeltaOrder.ts` | `constructPostDeltaOrder` | POST `/v2/orders` → `DeltaAuction<'Order'>` (the v2 `DeltaV2.DeltaAuction`) | -| `cancelDeltaOrder.ts` | `constructCancelDeltaOrder` | `signCancelDeltaOrderRequest` → `postCancelDeltaOrderRequest` → `cancelDeltaOrders` (orchestrator). POSTs to `/v2/orders/cancel`. | -| `getBridgeRoutes.ts` | `constructGetBridgeRoutes` | `getBridgeRoutes` (flat `BridgeRoute[]`) + `getBridgeProtocols` | -| `isTokenSupportedInDelta.ts` | `constructIsTokenSupportedInDelta` | GET `/v2/prices/is-token-supported` → `boolean` | -| `getAgentsList.ts` | `constructGetAgentsList` | GET `/v2/agents/list/:chainId` → `string[]` | -| `helpers/orders.ts` | — (exports `OrderHelpers`) | v2 order/auction guards + getters. Reached as `DeltaV2.OrderHelpers`. See "V2 Helpers" below. | - -On-chain methods (preSign, approve, deltaTokenModule) and `getPartnerFee`/`getDeltaContract` are **reused from v1** — no duplication. Inside the v2 folder they're imported from `../delta/*`. - -### SDK wiring (`sdk/full.ts`, `sdk/simple.ts`) - -Because v1 and v2 share unsuffixed names, the SDK assembly files import v2 either as a namespace (`import * as DeltaV2 from '../methods/deltaV2'`, used in `simple.ts`) or with local aliases that re-add the `V2` suffix (e.g., `constructAllDeltaOrdersHandlers as constructAllDeltaV2OrdersHandlers`, used in `full.ts`). Either form keeps the v1/v2 distinction visible in the wiring code. The pre-bound bag on `sdk.deltaV2.*` exposes methods under their unsuffixed names — `sdk.deltaV2.buildDeltaOrder()`, `sdk.deltaV2.postDeltaOrder()`, etc. - -### V2 Types (`src/methods/deltaV2/types.ts`) - -(Access via `DeltaV2.X` at the package boundary.) - -- `BuiltDeltaOrder` — server build response: `{ toSign: { domain, types, value }, orderHash }` -- `DeltaPrice` — v2 price response with `route: DeltaRoute` and `alternatives: DeltaRoute[]` -- `DeltaRoute` / `DeltaRouteStep` / `DeltaRouteBridge` / `DeltaRouteBridgeContractParams` — route shape -- `DeltaPriceToken` / `DeltaTokenAmount` — token identity and amount with USD value -- `BridgeTag` — `'recommended' | 'fastest' | 'best-return'` -- `BridgeRoute` — flat bridge route entry `{ srcChainId, destChainId, tokens }` -- `DeltaAuction` — the order shape returned by **every** v2 order method, both reads (`getDeltaOrders*` / `getDeltaOrderById*`) and posts (`postDeltaOrder` / `postExternalDeltaOrder` / `postTWAPDeltaOrder`). Generic over `onChainOrderType` exactly like v1's `DeltaAuction` (distributes over `OnChainOrderType`, narrowing `order` to `OnChainOrderMap[T]`), but with the v2 base fields (`status: DeltaOrderStatus`, `input`/`output: DeltaTokenSide`, flat `transactions`, etc.) instead of v1's. Reached as `DeltaV2.DeltaAuction` — a distinct type from the top-level v1 `DeltaAuction`; v2 method files import it from `./types`, never from `../delta`. -- `DeltaOrderStatus` — integrator-facing status enum values -- `DeltaTokenSide` / `DeltaTransaction` — order input/output and transaction entry types - -`PaginatedResponse` lives in `src/types.ts` (shared, still exported bare from the top of the package). - -### V2 Helpers (`src/methods/deltaV2/helpers/orders.ts`) - -Exposed as `DeltaV2.OrderHelpers` — the v2 counterpart of v1's top-level `OrderHelpers`, with the same `{ checks, getters }` shape. Two distinct objects: top-level `OrderHelpers` (v1) and `DeltaV2.OrderHelpers` (v2). - -Because the on-chain order structs (`auction.order`) and the `onChainOrderType` union are **shared** between v1 and v2, the v2 file reuses v1's implementations directly for: -- **order-struct guards** — `isTWAPOrder`, `isTWAPSellOrder`, `isTWAPBuyOrder`, `isExternalOrder`, `isDeltaOrder`, `isProductiveOrder`, `isOrderCrosschain` -- **auction discriminant guards** — `isTWAPAuction`, `isTWAPSellAuction`, `isTWAPBuyAuction`, `isDeltaAuction`, `isExternalAuction`, `isProductiveAuction` -- **order-level getters** — `getOrderTokenAddresses`, `getSwapSideFromDeltaOrder`, `getSwapSideFromTwapOrderType`, `getExpectedTwapSrcAmount`, `getExpectedTwapDestAmount`, `getExpectedTwapOrderAmounts` +### `OnChainOrderType` note -What's **reimplemented for the v2 auction envelope** (v2's `status: DeltaOrderStatus`, `input`/`output: DeltaTokenSide`, flat `transactions: DeltaTransaction`, explicit `side`): -- **status / execution guards** — `isCompletedAuction` (v2's `COMPLETED`, replaces v1's `isExecutedAuction`/`EXECUTED`), `isFailedAuction` (`FAILED`/`EXPIRED`/`CANCELLED`/`REFUNDED`), `isCanceledAuction`, `isExpiredAuction`, `isPendingAuction` (`PENDING`/`AWAITING_SIGNATURE`/`ACTIVE`/`BRIDGING`), `isPartiallyExecutedAuction` -- **`isFillableAuction`** — new guard for `onChainOrderType === 'FillableOrder'` (treat alongside `isDeltaAuction`) -- **auction-level getters** — `getAuctionSwapSide` (just `auction.side`), `getAuctionSrcChainId`/`getAuctionDestChainId` (from `input`/`output.chainId`), `getAuctionTokenAddresses`, `getTransactionAmounts`, `getFilledPercent`, `getAuctionAmounts` (returns `{ expected, executed }` — note `executed`, matching the API, vs v1's `final`), and `getUnifiedDeltaOrderData` (returns the shared `UnifiedDeltaOrderData` shape). +`'ProductiveOrder'` is part of `OnChainOrderType` and `OnChainOrderMap` — `DeltaAuction<'ProductiveOrder'>` resolves to `ProductiveDeltaOrder`. The type is wired through the public surface, but **no build/sign/post helpers** exist for productive orders (`constructSubmit*` / `construct(Build|Post)*` cover only `Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`). Productive orders are read-only from the SDK's perspective. Sides are inferred as `SELL` (productive orders carry no `OrderKind`). -### `OnChainOrderType` note +`'FillableOrder'` is likewise a member of `OnChainOrderType`/`OnChainOrderMap`, resolving (via `DeltaAuction<'FillableOrder'>`) to the same `DeltaAuctionOrder` shape as `'Order'`. It's the `onChainOrderType` the server reports for a `partiallyFillable` Standard order — there is no separate builder. Consumers narrowing a `DeltaAuction` should treat `onChainOrderType === 'FillableOrder'` the same as `'Order'` (`isDeltaAuction(a) || isFillableAuction(a)`). -`'ProductiveOrder'` is part of `OnChainOrderType` and `OnChainOrderMap` — `DeltaAuction<'ProductiveOrder'>` (also exported as `DeltaAuctionProductive`) resolves to `ProductiveDeltaOrder`. The type is wired through the public surface, but **no build/sign/post helpers** exist for productive orders yet (`constructSubmit*` / `construct(Build|Sign|Post)*` cover only `Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`). Productive orders are read-only from the SDK's perspective — produced and managed by the server. Sides are inferred as `SELL` (productive orders carry no `OrderKind`). +## Quote Module (`src/methods/quote/`) -`'FillableOrder'` is likewise a member of `OnChainOrderType`/`OnChainOrderMap`, resolving (via `DeltaAuction<'FillableOrder'>`, also exported as `DeltaAuctionFillable` and included in `DeltaAuctionUnion`) to the same `DeltaAuctionOrder` shape as `'Order'`. It's the `onChainOrderType` the server reports for a `partiallyFillable` Standard order — there is no separate builder. Consumers narrowing a `DeltaAuction` (v1 or v2) should treat `onChainOrderType === 'FillableOrder'` the same as `'Order'`. +`constructGetQuote` → `getQuote` hits **`GET /v2/quote`**. Same overloaded, `mode`-based shape as before (`mode: 'delta' | 'market' | 'all'`, with `'all'` returning Delta pricing or a market `fallbackReason`) — the only v2 change is that the delta side is the v2 `DeltaPrice` (route-based) from `methods/delta/types`, not the old v1 `DeltaPrice`/`BridgePrice`. Return types (`QuoteWithDeltaPrice`, `QuoteWithBridgePrice`, `QuoteWithDeltaPriceAndBridgePrice`, `QuoteWithMarketPrice`, `QuoteWithMarketPriceAsFallback`) and all function overloads are preserved. Exposed as `sdk.quote.getQuote`. ## Checklist: Adding a New On-Chain Method @@ -275,4 +200,5 @@ OrderWithSig tuple: - EIP-712 domain: `{ name: 'Portikus', version: '2.0.0', chainId, verifyingContract }` - Order hash: computed via viem's `hashTypedData` in `produceDeltaOrderHash()` - ABI style: always inline `const ... as const`, never imported from external ABI files -- Cross-chain detection: `isOrderCrosschain(order)` checks `bridge.destinationChainId !== 0`; `DEFAULT_BRIDGE` has all-zero values for same-chain orders +- Cross-chain detection: `isOrderCrosschain(order)` checks `bridge.destinationChainId !== 0` +- **Commit messages**: `prefix/what was done` — `prefix` is the file, function, or component that was changed. Examples: `OrderDetails/added button`, `useDeltaPrice/migrate to v2 route fields`. Do NOT add a `Co-Authored-By: Claude` trailer. diff --git a/README.md b/README.md index dc2cac961..851f9ddef 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,7 @@ const allowance = await sdk.getAllowance(userAddress, tokenAddress); ### Basic usage -The easiest way to make a trade is to rely on Quote method that communicates with [/quote API endpoint](https://developers.velora.xyz/api/velora-api/velora-delta-api/retrieve-delta-price-with-fallback-to-market) +The easiest way to make a trade is to rely on the Quote method that communicates with the `/v2/quote` API endpoint. With `mode: 'all'` it returns Delta v2 pricing when possible, falling back to the current market price (use `mode: 'delta'` or `mode: 'market'` to request a single source). ```typescript import axios from 'axios'; @@ -196,11 +196,12 @@ const quote = await simpleSDK.quote.getQuote({ srcDecimals: 18, destDecimals: 18, mode: 'all', // Delta quote if possible, with fallback to Market price - side: 'SELL', // Delta mode only supports side: SELL currenly + side: 'SELL', // Delta mode only supports side: SELL currently // partner: "..." // if available }); if ('delta' in quote) { + // quote.delta is the v2 DeltaPrice (route-based) const deltaPrice = quote.delta; const DeltaContract = await simpleSDK.delta.getDeltaContract(); @@ -208,58 +209,26 @@ if ('delta' in quote) { // or sign a Permit1 or Permit2 TransferFrom for DeltaContract await simpleSDK.delta.approveTokenForDelta(amount, Token1); - const slippagePercent = 0.5; - const destAmountAfterSlippage = BigInt( - // get rid of exponential notation - - +(+deltaPrice.destAmount * (1 - slippagePercent / 100)).toFixed(0) - // get rid of decimals - ).toString(10); - + // order building is server-side: pass the quoted route + side, no local amounts const deltaAuction = await simpleSDK.delta.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // or any deltaPrice.alternatives[i] + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send the output destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: Token1, - destToken: Token2, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + slippage: 50, // 50 bps = 0.5% }); - // poll if necessary - function isExecutedDeltaAuction( - auction: Omit, - waitForCrosschain = true // only consider executed when destChain work is done - ) { - if (auction.status !== 'EXECUTED') return false; - - // crosschain Order is executed on destChain if bridgeStatus is filled - if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) { - return auction.bridgeStatus === 'filled'; - } - - return true; - } - - function fetchOrderPeriodically(auctionId: string) { + // poll if necessary — v2 status COMPLETED already accounts for any dest-chain bridge + function startStatusCheck(auctionId: string) { const intervalId = setInterval(async () => { const auction = await simpleSDK.delta.getDeltaOrderById(auctionId); - console.log('checks: ', auction); // Handle or log the fetched auction as needed - - if (isExecutedDeltaAuction(auction)) { - clearInterval(intervalId); // Stop interval if completed + if (auction.status === 'COMPLETED') { + clearInterval(intervalId); console.log('Order completed'); } }, 3000); - console.log('Order Pending'); - // Return intervalId to enable clearing the interval if needed externally - return intervalId; - } - - function startStatusCheck(auctionId: string) { - const intervalId = fetchOrderPeriodically(auctionId); - setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + setTimeout(() => clearInterval(intervalId), 60000 * 5); // stop after 5 minutes } startStatusCheck(deltaAuction.id); @@ -297,33 +266,39 @@ This way the user doesn't need to make a transaction themselve but only to sign (For **Crosschain Delta Orders** refer to a separate documentation page [DELTA.md](./docs/DELTA.md#crosschain-delta-orders) ) -After getting **deltaPrice** from **/quote** endpoint, there are additional steps to sign the Order and wait for its execution. +In v2 the Order is **built by the server** from the quoted route — you sign the returned typed data and post it. After getting **deltaPrice**, there are a few steps to sign the Order and wait for its execution. -### 1. Get deltaPrice from /quote +### 1. Get deltaPrice ```ts const amount = '1000000000000'; // wei const Token1 = '0x1234...' const Token2 = '0xabcde...' +// ... from the quote endpoint (mode: 'delta' or 'all') const quote = await simpleSDK.quote.getQuote({ - srcToken: Token1, // Native token (ETH) is only supported in mode: 'market' + srcToken: Token1, destToken: Token2, amount, userAddress: account, srcDecimals: 18, destDecimals: 18, - mode: 'delta' // or mode: 'all' + mode: 'delta', + side: 'SELL', // partner: "..." // if available -}) - -// if used mode: 'all' -if ('delta' in quote) { - const deltaPrice = quote.delta; -} - -// if used mode: 'delta' +}); const deltaPrice = quote.delta; + +// ... or straight from the Delta price endpoint +const deltaPriceDirect = await simpleSDK.delta.getDeltaPrice({ + srcToken: Token1, + destToken: Token2, + amount, + srcDecimals: 18, + destDecimals: 18, + userAddress: account, + // destChainId: 42161, // for cross-chain — bridge details land in deltaPrice.route.bridge +}); ``` @@ -345,35 +320,28 @@ const signature = await signer._signTypedData(domain, types, message); See more on accepted Permit variants in [Velora documentation](https://developers.velora.xyz/api/velora-api/velora-delta-api/build-a-delta-order-to-sign#supported-permits) -### 3. Sign and submit a Delta Order +### 3. Build, sign and post a Delta Order ```ts -// calculate acceptable destAmount -const slippagePercent = 0.5; - const destAmountAfterSlippage = ( - +deltaPrice.destAmount * - (1 - slippagePercent / 100) - ).toString(10); - -const signableOrderData = await simpleSDK.delta.buildDeltaOrder({ - deltaPrice, +// build is server-side — pass the quoted route + side and your slippage +const built = await simpleSDK.delta.buildDeltaOrder({ + route: deltaPrice.route, // or any deltaPrice.alternatives[i] + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send the output destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: Token1, - destToken: Token2, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount - // partner: "..." // if available + slippage: 50, // 50 bps = 0.5% + // partner, partnerFeeBps — forwarded to the server }); -const signature = await simpleSDK.delta.signDeltaOrder(signableOrderData); +// one signer for every order family (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) +const signature = await simpleSDK.delta.signDeltaOrder(built); const deltaAuction = await simpleSDK.delta.postDeltaOrder({ - // partner: "..." // if available - // partiallyFillabel: true, // allow the Order to be partially filled as opposed to fill-or-kill - order: signableOrderData.data, + order: built.toSign.value, signature, + // partner: "...", + // partiallyFillable: true, // allow the Order to be partially filled as opposed to fill-or-kill }); ``` @@ -383,15 +351,13 @@ As an option the `buildDeltaOrder + signDeltaOrder + postDeltaOrder` can be comb ```ts const deltaAuction = await simpleSDK.delta.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send output destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - // partiallyFillabel: true, // allow the Order to be partially filled as opposed to fill-or-kill - srcToken: Token1, - destToken: Token2, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + // partiallyFillable: true, // allow the Order to be partially filled as opposed to fill-or-kill + slippage: 50, }); ``` @@ -399,69 +365,26 @@ This allows to simplify the flow at the expense of control over the Order signin #### 3.b adding partner fee -A portion of destToken will be collected as a partner fee if `partner` parameter is provided to `buildDeltaOrder` (and `submitDeltaOrder`). The `partnerFee` itself is `deltaPrice.partnerFee` - -To examine the default partnerFee parameters (`{partnerAddress: Address, partnerFee: number, takeSurplus: boolean}`), you can call `getPartnerFee` method. These parameters are then encoded in Order.partnerAndFee field. +A portion of destToken is collected as a partner fee when `partner` (and optionally `partnerFeeBps`) is provided to `buildDeltaOrder` / `submitDeltaOrder`. In v2 these are forwarded to the server, which encodes them into `Order.partnerAndFee`. You can inspect the default partner-fee parameters with `getPartnerFee`: ```ts const partnerFeeResponse = await simpleSDK.delta.getPartnerFee({ partner }); ``` -Alternatively, you can supply your own partnerFee parameters that will be encoded in Order.partnerAndFee field - -```ts -const signableOrderData = await simpleSDK.delta.buildDeltaOrder({ - deltaPrice, - owner: account, - // beneficiary: anotherAccount, // if need to send the output destToken to another account - // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - // partiallyFillabel: true, // allow the Order to be partially filled as opposed to fill-or-kill - srcToken: Token1, - destToken: Token2, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount - partnerAddress: '0x1234...', - partnerFee: 0.12, - takeSurplus: true, -}); -``` - ### 4. Wait for Delta Order execution ```ts -// poll if necessary -function isExecutedDeltaAuction( - auction: Omit, - waitForCrosschain = true // only consider executed when destChain work is done -) { - if (auction.status !== 'EXECUTED') return false; - - // crosschain Order is executed on destChain if bridgeStatus is filled - if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) { - return auction.bridgeStatus === 'filled'; - } - - return true; -} - -function fetchOrderPeriodically(auctionId: string) { +// poll if necessary — v2 status COMPLETED already accounts for any dest-chain bridge +function startStatusCheck(auctionId: string) { const intervalId = setInterval(async () => { const auction = await simpleSDK.delta.getDeltaOrderById(auctionId); - console.log('checks: ', auction); // Handle or log the fetched auction as needed - - if (isExecutedDeltaAuction(auction)) { - clearInterval(intervalId); // Stop interval if completed + if (auction.status === 'COMPLETED') { + clearInterval(intervalId); // stop interval once completed console.log('Order completed'); } }, 3000); - console.log('Order Pending'); - // Return intervalId to enable clearing the interval if needed externally - return intervalId; -} - -function startStatusCheck(auctionId: string) { - const intervalId = fetchOrderPeriodically(auctionId); - setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + // stop polling after 5 minutes + setTimeout(() => clearInterval(intervalId), 60000 * 5); } startStatusCheck(deltaAuction.id); @@ -475,72 +398,7 @@ For **External Delta Orders** (orders that delegate token handling to an externa ------------ -### Delta V2 (server-built orders) - -Delta V2 ships alongside v1. It moves order construction to the server (`POST /delta/v2/orders/build`), returns route-based prices with same-chain and cross-chain alternatives in one response, and uses a single signer for every order family (standard, external, TWAP). The pre-bound bag is available as `simpleSDK.deltaV2.*`. The raw constructors and types live under the `DeltaV2` namespace at the package root. - -```ts -import { constructSimpleSDK, DeltaV2 } from '@velora-dex/sdk'; - -// types: DeltaV2.DeltaPrice, DeltaV2.DeltaRoute, DeltaV2.BuiltDeltaOrder, -// DeltaV2.DeltaAuction, DeltaV2.BridgeRoute, ... -// values: DeltaV2.constructBuildDeltaOrder, DeltaV2.constructPostDeltaOrder, -// DeltaV2.constructAllDeltaOrdersHandlers, ... -``` - -#### Quick flow (simple SDK) - -```ts -const simpleSDK = constructSimpleSDK({ chainId: 1, axios }, { - ethersProviderOrSigner: signer, - EthersContract: ethers.Contract, - account, -}); - -const deltaPrice = await simpleSDK.deltaV2.getDeltaPrice({ - srcToken: Token1, - destToken: Token2, - amount, - srcDecimals: 18, - destDecimals: 18, - userAddress: account, - // destChainId: 42161, // for cross-chain — bridge details land in deltaPrice.route.bridge -}); - -// approve once (Permit1 / Permit2 also supported — see v1 flow above) -await simpleSDK.deltaV2.approveTokenForDelta(amount, Token1); - -// build → sign → post in one call -const deltaAuction = await simpleSDK.deltaV2.submitDeltaOrder({ - route: deltaPrice.route, // or any deltaPrice.alternatives[i] - side: deltaPrice.side, - owner: account, - slippage: 50, // 50 bps = 0.5% - // partner, partnerAddress, partnerFeeBps — passed through to the server -}); - -// status polling — v2 status COMPLETED already accounts for the dest-chain bridge -const isDone = (o: DeltaV2.DeltaAuction) => o.status === 'COMPLETED'; -``` - -#### Manual flow (full control over signing) - -```ts -const built = await simpleSDK.deltaV2.buildDeltaOrder({ - route: deltaPrice.route, - side: deltaPrice.side, - owner: account, - slippage: 50, -}); - -// one signer for every v2 family (Order / ExternalOrder / TWAPOrder / TWAPBuyOrder) -const signature = await simpleSDK.deltaV2.signDeltaOrder(built); - -const deltaAuction = await simpleSDK.deltaV2.postDeltaOrder({ - order: built.toSign.value, - signature, -}); -``` +### Advanced Delta usage #### TWAP order @@ -549,7 +407,7 @@ A TWAP sell splits `totalSrcAmount` into `numSlices` equal slices executed `inte ```ts const perSliceAmount = (BigInt(totalSrcAmount) / BigInt(numSlices)).toString(); -const slicePrice = await simpleSDK.deltaV2.getDeltaPrice({ +const slicePrice = await simpleSDK.delta.getDeltaPrice({ srcToken: Token1, destToken: Token2, amount: perSliceAmount, @@ -558,9 +416,9 @@ const slicePrice = await simpleSDK.deltaV2.getDeltaPrice({ userAddress: account, }); -await simpleSDK.deltaV2.approveTokenForDelta(totalSrcAmount, Token1); +await simpleSDK.delta.approveTokenForDelta(totalSrcAmount, Token1); -const twapAuction = await simpleSDK.deltaV2.submitTWAPDeltaOrder({ +const twapAuction = await simpleSDK.delta.submitTWAPDeltaOrder({ onChainOrderType: 'TWAPOrder', // or 'TWAPBuyOrder' route: slicePrice.route, owner: account, @@ -571,58 +429,56 @@ const twapAuction = await simpleSDK.deltaV2.submitTWAPDeltaOrder({ }); ``` -#### Partial SDK with v2 +#### Partial SDK -For bundle-savvy code, pull only the v2 constructors you need. The `DeltaV2` namespace doubles as a runtime object, so it tree-shakes cleanly. +For bundle-savvy code, pull only the Delta constructors you need — they tree-shake cleanly. ```ts import { constructPartialSDK, constructFetchFetcher, - DeltaV2, + constructGetDeltaPrice, + constructGetDeltaOrders, + constructGetBridgeRoutes, } from '@velora-dex/sdk'; const sdk = constructPartialSDK( { chainId: 1, fetcher: constructFetchFetcher(fetch) }, - DeltaV2.constructGetDeltaPrice, - DeltaV2.constructGetDeltaOrders, - DeltaV2.constructGetBridgeRoutes, + constructGetDeltaPrice, + constructGetDeltaOrders, + constructGetBridgeRoutes, ); const price = await sdk.getDeltaPrice({ /* ... */ }); const orders = await sdk.getDeltaOrders({ userAddress: account, page: 1, limit: 50 }); ``` -A complete v2 example (standard, external handler, TWAP, and order listing) is in [examples/deltaV2](./src/examples/deltaV2.ts). +A complete example (standard, external handler, TWAP, and order listing) is in [examples/delta](./src/examples/delta.ts). #### Productive Orders (read-only) -Alongside the four buildable families (`Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`), the SDK surfaces a fifth `onChainOrderType` — **`ProductiveOrder`** — through the read endpoints (`sdk.delta.getDeltaOrderById`, `sdk.deltaV2.getDeltaOrders`, etc.). Productive orders are produced and managed entirely by the server: there are deliberately **no `buildProductiveOrder`, `signProductiveOrder`, or `submitProductiveOrder` helpers**. The shape is wired through `OnChainOrderType`, `OnChainOrderMap`, and `DeltaAuctionUnion` (also exported individually as `DeltaAuctionProductive`) so that consumers iterating over an order list can type-narrow on `onChainOrderType === 'ProductiveOrder'` and read the order safely — productive orders carry no `OrderKind`, so the side is always `SELL`. - -`OnChainOrderType` additionally includes **`'FillableOrder'`**, which maps to the same shape as a Standard `'Order'` (`DeltaAuctionOrder`, also exported as `DeltaAuctionFillable` and part of `DeltaAuctionUnion`). It is not a separate buildable family — it's the `onChainOrderType` the server reports for a `partiallyFillable` Standard order, so treat it the same as `'Order'` when narrowing. +Alongside the four buildable families (`Order`, `ExternalOrder`, `TWAPOrder`, `TWAPBuyOrder`), the SDK surfaces a fifth `onChainOrderType` — **`ProductiveOrder`** — through the read endpoints (`sdk.delta.getDeltaOrderById`, `sdk.delta.getDeltaOrders`, etc.). Productive orders are produced and managed entirely by the server: there are deliberately **no `buildProductiveOrder`, `signProductiveOrder`, or `submitProductiveOrder` helpers**. The shape is wired through `OnChainOrderType` and `OnChainOrderMap` so that consumers iterating over an order list can type-narrow on `onChainOrderType === 'ProductiveOrder'` and read the order safely — productive orders carry no `OrderKind`, so the side is always `SELL`. -```ts -import { OrderHelpers, type DeltaAuctionUnion } from '@velora-dex/sdk'; +`OnChainOrderType` additionally includes **`'FillableOrder'`**, which maps to the same shape as a Standard `'Order'` (`DeltaAuctionOrder`). It is not a separate buildable family — it's the `onChainOrderType` the server reports for a `partiallyFillable` Standard order, so treat it the same as `'Order'` when narrowing. -function describe(order: DeltaAuctionUnion) { - if (order.onChainOrderType === 'ProductiveOrder') { - // order: DeltaAuctionProductive — read-only, no SDK builder - return `productive: ${order.order.srcToken}`; - } - // ... handle Order / ExternalOrder / TWAPOrder / TWAPBuyOrder -} -``` +#### Order helpers -The top-level `OrderHelpers` (above) works with **v1** auctions. For **v2** auctions (`DeltaV2.DeltaAuction`, returned by `sdk.deltaV2.*` read/post methods) use `DeltaV2.OrderHelpers`, which has the same `{ checks, getters }` shape but reads the v2 auction envelope (`status: DeltaOrderStatus`, `input`/`output`, flat `transactions`, explicit `side`): +`OrderHelpers` exposes `{ checks, getters }` for auctions returned by `sdk.delta.*` read/post methods (`status: DeltaOrderStatus`, `input`/`output`, flat `transactions`, explicit `side`): ```ts -import { DeltaV2 } from '@velora-dex/sdk'; +import { OrderHelpers } from '@velora-dex/sdk'; -const { checks, getters } = DeltaV2.OrderHelpers; +const { checks, getters } = OrderHelpers; + +if (checks.isProductiveAuction(auction)) { + // read-only, no SDK builder +} else if (checks.isFillableAuction(auction) || checks.isDeltaAuction(auction)) { + // treat FillableOrder the same as a standard Order +} if (checks.isCompletedAuction(auction)) { const { expected, executed } = getters.getAuctionAmounts(auction); - // executed (not v1's `final`) — matches the API convention + // `executed` — matches the API convention } const unified = getters.getUnifiedDeltaOrderData(auction); @@ -637,7 +493,7 @@ const unified = getters.getUnifiedDeltaOrderData(auction); Unlike the Delta Order, a Market swap requires the user themselves to submit a Swap transaction -### 1. Get Market priceRoute from /quote +### 1. Get Market priceRoute from /v2/quote ```ts const amount = '1000000000000'; // wei @@ -645,22 +501,17 @@ const Token1 = '0x1234...' const Token2 = '0xabcde...' const quote = await simpleSDK.quote.getQuote({ - srcToken: Token1, // Native token (ETH) is only supported in mode: 'market' + srcToken: Token1, destToken: Token2, amount, userAddress: account, srcDecimals: 18, destDecimals: 18, - mode: 'market' + mode: 'market', + side: 'SELL', // or 'BUY' // partner: "..." // if available }) -// if used mode: 'all' -if ('market' in quote) { - const priceRoute = quote.market; -} - -// if used mode: 'market' const priceRoute = quote.market; ``` diff --git a/docs/DELTA.md b/docs/DELTA.md index 4b251b13b..24a86a2b8 100644 --- a/docs/DELTA.md +++ b/docs/DELTA.md @@ -1,6 +1,7 @@ **Velora Delta** is an intent-based protocol that enables a Velora user to make gasless swaps where multiple agents compete to execute the trade at the best price possible. This way the user doesn't need to make a transaction themselves but only to sign a Delta Order. -The easiest way to make use of the Delta Order is to use the SDK following these steps: + +In Delta v2 the Order is **built by the server** from the route returned in the price response — you sign the returned typed data and post it. The easiest way to make use of the Delta Order is to use the SDK following these steps: ### 1. Construct an SDK object @@ -32,6 +33,8 @@ const deltaPrice = await deltaSDK.getDeltaPrice({ destDecimals: 6, // partner: "..." // if available }); + +// deltaPrice.route is the recommended route; deltaPrice.alternatives holds the rest ``` @@ -56,68 +59,42 @@ See more on accepted Permit variants in [Velora documentation](https://developer ### 4. Sign and submit a Delta Order -```ts -// calculate acceptable destAmount -const slippagePercent = 0.5; - const destAmountAfterSlippage = ( - +deltaPrice.destAmount * - (1 - slippagePercent / 100) - ).toString(10); +Order building is server-side: pass the quoted `route` + `side` and your acceptable `slippage` — the server computes the amounts. `submitDeltaOrder` bundles build → sign → post. +```ts const deltaAuction = await deltaSDK.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // or any deltaPrice.alternatives[i] + side: deltaPrice.side, owner: account, // beneficiary: anotherAccount, // if need to send destToken to another account // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount + slippage: 50, // 50 bps = 0.5% + // partner, partnerFeeBps — forwarded to the server }); ``` +For full control over signing, use `buildDeltaOrder` → `signDeltaOrder` → `postDeltaOrder` separately (see the main [README](../README.md)). + ### 5. Wait for Delta Order execution ```ts -// poll if necessary -function isExecutedDeltaAuction( - auction: Omit, - waitForCrosschain = true // only consider executed when destChain work is done -) { - if (auction.status !== 'EXECUTED') return false; - - // crosschain Order is executed on destChain if bridgeStatus is filled - if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) { - return auction.bridgeStatus === 'filled'; - } - - return true; -} - -function fetchOrderPeriodically(auctionId: string) { +// poll if necessary — v2 status COMPLETED already accounts for any dest-chain bridge +function startStatusCheck(auctionId: string) { const intervalId = setInterval(async () => { - const auction = await simpleSDK.delta.getDeltaOrderById(auctionId); - console.log('checks: ', auction); // Handle or log the fetched auction as needed - - if (isExecutedDeltaAuction(auction)) { - clearInterval(intervalId); // Stop interval if completed + const auction = await deltaSDK.getDeltaOrderById(auctionId); + if (auction.status === 'COMPLETED') { + clearInterval(intervalId); // stop interval once completed console.log('Order completed'); } }, 3000); - console.log('Order Pending'); - // Return intervalId to enable clearing the interval if needed externally - return intervalId; -} - -function startStatusCheck(auctionId: string) { - const intervalId = fetchOrderPeriodically(auctionId); - setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + // stop polling after 5 minutes + setTimeout(() => clearInterval(intervalId), 60000 * 5); } startStatusCheck(deltaAuction.id); ``` -#### A more detailed example of Delta Order usage can be found in [examples/delta](./src/examples/delta.ts) +#### A more detailed example of Delta Order usage can be found in [examples/delta](../src/examples/delta.ts) @@ -147,12 +124,15 @@ const deltaSDK = constructSimpleSDK( ### 2. Check which tokens are available on the destination chain. -A limited list of tokens are available in Across, the service facilitating crosschain bridging +A limited list of tokens are available in Across, the service facilitating crosschain bridging. ```ts -const bridgeInfo = await deltaSDK.getBridgeInfo(); +const bridgeRoutes = await deltaSDK.getBridgeRoutes(); -const tokensAvailableForBridging = bridgeInfo[SRC_CHAIN_ID]?.[DEST_CHAIN_ID] +const tokensAvailableForBridging = bridgeRoutes.find( + (route) => + route.srcChainId === SRC_CHAIN_ID && route.destChainId === DEST_CHAIN_ID +)?.tokens; ``` @@ -174,6 +154,8 @@ const deltaPrice = await deltaSDK.getDeltaPrice({ destDecimals: 6, // partner: "..." // if available }); + +// the returned deltaPrice.route already encodes the bridge step for the crosschain swap ``` @@ -198,71 +180,35 @@ See more on accepted Permit variants in [Velora documentation](https://developer ### 5. Sign and submit a Delta Order -```ts -// calculate acceptable destAmount -const slippagePercent = 0.5; -const destAmountAfterSlippage = ( - +deltaPrice.destAmount * - (1 - slippagePercent / 100) -).toString(10); +The crosschain `route` (from a `getDeltaPrice` call with `destChainId`) already carries the bridge details, so submitting is the same as a same-chain order — the server builds the cross-chain Order from the route. +```ts const deltaAuction = await deltaSDK.submitDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // crosschain route, includes the bridge step + side: deltaPrice.side, owner: account, + // beneficiary: anotherAccount, // if need to send destToken to another account on destChain // permit: "0x1234...", // if signed a Permit1 or Permit2 TransferFrom for DeltaContract - srcToken: DAI_TOKEN, - destToken: USDC_TOKEN_ON_DEST_CHAIN, - srcAmount: amount, - destAmount: destAmountAfterSlippage, // minimum acceptable destAmount - destChainId: DEST_CHAIN_ID, // required to construct a Crosschain Order - beneficiary: anotherAccount, // if need to send destToken to another account on destChain - beneficiaryType: 'EOA', // whether the beneficiary on destChain is a smart contract - // bridge, // user-constructed Bridge object for Crosschain Orders + slippage: 50, // 50 bps = 0.5% }); ``` -To construct a Crosschain Delta Order it is required to either: -* provide both `beneficiary` address and `beneficiaryType` value, so that the `Order.bridge` can be constructed automatically by the SDK. -* construct Bridge object. Refer to [documentation](https://developers.velora.xyz/api/velora-api/velora-delta-api/build-a-delta-order-to-sign#sign-an-order-cross-chain) for how to do that. - -This is necessary because Across, the service facilitating crosschain bridging, has [special logic when it comes to transferring ETH and WETH](https://docs.across.to/introduction/technical-faq#what-is-the-behavior-of-eth-weth-in-transfers). +Across, the service facilitating crosschain bridging, has [special logic when it comes to transferring ETH and WETH](https://docs.across.to/introduction/technical-faq#what-is-the-behavior-of-eth-weth-in-transfers). Refer to the [Velora documentation](https://developers.velora.xyz/api/velora-api/velora-delta-api/build-a-delta-order-to-sign#sign-an-order-cross-chain) for more on cross-chain orders. -### 5. Wait for Delta Order execution +### 6. Wait for Delta Order execution ```ts -// poll if necessary -function isExecutedDeltaAuction( - auction: Omit, - waitForCrosschain = true // only consider executed when destChain work is done -) { - if (auction.status !== 'EXECUTED') return false; - - // crosschain Order is executed on destChain if bridgeStatus is filled - if (waitForCrosschain && auction.order.bridge.destinationChainId !== 0) { - return auction.bridgeStatus === 'filled'; - } - - return true; -} - -function fetchOrderPeriodically(auctionId: string) { +// poll if necessary — v2 status COMPLETED already accounts for the dest-chain bridge +function startStatusCheck(auctionId: string) { const intervalId = setInterval(async () => { - const auction = await simpleSDK.delta.getDeltaOrderById(auctionId); - console.log('checks: ', auction); // Handle or log the fetched auction as needed - - if (isExecutedDeltaAuction(auction)) { - clearInterval(intervalId); // Stop interval if completed + const auction = await deltaSDK.getDeltaOrderById(auctionId); + if (auction.status === 'COMPLETED') { + clearInterval(intervalId); // stop interval once completed console.log('Order completed'); } }, 3000); - console.log('Order Pending'); - // Return intervalId to enable clearing the interval if needed externally - return intervalId; -} - -function startStatusCheck(auctionId: string) { - const intervalId = fetchOrderPeriodically(auctionId); - setTimeout(() => clearInterval(intervalId), 60000 * 5); // Stop after 5 minutes + // stop polling after 5 minutes + setTimeout(() => clearInterval(intervalId), 60000 * 5); } startStatusCheck(deltaAuction.id); diff --git a/docs/EXTERNAL_ORDERS.md b/docs/EXTERNAL_ORDERS.md index f9cf20cf0..8688a2315 100644 --- a/docs/EXTERNAL_ORDERS.md +++ b/docs/EXTERNAL_ORDERS.md @@ -2,6 +2,8 @@ External orders delegate token handling to an external **handler** contract, enabling complex DeFi strategies that go beyond simple token swaps. The handler manages the actual token logic (e.g. Aave flash loan + collateral/debt swap), while the Delta protocol handles the auction, settlement, and signature verification. +As with all Delta v2 orders, the Order is **built by the server** from the route returned by `getDeltaPrice` — you sign the returned typed data and post it. + ### Handler Contract The handler contract must be deployed by the integrator and implement the `IExternalProtocolHandler` interface: @@ -25,12 +27,13 @@ The `data` field carries protocol-specific parameters (e.g. an Aave operation ty | Feature | Standard Order | External Order | |---|---|---| -| `beneficiary` field | yes | no (output goes to owner) | -| `bridge` field | yes | no | | `handler` field | no | yes (required) | | `data` field | no | yes (required) | +| `bridge` field | yes | no | | Cross-chain support | yes | no | +`beneficiary` is supported by both (defaults to `owner`). + --- @@ -64,7 +67,7 @@ const deltaPrice = await deltaSDK.getDeltaPrice({ userAddress: account, srcDecimals: 6, destDecimals: 18, - side: SwapSide.SELL, + side: 'SELL', }); ``` @@ -83,41 +86,37 @@ await aUSDC.approve(AAVE_HANDLER, amount); #### Using `submitExternalDeltaOrder` (recommended) -The simplest approach — builds, signs, and posts the order in one call: +The simplest approach — builds, signs, and posts the order in one call. Pass the quoted `route` + `side` and your `slippage`; the server computes the amounts. ```ts const deltaAuction = await deltaSDK.submitExternalDeltaOrder({ - deltaPrice, + route: deltaPrice.route, // or any deltaPrice.alternatives[i] + side: deltaPrice.side, owner: account, handler: AAVE_HANDLER, // your deployed handler contract data: '0x0000000000000000000000000000000000000000000000000000000000000000', // protocol-specific bytes - srcToken: USDC, - destToken: WETH, - srcAmount: amount, slippage: 50, // 0.5% in bps }); ``` #### Using individual steps -For more control, you can build, sign, and post separately: +For more control, you can build, sign, and post separately. A single `signDeltaOrder` signs every order family. ```ts -const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ - deltaPrice, +const built = await deltaSDK.buildExternalDeltaOrder({ + route: deltaPrice.route, + side: deltaPrice.side, owner: account, handler: AAVE_HANDLER, data: '0x0000000000000000000000000000000000000000000000000000000000000000', - srcToken: USDC, - destToken: WETH, - srcAmount: amount, slippage: 50, // 0.5% in bps }); -const signature = await deltaSDK.signExternalDeltaOrder(signableOrderData); +const signature = await deltaSDK.signDeltaOrder(built); const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: signableOrderData.data, + order: built.toSign.value, signature, }); ``` @@ -129,7 +128,7 @@ const intervalId = setInterval(async () => { const auction = await deltaSDK.getDeltaOrderById(deltaAuction.id); console.log('Status:', auction.status); - if (auction.status === 'EXECUTED' || auction.status === 'FAILED') { + if (auction.status === 'COMPLETED' || auction.status === 'FAILED') { clearInterval(intervalId); } }, 3000); @@ -141,9 +140,9 @@ const intervalId = setInterval(async () => { // fetch a specific external order const order = await deltaSDK.getDeltaOrderById(orderId); -// list external orders only -const orders = await deltaSDK.getDeltaOrders({ - owner: account, +// list external orders only (paginated — `data` holds the orders) +const { data: externalOrders } = await deltaSDK.getDeltaOrders({ + userAddress: account, onChainOrderType: 'ExternalOrder', }); ``` @@ -152,34 +151,27 @@ const orders = await deltaSDK.getDeltaOrders({ ## Specifying Amounts -There are two ways to specify amounts: +Amounts are derived server-side from the quoted `route`. Two ways to control them: -**With `slippage` (recommended)** — the SDK computes the slippage-adjusted amount from `deltaPrice` automatically: +**With `slippage` (recommended)** — the server computes the slippage-adjusted amount from the route: ```ts -// SELL: provide srcAmount + slippage → destAmount auto-computed await deltaSDK.buildExternalDeltaOrder({ + route: deltaPrice.route, + side: deltaPrice.side, // 'SELL' or 'BUY' // ... - srcAmount: amount, slippage: 50, // 0.5% in bps }); - -// BUY: provide destAmount + slippage → srcAmount auto-computed -await deltaSDK.buildExternalDeltaOrder({ - // ... - destAmount: amount, - slippage: 50, -}); ``` -**With explicit amounts** — you compute both amounts yourself: +**With an explicit `limitAmount`** — pin the limit yourself; the server uses it as the SELL `destAmount` (or BUY `srcAmount`) and `expectedAmount`: ```ts await deltaSDK.buildExternalDeltaOrder({ + route: deltaPrice.route, + side: deltaPrice.side, // ... - srcAmount: amount, - destAmount: destAmountAfterSlippage, - side: SwapSide.SELL, // or SwapSide.BUY + limitAmount: destAmountLimit, }); ``` @@ -187,31 +179,29 @@ await deltaSDK.buildExternalDeltaOrder({ ## Pre-signing External Orders -For smart contract wallets or other cases where EIP-712 signatures are not available, you can pre-sign an external order on-chain: +For smart contract wallets or other cases where EIP-712 signatures are not available, you can pre-sign an external order on-chain using the `orderHash` returned by the server build: ```ts -const signableOrderData = await deltaSDK.buildExternalDeltaOrder({ - deltaPrice, +const built = await deltaSDK.buildExternalDeltaOrder({ + route: deltaPrice.route, + side: deltaPrice.side, owner: account, handler: AAVE_HANDLER, data: '0x0000000000000000000000000000000000000000000000000000000000000000', - srcToken: USDC, - destToken: WETH, - srcAmount: amount, slippage: 50, }); -// on-chain pre-sign transaction -const tx = await deltaSDK.preSignExternalDeltaOrder(signableOrderData); +// on-chain pre-sign transaction (setPreSignature for the built order hash) +const tx = await deltaSDK.setExternalDeltaOrderPreSignature(built.orderHash); await tx.wait(); // post with empty signature const deltaAuction = await deltaSDK.postExternalDeltaOrder({ - order: signableOrderData.data, + order: built.toSign.value, signature: '0x', }); ``` --- -#### A more detailed example can be found in [examples/externalDelta](../src/examples/externalDelta.ts) +#### A more detailed example can be found in [examples/delta](../src/examples/delta.ts)