UNPKG

@lifi/compose-spec

Version:

Public wire-format types and schemas for Compose flows

864 lines (848 loc) 24.9 kB
// src/flowSchema.ts import { Schema } from "effect"; // src/chainCapabilities.ts var EVM_NATIVE_SENTINEL = ( // eslint-disable-next-line @lifi/prefer-utils-constants -- compose-spec is the wire-format leaf and must not import @lifi/utils (enforced by scripts/check-compose-boundaries.mjs); the literal is intentional here "0x0000000000000000000000000000000000000000" ); var isNativeSentinel = (address) => address.toLowerCase() === EVM_NATIVE_SENTINEL.toLowerCase(); var TEMPO_CHAIN_ID = 4217; var TEMPO_NATIVE_ERC20 = { token: "0x20C0000000000000000000000000000000000000", symbol: "pathUSD", decimals: 6 }; var REGISTRY = /* @__PURE__ */ new Map([ [ TEMPO_CHAIN_ID, { kind: "as-erc20", chainId: TEMPO_CHAIN_ID, nativeErc20: TEMPO_NATIVE_ERC20 } ] ]); var getChainCapabilities = (chainId) => REGISTRY.get(chainId) ?? { kind: "evm-native", chainId }; var isAsErc20Chain = (chainId) => getChainCapabilities(chainId).kind === "as-erc20"; var canonicalNativeAddress = (chainId) => { const caps = getChainCapabilities(chainId); return caps.kind === "as-erc20" ? caps.nativeErc20.token : EVM_NATIVE_SENTINEL; }; var isNativeAddressForChain = (chainId, address) => { const caps = getChainCapabilities(chainId); const target = caps.kind === "as-erc20" ? caps.nativeErc20.token : EVM_NATIVE_SENTINEL; return address.toLowerCase() === target.toLowerCase(); }; var isMsgValueNative = (chainId, address) => !isAsErc20Chain(chainId) && isNativeSentinel(address); var normalizeResource = (r) => { if (r.kind !== "native") return r; const caps = getChainCapabilities(r.chainId); if (caps.kind !== "as-erc20") return r; return { kind: "erc20", chainId: r.chainId, token: caps.nativeErc20.token }; }; var normalizeNativeTokenAddress = (token, chainId) => isAsErc20Chain(chainId) && isNativeSentinel(token) ? canonicalNativeAddress(chainId) : token; // src/flowSchema.ts var SolTypeSchema = Schema.Literal( "uint8", "uint16", "uint32", "uint64", "uint128", "uint256", "int128", "int256", "address", "bool", "bytes", "bytes4", "bytes32", "string" ); var ChainIdSchema = Schema.Number.pipe( Schema.int(), Schema.positive() ); var RawResourceSchema = Schema.Union( Schema.Struct({ kind: Schema.Literal("native"), chainId: ChainIdSchema }), Schema.Struct({ kind: Schema.Literal("erc20"), token: Schema.String, chainId: ChainIdSchema }) ); var ResourceSchema = Schema.transform( RawResourceSchema, Schema.typeSchema(RawResourceSchema), { strict: true, decode: (raw) => normalizeResource(raw), encode: (resource2) => resource2 } ); var ResourceInputSchema = Schema.Struct({ name: Schema.String, resource: ResourceSchema }); var HandleInputSchema = Schema.Struct({ name: Schema.String, type: SolTypeSchema }); var FlowInputSchema = Schema.Union( ResourceInputSchema, HandleInputSchema ); var RefSchema = Schema.Struct({ $ref: Schema.String.pipe( Schema.filter((s) => s.indexOf(".") > 0, { message: () => '$ref must be a dotpath like "input.name" or "nodeId.port"' }) ) }); var LiteralBindingSchema = Schema.Struct({ kind: SolTypeSchema, value: Schema.String }); var BindValueSchema = Schema.Union(RefSchema, LiteralBindingSchema); var AppliedGuardSchema = Schema.Struct( { kind: Schema.String }, { key: Schema.String, value: Schema.Unknown } ); var CallSchema = Schema.Struct({ id: Schema.String, op: Schema.String, bind: Schema.optionalWith( Schema.Record({ key: Schema.String, value: BindValueSchema }), { default: () => ({}) } ), config: Schema.optionalWith( Schema.Record({ key: Schema.String, value: Schema.Unknown }), { default: () => ({}) } ), guards: Schema.optional(Schema.Array(AppliedGuardSchema)) }); var ContinuationSchema = Schema.Struct({ awaits: Schema.String, flowId: Schema.String }); var FlowSchema = Schema.Struct({ version: Schema.Literal(1), id: Schema.String, chainId: ChainIdSchema, inputs: Schema.Array(FlowInputSchema), nodes: Schema.Array(CallSchema), continuations: Schema.optional(Schema.Array(ContinuationSchema)) }); // src/continuation.ts import { Schema as Schema2 } from "effect"; var CONTINUATION_COMMITMENT_OP_ID = "continuation.commitment"; var RawContinuationOutcomeSchema = Schema2.Struct({ token: Schema2.String, minAmount: Schema2.String, destination: Schema2.String, chainId: ChainIdSchema }); var ContinuationOutcomeSchema = Schema2.transform( RawContinuationOutcomeSchema, Schema2.typeSchema(RawContinuationOutcomeSchema), { strict: true, decode: (raw) => ({ ...raw, token: normalizeNativeTokenAddress(raw.token, raw.chainId) }), encode: (outcome) => outcome } ); var ContinuationIntentSchema = Schema2.Struct({ // `NonEmptyArray` enforces ≥1 outcome at the parse boundary, so downstream needs no guard. outcomes: Schema2.NonEmptyArray(ContinuationOutcomeSchema), continuationFlow: Schema2.optional(FlowSchema), validity: Schema2.Struct({ expiresAtMs: Schema2.Number }), perpetual: Schema2.optional(Schema2.Boolean), provider: Schema2.optional(Schema2.String) }); var Phase1ArtifactSchema = Schema2.Union( Schema2.Struct({ kind: Schema2.Literal("transaction"), transactionRequest: Schema2.optional( Schema2.Struct({ to: Schema2.String, data: Schema2.String, value: Schema2.String }) ) }), Schema2.Struct({ kind: Schema2.Literal("signables"), typedData: Schema2.Array(Schema2.Unknown) }), Schema2.Struct({ kind: Schema2.Literal("none") }) ); var HexStringSchema = Schema2.String.pipe(Schema2.startsWith("0x")); var AssertionOwnerSchema = Schema2.Union( HexStringSchema, Schema2.Literal("escrow", "delivery") ); var Erc20BalanceGteSpecSchema = Schema2.Struct({ kind: Schema2.Literal("erc20BalanceGte"), chainId: ChainIdSchema, token: HexStringSchema, owner: HexStringSchema, minAmount: Schema2.String }); var NativeBalanceGteSpecSchema = Schema2.Struct({ kind: Schema2.Literal("nativeBalanceGte"), chainId: ChainIdSchema, owner: HexStringSchema, minAmount: Schema2.String }); var CallCheckSpecSchema = Schema2.Struct({ kind: Schema2.Literal("call"), chainId: ChainIdSchema, to: HexStringSchema, calldata: HexStringSchema, comparator: Schema2.Literal("gte", "eq", "lte"), value: Schema2.String }); var asErc20BalanceGteCheck = (chainId, owner, minAmount) => ({ kind: "erc20BalanceGte", chainId, token: canonicalNativeAddress(chainId), owner, minAmount }); var RawCheckSchema = Schema2.Union( Erc20BalanceGteSpecSchema, NativeBalanceGteSpecSchema, CallCheckSpecSchema ); var CheckSchema = Schema2.transform( RawCheckSchema, Schema2.typeSchema(RawCheckSchema), { strict: true, decode: (check) => check.kind === "nativeBalanceGte" && isAsErc20Chain(check.chainId) ? asErc20BalanceGteCheck(check.chainId, check.owner, check.minAmount) : check, encode: (check) => check } ); var Erc20BalanceDeltaGteSpecSchema = Schema2.Struct({ kind: Schema2.Literal("erc20BalanceDeltaGte"), chainId: ChainIdSchema, token: HexStringSchema, owner: AssertionOwnerSchema, minDelta: Schema2.String }); var NativeBalanceDeltaGteSpecSchema = Schema2.Struct({ kind: Schema2.Literal("nativeBalanceDeltaGte"), chainId: ChainIdSchema, owner: AssertionOwnerSchema, minDelta: Schema2.String }); var AssertionSpecSchema = Schema2.Union( Erc20BalanceGteSpecSchema, NativeBalanceGteSpecSchema, CallCheckSpecSchema, Erc20BalanceDeltaGteSpecSchema, NativeBalanceDeltaGteSpecSchema ); var ContinuationPlanSchema = Schema2.Struct({ chainId: ChainIdSchema, nextFlow: FlowSchema, check: CheckSchema, validity: Schema2.Struct({ expiresAtMs: Schema2.Number }), correlationId: Schema2.optional(Schema2.String) }); var isGTECheck = (check) => check.kind === "call" && check.comparator === "gte"; var isLTECheck = (check) => check.kind === "call" && check.comparator === "lte"; var isEQCheck = (check) => check.kind === "call" && check.comparator === "eq"; // src/descriptor.ts import { Schema as Schema3 } from "effect"; // src/hexPatterns.ts var BYTES32_LOWER_HEX = /^0x[0-9a-f]{64}$/; // src/descriptor.ts var Bytes32HexSchema = Schema3.String.pipe( Schema3.pattern(BYTES32_LOWER_HEX) ); var AssertedErc20BalanceGteSpecSchema = Schema3.Struct({ kind: Schema3.Literal("erc20BalanceGte"), chainId: ChainIdSchema, token: HexStringSchema, owner: AssertionOwnerSchema, minAmount: Schema3.String }); var AssertedNativeBalanceGteSpecSchema = Schema3.Struct({ kind: Schema3.Literal("nativeBalanceGte"), chainId: ChainIdSchema, owner: AssertionOwnerSchema, minAmount: Schema3.String }); var RawAssertedPredicateSchema = Schema3.Union( AssertedErc20BalanceGteSpecSchema, AssertedNativeBalanceGteSpecSchema, CallCheckSpecSchema, Erc20BalanceDeltaGteSpecSchema, NativeBalanceDeltaGteSpecSchema ); var AssertedPredicateSchema = Schema3.transform( RawAssertedPredicateSchema, Schema3.typeSchema(RawAssertedPredicateSchema), { strict: true, decode: (pred) => pred.kind === "nativeBalanceGte" && isAsErc20Chain(pred.chainId) ? asErc20BalanceGteCheck(pred.chainId, pred.owner, pred.minAmount) : pred, encode: (pred) => pred } ); var VerificationDescriptorSchema = Schema3.Struct({ validationProgramHash: Bytes32HexSchema, // The C5 echo's second hash (verified continuations, plan GD-8): `keccak256` // over the canonical params vector (`paramsHash`, GD-2 seam C1). Required and // jointly necessary with `validationProgramHash` — the program hash is // value-blind (it never binds the delivery address or amounts), so a descriptor // that enforces only it is a fund-redirect hole. Empty params still yield a // present `0x00…00`, so a real descriptor never omits it. Strict 32-byte // lowercase hex, same rule as `validationProgramHash`. paramsHash: Bytes32HexSchema, assertedPredicate: Schema3.Array(AssertedPredicateSchema) }); var canonicalJson = (value) => { if (Array.isArray(value)) { return `[${value.map(canonicalJson).join(",")}]`; } if (value !== null && typeof value === "object") { const record = value; const entries = Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`); return `{${entries.join(",")}}`; } return JSON.stringify(value); }; var canonicalAssertedPredicate = (specs) => canonicalJson(specs); // src/flow.ts var isResourceInput = (input) => "resource" in input; var flowInputType = (input) => isResourceInput(input) ? "uint256" : input.type; var flowInputMode = (input) => isResourceInput(input) ? "linear" : "copy"; var flowInputResource = (input) => isResourceInput(input) ? input.resource : void 0; var isResourcePort = (port) => port.kind === "resource"; var isHandlePort = (port) => port.kind === "handle"; var isResourceOutputPort = (port) => port.kind === "resource_output"; var isFutureResourceOutput = (port) => isResourceOutputPort(port) && port.availability === "future"; var isMaterialiserInput = (s) => typeof s === "object" && s !== null && "kind" in s; // src/resource.ts var erc20Resource = (token, chainId) => ({ kind: "erc20", token, chainId }); var nativeResource = (chainId) => ({ kind: "native", chainId }); var isERC20Resource = (r) => r.kind === "erc20"; var isNativeResource = (r) => r.kind === "native"; var resourcesEqual = (a, b) => { 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; }; var foldResource = (r, cases) => r.kind === "native" ? cases.native(r.chainId) : cases.erc20(r.token, r.chainId); var resourceToken = (r) => foldResource(r, { native: () => EVM_NATIVE_SENTINEL, erc20: (token) => token }); var resourceKey = (r) => foldResource(r, { native: (chainId) => `native:${chainId}`, erc20: (token, chainId) => `erc20:${token.toLowerCase()}:${chainId}` }); var erc20Token = (r) => { if (r.kind !== "erc20") throw new Error(`Expected erc20 resource, got ${r.kind}`); return r.token; }; // src/flashloan.ts var PROVIDER_KIND = { AAVE_V3: 0, ERC3156: 1, BALANCER_V2: 2, MORPHO_BLUE: 3 }; var providerKindNames = [ "aave-v3", "erc3156", "balancer-v2", "morpho-blue" ]; var providerKindByName = { "aave-v3": PROVIDER_KIND.AAVE_V3, erc3156: PROVIDER_KIND.ERC3156, "balancer-v2": PROVIDER_KIND.BALANCER_V2, "morpho-blue": PROVIDER_KIND.MORPHO_BLUE }; // src/constructors.ts var inputRef = (port) => ({ $ref: `input.${port}` }); var outputRef = (node, port) => ({ $ref: `${node}.${port}` }); var optionalProp = (key, value) => value !== void 0 && value !== null ? { [key]: value } : {}; var linear = (name, type) => ({ name, type, mode: "linear", availability: "now" }); var copy = (name, type) => ({ name, type, mode: "copy", availability: "now" }); var handle = (name, type) => ({ name, type }); var native = (name, chainId) => ({ name, resource: nativeResource(chainId) }); var erc20 = (name, token, chainId) => ({ name, resource: erc20Resource(token, chainId) }); var resource = (name, accepts, options) => ({ kind: "resource", name, accepts, mode: "linear", ...optionalProp("optional", options?.optional) }); var readResource = (name, accepts) => ({ kind: "resource", name, accepts, mode: "copy" }); var opHandle = (name, type, options) => ({ kind: "handle", name, type, mode: "copy", ...optionalProp("expose", options?.expose), ...optionalProp("units", options?.units), ...optionalProp("optional", options?.optional) }); var resourceOutput = (name, options) => { const raw = options; const opts = typeof raw === "string" ? { availability: raw } : raw; return { kind: "resource_output", name, mode: "linear", ...optionalProp("availability", opts?.availability), ...optionalProp("providesMinimum", opts?.providesMinimum), ...optionalProp("omitIfZero", opts?.omitIfZero), ...optionalProp("deliveryAddressInput", opts?.deliveryAddressInput) }; }; // src/ref.ts var isContextKey = (key) => key === "sender" || key === "executionAddress"; var RESERVED_REF_SCOPES = /* @__PURE__ */ new Set([ "input", "context", "literal" ]); var isRef = (v) => typeof v === "object" && v !== null && "$ref" in v && typeof v.$ref === "string"; var parseRef = (ref) => { const dot = ref.$ref.indexOf("."); if (dot === -1) throw new Error(`Invalid ref: "${ref.$ref}" (must contain a dot)`); const prefix = ref.$ref.slice(0, dot); const suffix = ref.$ref.slice(dot + 1); if (prefix === "input") return { scope: "input", port: suffix }; if (prefix === "context") { if (!isContextKey(suffix)) throw new Error(`Unknown context key: "${suffix}"`); return { scope: "context", key: suffix }; } return { scope: "output", node: prefix, port: suffix }; }; var foldRef = (ref, cases) => { if (ref.scope === "input") return cases.input(ref.port); if (ref.scope === "context") return cases.context(ref.key); return cases.output(ref.node, ref.port); }; var refKey = (ref) => foldRef(parseRef(ref), { input: (port) => `input:${port}`, context: (key) => `context:${key}`, output: (node, port) => `output:${node}:${port}` }); // src/preconditions.ts var erc20Balance = (config) => ({ type: "Erc20Balance", ...config }); var nativeBalance = (config) => ({ type: "NativeBalance", ...config }); var erc20Allowance = (config) => ({ type: "Erc20Allowance", ...config }); var isErc20AllowancePrecondition = (p) => p.type === "Erc20Allowance"; var isNativeBalancePrecondition = (p) => p.type === "NativeBalance"; // src/simulate.ts var SIMULATE_MAX_TRACKED_BALANCES = 40; var SIMULATE_MAX_REQUIREMENTS = 40; // src/materialiserMetadata.ts var foldMaterialiserMetadata = (meta, cases) => { if (meta.kind === "exact") return cases.exact(meta.amount); if (meta.kind === "exact-native") return cases.exactNative(meta.amount); return cases.runtime(); }; // src/zodSchemas.ts import z from "zod"; var chainIdZod = z.number().int().positive(); var SolTypeZod = z.enum([ "uint8", "uint16", "uint32", "uint64", "uint128", "uint256", "int128", "int256", "address", "bool", "bytes", "bytes4", "bytes32", "string" ]); var ResourcePortZod = z.object({ kind: z.literal("resource"), name: z.string(), accepts: z.enum(["erc20", "native", "any"]), mode: z.enum(["linear", "copy"]), optional: z.boolean().optional() }); var HANDLE_UNITS = [ "raw", "wad", "ray", "bps", "token-decimals" ]; var STATIC_SOL_TYPES = [ "uint256", "uint128", "uint64", "uint32", "uint16", "uint8", "address", "bool", "bytes32" ]; var HandleUnitsZod = z.enum(HANDLE_UNITS); var StaticSolTypeZod = z.enum(STATIC_SOL_TYPES); var STATIC_SOL_TYPE_SET = new Set(STATIC_SOL_TYPES); var isStaticSolType = (value) => STATIC_SOL_TYPE_SET.has(value); var HandlePortZod = z.object({ kind: z.literal("handle"), name: z.string(), type: SolTypeZod, mode: z.enum(["linear", "copy"]), expose: z.boolean().optional(), units: HandleUnitsZod.optional(), optional: z.boolean().optional() }); var InputPortZod = z.discriminatedUnion("kind", [ ResourcePortZod, HandlePortZod ]); var ResourceOutputPortZod = z.object({ kind: z.literal("resource_output"), name: z.string(), mode: z.enum(["linear", "copy"]), availability: z.enum(["now", "future"]).optional(), providesMinimum: z.boolean().optional(), omitIfZero: z.boolean().optional(), deliveryAddressInput: z.string().optional() }); var OutputPortZod = z.discriminatedUnion("kind", [ ResourceOutputPortZod, HandlePortZod ]); var ManifestOperationZod = z.object({ id: z.string(), description: z.string().optional(), inputs: z.array(InputPortZod), outputs: z.array(OutputPortZod), configSchema: z.unknown().optional() }); var PortKindEnum = z.enum(["resource", "resource_output", "handle"]); var SelectorMatchZod = z.object({ kind: z.union([PortKindEnum, z.array(PortKindEnum)]), mode: z.enum(["linear", "copy"]).optional(), type: z.enum(["erc20", "native", "any"]).optional() }); var ConfigSelectionZod = z.object({ kind: z.literal("config"), configKey: z.string(), cardinality: z.enum(["one", "many"]) }); var AllMatchingSelectionZod = z.object({ kind: z.literal("all_matching") }); var SelectorSelectionZod = z.discriminatedUnion("kind", [ ConfigSelectionZod, AllMatchingSelectionZod ]); var GuardSelectorZod = z.object({ binding: z.string(), source: z.enum(["inputs", "outputs"]), match: SelectorMatchZod, selection: SelectorSelectionZod }); var GuardCompatibilityZod = z.object({ selectors: z.array(GuardSelectorZod) }); var ManifestGuardZod = z.object({ kind: z.string(), description: z.string().optional(), configSchema: z.unknown().optional(), compatibility: GuardCompatibilityZod.optional() }); var ManifestMaterialiserZod = z.object({ kind: z.string(), description: z.string().optional(), accepts: z.enum(["resource", "handle", "any"]), configSchema: z.unknown().optional() }); var ManifestPreconditionZod = z.object({ type: z.string(), description: z.string().optional(), configSchema: z.unknown().optional() }); var ComposeManifestZod = z.object({ manifestVersion: z.number(), manifestHash: z.string(), flowSchema: z.object({}).passthrough(), operations: z.array(ManifestOperationZod), guards: z.array(ManifestGuardZod), materialisers: z.array(ManifestMaterialiserZod), preconditions: z.array(ManifestPreconditionZod).optional() }); var Phase1ArtifactZod = z.discriminatedUnion("kind", [ z.object({ kind: z.literal("transaction"), transactionRequest: z.object({ to: z.string(), data: z.string(), value: z.string() }).optional() }), z.object({ kind: z.literal("signables"), typedData: z.array(z.unknown()) }), z.object({ kind: z.literal("none") }) ]); var hexStringZod = z.string().startsWith("0x"); var assertionOwnerZod = z.union([ hexStringZod, z.enum(["escrow", "delivery"]) ]); var CheckZod = z.discriminatedUnion("kind", [ z.object({ kind: z.literal("erc20BalanceGte"), chainId: chainIdZod, token: hexStringZod, owner: hexStringZod, minAmount: z.string() }), z.object({ kind: z.literal("nativeBalanceGte"), chainId: chainIdZod, owner: hexStringZod, minAmount: z.string() }), z.object({ kind: z.literal("call"), chainId: chainIdZod, to: hexStringZod, calldata: hexStringZod, comparator: z.enum(["gte", "eq", "lte"]), value: z.string() }) ]); var AssertionSpecZod = z.discriminatedUnion("kind", [ ...CheckZod.options, z.object({ kind: z.literal("erc20BalanceDeltaGte"), chainId: z.number().int().positive(), token: hexStringZod, owner: assertionOwnerZod, minDelta: z.string() }), z.object({ kind: z.literal("nativeBalanceDeltaGte"), chainId: z.number().int().positive(), owner: assertionOwnerZod, minDelta: z.string() }) ]); var assertionSpecOptionByKind = (kind) => { const option = AssertionSpecZod.options.find( (o) => o.shape.kind.value === kind ); if (option === void 0) { throw new Error(`AssertionSpecZod has no member with kind "${kind}"`); } return option; }; var AssertedPredicateZod = z.discriminatedUnion("kind", [ z.object({ kind: z.literal("erc20BalanceGte"), chainId: z.number().int().positive(), token: hexStringZod, owner: assertionOwnerZod, minAmount: z.string() }), z.object({ kind: z.literal("nativeBalanceGte"), chainId: z.number().int().positive(), owner: assertionOwnerZod, minAmount: z.string() }), assertionSpecOptionByKind("call"), assertionSpecOptionByKind("erc20BalanceDeltaGte"), assertionSpecOptionByKind("nativeBalanceDeltaGte") ]); var VerificationDescriptorZod = z.object({ validationProgramHash: z.string().regex(BYTES32_LOWER_HEX), // The C5 echo's second hash (GD-8): the params-vector content hash // (`paramsHash`, C1). Required and jointly necessary with the value-blind // `validationProgramHash`. paramsHash: z.string().regex(BYTES32_LOWER_HEX), assertedPredicate: z.array(AssertedPredicateZod) }); var ContinuationPlanZod = z.object({ chainId: chainIdZod, nextFlow: z.unknown(), check: CheckZod, validity: z.object({ expiresAtMs: z.number() }), correlationId: z.string().optional() }); export { AppliedGuardSchema, AssertedErc20BalanceGteSpecSchema, AssertedNativeBalanceGteSpecSchema, AssertedPredicateSchema, AssertedPredicateZod, AssertionOwnerSchema, AssertionSpecSchema, AssertionSpecZod, BindValueSchema, Bytes32HexSchema, CONTINUATION_COMMITMENT_OP_ID, CallCheckSpecSchema, CallSchema, CheckSchema, CheckZod, ComposeManifestZod, ContinuationIntentSchema, ContinuationOutcomeSchema, ContinuationPlanSchema, ContinuationPlanZod, ContinuationSchema, EVM_NATIVE_SENTINEL, Erc20BalanceDeltaGteSpecSchema, Erc20BalanceGteSpecSchema, FlowInputSchema, FlowSchema, GuardCompatibilityZod, GuardSelectorZod, HANDLE_UNITS, HandleInputSchema, HandlePortZod, HandleUnitsZod, HexStringSchema, InputPortZod, LiteralBindingSchema, ManifestGuardZod, ManifestMaterialiserZod, ManifestOperationZod, ManifestPreconditionZod, NativeBalanceDeltaGteSpecSchema, NativeBalanceGteSpecSchema, OutputPortZod, PROVIDER_KIND, Phase1ArtifactSchema, Phase1ArtifactZod, RESERVED_REF_SCOPES, RefSchema, ResourceInputSchema, ResourceOutputPortZod, ResourcePortZod, ResourceSchema, SIMULATE_MAX_REQUIREMENTS, SIMULATE_MAX_TRACKED_BALANCES, STATIC_SOL_TYPES, SolTypeSchema, StaticSolTypeZod, TEMPO_CHAIN_ID, TEMPO_NATIVE_ERC20, VerificationDescriptorSchema, VerificationDescriptorZod, canonicalAssertedPredicate, canonicalNativeAddress, copy, erc20, erc20Allowance, erc20Balance, erc20Resource, erc20Token, flowInputMode, flowInputResource, flowInputType, foldMaterialiserMetadata, foldRef, foldResource, getChainCapabilities, handle, inputRef, isAsErc20Chain, isContextKey, isEQCheck, isERC20Resource, isErc20AllowancePrecondition, isFutureResourceOutput, isGTECheck, isHandlePort, isLTECheck, isMaterialiserInput, isMsgValueNative, isNativeAddressForChain, isNativeBalancePrecondition, isNativeResource, isRef, isResourceInput, isResourceOutputPort, isResourcePort, isStaticSolType, linear, native, nativeBalance, nativeResource, normalizeNativeTokenAddress, normalizeResource, opHandle, outputRef, parseRef, providerKindByName, providerKindNames, readResource, refKey, resource, resourceKey, resourceOutput, resourceToken, resourcesEqual };