@lifi/compose-spec
Version:
Public wire-format types and schemas for Compose flows
133 lines (118 loc) • 4.95 kB
text/typescript
import type { VerificationDescriptor } from './descriptor.js';
import type { InputSpec, Precondition } from './flow.js';
import type { Flow } from './flowSchema.js';
import type { ProducedResource } from './resource.js';
import type { ContinuationPlanWire, Phase1ArtifactWire } from './zodSchemas.js';
export type SimulationPolicy = 'strict' | 'allow-revert';
/**
* Destination for sweeping proxy-held terminal resources after execution.
* Either a literal EVM address or a `{ $ref }` context reference
* (e.g. `{ $ref: "context.sender" }`).
*/
export type SweepTo = string | { readonly $ref: string };
export interface ComposeRun {
readonly inputs: Record<string, InputSpec>;
readonly preconditions?: readonly Precondition[];
readonly signer: string;
readonly assumptions?: Record<string, bigint>;
readonly referrer?: string;
readonly integratorFeeBps?: number;
readonly maxPriceImpactBps?: number;
readonly sweepTo?: SweepTo;
readonly simulationPolicy?: SimulationPolicy;
readonly checkOnChainAllowances?: boolean;
}
export interface ComposeCompileRequest {
readonly flow: Flow;
readonly run: ComposeRun;
}
export interface PriceImpact {
readonly inputValueUsd: number;
readonly outputValueUsd: number;
readonly impactBps: number;
readonly unpricedInputs: readonly string[];
readonly unpricedOutputs: readonly string[];
}
export interface ApprovalEntry {
readonly token: string;
readonly spender: string;
readonly amount: string;
readonly transactionRequest: {
readonly to: string;
readonly data: string;
readonly value: '0';
};
}
export interface SimulationRevert {
readonly code: number;
readonly rawErrorBytes: string;
readonly decodeResult?: {
readonly errorCandidates?: readonly {
readonly decodedErrorSignature: string;
readonly decodedParams: readonly string[];
}[];
readonly error?: string;
};
}
export interface ComposeTransactionRequest {
readonly to: string;
readonly data: string;
readonly value: string;
readonly gasLimit?: string;
}
// A single continuation pointer: the node whose `future` output is awaited and
// the downstream flow that consumes its proceeds. A flow can declare several,
// carried in the response as `continuations`.
export interface ComposeContinuation {
readonly awaits: string;
readonly flowId: string;
}
// Continuation fields shared by the success and partial-error responses, so the
// two shapes cannot drift. `phase1ByNode` / `continuationPlans` reuse the
// Zod-inferred wire types from `zodSchemas.ts`, pinning these SDK-facing types
// to the server contract rather than hand-transcribing them.
interface ComposeContinuationData {
// One pointer per `continuation.settle` branch (a flow can fork into several).
readonly continuations?: readonly ComposeContinuation[];
// Phase-1 action to sign/fund now, keyed by settle node. Absent for an atomic flow.
readonly phase1ByNode?: Record<string, Phase1ArtifactWire>;
// Self-serve second leg to re-submit later, keyed by settle node. Present only
// for providers that hand the next leg back to the caller (manual-relay).
readonly continuationPlans?: Record<string, ContinuationPlanWire>;
}
// One funding leg the compiled fill consumes: the resource input's token
// (native → zero address) and its statically resolved amount as a decimal
// string (verified continuations, plan GD-8, seam C5).
export interface SpendEntry {
readonly token: string;
readonly amount: string;
}
export interface ComposeCompileSuccessData extends ComposeContinuationData {
readonly producedResources: Record<string, ProducedResource>;
readonly transactionRequest: ComposeTransactionRequest;
readonly userProxy: string;
readonly priceImpact?: PriceImpact;
readonly approvals?: readonly ApprovalEntry[];
// GD-8 settlement-fill fields (seam C5), additive on every success response:
// `spends` (the exact token amounts the fill consumes) and `quote.validUntilMs`
// (fill freshness bound — earliest prepared-node `expiresAtMs`, else a
// far-future sentinel).
// `verificationDescriptor` (the echo) is present only when the flow carried a
// `continuation.commitment` node.
readonly spends?: readonly SpendEntry[];
readonly quote?: { readonly validUntilMs: number };
readonly verificationDescriptor?: VerificationDescriptor;
}
export interface ComposeCompilePartialData extends ComposeContinuationData {
readonly producedResources: Record<string, ProducedResource>;
readonly transactionRequest: ComposeTransactionRequest;
readonly userProxy: string;
readonly simulationRevert: SimulationRevert;
readonly approvals?: readonly ApprovalEntry[];
}
export type ComposeCompileResult =
| (ComposeCompileSuccessData & { readonly status: 'success' })
| (ComposeCompilePartialData & {
readonly status: 'partial';
readonly error: { readonly kind: string; readonly message: string };
});