UNPKG

@lifi/compose-spec

Version:

Public wire-format types and schemas for Compose flows

135 lines (121 loc) 3.99 kB
import type { HandleInput, Ref, ResourceInput, SolType } from "./flowSchema.js"; import type { Port, ResourcePort, HandlePort, ResourceOutputPort, } from "./flow.js"; import type { Availability } from "./resource.js"; import { erc20Resource, nativeResource } from "./resource.js"; import type { HandleUnits } from "./zodSchemas.js"; export interface OpHandleOptions { readonly expose?: boolean; readonly units?: HandleUnits; } export const inputRef = (port: string): Ref => ({ $ref: `input.${port}` }); export const outputRef = (node: string, port: string): Ref => ({ $ref: `${node}.${port}`, }); /** Returns `{ [key]: value }` when `value` is not nullish, else `{}`. */ const optionalProp = <K extends string, V>( key: K, value: V | undefined | null ): Partial<Record<K, V>> => value != null ? ({ [key]: value } as Partial<Record<K, V>>) : {}; export const linear = <N extends string, T extends SolType>( name: N, type: T ): Port & { readonly name: N; readonly type: T; readonly mode: "linear" } => ({ name, type, mode: "linear", availability: "now" } as Port & { readonly name: N; readonly type: T; readonly mode: "linear"; }); export const copy = <N extends string, T extends SolType>( name: N, type: T ): Port & { readonly name: N; readonly type: T; readonly mode: "copy" } => ({ name, type, mode: "copy", availability: "now" } as Port & { readonly name: N; readonly type: T; readonly mode: "copy"; }); export const handle = <N extends string, T extends SolType>( name: N, type: T ): HandleInput & { readonly name: N; readonly type: T } => ({ name, type } as HandleInput & { readonly name: N; readonly type: T }); export const native = <N extends string>( name: N, chainId: number ): ResourceInput & { readonly name: N } => ({ name, resource: nativeResource(chainId) } as ResourceInput & { readonly name: N; }); export const erc20 = <N extends string>( name: N, token: string, chainId: number ): ResourceInput & { readonly name: N } => ({ name, resource: erc20Resource(token, chainId) } as ResourceInput & { readonly name: N; }); export const resource = <N extends string, Opt extends boolean = false>( name: N, accepts: "erc20" | "native" | "any", options?: { optional?: Opt } ): ResourcePort & { readonly name: N; readonly optional: Opt } => ({ kind: "resource", name, accepts, mode: "linear", ...optionalProp("optional", options?.optional), } as ResourcePort & { readonly name: N; readonly optional: Opt }); export const readResource = <N extends string>( name: N, accepts: "erc20" | "native" | "any" ): ResourcePort & { readonly name: N; readonly mode: "copy" } => ({ kind: "resource", name, accepts, mode: "copy" } as ResourcePort & { readonly name: N; readonly mode: "copy"; }); export const opHandle = <N extends string, T extends SolType>( name: N, type: T, options?: OpHandleOptions ): HandlePort & { readonly name: N; readonly type: T } => ({ kind: "handle", name, type, mode: "copy", ...optionalProp("expose", options?.expose), ...optionalProp("units", options?.units), } as HandlePort & { readonly name: N; readonly type: T; }); export const resourceOutput = <N extends string>( name: N, options?: | Availability | { availability?: Availability; providesMinimum?: boolean; omitIfZero?: boolean; deliveryAddressInput?: string; } ): ResourceOutputPort & { readonly name: N } => { const opts = typeof options === "string" ? { availability: options } : options; return { kind: "resource_output", name, mode: "linear", ...optionalProp("availability", opts?.availability), ...optionalProp("providesMinimum", opts?.providesMinimum), ...optionalProp("omitIfZero", opts?.omitIfZero), ...optionalProp("deliveryAddressInput", opts?.deliveryAddressInput), } as ResourceOutputPort & { readonly name: N }; };