What breaks if you do nothing
Nothing. Delta V1 (/delta/*) remains fully supported and shares on-chain contracts with V2. Your existing integration keeps working as-is.
Why migrate
V2 keeps the same on-chain settlement model. The main reason to migrate is that V2 is built crosschain-first: same-chain and crosschain intents share one route model, so you quote the source chain, optionally adddestChainId, and pass the returned route into build unchanged.
That crosschain-first model also cleans up the protocol surface:
- Crosschain is native to pricing.
GET /v2/quoteorGET /v2/delta/pricesreturns a recommendedroutewithroute.bridgepopulated for crosschain, plusalternativeswhen other bridge routes are available. - Orders are built server-side.
POST /v2/delta/orders/buildreturns EIP-712 typed data ready to sign, and you stop composingdomain,types, andvalueon the client. - Pricing is route-based. The route replaces the
bridge/bridgeInfo/availableBridgestriple V1 returns. - Limit orders use the same build flow. Add
limitAmounttoPOST /v2/delta/orders/build, then submit the signed order withtype: "LIMIT". - Order history is paginated.
GET /v2/delta/ordersreturns{ data, total, page, limit, hasMore }where V1 returns a flat array with no total. - Status is a single field. Twelve values (
PENDING,AWAITING_SIGNATURE,ACTIVE,SUSPENDED,CANCELLING,BRIDGING,COMPLETED,FAILED,EXPIRED,REFUNDING,CANCELLED,REFUNDED) replace V1’sstatus+bridgeStatuspair. - Partner fees resolve on the server. Pass
partner/partnerAddress/partnerFeeBpsdirectly on every call; the separateGET /prices/partnerfee/{chainId}round-trip goes away. - The
hmacis gone. V2 doesn’t sign the price payload, so there’s no opaque blob to thread from/pricesinto/orders/build.
Endpoint mapping
| V1 | V2 | Notes |
|---|---|---|
GET /delta/prices | GET /v2/delta/prices | Response carries route + alternatives; price.hmac removed |
GET /delta/prices/bridge-info | GET /v2/delta/prices/bridge-routes | Flat routes[] array instead of nested srcChainId → destChainId → tokens[] map |
GET /delta/prices/bridge-protocols | GET /v2/delta/prices/bridge-protocols | Same shape |
GET /delta/prices/strategies/{chainId} | GET /v2/delta/prices/strategies/{chainId} | Same shape |
GET /delta/prices/is-token-supported | GET /v2/delta/prices/is-token-supported | Same shape |
GET /prices/partnerfee/{chainId} | Not needed | Pass partner / partnerAddress / partnerFeeBps raw on every V2 call |
POST /delta/orders/build | POST /v2/delta/orders/build | Different body — pass route (not price + hmac); response wraps typed data in toSign |
POST /delta/orders | POST /v2/delta/orders | Submit order: built.toSign.value instead of data from V1 build |
POST /delta/orders/cancel | POST /v2/delta/orders/cancel | Same shape |
GET /delta/orders | GET /v2/delta/orders | Wraps array in { data, total, page, limit, hasMore } |
GET /delta/orders/{orderId} | GET /v2/delta/orders/{orderId} | New response shape — input / output carry expected + executed amounts |
GET /delta/orders/hash/{hash} | GET /v2/delta/orders/hash/{hash} | Same as above |
GET /delta/orders/fillablebalance/... | GET /v2/delta/orders/fillablebalance/... | Same shape |
GET /delta/agents/list/{chainId} | GET /v2/delta/agents/list/{chainId} | Same shape |
GET /quote (mode=ALL) | GET /v2/quote | Delta-or-Market fallback still exists; branch on top-level delta or market |
Steps
1. Pricing
V1 returns a flat price object with a server-signedhmac. V2 returns a structured route plus alternatives. You can read that Delta route directly from GET /v2/delta/prices, or from the delta block of GET /v2/quote?mode=DELTA.
/v2/quote:
mode=ALL, V2 returns one path for you to handle: a top-level delta block when Delta can price the trade, or a top-level market block when it falls back to Market. Do not expect both blocks in one response.
V1 response:
price.hmacis gone; don’t thread it into/orders/build.deltaAddressmoved tospender. Approvespenderas the ERC-20 spender (the on-chain Delta contract address itself is unchanged).- Bridge detection changed. V1 used
bridge.destinationChainId !== 0; V2 setsroute.bridgetonullfor same-chain and populates it for crosschain. Readroute.origin.input.token.chainIdvsroute.destination.output.token.chainIdif you need a direct check.
2. Build
V1 takes the price object + hmac. V2 takes the route plus order params on top. Pass the route fromGET /v2/delta/prices, or delta.route from GET /v2/quote, without editing it.
The chain ID is no longer part of the build request; V2 derives it from the route.
V1 returned { data, orderHash, domain, types }, where data was the on-chain Order struct.
V2 returns { toSign: { domain, types, value }, orderHash }: value is the on-chain Order struct, wrapped one level deeper.
3. Sign
The EIP-712 domain (name: "Portikus", version: "2.0.0", chainId, verifyingContract) is unchanged. The signature you compute over V2’s toSign is the same string V1 would produce over its data/domain/types triple.
4. Submit
V1 took{ order, signature, partner, ... }. V2 is the same shape; only the source of order changes.
referrerAddress differently: same field, same semantics.
5. Limit orders
V1 limit-order code often had a separate builder path. In V2, a limit order is a Delta order with a target-price constraint, so you use the samePOST /v2/delta/orders/build endpoint and add limitAmount.
limitAmount is the minimum destination amount the user accepts. For BUY orders, it is the maximum source amount the user is willing to spend. The response is still { toSign, orderHash }; after the user signs, submit toSign.value with type: "LIMIT":
6. Poll for status
V1 status (DeltaAuctionStatus) splits into status + bridgeStatus. V2 collapses both into one status field.
V1 (status + bridgeStatus) | V2 (status) |
|---|---|
NOT_STARTED | PENDING |
AWAITING_PRE_SIGNATURE | AWAITING_SIGNATURE |
RUNNING, EXECUTING | ACTIVE |
| Suspension states (insufficient balance/allowance) | SUSPENDED |
CANCELLING | CANCELLING |
EXECUTED + bridgeStatus: PENDING | BRIDGING |
EXECUTED + (same-chain OR bridgeStatus: FILLED) | COMPLETED |
FAILED, INVALIDATED | FAILED |
EXPIRED (or bridgeStatus: EXPIRED) | EXPIRED |
EXECUTED + bridgeStatus: REFUNDING | REFUNDING |
CANCELLED | CANCELLED |
REFUNDED (or bridgeStatus: REFUNDED) | REFUNDED |
REFUNDING means the bridge leg failed or expired and Velora is still polling for the actual refund transaction. REFUNDED means the refund is complete. V1 order endpoints temporarily map bridgeStatus: REFUNDING back to REFUNDED for compatibility, so migrate status handling before relying on that distinction.
The V2 response also restructures order details: input and output each carry { chainId, token, amount } (SELL: input has amount, output has expectedAmount + executedAmount; BUY: vice versa). V1 returned order.srcToken / order.destToken plus a separate transactions[] array. V2 keeps both, but the headline numbers move to input / output.
For crosschain refunds, V2 also adds top-level refunds[] to the order response. Each verified refund item has:
refunds[] can stay empty while the order is REFUNDING, and it can also be empty for bridge-provider failure modes that do not emit source-chain token refund metadata.
7. List orders
limit”.
8. Cancel
No semantic change: same path under/v2, same request body.
9. Partner fee
V1: integrators calledGET /prices/partnerfee/{chainId}?partner=... to look up the registered config, then encoded it into the order locally.
V2: just pass partner on every call (/v2/delta/prices, /v2/delta/orders/build, /v2/delta/orders). The server resolves the registered config, validates the fee, and encodes it into the on-chain order. To override per call, pass partnerAddress and partnerFeeBps (and/or partnerTakesSurplus) on the same call.
GET /prices/partnerfee/{chainId} still exists; keep using it if you need the resolved config for your UI (e.g., to show “0.25% fee” alongside the quote).
Breaking changes you might miss
price.hmacis gone in V2. Existing code that re-attacheshmacto the build payload will fail validation.- The replacement for V1
GET /quoteisGET /v2/quote, not “no quote endpoint.” Withmode=ALL, branch on top-leveldeltaormarket. - Limit orders move onto the standard V2 build path. Add
limitAmounttoPOST /v2/delta/orders/build, then submit withtype: "LIMIT". - The
bridge.destinationChainId !== 0check breaks. V2 setsroute.bridge = nullfor same-chain; the V1 sentinel is no longer present in V2 responses. bridge-infochanged shape, from a nested object to a flatroutes[]array, and the replacement endpoint is namedbridge-routes.- The status enum changed, so your status-handling code needs the mapping table above. Don’t rely on
EXECUTEDalone: V2 reportsCOMPLETEDfor executed-and-finalized orders,BRIDGINGwhile the destination leg is still pending, andREFUNDINGwhile a failed bridge leg is waiting for a verified refund transaction. REFUNDEDis now distinct fromREFUNDINGin V2. If your V1 UI showed any refund state as final, add an in-progress state before moving users to V2.- The order list response changed from
Order[]to{ data: Order[], total, page, limit, hasMore }. Code that doesorders.lengthororders.map(...)on the response needs to unwrap.datafirst.
End-state check
GET /v2/quote?mode=DELTAorGET /v2/delta/pricesreturns arouteand a non-emptyspender.POST /v2/delta/orders/buildreturns{ toSign, orderHash }.- The signature your wallet produces over
toSignis accepted byPOST /v2/delta/orders(status200, response carries the new order shape withidandstatus: "PENDING"). GET /v2/delta/orders/{id}polls throughACTIVE→COMPLETED(orBRIDGING→COMPLETEDfor crosschain). If a bridge refund happens, your UI can showREFUNDINGuntil the order reachesREFUNDEDand any verifiedrefunds[]entries appear.- A limit-order build with
limitAmountreturns{ toSign, orderHash }, and the signed order submits withtype: "LIMIT". grep -r "partnerfee\|/delta/prices\b\|/delta/orders\b" your-codebase/: every hit is intentional (e.g.,/prices/partnerfeefor UI lookup;/delta/ordersonly if you intentionally stayed on V1).
Related pages
- Delta V2 API overview — the recommended surface.
- SDK → Migrate from V1 to V2 — same migration at the TypeScript SDK level.
- Crosschain Delta swaps — how
destChainId, bridge routes, and crosschain status work. - Limit order API integration — build with
limitAmount, then submit withtype: "LIMIT".