UNPKG

@lifi/compose-spec

Version:

Public wire-format types and schemas for Compose flows

80 lines (67 loc) 2 kB
export type Availability = "now" | "future"; export interface OutputAmount { readonly expected: bigint; readonly min?: bigint; } export type Resource = | { readonly kind: "native"; readonly chainId: number } | { readonly kind: "erc20"; readonly token: string; readonly chainId: number; }; export type SimulatedAmounts = { readonly amountOut: bigint; readonly amountOutMin: bigint; }; export type ProducedResource = Resource & { readonly availability: Availability; readonly simulated?: SimulatedAmounts; readonly owner: string; }; export const erc20Resource = (token: string, chainId: number): Resource => ({ kind: "erc20", token, chainId, }); export const nativeResource = (chainId: number): Resource => ({ kind: "native", chainId, }); export const isERC20Resource = ( r: Resource, ): r is Extract<Resource, { kind: "erc20" }> => r.kind === "erc20"; export const isNativeResource = ( r: Resource, ): r is Extract<Resource, { kind: "native" }> => r.kind === "native"; export const resourcesEqual = (a: Resource, b: Resource): boolean => { if (isNativeResource(a) && isNativeResource(b)) { return a.chainId === b.chainId; } if (isERC20Resource(a) && isERC20Resource(b)) { return ( a.chainId === b.chainId && a.token.toLowerCase() === b.token.toLowerCase() ); } return false; }; export const foldResource = <R>( r: Resource, cases: { readonly native: (chainId: number) => R; readonly erc20: (token: string, chainId: number) => R; }, ): R => r.kind === "native" ? cases.native(r.chainId) : cases.erc20(r.token, r.chainId); export const resourceKey = (r: Resource): string => foldResource(r, { native: (chainId) => `native:${chainId}`, erc20: (token, chainId) => `erc20:${token.toLowerCase()}:${chainId}`, }); export const erc20Token = (r: Resource): string => { if (r.kind !== "erc20") throw new Error(`Expected erc20 resource, got ${r.kind}`); return r.token; };