Skip to content
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lifi/types",
"version": "17.83.0",
"version": "17.84.0-alpha.0",
"description": "Types for the LI.FI stack",
"keywords": [
"sdk",
Expand Down
58 changes: 54 additions & 4 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,54 @@ export interface RouteOptionsBase {
executionType?: ExecutionType
}

/**
* A single entry in the `distributionFees` request parameter.
*
* `distributionFees` lets a verified integrator carve additional on-chain
* recipients out of their integrator-fee pool, in parallel with the
* optional `intermediary` carve. Each entry produces an extra fee transfer
* to `receiver` proportional to `percentage` of the source amount, executed
* via the LI.FI FeeForwarder contract. Partner-provided receivers are
* sanction-screened at quote time (warn-log on failure, see backend logs).
*
* Constraints (enforced server-side, subject to change without a types
* major bump — read the current values from the API error responses if
* you need them programmatically):
* - `percentage` is a decimal proportion ( `0.001` = 0.1% ), exclusive of 0
* and bounded by a per-request cap. The aggregate fee (integrator `fee`
* plus all `distributionFees[].percentage`) is also capped by the
* backend; exceeding either limit yields a `ValidationError`.
* - At most ~10 entries per request.
* - `receiver` must be a non-zero EVM address (`0x` followed by 40 hex
* characters). Non-EVM receivers are not yet supported.
*
* Only meaningful when `integrator` is set and has an active fee agreement.
*/
export interface DistributionFee {
/** Fraction of the swap input taken as a distribution fee (e.g. `0.001` = 0.1%). */
percentage: number
/** On-chain EVM recipient address; must be a non-zero `0x`-prefixed hex address. */
receiver: string
}

export interface RouteOptions extends RouteOptionsBase {
/** Should contain the identifier of the integrator. Usually, it's dApp/company name. */
integrator?: string

/** Optional intermediary identifier for multi-party fee splitting.
* Requires a registered integrator with a `fee` and a configured intermediary share on the backend. */
intermediary?: string

/**
* Partner-provided fee distribution recipients. Each entry adds an
* independent on-chain transfer to `receiver` in proportion to
* `percentage` of the swap input, in parallel with the integrator and
* (optional) intermediary carves. Requires a verified `integrator` with
* an active fee agreement.
* @see {@link DistributionFee} for per-entry constraints.
*/
distributionFees?: DistributionFee[]

/** Integrators can set a wallet address as a referrer to track them */
referrer?: string

Expand Down Expand Up @@ -368,6 +412,11 @@ export interface QuoteRequest extends ToolConfiguration, TimingStrings {
order?: Order
slippage?: number | string
integrator?: string
/** Optional intermediary identifier for multi-party fee splitting.
* Requires a registered integrator with a `fee` and a configured intermediary share on the backend. */
intermediary?: string
/** @see {@link RouteOptions.distributionFees} and {@link DistributionFee} */
distributionFees?: DistributionFee[]
referrer?: string
fee?: number | string

Expand Down Expand Up @@ -406,8 +455,10 @@ export interface QuoteRequest extends ToolConfiguration, TimingStrings {
insurance?: boolean
}

export interface QuoteToAmountRequest
extends Omit<QuoteRequest, 'fromAmount' | 'fromAmountForGas' | 'insurance'> {
export interface QuoteToAmountRequest extends Omit<
QuoteRequest,
'fromAmount' | 'fromAmountForGas' | 'insurance'
> {
toAmount: string
}

Expand Down Expand Up @@ -850,8 +901,7 @@ export type TransferSummary = {
totalReceivedAmount: number
}

export interface TransferSummariesResponse
extends PaginatedResponse<TransferSummary> {}
export interface TransferSummariesResponse extends PaginatedResponse<TransferSummary> {}

export interface GetStepRequest {
stepId: string
Expand Down
77 changes: 77 additions & 0 deletions src/step.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,78 @@ import type {
} from './api.js'
import type { Token } from './tokens/index.js'

/**
* How a fee was calculated / the role of the recipient in the split.
*
* - `FIXED` — a fixed LI.FI cut applied alongside the integrator's own fee.
* - `SHARED` — a single shared pool divided between LI.FI and the integrator.
* - `DYNAMIC` — fee resolved at quote time from configured rules (e.g. dynamic
* stablecoin pricing).
* - `INTERMEDIARY` — a third-party recipient that carves a configured share
* from the integrator pool (e.g. a widget or aggregator).
* - `DISTRIBUTION` — a partner-specified extra recipient added in parallel to
* the integrator/intermediary split via the `distributionFees` request param.
*
* The union is expected to grow over time. When pattern-matching with a
* `switch`, always include a `default` branch so adding a new value remains
* a non-breaking minor for consumers.
*/
export type FeeSplitType =
| 'FIXED'
| 'SHARED'
| 'DYNAMIC'
| 'INTERMEDIARY'
| 'DISTRIBUTION'

export interface FeeRecipient {
/** Recipient identifier. Polymorphic — interpret in conjunction with `type`:
* - `'lifi'` for the LI.FI platform recipient,
* - the integrator id (e.g. `'jumper'`) for the integrator recipient,
* - the intermediary id (e.g. `'mesh'`) when `type === 'INTERMEDIARY'`,
* - the recipient wallet address when `type === 'DISTRIBUTION'`.
*
* Do not display this value directly in user-facing UI without
* `type`-aware formatting — for `DISTRIBUTION` rows the value is a
* raw hex address. */
name: string

/** Absolute fee amount, a big number in source token base units (string-encoded). */
fee: string

/** Fee calculation type. Absent when not statically determinable (e.g.
* an integrator entry whose `feeType` could not be resolved from the
* matching planned fee cost). Consumers should null-check before reading. */
type?: FeeSplitType

/** Recipient wallet address on the source chain. */
walletAddress?: string
}

export interface FeeSplit {
/** LI.FI's slice of THIS `FeeCost.amount`. */
lifiFee: string

/** The integrator's slice of THIS `FeeCost.amount` — the integrator's
* portion only, NOT including any intermediary or distribution amounts. */
integratorFee: string

/** The intermediary's slice of THIS `FeeCost.amount` when an intermediary
* participates in the split. Absent otherwise. */
intermediaryFee?: string

/** Per-recipient breakdown of THIS `FeeCost.amount`. Source of truth for
* new consumers — the aggregate fields above are disjoint slices kept
* for backward compatibility with 2-recipient consumers.
*
* Note: partner-specified distribution recipients are emitted as
* separate `FeeCost` entries (one per receiver, `name: "Fee Forward"`)
* at quote/route estimation time. At status-response time the same
* recipients may appear merged on the integrator's `FeeCost` for
* compactness. Iterate `estimate.feeCosts[]` to discover all
* recipients across both shapes. */
recipients?: FeeRecipient[]
}

export interface FeeCost {
name: string
description: string
Expand All @@ -14,6 +86,8 @@ export interface FeeCost {
amount: string
amountUSD: string
included: boolean

feeSplit?: FeeSplit
}

export interface GasCost {
Expand Down Expand Up @@ -101,6 +175,9 @@ export interface StepBase {
tool: StepTool
toolDetails: StepToolDetails
integrator?: string
/** Intermediary identifier set when the route was generated with a multi-party fee split.
* Threaded through to /stepTransaction so the same split can be reproduced at tx-generation time. */
intermediary?: string
referrer?: string
action: Action
estimate?: Estimate
Expand Down
Loading