src is the domain layer for orders and intents.
It owns:
- Order data models and type guards.
- Intent creation and conversion logic.
- Order id and hashing logic for standard + multichain flows.
- Core validation/parsing used by higher-level libraries/screens.
- Dependency-injected domain behavior (for chain/oracle policy), without importing app config.
It does not own:
- UI behavior from app workspaces (
app/*). - External orchestration wrappers that live outside this package (except core parsing helpers in
api/).
npm install @lifi/lintentRuntime target: Node.js 20+.
types.ts- Canonical types such as
StandardOrder,MultichainOrder, andOrderContainer. - Core token model is chain-id based (
token.chainId), not chain-name based.
- Canonical types such as
deps.ts- Minimal dependency interfaces consumed by core constructors/functions.
intent/create.ts: High-levelIntentbuilder.fromOrder.ts:orderToIntent(...)andisStandardOrder(...).standard.ts/multichain.ts: Concrete intent implementations and order-id derivation.compact/*: Compact conversions/signing/claims helpers used by intent flows.
orderLib.ts- Validation helpers (
validateOrder...) and output encoding/hash helpers. - Multi-argument helpers accept object params, e.g.
validateOrderWithReason({ order, deps }).
- Validation helpers (
api/intentApi.ts- Normalization/parsing for intent-api payloads.
typedMessage.ts- EIP-712 type definitions and precomputed type hashes used in compact flows.
helpers/andcompact/- Shared low-level helpers (conversions and compact lock/id utilities).
Most contributors start with intent/index.ts:
orderToIntent(...)isStandardOrder(...)StandardOrderIntentMultichainOrderIntentcomputeStandardOrderId(...)computeMultichainEscrowOrderId(...)computeMultichainCompactOrderId(...)hashMultichainInputs(...)
OrderContainer wraps:
inputSettlerorder(StandardOrder | MultichainOrder)- sponsor/allocator signatures
Use isStandardOrder(...) as the canonical discriminator for branching between single-chain and multichain order logic.
Typical contributor path:
- Build an intent with
Intentinintent/create.tsand injectIntentDeps. - Convert/hydrate with
orderToIntent(...)fromintent/fromOrder.ts. - Compute
orderId()and chain-specific behavior throughStandardOrderIntentorMultichainOrderIntent.
Example: create/convert and derive order id.
import { orderToIntent } from "@lifi/lintent";
import type { OrderContainer } from "@lifi/lintent";
function getOrderId(orderContainer: OrderContainer): `0x${string}` {
return orderToIntent(orderContainer).orderId();
}Example: branch behavior by order type during creation/execution logic.
import { isStandardOrder, orderToIntent } from "@lifi/lintent";
import type { OrderContainer } from "@lifi/lintent";
function getInputCount(orderContainer: OrderContainer): number {
if (isStandardOrder(orderContainer.order))
return orderContainer.order.inputs.length;
return orderContainer.order.inputs.reduce(
(sum, v) => sum + v.inputs.length,
0,
);
}
function getInputChains(orderContainer: OrderContainer): bigint[] {
return orderToIntent(orderContainer).inputChains();
}typedMessage.ts defines EIP-712 type structures and verifies that computed type hashes match expected on-chain constants. Any change here can break compact claim/signature compatibility.
When touching compact hashing or typed message definitions:
- Keep encodings aligned with contracts.
- Treat hash constant changes as protocol-level changes.
orderLib.tsvalidateOrderWithReason(...)validateOrderContainerWithReason(...)
api/intentApi.tsparseOrderStatusPayload(...)
These utilities are the core gate for normalizing and validating inbound order data before execution paths consume it.
- Core has no direct imports from app config/util modules.
- Dependencies are passed in scope at creation time (constructor/function), never via global mutable runtime.
- Keep dependencies minimal:
IntentreceivesIntentDeps.- Standard order validation receives
StandardOrderValidationDeps({ order, deps }). - Container validation receives
OrderContainerValidationDeps({ orderContainer, deps }), addinginputSettlersfor compact input-settler policy. - Core-internal protocol constants live in
constants.ts.
- Unit tests are colocated with features in
src/**/<feature>.spec.ts. - Every non-
index.tsruntime module insrc/must have a sibling.spec.ts. index.tsbarrel files are excluded from that requirement.- Type-only modules (for example
src/types/**andsrc/intent/types.ts) should not have individual.spec.tscoverage. - Rely on TypeScript checks and behavior tests that consume those types.
- Integration tests live under
tests/. - Bare spec files in
src/(no sibling source module) are not allowed.
- Use
isStandardOrder(...)for order branching, not ad-hoc property checks. - Keep hashing/encoding behavior stable unless you are intentionally changing protocol semantics.
- Keep core APIs chain-id based. Map app chain names to ids at app boundaries.
- Update/add tests when changing order construction, parsing, or hashing behavior.
- Run
bun run checkand relevant unit tests before merging.
src/types/index.tssrc/intent/index.tssrc/intent/create.tssrc/intent/fromOrder.tssrc/intent/standard.tssrc/intent/multichain.tssrc/output.tssrc/validation.tssrc/api/intentApi.tssrc/typedMessage.ts