UNPKG

@lifi/compose-spec

Version:

Public wire-format types and schemas for Compose flows

128 lines (122 loc) 5.57 kB
/** * Canonical request types for the `POST /compose/route` convenience endpoint. * Amounts accept `bigint | string` for authoring convenience; the JSON wire * format is always a decimal string, which the SDK serialises for you. * * `/compose/route` trades authoring power for brevity. Instead of a full flow * document it takes a single from/to token pair; the server builds a * `lifi.zap` flow with a `directDeposit` input on the caller's behalf and runs * it through the same compile pipeline as `POST /compose`. As of today the flow * it builds is a single zap step — one edge of the server's routing catalog — * and it is meant to author richer flows later, which this request shape is * deliberately agnostic about. Its response body is byte-identical to that of * `POST /compose` — the enveloped `ComposeCompileSuccessData` on HTTP 200 and * `ComposeCompilePartialData` on HTTP 206 — so this file declares only the * request shape and reuses `ComposeCompileResult` from `./compile.js` for the * result. * * These are the single source of truth for the request shape, hand-authored * here for the same reason as `./compile.ts` and `./simulate.ts` rather than * derived from the validating schema: that schema is the Zod one in * `@lifi/api-schemas` (`src/routes/composeRoute.ts`), a package that depends on * this one, so importing its inferred types here would invert the dependency — * and the public SDK ships this package as its only peer dependency, never the * server's schema package. The two definitions are held in lockstep by a * compile-time conformance assertion * (`api-schemas/src/routes/composeRoute.typecheck.ts`), which fails the build * if either side drifts. */ import type { SimulationPolicy, SweepTo } from './compile.js'; /** * Spend an exact amount of `fromToken`. * * `amount` is in the token's smallest unit. Accepts `bigint | string`; the wire * format is a non-negative decimal string. */ export interface RouteAmountExact { readonly type: 'EXACT'; readonly amount: bigint | string; } /** * Spend the signer's entire `fromToken` balance, whatever it is at execution * time. * * The on-chain amount is resolved by a deposit-all materialiser, so it is not * known when the route is compiled. `simAmount` is the stand-in the server * quotes and simulates against — make it a realistic estimate of the balance, * because it determines the quote and the derived preconditions, not the amount * actually moved. Accepts `bigint | string`; the wire format is a non-negative * decimal string. * * Not supported when `fromToken` is the chain's native sentinel: a gas coin * arrives via `msg.value`, so there is no on-chain balance to sweep, and the * server rejects the combination with a `validation_error`. Use * {@link RouteAmountExact} for native inputs. */ export interface RouteAmountAll { readonly type: 'ALL'; readonly simAmount: bigint | string; } /** * How much of `fromToken` a route spends. Two variants, discriminated by * `type`. */ export type RouteAmount = RouteAmountExact | RouteAmountAll; /** Request body for `POST /compose/route`. */ export interface ComposeRouteRequest { /** EVM chain id. Both tokens must live on this chain — routes are same-chain. */ readonly chainId: number; /** * Token to spend. Use the chain's native sentinel address for the gas coin * (the zero address on EVM-native chains). */ readonly fromToken: string; /** Token to receive. */ readonly toToken: string; /** How much of `fromToken` to spend — an exact amount or the whole balance. */ readonly amount: RouteAmount; /** Address that funds the route and, by default, owns its output. */ readonly signer: string; /** * Slippage tolerance in basis points, applied as a guard on the route's * output. Range 0–10000. Defaults to `100` (1%) server-side when omitted. */ readonly slippageBps?: number; /** * Reject the route when its quoted price impact exceeds this many basis * points. Range 0–10000. Omitted ⇒ no price-impact guard is installed. */ readonly maxPriceImpactBps?: number; /** * Integrator fee in basis points, taken from the input amount. Range 0–9000. * Defaults to `0` server-side when omitted. A non-zero value requires an * integration-scoped API key; the server rejects it otherwise. */ readonly integratorFeeBps?: number; /** Opaque referrer tag forwarded to the underlying quote provider. */ readonly referrer?: string; /** * Owner of the route's output; defaults to `signer`. Routes whose protocol * mints to a named receiver (surfaced as `recipient: 'required'` by * `GET /compose/zap-packs`) bind this address at mint time rather than * transferring afterwards. Accepts an address or `{ $ref: 'context.sender' }`; * `{ $ref: 'context.executionAddress' }` is rejected. */ readonly sweepTo?: SweepTo; /** * `'strict'` (the default) fails the request when simulation detects a * revert; `'allow-revert'` returns a partial result with revert diagnostics * instead. */ readonly simulationPolicy?: SimulationPolicy; /** * Also simulate the final user-facing transaction after the structured * simulation succeeds. Reverts honour `simulationPolicy`. Defaults to `false`. */ readonly simulateUserProgram?: boolean; /** * Filter the returned `approvals` against current on-chain allowances, * omitting approvals that are already sufficient. Defaults to `false`. */ readonly checkOnChainAllowances?: boolean; }