@lifi/composer-sdk 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +202 -189
  2. package/dist/authoring/FlowBuilderCore.cjs +16 -3
  3. package/dist/authoring/FlowBuilderCore.cjs.map +1 -1
  4. package/dist/authoring/FlowBuilderCore.d.cts +12 -4
  5. package/dist/authoring/FlowBuilderCore.d.ts +12 -4
  6. package/dist/authoring/FlowBuilderCore.js +19 -3
  7. package/dist/authoring/FlowBuilderCore.js.map +1 -1
  8. package/dist/authoring/handles.cjs.map +1 -1
  9. package/dist/authoring/handles.d.cts +35 -1
  10. package/dist/authoring/handles.d.ts +35 -1
  11. package/dist/authoring/handles.js.map +1 -1
  12. package/dist/client.cjs +1 -1
  13. package/dist/client.js +1 -1
  14. package/dist/generated/config.generated.cjs.map +1 -1
  15. package/dist/generated/config.generated.d.cts +500 -6
  16. package/dist/generated/config.generated.d.ts +500 -6
  17. package/dist/generated/operations.generated.cjs +7 -0
  18. package/dist/generated/operations.generated.cjs.map +1 -1
  19. package/dist/generated/operations.generated.d.cts +20 -5
  20. package/dist/generated/operations.generated.d.ts +20 -5
  21. package/dist/generated/operations.generated.js +7 -0
  22. package/dist/generated/operations.generated.js.map +1 -1
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +3 -3
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.js.map +1 -1
  27. package/dist/sdk.cjs.map +1 -1
  28. package/dist/sdk.d.cts +5 -6
  29. package/dist/sdk.d.ts +5 -6
  30. package/dist/sdk.js.map +1 -1
  31. package/package.json +4 -3
  32. package/src/authoring/FlowBuilderCore.ts +55 -18
  33. package/src/authoring/handles.ts +67 -0
  34. package/src/examples/splitAndZap.ts +9 -8
  35. package/src/generated/config.generated.ts +516 -5
  36. package/src/generated/operations.generated.ts +52 -3
  37. package/src/index.ts +5 -1
  38. package/src/sdk.ts +5 -6
@@ -21,6 +21,7 @@ __export(FlowBuilderCore_exports, {
21
21
  createFlowBuilderCore: () => createFlowBuilderCore
22
22
  });
23
23
  module.exports = __toCommonJS(FlowBuilderCore_exports);
24
+ var import_compose_spec = require("@lifi/compose-spec");
24
25
  var import_handles = require("./handles.js");
25
26
  var import_raw = require("./raw.js");
26
27
  const isResource = (decl) => typeof decl === "object" && decl !== null && "kind" in decl;
@@ -44,21 +45,27 @@ const createFlowBuilderCore = (chainId, options) => {
44
45
  inputHandles[name] = { _tag: "input", inputName: name };
45
46
  }
46
47
  }
47
- const call = (nodeId, op, args, outputs) => {
48
+ const call = (nodeId, op, args, outputs, families) => {
48
49
  if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: "${nodeId}"`);
49
50
  nodeIds.add(nodeId);
50
51
  const bind = {};
51
52
  for (const [key, val] of Object.entries(args.bind)) {
52
53
  bind[key] = (0, import_handles.toBindValue)(val);
53
54
  }
55
+ const config = args.config ?? {};
54
56
  const node = {
55
57
  id: nodeId,
56
58
  op,
57
59
  bind,
58
- config: args.config ?? {},
60
+ config,
59
61
  ...args.guards && args.guards.length > 0 && { guards: args.guards }
60
62
  };
61
63
  nodes.push(node);
64
+ const outputHandle = (portName) => ({
65
+ _tag: "output",
66
+ nodeId,
67
+ portName
68
+ });
62
69
  return new Proxy({}, {
63
70
  get: (_target, prop) => {
64
71
  if (typeof prop !== "string" || prop === "then") return void 0;
@@ -69,7 +76,13 @@ const createFlowBuilderCore = (chainId, options) => {
69
76
  ).join(", ")}`
70
77
  );
71
78
  }
72
- return { _tag: "output", nodeId, portName: prop };
79
+ const countFrom = families?.[prop];
80
+ if (countFrom === void 0) return outputHandle(prop);
81
+ const size = (0, import_compose_spec.familySize)({ name: prop, countFrom }, config);
82
+ return Array.from(
83
+ { length: size },
84
+ (_, index) => outputHandle((0, import_compose_spec.instancePortName)(prop, index))
85
+ );
73
86
  }
74
87
  });
75
88
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/authoring/FlowBuilderCore.ts"],"sourcesContent":["import type {\n AppliedGuard,\n BindValue,\n Call,\n Flow,\n FlowInput,\n Ref,\n Resource,\n SolType,\n} from '@lifi/compose-spec';\n\nimport type {\n InputDecl,\n InputSchema,\n OutputKind,\n TypedGuard,\n TypedLiteral,\n TypedRef,\n} from '../types.js';\n\nimport type {\n InputHandle,\n OutputHandle,\n ResourceInputHandle,\n} from './handles.js';\nimport { toBindValue } from './handles.js';\nimport { ref } from './raw.js';\n\n/**\n * Arguments for calling an operation node in a flow.\n */\nexport interface CallArgs {\n /** Maps parameter names to input/output handles or raw `$ref` pointers. */\n readonly bind: Record<string, AnyBindable>;\n /** Optional operation-specific configuration. */\n readonly config?: object;\n /** Optional guards (e.g. slippage checks) applied to this operation's outputs. */\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Any value that can be bound to an operation parameter: an input handle, an\n * output handle from a previous operation, a typed `$ref` pointer, a typed\n * literal, or a bare `{ $ref }` pointer.\n *\n * This is the bind type of {@link FlowBuilderInternal.call}, the entry point\n * every generated operation lowers into — not a public authoring surface. A\n * bare `Ref` belongs here because a generated op resolves its own typed binds\n * to wire refs (`toBindRef` in `./signatureArgs.js`) before calling it. Typed\n * operation slots use `Bindable<T>`, which rejects a bare `Ref`; see\n * `RefBindable` in `./handles.js`.\n *\n * Use `raw.ref<T>()` to create a typed ref from a raw path string, and\n * `raw.literal<T>()` to bake in a constant.\n */\nexport type AnyBindable =\n InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref;\n\n/**\n * Provides references to runtime context values available inside a flow.\n * Access via `builder.context`.\n */\nexport interface ContextAccessor {\n /** A `$ref` pointing to the transaction sender (signer) address. */\n readonly sender: TypedRef<'address'>;\n /** A `$ref` pointing to the on-chain execution (proxy) address. */\n readonly executionAddress: TypedRef<'address'>;\n}\n\ntype InputHandleOf<D extends InputDecl> = D extends Resource\n ? ResourceInputHandle\n : D extends SolType\n ? InputHandle<D>\n : InputHandle;\n\n/**\n * A mapped type that converts an input schema into typed handles.\n * Resource inputs produce {@link ResourceInputHandle}; scalar inputs produce {@link InputHandle}.\n *\n * @typeParam T - The flow's input schema.\n */\nexport type InputHandles<T extends InputSchema> = {\n readonly [K in keyof T]: InputHandleOf<T[K]>;\n};\n\n/**\n * Options for creating a new flow builder.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowOptions<T extends InputSchema> {\n /** Optional human-readable name for the flow. Defaults to a random UUID. */\n readonly name?: string;\n /** Input declarations mapping names to resource or scalar types. */\n readonly inputs: T;\n}\n\n/**\n * A Flow document branded with its input schema for type-safe request building.\n *\n * The `__inputs` field is a phantom type — it exists only at compile time for\n * TypeScript inference and is never present at runtime.\n */\nexport type TypedFlow<T extends InputSchema = InputSchema> = Flow & {\n readonly __inputs?: T;\n};\n\n/**\n * Core flow builder interface providing low-level access to flow construction.\n *\n * For most use cases, prefer the {@link FlowBuilder} type returned by `sdk.flow()`\n * which adds generated operation methods and a `compile` method.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowBuilderCore<T extends InputSchema = InputSchema> {\n /** Runtime context references (sender address, execution address). */\n readonly context: ContextAccessor;\n /** Typed handles for each declared flow input, used to bind inputs to operations. */\n readonly inputs: InputHandles<T>;\n /**\n * Appends an untyped operation node to the flow. This is an escape hatch\n * for operations not yet covered by the generated methods.\n *\n * Use `raw.ref<T>()` to reference this node's outputs in subsequent typed\n * operations.\n *\n * @param id - Unique node identifier within the flow.\n * @param op - The operation name (e.g. `\"custom.vaultQuery\"`).\n * @param args - Bind map, config, and optional guards for the node.\n * @throws Error if a node with the same `id` already exists in the flow.\n */\n readonly untypedOp: (\n id: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ) => void;\n /** Serialises the builder state into a {@link TypedFlow} document. */\n readonly build: () => TypedFlow<T>;\n}\n\n/** Maps output port names to their output kind for compile-time and runtime validation. */\nexport type OutputSpec = Record<string, OutputKind>;\n\n/** Internal interface exposed to bindGeneratedOps — not part of the public API. */\nexport interface FlowBuilderInternal<\n T extends InputSchema = InputSchema,\n> extends FlowBuilderCore<T> {\n readonly call: <O extends OutputSpec>(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n ) => { readonly [K in keyof O & string]: OutputHandle<O[K]> };\n}\n\nconst isResource = (decl: InputDecl): decl is Resource =>\n typeof decl === 'object' && decl !== null && 'kind' in decl;\n\n/**\n * Creates a new flow builder targeting the given chain.\n *\n * @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).\n * @param options - Flow configuration including input declarations.\n * @returns A {@link FlowBuilderInternal} instance.\n * @internal\n */\nexport const createFlowBuilderCore = <T extends InputSchema>(\n chainId: number,\n options: FlowOptions<T>,\n): FlowBuilderInternal<T> => {\n const id = options.name ?? crypto.randomUUID();\n const flowInputs: FlowInput[] = [];\n const nodes: Call[] = [];\n const nodeIds = new Set<string>();\n\n const inputHandles = {} as Record<string, InputHandle | ResourceInputHandle>;\n for (const [name, decl] of Object.entries(options.inputs)) {\n if (isResource(decl)) {\n if (decl.chainId !== chainId) {\n throw new Error(\n `Input \"${name}\" has chainId ${decl.chainId} but flow targets chain ${chainId}`,\n );\n }\n flowInputs.push({ name, resource: decl });\n inputHandles[name] = { _tag: 'input', inputName: name, resource: decl };\n } else {\n flowInputs.push({ name, type: decl });\n inputHandles[name] = { _tag: 'input', inputName: name };\n }\n }\n\n const call = <O extends OutputSpec>(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n ): { readonly [K in keyof O & string]: OutputHandle<O[K]> } => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n\n const bind: Record<string, BindValue> = {};\n for (const [key, val] of Object.entries(args.bind)) {\n bind[key] = toBindValue(val);\n }\n\n const node: Call = {\n id: nodeId,\n op,\n bind,\n config: (args.config ?? {}) as Record<string, unknown>,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n\n type Result = { readonly [K in keyof O & string]: OutputHandle<O[K]> };\n return new Proxy({} as Result, {\n get: (_target, prop): OutputHandle | undefined => {\n if (typeof prop !== 'string' || prop === 'then') return undefined;\n if (!(prop in outputs)) {\n throw new Error(\n `Op \"${op}\" has no output port \"${prop}\". Valid ports: ${Object.keys(\n outputs,\n ).join(', ')}`,\n );\n }\n return { _tag: 'output', nodeId, portName: prop };\n },\n });\n };\n\n const untypedOp = (\n nodeId: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ): void => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n const node: Call = {\n id: nodeId,\n op,\n bind: args.bind,\n config: args.config,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n };\n\n const build = (): TypedFlow<T> => ({\n version: 1,\n id,\n chainId,\n inputs: [...flowInputs],\n nodes: [...nodes],\n });\n\n const context: ContextAccessor = {\n sender: ref<'address'>('context.sender'),\n executionAddress: ref<'address'>('context.executionAddress'),\n };\n\n return {\n context,\n inputs: inputHandles as InputHandles<T>,\n call,\n untypedOp,\n build,\n };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/authoring/FlowBuilderCore.ts"],"sourcesContent":["import {\n type AppliedGuard,\n type BindValue,\n type Call,\n familySize,\n type Flow,\n type FlowInput,\n instancePortName,\n type Ref,\n type Resource,\n type SolType,\n} from '@lifi/compose-spec';\n\nimport type {\n InputDecl,\n InputSchema,\n OutputKind,\n TypedGuard,\n TypedLiteral,\n TypedRef,\n} from '../types.js';\n\nimport type {\n InputHandle,\n OutputHandle,\n ResourceInputHandle,\n} from './handles.js';\nimport { toBindValue } from './handles.js';\nimport { ref } from './raw.js';\n\n/**\n * Arguments for calling an operation node in a flow.\n */\nexport interface CallArgs {\n /** Maps parameter names to input/output handles or raw `$ref` pointers. */\n readonly bind: Record<string, AnyBindable>;\n /** Optional operation-specific configuration. */\n readonly config?: object;\n /** Optional guards (e.g. slippage checks) applied to this operation's outputs. */\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Any value that can be bound to an operation parameter: an input handle, an\n * output handle from a previous operation, a typed `$ref` pointer, a typed\n * literal, or a bare `{ $ref }` pointer.\n *\n * This is the bind type of {@link FlowBuilderInternal.call}, the entry point\n * every generated operation lowers into — not a public authoring surface. A\n * bare `Ref` belongs here because a generated op resolves its own typed binds\n * to wire refs (`toBindRef` in `./signatureArgs.js`) before calling it. Typed\n * operation slots use `Bindable<T>`, which rejects a bare `Ref`; see\n * `RefBindable` in `./handles.js`.\n *\n * Use `raw.ref<T>()` to create a typed ref from a raw path string, and\n * `raw.literal<T>()` to bake in a constant.\n */\nexport type AnyBindable =\n InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref;\n\n/**\n * Provides references to runtime context values available inside a flow.\n * Access via `builder.context`.\n */\nexport interface ContextAccessor {\n /** A `$ref` pointing to the transaction sender (signer) address. */\n readonly sender: TypedRef<'address'>;\n /** A `$ref` pointing to the on-chain execution (proxy) address. */\n readonly executionAddress: TypedRef<'address'>;\n}\n\ntype InputHandleOf<D extends InputDecl> = D extends Resource\n ? ResourceInputHandle\n : D extends SolType\n ? InputHandle<D>\n : InputHandle;\n\n/**\n * A mapped type that converts an input schema into typed handles.\n * Resource inputs produce {@link ResourceInputHandle}; scalar inputs produce {@link InputHandle}.\n *\n * @typeParam T - The flow's input schema.\n */\nexport type InputHandles<T extends InputSchema> = {\n readonly [K in keyof T]: InputHandleOf<T[K]>;\n};\n\n/**\n * Options for creating a new flow builder.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowOptions<T extends InputSchema> {\n /** Optional human-readable name for the flow. Defaults to a random UUID. */\n readonly name?: string;\n /** Input declarations mapping names to resource or scalar types. */\n readonly inputs: T;\n}\n\n/**\n * A Flow document branded with its input schema for type-safe request building.\n *\n * The `__inputs` field is a phantom type — it exists only at compile time for\n * TypeScript inference and is never present at runtime.\n */\nexport type TypedFlow<T extends InputSchema = InputSchema> = Flow & {\n readonly __inputs?: T;\n};\n\n/**\n * Core flow builder interface providing low-level access to flow construction.\n *\n * For most use cases, prefer the {@link FlowBuilder} type returned by `sdk.flow()`\n * which adds generated operation methods and a `compile` method.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowBuilderCore<T extends InputSchema = InputSchema> {\n /** Runtime context references (sender address, execution address). */\n readonly context: ContextAccessor;\n /** Typed handles for each declared flow input, used to bind inputs to operations. */\n readonly inputs: InputHandles<T>;\n /**\n * Appends an untyped operation node to the flow. This is an escape hatch\n * for operations not yet covered by the generated methods.\n *\n * Use `raw.ref<T>()` to reference this node's outputs in subsequent typed\n * operations.\n *\n * @param id - Unique node identifier within the flow.\n * @param op - The operation name (e.g. `\"custom.vaultQuery\"`).\n * @param args - Bind map, config, and optional guards for the node.\n * @throws Error if a node with the same `id` already exists in the flow.\n */\n readonly untypedOp: (\n id: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ) => void;\n /** Serialises the builder state into a {@link TypedFlow} document. */\n readonly build: () => TypedFlow<T>;\n}\n\n/** Maps output port names to their output kind for compile-time and runtime validation. */\nexport type OutputSpec = Record<string, OutputKind>;\n\n/**\n * Maps each output family's port name to the config key that sizes it: an\n * array (one instance per element) or a non-negative integer count.\n * A family port is also listed in the {@link OutputSpec}, as `'resource'`.\n */\nexport type FamilySpec = Readonly<Record<string, string>>;\n\n/** The handles `call` returns for an {@link OutputSpec} and its families. */\nexport type OutputHandles<O extends OutputSpec, F extends FamilySpec> = {\n readonly [K in keyof O & string]: K extends keyof F\n ? readonly OutputHandle<'resource'>[]\n : OutputHandle<O[K]>;\n};\n\n/** Internal interface exposed to bindGeneratedOps — not part of the public API. */\nexport interface FlowBuilderInternal<\n T extends InputSchema = InputSchema,\n> extends FlowBuilderCore<T> {\n readonly call: <\n O extends OutputSpec,\n F extends FamilySpec = Record<never, string>,\n >(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n families?: F,\n ) => OutputHandles<O, F>;\n}\n\nconst isResource = (decl: InputDecl): decl is Resource =>\n typeof decl === 'object' && decl !== null && 'kind' in decl;\n\n/**\n * Creates a new flow builder targeting the given chain.\n *\n * @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).\n * @param options - Flow configuration including input declarations.\n * @returns A {@link FlowBuilderInternal} instance.\n * @internal\n */\nexport const createFlowBuilderCore = <T extends InputSchema>(\n chainId: number,\n options: FlowOptions<T>,\n): FlowBuilderInternal<T> => {\n const id = options.name ?? crypto.randomUUID();\n const flowInputs: FlowInput[] = [];\n const nodes: Call[] = [];\n const nodeIds = new Set<string>();\n\n const inputHandles = {} as Record<string, InputHandle | ResourceInputHandle>;\n for (const [name, decl] of Object.entries(options.inputs)) {\n if (isResource(decl)) {\n if (decl.chainId !== chainId) {\n throw new Error(\n `Input \"${name}\" has chainId ${decl.chainId} but flow targets chain ${chainId}`,\n );\n }\n flowInputs.push({ name, resource: decl });\n inputHandles[name] = { _tag: 'input', inputName: name, resource: decl };\n } else {\n flowInputs.push({ name, type: decl });\n inputHandles[name] = { _tag: 'input', inputName: name };\n }\n }\n\n const call = <\n O extends OutputSpec,\n F extends FamilySpec = Record<never, string>,\n >(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n families?: F,\n ): OutputHandles<O, F> => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n\n const bind: Record<string, BindValue> = {};\n for (const [key, val] of Object.entries(args.bind)) {\n bind[key] = toBindValue(val);\n }\n\n const config = (args.config ?? {}) as Record<string, unknown>;\n const node: Call = {\n id: nodeId,\n op,\n bind,\n config,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n\n const outputHandle = (portName: string): OutputHandle => ({\n _tag: 'output',\n nodeId,\n portName,\n });\n return new Proxy({} as OutputHandles<O, F>, {\n get: (\n _target,\n prop,\n ): OutputHandle | readonly OutputHandle[] | undefined => {\n if (typeof prop !== 'string' || prop === 'then') return undefined;\n if (!(prop in outputs)) {\n throw new Error(\n `Op \"${op}\" has no output port \"${prop}\". Valid ports: ${Object.keys(\n outputs,\n ).join(', ')}`,\n );\n }\n const countFrom = families?.[prop];\n if (countFrom === undefined) return outputHandle(prop);\n const size = familySize({ name: prop, countFrom }, config);\n return Array.from({ length: size }, (_, index) =>\n outputHandle(instancePortName(prop, index)),\n );\n },\n });\n };\n\n const untypedOp = (\n nodeId: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ): void => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n const node: Call = {\n id: nodeId,\n op,\n bind: args.bind,\n config: args.config,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n };\n\n const build = (): TypedFlow<T> => ({\n version: 1,\n id,\n chainId,\n inputs: [...flowInputs],\n nodes: [...nodes],\n });\n\n const context: ContextAccessor = {\n sender: ref<'address'>('context.sender'),\n executionAddress: ref<'address'>('context.executionAddress'),\n };\n\n return {\n context,\n inputs: inputHandles as InputHandles<T>,\n call,\n untypedOp,\n build,\n };\n};\n"],"mappings":"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","names":[]}
@@ -104,11 +104,19 @@ interface FlowBuilderCore<T extends InputSchema = InputSchema> {
104
104
  }
105
105
  /** Maps output port names to their output kind for compile-time and runtime validation. */
106
106
  type OutputSpec = Record<string, OutputKind>;
107
+ /**
108
+ * Maps each output family's port name to the config key that sizes it: an
109
+ * array (one instance per element) or a non-negative integer count.
110
+ * A family port is also listed in the {@link OutputSpec}, as `'resource'`.
111
+ */
112
+ type FamilySpec = Readonly<Record<string, string>>;
113
+ /** The handles `call` returns for an {@link OutputSpec} and its families. */
114
+ type OutputHandles<O extends OutputSpec, F extends FamilySpec> = {
115
+ readonly [K in keyof O & string]: K extends keyof F ? readonly OutputHandle<'resource'>[] : OutputHandle<O[K]>;
116
+ };
107
117
  /** Internal interface exposed to bindGeneratedOps — not part of the public API. */
108
118
  interface FlowBuilderInternal<T extends InputSchema = InputSchema> extends FlowBuilderCore<T> {
109
- readonly call: <O extends OutputSpec>(nodeId: string, op: string, args: CallArgs, outputs: O) => {
110
- readonly [K in keyof O & string]: OutputHandle<O[K]>;
111
- };
119
+ readonly call: <O extends OutputSpec, F extends FamilySpec = Record<never, string>>(nodeId: string, op: string, args: CallArgs, outputs: O, families?: F) => OutputHandles<O, F>;
112
120
  }
113
121
  /**
114
122
  * Creates a new flow builder targeting the given chain.
@@ -120,4 +128,4 @@ interface FlowBuilderInternal<T extends InputSchema = InputSchema> extends FlowB
120
128
  */
121
129
  declare const createFlowBuilderCore: <T extends InputSchema>(chainId: number, options: FlowOptions<T>) => FlowBuilderInternal<T>;
122
130
 
123
- export { type AnyBindable, type CallArgs, type ContextAccessor, type FlowBuilderCore, type FlowBuilderInternal, type FlowOptions, type InputHandles, type OutputSpec, type TypedFlow, createFlowBuilderCore };
131
+ export { type AnyBindable, type CallArgs, type ContextAccessor, type FamilySpec, type FlowBuilderCore, type FlowBuilderInternal, type FlowOptions, type InputHandles, type OutputHandles, type OutputSpec, type TypedFlow, createFlowBuilderCore };
@@ -104,11 +104,19 @@ interface FlowBuilderCore<T extends InputSchema = InputSchema> {
104
104
  }
105
105
  /** Maps output port names to their output kind for compile-time and runtime validation. */
106
106
  type OutputSpec = Record<string, OutputKind>;
107
+ /**
108
+ * Maps each output family's port name to the config key that sizes it: an
109
+ * array (one instance per element) or a non-negative integer count.
110
+ * A family port is also listed in the {@link OutputSpec}, as `'resource'`.
111
+ */
112
+ type FamilySpec = Readonly<Record<string, string>>;
113
+ /** The handles `call` returns for an {@link OutputSpec} and its families. */
114
+ type OutputHandles<O extends OutputSpec, F extends FamilySpec> = {
115
+ readonly [K in keyof O & string]: K extends keyof F ? readonly OutputHandle<'resource'>[] : OutputHandle<O[K]>;
116
+ };
107
117
  /** Internal interface exposed to bindGeneratedOps — not part of the public API. */
108
118
  interface FlowBuilderInternal<T extends InputSchema = InputSchema> extends FlowBuilderCore<T> {
109
- readonly call: <O extends OutputSpec>(nodeId: string, op: string, args: CallArgs, outputs: O) => {
110
- readonly [K in keyof O & string]: OutputHandle<O[K]>;
111
- };
119
+ readonly call: <O extends OutputSpec, F extends FamilySpec = Record<never, string>>(nodeId: string, op: string, args: CallArgs, outputs: O, families?: F) => OutputHandles<O, F>;
112
120
  }
113
121
  /**
114
122
  * Creates a new flow builder targeting the given chain.
@@ -120,4 +128,4 @@ interface FlowBuilderInternal<T extends InputSchema = InputSchema> extends FlowB
120
128
  */
121
129
  declare const createFlowBuilderCore: <T extends InputSchema>(chainId: number, options: FlowOptions<T>) => FlowBuilderInternal<T>;
122
130
 
123
- export { type AnyBindable, type CallArgs, type ContextAccessor, type FlowBuilderCore, type FlowBuilderInternal, type FlowOptions, type InputHandles, type OutputSpec, type TypedFlow, createFlowBuilderCore };
131
+ export { type AnyBindable, type CallArgs, type ContextAccessor, type FamilySpec, type FlowBuilderCore, type FlowBuilderInternal, type FlowOptions, type InputHandles, type OutputHandles, type OutputSpec, type TypedFlow, createFlowBuilderCore };
@@ -1,3 +1,7 @@
1
+ import {
2
+ familySize,
3
+ instancePortName
4
+ } from "@lifi/compose-spec";
1
5
  import { toBindValue } from "./handles.js";
2
6
  import { ref } from "./raw.js";
3
7
  const isResource = (decl) => typeof decl === "object" && decl !== null && "kind" in decl;
@@ -21,21 +25,27 @@ const createFlowBuilderCore = (chainId, options) => {
21
25
  inputHandles[name] = { _tag: "input", inputName: name };
22
26
  }
23
27
  }
24
- const call = (nodeId, op, args, outputs) => {
28
+ const call = (nodeId, op, args, outputs, families) => {
25
29
  if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: "${nodeId}"`);
26
30
  nodeIds.add(nodeId);
27
31
  const bind = {};
28
32
  for (const [key, val] of Object.entries(args.bind)) {
29
33
  bind[key] = toBindValue(val);
30
34
  }
35
+ const config = args.config ?? {};
31
36
  const node = {
32
37
  id: nodeId,
33
38
  op,
34
39
  bind,
35
- config: args.config ?? {},
40
+ config,
36
41
  ...args.guards && args.guards.length > 0 && { guards: args.guards }
37
42
  };
38
43
  nodes.push(node);
44
+ const outputHandle = (portName) => ({
45
+ _tag: "output",
46
+ nodeId,
47
+ portName
48
+ });
39
49
  return new Proxy({}, {
40
50
  get: (_target, prop) => {
41
51
  if (typeof prop !== "string" || prop === "then") return void 0;
@@ -46,7 +56,13 @@ const createFlowBuilderCore = (chainId, options) => {
46
56
  ).join(", ")}`
47
57
  );
48
58
  }
49
- return { _tag: "output", nodeId, portName: prop };
59
+ const countFrom = families?.[prop];
60
+ if (countFrom === void 0) return outputHandle(prop);
61
+ const size = familySize({ name: prop, countFrom }, config);
62
+ return Array.from(
63
+ { length: size },
64
+ (_, index) => outputHandle(instancePortName(prop, index))
65
+ );
50
66
  }
51
67
  });
52
68
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/authoring/FlowBuilderCore.ts"],"sourcesContent":["import type {\n AppliedGuard,\n BindValue,\n Call,\n Flow,\n FlowInput,\n Ref,\n Resource,\n SolType,\n} from '@lifi/compose-spec';\n\nimport type {\n InputDecl,\n InputSchema,\n OutputKind,\n TypedGuard,\n TypedLiteral,\n TypedRef,\n} from '../types.js';\n\nimport type {\n InputHandle,\n OutputHandle,\n ResourceInputHandle,\n} from './handles.js';\nimport { toBindValue } from './handles.js';\nimport { ref } from './raw.js';\n\n/**\n * Arguments for calling an operation node in a flow.\n */\nexport interface CallArgs {\n /** Maps parameter names to input/output handles or raw `$ref` pointers. */\n readonly bind: Record<string, AnyBindable>;\n /** Optional operation-specific configuration. */\n readonly config?: object;\n /** Optional guards (e.g. slippage checks) applied to this operation's outputs. */\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Any value that can be bound to an operation parameter: an input handle, an\n * output handle from a previous operation, a typed `$ref` pointer, a typed\n * literal, or a bare `{ $ref }` pointer.\n *\n * This is the bind type of {@link FlowBuilderInternal.call}, the entry point\n * every generated operation lowers into — not a public authoring surface. A\n * bare `Ref` belongs here because a generated op resolves its own typed binds\n * to wire refs (`toBindRef` in `./signatureArgs.js`) before calling it. Typed\n * operation slots use `Bindable<T>`, which rejects a bare `Ref`; see\n * `RefBindable` in `./handles.js`.\n *\n * Use `raw.ref<T>()` to create a typed ref from a raw path string, and\n * `raw.literal<T>()` to bake in a constant.\n */\nexport type AnyBindable =\n InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref;\n\n/**\n * Provides references to runtime context values available inside a flow.\n * Access via `builder.context`.\n */\nexport interface ContextAccessor {\n /** A `$ref` pointing to the transaction sender (signer) address. */\n readonly sender: TypedRef<'address'>;\n /** A `$ref` pointing to the on-chain execution (proxy) address. */\n readonly executionAddress: TypedRef<'address'>;\n}\n\ntype InputHandleOf<D extends InputDecl> = D extends Resource\n ? ResourceInputHandle\n : D extends SolType\n ? InputHandle<D>\n : InputHandle;\n\n/**\n * A mapped type that converts an input schema into typed handles.\n * Resource inputs produce {@link ResourceInputHandle}; scalar inputs produce {@link InputHandle}.\n *\n * @typeParam T - The flow's input schema.\n */\nexport type InputHandles<T extends InputSchema> = {\n readonly [K in keyof T]: InputHandleOf<T[K]>;\n};\n\n/**\n * Options for creating a new flow builder.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowOptions<T extends InputSchema> {\n /** Optional human-readable name for the flow. Defaults to a random UUID. */\n readonly name?: string;\n /** Input declarations mapping names to resource or scalar types. */\n readonly inputs: T;\n}\n\n/**\n * A Flow document branded with its input schema for type-safe request building.\n *\n * The `__inputs` field is a phantom type — it exists only at compile time for\n * TypeScript inference and is never present at runtime.\n */\nexport type TypedFlow<T extends InputSchema = InputSchema> = Flow & {\n readonly __inputs?: T;\n};\n\n/**\n * Core flow builder interface providing low-level access to flow construction.\n *\n * For most use cases, prefer the {@link FlowBuilder} type returned by `sdk.flow()`\n * which adds generated operation methods and a `compile` method.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowBuilderCore<T extends InputSchema = InputSchema> {\n /** Runtime context references (sender address, execution address). */\n readonly context: ContextAccessor;\n /** Typed handles for each declared flow input, used to bind inputs to operations. */\n readonly inputs: InputHandles<T>;\n /**\n * Appends an untyped operation node to the flow. This is an escape hatch\n * for operations not yet covered by the generated methods.\n *\n * Use `raw.ref<T>()` to reference this node's outputs in subsequent typed\n * operations.\n *\n * @param id - Unique node identifier within the flow.\n * @param op - The operation name (e.g. `\"custom.vaultQuery\"`).\n * @param args - Bind map, config, and optional guards for the node.\n * @throws Error if a node with the same `id` already exists in the flow.\n */\n readonly untypedOp: (\n id: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ) => void;\n /** Serialises the builder state into a {@link TypedFlow} document. */\n readonly build: () => TypedFlow<T>;\n}\n\n/** Maps output port names to their output kind for compile-time and runtime validation. */\nexport type OutputSpec = Record<string, OutputKind>;\n\n/** Internal interface exposed to bindGeneratedOps — not part of the public API. */\nexport interface FlowBuilderInternal<\n T extends InputSchema = InputSchema,\n> extends FlowBuilderCore<T> {\n readonly call: <O extends OutputSpec>(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n ) => { readonly [K in keyof O & string]: OutputHandle<O[K]> };\n}\n\nconst isResource = (decl: InputDecl): decl is Resource =>\n typeof decl === 'object' && decl !== null && 'kind' in decl;\n\n/**\n * Creates a new flow builder targeting the given chain.\n *\n * @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).\n * @param options - Flow configuration including input declarations.\n * @returns A {@link FlowBuilderInternal} instance.\n * @internal\n */\nexport const createFlowBuilderCore = <T extends InputSchema>(\n chainId: number,\n options: FlowOptions<T>,\n): FlowBuilderInternal<T> => {\n const id = options.name ?? crypto.randomUUID();\n const flowInputs: FlowInput[] = [];\n const nodes: Call[] = [];\n const nodeIds = new Set<string>();\n\n const inputHandles = {} as Record<string, InputHandle | ResourceInputHandle>;\n for (const [name, decl] of Object.entries(options.inputs)) {\n if (isResource(decl)) {\n if (decl.chainId !== chainId) {\n throw new Error(\n `Input \"${name}\" has chainId ${decl.chainId} but flow targets chain ${chainId}`,\n );\n }\n flowInputs.push({ name, resource: decl });\n inputHandles[name] = { _tag: 'input', inputName: name, resource: decl };\n } else {\n flowInputs.push({ name, type: decl });\n inputHandles[name] = { _tag: 'input', inputName: name };\n }\n }\n\n const call = <O extends OutputSpec>(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n ): { readonly [K in keyof O & string]: OutputHandle<O[K]> } => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n\n const bind: Record<string, BindValue> = {};\n for (const [key, val] of Object.entries(args.bind)) {\n bind[key] = toBindValue(val);\n }\n\n const node: Call = {\n id: nodeId,\n op,\n bind,\n config: (args.config ?? {}) as Record<string, unknown>,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n\n type Result = { readonly [K in keyof O & string]: OutputHandle<O[K]> };\n return new Proxy({} as Result, {\n get: (_target, prop): OutputHandle | undefined => {\n if (typeof prop !== 'string' || prop === 'then') return undefined;\n if (!(prop in outputs)) {\n throw new Error(\n `Op \"${op}\" has no output port \"${prop}\". Valid ports: ${Object.keys(\n outputs,\n ).join(', ')}`,\n );\n }\n return { _tag: 'output', nodeId, portName: prop };\n },\n });\n };\n\n const untypedOp = (\n nodeId: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ): void => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n const node: Call = {\n id: nodeId,\n op,\n bind: args.bind,\n config: args.config,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n };\n\n const build = (): TypedFlow<T> => ({\n version: 1,\n id,\n chainId,\n inputs: [...flowInputs],\n nodes: [...nodes],\n });\n\n const context: ContextAccessor = {\n sender: ref<'address'>('context.sender'),\n executionAddress: ref<'address'>('context.executionAddress'),\n };\n\n return {\n context,\n inputs: inputHandles as InputHandles<T>,\n call,\n untypedOp,\n build,\n };\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/authoring/FlowBuilderCore.ts"],"sourcesContent":["import {\n type AppliedGuard,\n type BindValue,\n type Call,\n familySize,\n type Flow,\n type FlowInput,\n instancePortName,\n type Ref,\n type Resource,\n type SolType,\n} from '@lifi/compose-spec';\n\nimport type {\n InputDecl,\n InputSchema,\n OutputKind,\n TypedGuard,\n TypedLiteral,\n TypedRef,\n} from '../types.js';\n\nimport type {\n InputHandle,\n OutputHandle,\n ResourceInputHandle,\n} from './handles.js';\nimport { toBindValue } from './handles.js';\nimport { ref } from './raw.js';\n\n/**\n * Arguments for calling an operation node in a flow.\n */\nexport interface CallArgs {\n /** Maps parameter names to input/output handles or raw `$ref` pointers. */\n readonly bind: Record<string, AnyBindable>;\n /** Optional operation-specific configuration. */\n readonly config?: object;\n /** Optional guards (e.g. slippage checks) applied to this operation's outputs. */\n readonly guards?: readonly TypedGuard[];\n}\n\n/**\n * Any value that can be bound to an operation parameter: an input handle, an\n * output handle from a previous operation, a typed `$ref` pointer, a typed\n * literal, or a bare `{ $ref }` pointer.\n *\n * This is the bind type of {@link FlowBuilderInternal.call}, the entry point\n * every generated operation lowers into — not a public authoring surface. A\n * bare `Ref` belongs here because a generated op resolves its own typed binds\n * to wire refs (`toBindRef` in `./signatureArgs.js`) before calling it. Typed\n * operation slots use `Bindable<T>`, which rejects a bare `Ref`; see\n * `RefBindable` in `./handles.js`.\n *\n * Use `raw.ref<T>()` to create a typed ref from a raw path string, and\n * `raw.literal<T>()` to bake in a constant.\n */\nexport type AnyBindable =\n InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref;\n\n/**\n * Provides references to runtime context values available inside a flow.\n * Access via `builder.context`.\n */\nexport interface ContextAccessor {\n /** A `$ref` pointing to the transaction sender (signer) address. */\n readonly sender: TypedRef<'address'>;\n /** A `$ref` pointing to the on-chain execution (proxy) address. */\n readonly executionAddress: TypedRef<'address'>;\n}\n\ntype InputHandleOf<D extends InputDecl> = D extends Resource\n ? ResourceInputHandle\n : D extends SolType\n ? InputHandle<D>\n : InputHandle;\n\n/**\n * A mapped type that converts an input schema into typed handles.\n * Resource inputs produce {@link ResourceInputHandle}; scalar inputs produce {@link InputHandle}.\n *\n * @typeParam T - The flow's input schema.\n */\nexport type InputHandles<T extends InputSchema> = {\n readonly [K in keyof T]: InputHandleOf<T[K]>;\n};\n\n/**\n * Options for creating a new flow builder.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowOptions<T extends InputSchema> {\n /** Optional human-readable name for the flow. Defaults to a random UUID. */\n readonly name?: string;\n /** Input declarations mapping names to resource or scalar types. */\n readonly inputs: T;\n}\n\n/**\n * A Flow document branded with its input schema for type-safe request building.\n *\n * The `__inputs` field is a phantom type — it exists only at compile time for\n * TypeScript inference and is never present at runtime.\n */\nexport type TypedFlow<T extends InputSchema = InputSchema> = Flow & {\n readonly __inputs?: T;\n};\n\n/**\n * Core flow builder interface providing low-level access to flow construction.\n *\n * For most use cases, prefer the {@link FlowBuilder} type returned by `sdk.flow()`\n * which adds generated operation methods and a `compile` method.\n *\n * @typeParam T - The flow's input schema.\n */\nexport interface FlowBuilderCore<T extends InputSchema = InputSchema> {\n /** Runtime context references (sender address, execution address). */\n readonly context: ContextAccessor;\n /** Typed handles for each declared flow input, used to bind inputs to operations. */\n readonly inputs: InputHandles<T>;\n /**\n * Appends an untyped operation node to the flow. This is an escape hatch\n * for operations not yet covered by the generated methods.\n *\n * Use `raw.ref<T>()` to reference this node's outputs in subsequent typed\n * operations.\n *\n * @param id - Unique node identifier within the flow.\n * @param op - The operation name (e.g. `\"custom.vaultQuery\"`).\n * @param args - Bind map, config, and optional guards for the node.\n * @throws Error if a node with the same `id` already exists in the flow.\n */\n readonly untypedOp: (\n id: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ) => void;\n /** Serialises the builder state into a {@link TypedFlow} document. */\n readonly build: () => TypedFlow<T>;\n}\n\n/** Maps output port names to their output kind for compile-time and runtime validation. */\nexport type OutputSpec = Record<string, OutputKind>;\n\n/**\n * Maps each output family's port name to the config key that sizes it: an\n * array (one instance per element) or a non-negative integer count.\n * A family port is also listed in the {@link OutputSpec}, as `'resource'`.\n */\nexport type FamilySpec = Readonly<Record<string, string>>;\n\n/** The handles `call` returns for an {@link OutputSpec} and its families. */\nexport type OutputHandles<O extends OutputSpec, F extends FamilySpec> = {\n readonly [K in keyof O & string]: K extends keyof F\n ? readonly OutputHandle<'resource'>[]\n : OutputHandle<O[K]>;\n};\n\n/** Internal interface exposed to bindGeneratedOps — not part of the public API. */\nexport interface FlowBuilderInternal<\n T extends InputSchema = InputSchema,\n> extends FlowBuilderCore<T> {\n readonly call: <\n O extends OutputSpec,\n F extends FamilySpec = Record<never, string>,\n >(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n families?: F,\n ) => OutputHandles<O, F>;\n}\n\nconst isResource = (decl: InputDecl): decl is Resource =>\n typeof decl === 'object' && decl !== null && 'kind' in decl;\n\n/**\n * Creates a new flow builder targeting the given chain.\n *\n * @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).\n * @param options - Flow configuration including input declarations.\n * @returns A {@link FlowBuilderInternal} instance.\n * @internal\n */\nexport const createFlowBuilderCore = <T extends InputSchema>(\n chainId: number,\n options: FlowOptions<T>,\n): FlowBuilderInternal<T> => {\n const id = options.name ?? crypto.randomUUID();\n const flowInputs: FlowInput[] = [];\n const nodes: Call[] = [];\n const nodeIds = new Set<string>();\n\n const inputHandles = {} as Record<string, InputHandle | ResourceInputHandle>;\n for (const [name, decl] of Object.entries(options.inputs)) {\n if (isResource(decl)) {\n if (decl.chainId !== chainId) {\n throw new Error(\n `Input \"${name}\" has chainId ${decl.chainId} but flow targets chain ${chainId}`,\n );\n }\n flowInputs.push({ name, resource: decl });\n inputHandles[name] = { _tag: 'input', inputName: name, resource: decl };\n } else {\n flowInputs.push({ name, type: decl });\n inputHandles[name] = { _tag: 'input', inputName: name };\n }\n }\n\n const call = <\n O extends OutputSpec,\n F extends FamilySpec = Record<never, string>,\n >(\n nodeId: string,\n op: string,\n args: CallArgs,\n outputs: O,\n families?: F,\n ): OutputHandles<O, F> => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n\n const bind: Record<string, BindValue> = {};\n for (const [key, val] of Object.entries(args.bind)) {\n bind[key] = toBindValue(val);\n }\n\n const config = (args.config ?? {}) as Record<string, unknown>;\n const node: Call = {\n id: nodeId,\n op,\n bind,\n config,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n\n const outputHandle = (portName: string): OutputHandle => ({\n _tag: 'output',\n nodeId,\n portName,\n });\n return new Proxy({} as OutputHandles<O, F>, {\n get: (\n _target,\n prop,\n ): OutputHandle | readonly OutputHandle[] | undefined => {\n if (typeof prop !== 'string' || prop === 'then') return undefined;\n if (!(prop in outputs)) {\n throw new Error(\n `Op \"${op}\" has no output port \"${prop}\". Valid ports: ${Object.keys(\n outputs,\n ).join(', ')}`,\n );\n }\n const countFrom = families?.[prop];\n if (countFrom === undefined) return outputHandle(prop);\n const size = familySize({ name: prop, countFrom }, config);\n return Array.from({ length: size }, (_, index) =>\n outputHandle(instancePortName(prop, index)),\n );\n },\n });\n };\n\n const untypedOp = (\n nodeId: string,\n op: string,\n args: {\n readonly bind: Record<string, BindValue>;\n readonly config: Record<string, unknown>;\n readonly guards?: readonly AppliedGuard[];\n },\n ): void => {\n if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: \"${nodeId}\"`);\n nodeIds.add(nodeId);\n const node: Call = {\n id: nodeId,\n op,\n bind: args.bind,\n config: args.config,\n ...(args.guards && args.guards.length > 0 && { guards: args.guards }),\n };\n nodes.push(node);\n };\n\n const build = (): TypedFlow<T> => ({\n version: 1,\n id,\n chainId,\n inputs: [...flowInputs],\n nodes: [...nodes],\n });\n\n const context: ContextAccessor = {\n sender: ref<'address'>('context.sender'),\n executionAddress: ref<'address'>('context.executionAddress'),\n };\n\n return {\n context,\n inputs: inputHandles as InputHandles<T>,\n call,\n untypedOp,\n build,\n };\n};\n"],"mappings":"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","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/authoring/handles.ts"],"sourcesContent":["import type {\n BindValue,\n Ref,\n Resource,\n SolType,\n StaticSolType,\n} from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * A handle referencing a flow input declared in the flow's input schema.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface InputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'input';\n readonly inputName: string;\n readonly __outputKind?: T;\n}\n\n/**\n * An input handle for a resource (token) input, carrying the resource\n * declaration alongside the reference.\n */\nexport interface ResourceInputHandle extends InputHandle<'resource'> {\n readonly resource: Resource;\n}\n\n/**\n * A handle referencing an output port of a previously declared operation node.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface OutputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'output';\n readonly nodeId: string;\n readonly portName: string;\n readonly __outputKind?: T;\n}\n\n/** Discriminated union of all handle types that can be bound to operation arguments. */\nexport type AnyHandle = InputHandle | OutputHandle;\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */\nexport const isInputHandle = (h: AnyHandle): h is InputHandle =>\n h._tag === 'input';\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link OutputHandle}. */\nexport const isOutputHandle = (h: AnyHandle): h is OutputHandle =>\n h._tag === 'output';\n\n/**\n * Converts a handle to a JSON `$ref` pointer used in the flow document.\n * Input handles become `\"input.<name>\"`; output handles become `\"<nodeId>.<port>\"`.\n */\nexport const handleToRef = (h: AnyHandle): { $ref: string } => {\n if (h._tag === 'input') {\n if (!h.inputName) throw new Error('InputHandle has empty inputName');\n return { $ref: `input.${h.inputName}` };\n }\n if (!h.nodeId) throw new Error('OutputHandle has empty nodeId');\n if (!h.portName) throw new Error('OutputHandle has empty portName');\n return { $ref: `${h.nodeId}.${h.portName}` };\n};\n\n/**\n * For a bind slot expecting type T, widen the set of accepted handle types:\n * - `'bytes32'` is the raw 32-byte word type: accept any static-32-byte handle\n * (`uint256`/`uintN`/`address`/`bool`/`bytes32`) plus `'resource'` (a uint256\n * amount). At the IR1 boundary every value is a type-erased word, so any\n * static-32-byte handle is a sound bind for a `bytes32` payload port.\n * - `'uint256'` keeps its existing widening to also accept `'resource'`-tagged\n * handles (resources are uint256 amounts).\n * - every other type keeps exact-SolType matching.\n */\ntype SlotAssignable<T extends OutputKind> = T extends 'bytes32'\n ? StaticSolType | 'resource'\n : T extends 'uint256'\n ? T | 'resource'\n : T;\n\n/**\n * The values accepted by a typed slot that must resolve to a `$ref`:\n * - `OutputHandle<T>` / `InputHandle<T>` (same type)\n * - For `'uint256'` slots, also `'resource'`-tagged handles\n * - For `'bytes32'` slots, any static-32-byte handle (and `'resource'`)\n * - `TypedRef<T>` (typed context refs, subject to `SlotAssignable`)\n *\n * Plain `{ $ref: '...' }` objects are **not** accepted - use `raw.ref<T>()`\n * to create a typed ref when you need to reference a raw path.\n */\nexport type RefBindable<T extends OutputKind> =\n | OutputHandle<SlotAssignable<T>>\n | InputHandle<SlotAssignable<T>>\n | TypedRef<SlotAssignable<T>>;\n\n/**\n * Any ref-resolving bindable, with no per-slot type constraint.\n */\nexport type AnyRefBindable = InputHandle | OutputHandle | TypedRef;\n\n/**\n * The set of values accepted by a typed operation bind slot: everything\n * {@link RefBindable} accepts, plus a {@link TypedLiteral} constant baked\n * into the flow document. A `'resource'` slot rejects a literal: a token\n * resource is not a scalar constant.\n *\n * Use `raw.literal<T>()` to create one.\n */\nexport type Bindable<T extends OutputKind> =\n RefBindable<T> | LiteralBindable<SlotAssignable<T>>;\n\n// Distributes over the slot's assignable kinds and keeps the scalar ones: a\n// `'resource'` slot has no scalar arm, so its literal arm collapses to\n// `never` and a literal is rejected outright.\ntype LiteralBindable<K extends OutputKind> = K extends SolType\n ? TypedLiteral<K>\n : never;\n\n/**\n * Converts a bindable to the wire `bind` value it denotes: handles become\n * `$ref` pointers, refs and literals pass through as-is.\n */\nexport const toBindValue = (\n bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref,\n): BindValue => ('_tag' in bindable ? handleToRef(bindable) : bindable);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CO,MAAM,gBAAgB,CAAC,MAC5B,EAAE,SAAS;AAGN,MAAM,iBAAiB,CAAC,MAC7B,EAAE,SAAS;AAMN,MAAM,cAAc,CAAC,MAAmC;AAC7D,MAAI,EAAE,SAAS,SAAS;AACtB,QAAI,CAAC,EAAE,UAAW,OAAM,IAAI,MAAM,iCAAiC;AACnE,WAAO,EAAE,MAAM,SAAS,EAAE,SAAS,GAAG;AAAA,EACxC;AACA,MAAI,CAAC,EAAE,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAC9D,MAAI,CAAC,EAAE,SAAU,OAAM,IAAI,MAAM,iCAAiC;AAClE,SAAO,EAAE,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAG;AAC7C;AA4DO,MAAM,cAAc,CACzB,aACe,UAAU,WAAW,YAAY,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../../src/authoring/handles.ts"],"sourcesContent":["import type {\n BindValue,\n Ref,\n Resource,\n SolType,\n StaticSolType,\n} from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * A handle referencing a flow input declared in the flow's input schema.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface InputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'input';\n readonly inputName: string;\n readonly __outputKind?: T;\n}\n\n/**\n * An input handle for a resource (token) input, carrying the resource\n * declaration alongside the reference.\n */\nexport interface ResourceInputHandle extends InputHandle<'resource'> {\n readonly resource: Resource;\n}\n\n/**\n * A handle referencing an output port of a previously declared operation node.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface OutputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'output';\n readonly nodeId: string;\n readonly portName: string;\n readonly __outputKind?: T;\n}\n\n/**\n * What an output family's sizing parameter accepts, given the config field the\n * family counts from: an array of that field's elements, or a number.\n */\nexport type FamilySource<Field> = Field extends readonly (infer E)[]\n ? readonly E[]\n : number;\n\n/** Whether a number literal is a valid family count: a non-negative integer. */\ntype IsCountLiteral<N extends number> = `${N}` extends\n `-${string}` | `${string}.${string}` | `${string}e${string}`\n ? false\n : true;\n\n/**\n * `N` resource handles as a tuple. A non-literal `number`, or a literal that is\n * not a valid count, gives an open array; {@link FamilyCount} rejects the\n * invalid literal at the call site.\n */\ntype HandleTuple<\n N extends number,\n Acc extends readonly OutputHandle<'resource'>[] = readonly [],\n> = number extends N\n ? readonly OutputHandle<'resource'>[]\n : IsCountLiteral<N> extends false\n ? readonly OutputHandle<'resource'>[]\n : Acc['length'] extends N\n ? Acc\n : HandleTuple<N, readonly [...Acc, OutputHandle<'resource'>]>;\n\n/**\n * The handles of an output family: one resource {@link OutputHandle} per\n * element of the config array the family counts from, or as many as the config\n * count. A literal array or count yields a tuple of that length, so indexing\n * past the last instance is a type error.\n */\nexport type OutputFamilyHandles<TCount extends readonly unknown[] | number> =\n TCount extends readonly unknown[]\n ? { readonly [I in keyof TCount]: OutputHandle<'resource'> }\n : TCount extends number\n ? HandleTuple<TCount>\n : never;\n\n/**\n * Holds the config value an output family counts from to the op's own type. A\n * runtime-sized array or count passes as is. A literal tuple must also satisfy\n * `Shape`, so a tuple shorter than the op's `minItems` fails at the call site\n * instead of at the server's bind step. A literal count must be a non-negative\n * integer.\n */\nexport type FamilyCount<\n TCount extends readonly unknown[] | number,\n Shape,\n> = TCount extends readonly unknown[]\n ? number extends TCount['length']\n ? unknown\n : TCount extends Shape\n ? unknown\n : { readonly 'output family config array has too few entries': never }\n : TCount extends number\n ? IsCountLiteral<TCount> extends true\n ? unknown\n : {\n readonly 'output family count must be a non-negative integer': never;\n }\n : unknown;\n\n/** Discriminated union of all handle types that can be bound to operation arguments. */\nexport type AnyHandle = InputHandle | OutputHandle;\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */\nexport const isInputHandle = (h: AnyHandle): h is InputHandle =>\n h._tag === 'input';\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link OutputHandle}. */\nexport const isOutputHandle = (h: AnyHandle): h is OutputHandle =>\n h._tag === 'output';\n\n/**\n * Converts a handle to a JSON `$ref` pointer used in the flow document.\n * Input handles become `\"input.<name>\"`; output handles become `\"<nodeId>.<port>\"`.\n */\nexport const handleToRef = (h: AnyHandle): { $ref: string } => {\n if (h._tag === 'input') {\n if (!h.inputName) throw new Error('InputHandle has empty inputName');\n return { $ref: `input.${h.inputName}` };\n }\n if (!h.nodeId) throw new Error('OutputHandle has empty nodeId');\n if (!h.portName) throw new Error('OutputHandle has empty portName');\n return { $ref: `${h.nodeId}.${h.portName}` };\n};\n\n/**\n * For a bind slot expecting type T, widen the set of accepted handle types:\n * - `'bytes32'` is the raw 32-byte word type: accept any static-32-byte handle\n * (`uint256`/`uintN`/`address`/`bool`/`bytes32`) plus `'resource'` (a uint256\n * amount). At the IR1 boundary every value is a type-erased word, so any\n * static-32-byte handle is a sound bind for a `bytes32` payload port.\n * - `'uint256'` keeps its existing widening to also accept `'resource'`-tagged\n * handles (resources are uint256 amounts).\n * - every other type keeps exact-SolType matching.\n */\ntype SlotAssignable<T extends OutputKind> = T extends 'bytes32'\n ? StaticSolType | 'resource'\n : T extends 'uint256'\n ? T | 'resource'\n : T;\n\n/**\n * The values accepted by a typed slot that must resolve to a `$ref`:\n * - `OutputHandle<T>` / `InputHandle<T>` (same type)\n * - For `'uint256'` slots, also `'resource'`-tagged handles\n * - For `'bytes32'` slots, any static-32-byte handle (and `'resource'`)\n * - `TypedRef<T>` (typed context refs, subject to `SlotAssignable`)\n *\n * Plain `{ $ref: '...' }` objects are **not** accepted - use `raw.ref<T>()`\n * to create a typed ref when you need to reference a raw path.\n */\nexport type RefBindable<T extends OutputKind> =\n | OutputHandle<SlotAssignable<T>>\n | InputHandle<SlotAssignable<T>>\n | TypedRef<SlotAssignable<T>>;\n\n/**\n * Any ref-resolving bindable, with no per-slot type constraint.\n */\nexport type AnyRefBindable = InputHandle | OutputHandle | TypedRef;\n\n/**\n * The set of values accepted by a typed operation bind slot: everything\n * {@link RefBindable} accepts, plus a {@link TypedLiteral} constant baked\n * into the flow document. A `'resource'` slot rejects a literal: a token\n * resource is not a scalar constant.\n *\n * Use `raw.literal<T>()` to create one.\n */\nexport type Bindable<T extends OutputKind> =\n RefBindable<T> | LiteralBindable<SlotAssignable<T>>;\n\n// Distributes over the slot's assignable kinds and keeps the scalar ones: a\n// `'resource'` slot has no scalar arm, so its literal arm collapses to\n// `never` and a literal is rejected outright.\ntype LiteralBindable<K extends OutputKind> = K extends SolType\n ? TypedLiteral<K>\n : never;\n\n/**\n * Converts a bindable to the wire `bind` value it denotes: handles become\n * `$ref` pointers, refs and literals pass through as-is.\n */\nexport const toBindValue = (\n bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref,\n): BindValue => ('_tag' in bindable ? handleToRef(bindable) : bindable);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgHO,MAAM,gBAAgB,CAAC,MAC5B,EAAE,SAAS;AAGN,MAAM,iBAAiB,CAAC,MAC7B,EAAE,SAAS;AAMN,MAAM,cAAc,CAAC,MAAmC;AAC7D,MAAI,EAAE,SAAS,SAAS;AACtB,QAAI,CAAC,EAAE,UAAW,OAAM,IAAI,MAAM,iCAAiC;AACnE,WAAO,EAAE,MAAM,SAAS,EAAE,SAAS,GAAG;AAAA,EACxC;AACA,MAAI,CAAC,EAAE,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAC9D,MAAI,CAAC,EAAE,SAAU,OAAM,IAAI,MAAM,iCAAiC;AAClE,SAAO,EAAE,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAG;AAC7C;AA4DO,MAAM,cAAc,CACzB,aACe,UAAU,WAAW,YAAY,QAAQ,IAAI;","names":[]}
@@ -29,6 +29,40 @@ interface OutputHandle<T extends OutputKind = OutputKind> {
29
29
  readonly portName: string;
30
30
  readonly __outputKind?: T;
31
31
  }
32
+ /**
33
+ * What an output family's sizing parameter accepts, given the config field the
34
+ * family counts from: an array of that field's elements, or a number.
35
+ */
36
+ type FamilySource<Field> = Field extends readonly (infer E)[] ? readonly E[] : number;
37
+ /** Whether a number literal is a valid family count: a non-negative integer. */
38
+ type IsCountLiteral<N extends number> = `${N}` extends `-${string}` | `${string}.${string}` | `${string}e${string}` ? false : true;
39
+ /**
40
+ * `N` resource handles as a tuple. A non-literal `number`, or a literal that is
41
+ * not a valid count, gives an open array; {@link FamilyCount} rejects the
42
+ * invalid literal at the call site.
43
+ */
44
+ type HandleTuple<N extends number, Acc extends readonly OutputHandle<'resource'>[] = readonly []> = number extends N ? readonly OutputHandle<'resource'>[] : IsCountLiteral<N> extends false ? readonly OutputHandle<'resource'>[] : Acc['length'] extends N ? Acc : HandleTuple<N, readonly [...Acc, OutputHandle<'resource'>]>;
45
+ /**
46
+ * The handles of an output family: one resource {@link OutputHandle} per
47
+ * element of the config array the family counts from, or as many as the config
48
+ * count. A literal array or count yields a tuple of that length, so indexing
49
+ * past the last instance is a type error.
50
+ */
51
+ type OutputFamilyHandles<TCount extends readonly unknown[] | number> = TCount extends readonly unknown[] ? {
52
+ readonly [I in keyof TCount]: OutputHandle<'resource'>;
53
+ } : TCount extends number ? HandleTuple<TCount> : never;
54
+ /**
55
+ * Holds the config value an output family counts from to the op's own type. A
56
+ * runtime-sized array or count passes as is. A literal tuple must also satisfy
57
+ * `Shape`, so a tuple shorter than the op's `minItems` fails at the call site
58
+ * instead of at the server's bind step. A literal count must be a non-negative
59
+ * integer.
60
+ */
61
+ type FamilyCount<TCount extends readonly unknown[] | number, Shape> = TCount extends readonly unknown[] ? number extends TCount['length'] ? unknown : TCount extends Shape ? unknown : {
62
+ readonly 'output family config array has too few entries': never;
63
+ } : TCount extends number ? IsCountLiteral<TCount> extends true ? unknown : {
64
+ readonly 'output family count must be a non-negative integer': never;
65
+ } : unknown;
32
66
  /** Discriminated union of all handle types that can be bound to operation arguments. */
33
67
  type AnyHandle = InputHandle | OutputHandle;
34
68
  /** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */
@@ -84,4 +118,4 @@ type LiteralBindable<K extends OutputKind> = K extends SolType ? TypedLiteral<K>
84
118
  */
85
119
  declare const toBindValue: (bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref) => BindValue;
86
120
 
87
- export { type AnyHandle, type AnyRefBindable, type Bindable, type InputHandle, type OutputHandle, type RefBindable, type ResourceInputHandle, handleToRef, isInputHandle, isOutputHandle, toBindValue };
121
+ export { type AnyHandle, type AnyRefBindable, type Bindable, type FamilyCount, type FamilySource, type InputHandle, type OutputFamilyHandles, type OutputHandle, type RefBindable, type ResourceInputHandle, handleToRef, isInputHandle, isOutputHandle, toBindValue };
@@ -29,6 +29,40 @@ interface OutputHandle<T extends OutputKind = OutputKind> {
29
29
  readonly portName: string;
30
30
  readonly __outputKind?: T;
31
31
  }
32
+ /**
33
+ * What an output family's sizing parameter accepts, given the config field the
34
+ * family counts from: an array of that field's elements, or a number.
35
+ */
36
+ type FamilySource<Field> = Field extends readonly (infer E)[] ? readonly E[] : number;
37
+ /** Whether a number literal is a valid family count: a non-negative integer. */
38
+ type IsCountLiteral<N extends number> = `${N}` extends `-${string}` | `${string}.${string}` | `${string}e${string}` ? false : true;
39
+ /**
40
+ * `N` resource handles as a tuple. A non-literal `number`, or a literal that is
41
+ * not a valid count, gives an open array; {@link FamilyCount} rejects the
42
+ * invalid literal at the call site.
43
+ */
44
+ type HandleTuple<N extends number, Acc extends readonly OutputHandle<'resource'>[] = readonly []> = number extends N ? readonly OutputHandle<'resource'>[] : IsCountLiteral<N> extends false ? readonly OutputHandle<'resource'>[] : Acc['length'] extends N ? Acc : HandleTuple<N, readonly [...Acc, OutputHandle<'resource'>]>;
45
+ /**
46
+ * The handles of an output family: one resource {@link OutputHandle} per
47
+ * element of the config array the family counts from, or as many as the config
48
+ * count. A literal array or count yields a tuple of that length, so indexing
49
+ * past the last instance is a type error.
50
+ */
51
+ type OutputFamilyHandles<TCount extends readonly unknown[] | number> = TCount extends readonly unknown[] ? {
52
+ readonly [I in keyof TCount]: OutputHandle<'resource'>;
53
+ } : TCount extends number ? HandleTuple<TCount> : never;
54
+ /**
55
+ * Holds the config value an output family counts from to the op's own type. A
56
+ * runtime-sized array or count passes as is. A literal tuple must also satisfy
57
+ * `Shape`, so a tuple shorter than the op's `minItems` fails at the call site
58
+ * instead of at the server's bind step. A literal count must be a non-negative
59
+ * integer.
60
+ */
61
+ type FamilyCount<TCount extends readonly unknown[] | number, Shape> = TCount extends readonly unknown[] ? number extends TCount['length'] ? unknown : TCount extends Shape ? unknown : {
62
+ readonly 'output family config array has too few entries': never;
63
+ } : TCount extends number ? IsCountLiteral<TCount> extends true ? unknown : {
64
+ readonly 'output family count must be a non-negative integer': never;
65
+ } : unknown;
32
66
  /** Discriminated union of all handle types that can be bound to operation arguments. */
33
67
  type AnyHandle = InputHandle | OutputHandle;
34
68
  /** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */
@@ -84,4 +118,4 @@ type LiteralBindable<K extends OutputKind> = K extends SolType ? TypedLiteral<K>
84
118
  */
85
119
  declare const toBindValue: (bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref) => BindValue;
86
120
 
87
- export { type AnyHandle, type AnyRefBindable, type Bindable, type InputHandle, type OutputHandle, type RefBindable, type ResourceInputHandle, handleToRef, isInputHandle, isOutputHandle, toBindValue };
121
+ export { type AnyHandle, type AnyRefBindable, type Bindable, type FamilyCount, type FamilySource, type InputHandle, type OutputFamilyHandles, type OutputHandle, type RefBindable, type ResourceInputHandle, handleToRef, isInputHandle, isOutputHandle, toBindValue };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/authoring/handles.ts"],"sourcesContent":["import type {\n BindValue,\n Ref,\n Resource,\n SolType,\n StaticSolType,\n} from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * A handle referencing a flow input declared in the flow's input schema.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface InputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'input';\n readonly inputName: string;\n readonly __outputKind?: T;\n}\n\n/**\n * An input handle for a resource (token) input, carrying the resource\n * declaration alongside the reference.\n */\nexport interface ResourceInputHandle extends InputHandle<'resource'> {\n readonly resource: Resource;\n}\n\n/**\n * A handle referencing an output port of a previously declared operation node.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface OutputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'output';\n readonly nodeId: string;\n readonly portName: string;\n readonly __outputKind?: T;\n}\n\n/** Discriminated union of all handle types that can be bound to operation arguments. */\nexport type AnyHandle = InputHandle | OutputHandle;\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */\nexport const isInputHandle = (h: AnyHandle): h is InputHandle =>\n h._tag === 'input';\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link OutputHandle}. */\nexport const isOutputHandle = (h: AnyHandle): h is OutputHandle =>\n h._tag === 'output';\n\n/**\n * Converts a handle to a JSON `$ref` pointer used in the flow document.\n * Input handles become `\"input.<name>\"`; output handles become `\"<nodeId>.<port>\"`.\n */\nexport const handleToRef = (h: AnyHandle): { $ref: string } => {\n if (h._tag === 'input') {\n if (!h.inputName) throw new Error('InputHandle has empty inputName');\n return { $ref: `input.${h.inputName}` };\n }\n if (!h.nodeId) throw new Error('OutputHandle has empty nodeId');\n if (!h.portName) throw new Error('OutputHandle has empty portName');\n return { $ref: `${h.nodeId}.${h.portName}` };\n};\n\n/**\n * For a bind slot expecting type T, widen the set of accepted handle types:\n * - `'bytes32'` is the raw 32-byte word type: accept any static-32-byte handle\n * (`uint256`/`uintN`/`address`/`bool`/`bytes32`) plus `'resource'` (a uint256\n * amount). At the IR1 boundary every value is a type-erased word, so any\n * static-32-byte handle is a sound bind for a `bytes32` payload port.\n * - `'uint256'` keeps its existing widening to also accept `'resource'`-tagged\n * handles (resources are uint256 amounts).\n * - every other type keeps exact-SolType matching.\n */\ntype SlotAssignable<T extends OutputKind> = T extends 'bytes32'\n ? StaticSolType | 'resource'\n : T extends 'uint256'\n ? T | 'resource'\n : T;\n\n/**\n * The values accepted by a typed slot that must resolve to a `$ref`:\n * - `OutputHandle<T>` / `InputHandle<T>` (same type)\n * - For `'uint256'` slots, also `'resource'`-tagged handles\n * - For `'bytes32'` slots, any static-32-byte handle (and `'resource'`)\n * - `TypedRef<T>` (typed context refs, subject to `SlotAssignable`)\n *\n * Plain `{ $ref: '...' }` objects are **not** accepted - use `raw.ref<T>()`\n * to create a typed ref when you need to reference a raw path.\n */\nexport type RefBindable<T extends OutputKind> =\n | OutputHandle<SlotAssignable<T>>\n | InputHandle<SlotAssignable<T>>\n | TypedRef<SlotAssignable<T>>;\n\n/**\n * Any ref-resolving bindable, with no per-slot type constraint.\n */\nexport type AnyRefBindable = InputHandle | OutputHandle | TypedRef;\n\n/**\n * The set of values accepted by a typed operation bind slot: everything\n * {@link RefBindable} accepts, plus a {@link TypedLiteral} constant baked\n * into the flow document. A `'resource'` slot rejects a literal: a token\n * resource is not a scalar constant.\n *\n * Use `raw.literal<T>()` to create one.\n */\nexport type Bindable<T extends OutputKind> =\n RefBindable<T> | LiteralBindable<SlotAssignable<T>>;\n\n// Distributes over the slot's assignable kinds and keeps the scalar ones: a\n// `'resource'` slot has no scalar arm, so its literal arm collapses to\n// `never` and a literal is rejected outright.\ntype LiteralBindable<K extends OutputKind> = K extends SolType\n ? TypedLiteral<K>\n : never;\n\n/**\n * Converts a bindable to the wire `bind` value it denotes: handles become\n * `$ref` pointers, refs and literals pass through as-is.\n */\nexport const toBindValue = (\n bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref,\n): BindValue => ('_tag' in bindable ? handleToRef(bindable) : bindable);\n"],"mappings":"AA6CO,MAAM,gBAAgB,CAAC,MAC5B,EAAE,SAAS;AAGN,MAAM,iBAAiB,CAAC,MAC7B,EAAE,SAAS;AAMN,MAAM,cAAc,CAAC,MAAmC;AAC7D,MAAI,EAAE,SAAS,SAAS;AACtB,QAAI,CAAC,EAAE,UAAW,OAAM,IAAI,MAAM,iCAAiC;AACnE,WAAO,EAAE,MAAM,SAAS,EAAE,SAAS,GAAG;AAAA,EACxC;AACA,MAAI,CAAC,EAAE,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAC9D,MAAI,CAAC,EAAE,SAAU,OAAM,IAAI,MAAM,iCAAiC;AAClE,SAAO,EAAE,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAG;AAC7C;AA4DO,MAAM,cAAc,CACzB,aACe,UAAU,WAAW,YAAY,QAAQ,IAAI;","names":[]}
1
+ {"version":3,"sources":["../../src/authoring/handles.ts"],"sourcesContent":["import type {\n BindValue,\n Ref,\n Resource,\n SolType,\n StaticSolType,\n} from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedLiteral, TypedRef } from '../types.js';\n\n/**\n * A handle referencing a flow input declared in the flow's input schema.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface InputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'input';\n readonly inputName: string;\n readonly __outputKind?: T;\n}\n\n/**\n * An input handle for a resource (token) input, carrying the resource\n * declaration alongside the reference.\n */\nexport interface ResourceInputHandle extends InputHandle<'resource'> {\n readonly resource: Resource;\n}\n\n/**\n * A handle referencing an output port of a previously declared operation node.\n * The phantom `__outputKind` field carries the type parameter through\n * TypeScript's structural type system without affecting runtime shape.\n */\nexport interface OutputHandle<T extends OutputKind = OutputKind> {\n readonly _tag: 'output';\n readonly nodeId: string;\n readonly portName: string;\n readonly __outputKind?: T;\n}\n\n/**\n * What an output family's sizing parameter accepts, given the config field the\n * family counts from: an array of that field's elements, or a number.\n */\nexport type FamilySource<Field> = Field extends readonly (infer E)[]\n ? readonly E[]\n : number;\n\n/** Whether a number literal is a valid family count: a non-negative integer. */\ntype IsCountLiteral<N extends number> = `${N}` extends\n `-${string}` | `${string}.${string}` | `${string}e${string}`\n ? false\n : true;\n\n/**\n * `N` resource handles as a tuple. A non-literal `number`, or a literal that is\n * not a valid count, gives an open array; {@link FamilyCount} rejects the\n * invalid literal at the call site.\n */\ntype HandleTuple<\n N extends number,\n Acc extends readonly OutputHandle<'resource'>[] = readonly [],\n> = number extends N\n ? readonly OutputHandle<'resource'>[]\n : IsCountLiteral<N> extends false\n ? readonly OutputHandle<'resource'>[]\n : Acc['length'] extends N\n ? Acc\n : HandleTuple<N, readonly [...Acc, OutputHandle<'resource'>]>;\n\n/**\n * The handles of an output family: one resource {@link OutputHandle} per\n * element of the config array the family counts from, or as many as the config\n * count. A literal array or count yields a tuple of that length, so indexing\n * past the last instance is a type error.\n */\nexport type OutputFamilyHandles<TCount extends readonly unknown[] | number> =\n TCount extends readonly unknown[]\n ? { readonly [I in keyof TCount]: OutputHandle<'resource'> }\n : TCount extends number\n ? HandleTuple<TCount>\n : never;\n\n/**\n * Holds the config value an output family counts from to the op's own type. A\n * runtime-sized array or count passes as is. A literal tuple must also satisfy\n * `Shape`, so a tuple shorter than the op's `minItems` fails at the call site\n * instead of at the server's bind step. A literal count must be a non-negative\n * integer.\n */\nexport type FamilyCount<\n TCount extends readonly unknown[] | number,\n Shape,\n> = TCount extends readonly unknown[]\n ? number extends TCount['length']\n ? unknown\n : TCount extends Shape\n ? unknown\n : { readonly 'output family config array has too few entries': never }\n : TCount extends number\n ? IsCountLiteral<TCount> extends true\n ? unknown\n : {\n readonly 'output family count must be a non-negative integer': never;\n }\n : unknown;\n\n/** Discriminated union of all handle types that can be bound to operation arguments. */\nexport type AnyHandle = InputHandle | OutputHandle;\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */\nexport const isInputHandle = (h: AnyHandle): h is InputHandle =>\n h._tag === 'input';\n\n/** Type guard that narrows an {@link AnyHandle} to an {@link OutputHandle}. */\nexport const isOutputHandle = (h: AnyHandle): h is OutputHandle =>\n h._tag === 'output';\n\n/**\n * Converts a handle to a JSON `$ref` pointer used in the flow document.\n * Input handles become `\"input.<name>\"`; output handles become `\"<nodeId>.<port>\"`.\n */\nexport const handleToRef = (h: AnyHandle): { $ref: string } => {\n if (h._tag === 'input') {\n if (!h.inputName) throw new Error('InputHandle has empty inputName');\n return { $ref: `input.${h.inputName}` };\n }\n if (!h.nodeId) throw new Error('OutputHandle has empty nodeId');\n if (!h.portName) throw new Error('OutputHandle has empty portName');\n return { $ref: `${h.nodeId}.${h.portName}` };\n};\n\n/**\n * For a bind slot expecting type T, widen the set of accepted handle types:\n * - `'bytes32'` is the raw 32-byte word type: accept any static-32-byte handle\n * (`uint256`/`uintN`/`address`/`bool`/`bytes32`) plus `'resource'` (a uint256\n * amount). At the IR1 boundary every value is a type-erased word, so any\n * static-32-byte handle is a sound bind for a `bytes32` payload port.\n * - `'uint256'` keeps its existing widening to also accept `'resource'`-tagged\n * handles (resources are uint256 amounts).\n * - every other type keeps exact-SolType matching.\n */\ntype SlotAssignable<T extends OutputKind> = T extends 'bytes32'\n ? StaticSolType | 'resource'\n : T extends 'uint256'\n ? T | 'resource'\n : T;\n\n/**\n * The values accepted by a typed slot that must resolve to a `$ref`:\n * - `OutputHandle<T>` / `InputHandle<T>` (same type)\n * - For `'uint256'` slots, also `'resource'`-tagged handles\n * - For `'bytes32'` slots, any static-32-byte handle (and `'resource'`)\n * - `TypedRef<T>` (typed context refs, subject to `SlotAssignable`)\n *\n * Plain `{ $ref: '...' }` objects are **not** accepted - use `raw.ref<T>()`\n * to create a typed ref when you need to reference a raw path.\n */\nexport type RefBindable<T extends OutputKind> =\n | OutputHandle<SlotAssignable<T>>\n | InputHandle<SlotAssignable<T>>\n | TypedRef<SlotAssignable<T>>;\n\n/**\n * Any ref-resolving bindable, with no per-slot type constraint.\n */\nexport type AnyRefBindable = InputHandle | OutputHandle | TypedRef;\n\n/**\n * The set of values accepted by a typed operation bind slot: everything\n * {@link RefBindable} accepts, plus a {@link TypedLiteral} constant baked\n * into the flow document. A `'resource'` slot rejects a literal: a token\n * resource is not a scalar constant.\n *\n * Use `raw.literal<T>()` to create one.\n */\nexport type Bindable<T extends OutputKind> =\n RefBindable<T> | LiteralBindable<SlotAssignable<T>>;\n\n// Distributes over the slot's assignable kinds and keeps the scalar ones: a\n// `'resource'` slot has no scalar arm, so its literal arm collapses to\n// `never` and a literal is rejected outright.\ntype LiteralBindable<K extends OutputKind> = K extends SolType\n ? TypedLiteral<K>\n : never;\n\n/**\n * Converts a bindable to the wire `bind` value it denotes: handles become\n * `$ref` pointers, refs and literals pass through as-is.\n */\nexport const toBindValue = (\n bindable: InputHandle | OutputHandle | TypedRef | TypedLiteral | Ref,\n): BindValue => ('_tag' in bindable ? handleToRef(bindable) : bindable);\n"],"mappings":"AAgHO,MAAM,gBAAgB,CAAC,MAC5B,EAAE,SAAS;AAGN,MAAM,iBAAiB,CAAC,MAC7B,EAAE,SAAS;AAMN,MAAM,cAAc,CAAC,MAAmC;AAC7D,MAAI,EAAE,SAAS,SAAS;AACtB,QAAI,CAAC,EAAE,UAAW,OAAM,IAAI,MAAM,iCAAiC;AACnE,WAAO,EAAE,MAAM,SAAS,EAAE,SAAS,GAAG;AAAA,EACxC;AACA,MAAI,CAAC,EAAE,OAAQ,OAAM,IAAI,MAAM,+BAA+B;AAC9D,MAAI,CAAC,EAAE,SAAU,OAAM,IAAI,MAAM,iCAAiC;AAClE,SAAO,EAAE,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,QAAQ,GAAG;AAC7C;AA4DO,MAAM,cAAc,CACzB,aACe,UAAU,WAAW,YAAY,QAAQ,IAAI;","names":[]}
package/dist/client.cjs CHANGED
@@ -25,7 +25,7 @@ module.exports = __toCommonJS(client_exports);
25
25
  var import_compose_spec = require("@lifi/compose-spec");
26
26
  var import_errors = require("./errors.js");
27
27
  var import_responseSchemas = require("./responseSchemas.js");
28
- const SDK_VERSION = true ? "0.6.2" : "dev";
28
+ const SDK_VERSION = true ? "0.7.0" : "dev";
29
29
  const SDK_VERSION_TRIPLE = (0, import_compose_spec.parseVersion)(SDK_VERSION);
30
30
  const bigintReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
31
31
  const isNonNullObject = (v) => typeof v === "object" && v !== null;
package/dist/client.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  parseCompilePartialEnvelope,
10
10
  parseSimulateResult
11
11
  } from "./responseSchemas.js";
12
- const SDK_VERSION = true ? "0.6.2" : "dev";
12
+ const SDK_VERSION = true ? "0.7.0" : "dev";
13
13
  const SDK_VERSION_TRIPLE = parseVersion(SDK_VERSION);
14
14
  const bigintReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
15
15
  const isNonNullObject = (v) => typeof v === "object" && v !== null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/generated/config.generated.ts"],"sourcesContent":["// AUTO-GENERATED from manifest.json — do not edit by hand.\n// Regenerate with: yarn workspace @lifi/composer-sdk generate\n\nimport type { Address, IntegerStringInput } from '../types.js';\n\n/**\n * a number between 0 and 10000\n */\nexport type Between010000 = number;\n\nexport interface CoreSplitConfig {\n bps: Between010000;\n}\n\n/**\n * a positive number\n */\nexport type Positive = number;\n/**\n * a string at most 64 character(s) long\n */\nexport type MaxLength64 = string;\n/**\n * an array of at most 50 item(s)\n *\n * @maxItems 50\n */\nexport type MaxItems50 = MaxLength64[];\n\nexport interface LifiSwapConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n slippage?: number;\n timing?: {\n swapStepTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n routeTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n };\n exchanges?: {\n allow?: MaxItems50;\n deny?: MaxItems50;\n prefer?: MaxItems50;\n };\n}\n\n/**\n * a string starting with \"0x\"\n */\nexport type StartsWith0X = string;\n/**\n * a number between 0 and 1\n */\nexport type Between01 = number;\n\nexport interface LifiBridgeConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n destination: StartsWith0X;\n slippage?: Between01;\n timing?: {\n swapStepTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n routeTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n };\n bridges?: {\n allow?: MaxItems50;\n deny?: MaxItems50;\n prefer?: MaxItems50;\n };\n exchanges?: {\n allow?: MaxItems50;\n deny?: MaxItems50;\n prefer?: MaxItems50;\n };\n order?: 'FASTEST' | 'CHEAPEST';\n}\n\nexport interface InvariantNumericConfig {\n op: 'gte' | 'gt' | 'lte' | 'lt' | 'eq' | 'neq';\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantNumericInRangeConfig {\n min: IntegerStringInput;\n max: IntegerStringInput;\n}\n\nexport interface InvariantGteConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantGtConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantLteConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantLtConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantEqConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantNeqConfig {\n threshold: IntegerStringInput;\n}\n\n/**\n * a non-negative number\n */\nexport type NonNegative = number;\n\nexport interface CoreBpsDownConfig {\n bps: NonNegative;\n}\n\nexport interface CoreBpsUpConfig {\n bps: NonNegative;\n}\n\nexport interface CoreApproveConfig {\n spender: Address;\n}\n\nexport interface CoreBalanceOfConfig {\n token: Address;\n owner?: Address;\n}\n\nexport interface CoreTransferConfig {\n amount?: IntegerStringInput;\n}\n\nexport interface CoreEmitEvent1Config {\n signature: string;\n}\n\nexport interface CoreEmitEvent2Config {\n signature: string;\n}\n\nexport interface CoreEmitEvent3Config {\n signature: string;\n}\n\nexport interface CoreEmitEvent4Config {\n signature: string;\n}\n\n/**\n * a string at most 65536 character(s) long\n */\nexport type MaxLength65536 = string;\n\nexport interface CoreCallConfig {\n target: Address;\n functionSignature: string;\n callType?: 'Call' | 'ValueCall';\n args?: (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )[]\n )[]\n )[]\n )[]\n )[]\n )[];\n approvals?: (\n | {\n spender: Address;\n }\n | {\n from: 'sender';\n }\n )[];\n}\n\nexport interface CoreStaticCallConfig {\n target: Address;\n functionSignature: string;\n args?: (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )[]\n )[]\n )[]\n )[]\n )[]\n )[];\n}\n\nexport interface CoreRawCallConfig {\n target: Address;\n calldata: string;\n callType?: 'Call' | 'StaticCall' | 'ValueCall' | 'DelegateCall';\n resultType?: string;\n}\n\nexport interface CoreInvokeConfig {\n target: Address;\n functionSignature: string;\n callType?: 'Call' | 'ValueCall';\n args?: (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )[]\n )[]\n )[]\n )[]\n )[]\n )[];\n}\n\nexport interface CoreAsResourceConfig {\n resource:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n}\n\nexport interface AaveBorrowConfig {\n pool: string;\n asset: string;\n variableDebtToken: string;\n amount: IntegerStringInput;\n referralId?: number;\n}\n\nexport type AaveRepayConfig =\n | {\n pool: string;\n mode: 'exact';\n }\n | {\n pool: string;\n mode: 'max';\n };\n\nexport interface AaveRepayWithATokensConfig {\n pool: string;\n asset: string;\n}\n\nexport interface AaveClaimRewardsConfig {\n rewardsController: string;\n assets: string[];\n reward: string;\n amount?: IntegerStringInput;\n to?: string;\n}\n\n/**\n * a number between 0 and 255\n */\nexport type Between0255 = number;\n\nexport interface AaveSetEModeConfig {\n pool: string;\n category: Between0255;\n}\n\nexport interface AaveGetHealthFactorConfig {\n pool: string;\n user?: string;\n}\n\nexport type MorphoBlueSupplyCollateralConfig =\n | (\n | {\n morpho?: string;\n onBehalfOf?: string;\n mode: 'exact';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n onBehalfOf?: string;\n mode: 'exact';\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n }\n )\n | (\n | {\n morpho?: string;\n onBehalfOf?: string;\n mode: 'all';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n onBehalfOf?: string;\n mode: 'all';\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n }\n );\n\nexport type MorphoBlueWithdrawCollateralConfig =\n | {\n morpho?: string;\n amount: IntegerStringInput;\n onBehalfOf?: string;\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n amount: IntegerStringInput;\n onBehalfOf?: string;\n receiver?: string;\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n };\n\nexport type MorphoBlueBorrowConfig =\n | {\n morpho?: string;\n amount: IntegerStringInput;\n onBehalfOf?: string;\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n amount: IntegerStringInput;\n onBehalfOf?: string;\n receiver?: string;\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n };\n\nexport type MorphoBlueRepayConfig =\n | (\n | {\n morpho?: string;\n mode: 'exact';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n mode: 'exact';\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n }\n )\n | (\n | {\n morpho?: string;\n mode: 'max';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n mode: 'max';\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n }\n );\n\nexport type MorphoBlueSupplyConfig =\n | {\n morpho?: string;\n onBehalfOf?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n onBehalfOf?: string;\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n };\n\nexport type MorphoBlueWithdrawConfig =\n | (\n | {\n morpho?: string;\n mode: 'exact';\n amount: IntegerStringInput;\n onBehalfOf?: string;\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n mode: 'exact';\n amount: IntegerStringInput;\n onBehalfOf?: string;\n receiver?: string;\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n }\n )\n | (\n | {\n morpho?: string;\n mode: 'max';\n onBehalfOf?: string;\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n mode: 'max';\n onBehalfOf?: string;\n receiver?: string;\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n }\n );\n\nexport type MorphoBlueGetPositionConfig =\n | {\n morpho?: string;\n user?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n morpho?: string;\n user?: string;\n marketParams: {\n loanToken: string;\n collateralToken: string;\n oracle: string;\n irm: string;\n lltv: string;\n };\n };\n\nexport interface LifiFlashloanRepayConfig {\n leg: string;\n fee?: string;\n}\n\nexport type ContinuationAssertReadyConfig =\n | {\n kind: 'erc20BalanceGte';\n chainId: Positive;\n token: StartsWith0X;\n owner: StartsWith0X;\n minAmount: string;\n }\n | {\n kind: 'nativeBalanceGte';\n chainId: Positive;\n owner: StartsWith0X;\n minAmount: string;\n }\n | {\n kind: 'call';\n chainId: Positive;\n to: StartsWith0X;\n calldata: StartsWith0X;\n comparator: 'gte' | 'eq' | 'lte';\n value: string;\n };\n\nexport interface LifiZapConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n}\n\nexport interface LifiZapAsyncConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n}\n\nexport interface ParaswapBuyConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n exactAmountOut: string;\n srcDecimals: NonNegative;\n destDecimals: NonNegative;\n maxSlippageBps?: Between010000;\n partner?: string;\n partnerAddress?: string;\n /**\n * Integrator fee in basis points; non-negative integer string capped at 9000.\n */\n partnerFeeBps?: string;\n}\n\nexport interface CorePeekConfig {\n target: Address;\n functionSignature: string;\n args?: string[];\n}\n\n/**\n * a number between 0 and 3318\n */\nexport type Between03318 = number;\n/**\n * a number between 0 and 5000\n */\nexport type Between05000 = number;\n\nexport interface FlySwapConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n token: Address;\n chainId: Positive;\n };\n inputVarianceBps?: Between03318;\n maxSlippageBps?: Between05000;\n}\n\nexport interface SlippageGuardConfig {\n port: string;\n bps: Between010000;\n}\n\nexport interface CoreNumericInvariantGuardConfig {\n port: string;\n op: 'gte' | 'gt' | 'lte' | 'lt' | 'eq' | 'neq';\n threshold: IntegerStringInput;\n}\n\nexport interface BalanceOfMaterialiserConfig {\n owner: Address;\n}\n\nexport type DirectDepositMaterialiserConfig =\n | {\n amount: IntegerStringInput;\n allowNonExact?: false;\n }\n | {\n amount: IntegerStringInput;\n allowNonExact: true;\n }\n | {\n allowNonExact: true;\n simAmount?: string;\n };\n\nexport interface CallMaterialiserConfig {\n target: Address;\n calldata: string;\n}\n\nexport interface FlashloanMaterialiserConfig {\n providerKind: 'aave-v3' | 'erc3156' | 'balancer-v2' | 'morpho-blue';\n amount: IntegerStringInput;\n}\n\nexport interface Erc20BalancePreconditionConfig {\n wallet: Address;\n token: Address;\n balance: IntegerStringInput;\n}\n\nexport interface NativeBalancePreconditionConfig {\n wallet: Address;\n balance: IntegerStringInput;\n}\n\nexport interface Erc20AllowancePreconditionConfig {\n owner: Address;\n spender: Address;\n token: Address;\n allowance: IntegerStringInput;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/generated/config.generated.ts"],"sourcesContent":["// AUTO-GENERATED from manifest.json — do not edit by hand.\n// Regenerate with: yarn workspace @lifi/composer-sdk generate\n\nimport type { Address, IntegerStringInput } from '../types.js';\n\n/**\n * a number between 0 and 10000\n */\nexport type Between010000 = number;\n\nexport interface CoreSplitConfig {\n bps: Between010000;\n}\n\n/**\n * an array of at most 16 item(s)\n *\n * @minItems 2\n * @maxItems 16\n */\nexport type MaxItems16 =\n | [Between19999, Between19999]\n | [Between19999, Between19999, Between19999]\n | [Between19999, Between19999, Between19999, Between19999]\n | [Between19999, Between19999, Between19999, Between19999, Between19999]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ]\n | [\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n Between19999,\n ];\n/**\n * a number between 1 and 9999\n */\nexport type Between19999 = number;\n\nexport interface CorePartitionConfig {\n bps: MaxItems16;\n}\n\n/**\n * a positive number\n */\nexport type Positive = number;\n/**\n * a string at most 64 character(s) long\n */\nexport type MaxLength64 = string;\n/**\n * an array of at most 50 item(s)\n *\n * @maxItems 50\n */\nexport type MaxItems50 = MaxLength64[];\n\nexport interface LifiSwapConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n slippage?: number;\n timing?: {\n swapStepTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n routeTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n };\n exchanges?: {\n allow?: MaxItems50;\n deny?: MaxItems50;\n prefer?: MaxItems50;\n };\n}\n\n/**\n * a string starting with \"0x\"\n */\nexport type StartsWith0X = string;\n/**\n * a number between 0 and 1\n */\nexport type Between01 = number;\n\nexport interface LifiBridgeConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n destination: StartsWith0X;\n slippage?: Between01;\n timing?: {\n swapStepTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n routeTimingStrategies?: {\n strategy: 'minWaitTime';\n minWaitTimeMs: number;\n startingExpectedResults: number;\n reduceEveryMs: number;\n }[];\n };\n bridges?: {\n allow?: MaxItems50;\n deny?: MaxItems50;\n prefer?: MaxItems50;\n };\n exchanges?: {\n allow?: MaxItems50;\n deny?: MaxItems50;\n prefer?: MaxItems50;\n };\n order?: 'FASTEST' | 'CHEAPEST';\n}\n\nexport interface InvariantNumericConfig {\n op: 'gte' | 'gt' | 'lte' | 'lt' | 'eq' | 'neq';\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantNumericInRangeConfig {\n min: IntegerStringInput;\n max: IntegerStringInput;\n}\n\nexport interface InvariantGteConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantGtConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantLteConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantLtConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantEqConfig {\n threshold: IntegerStringInput;\n}\n\nexport interface InvariantNeqConfig {\n threshold: IntegerStringInput;\n}\n\n/**\n * a non-negative number\n */\nexport type NonNegative = number;\n\nexport interface CoreBpsDownConfig {\n bps: NonNegative;\n}\n\nexport interface CoreBpsUpConfig {\n bps: NonNegative;\n}\n\nexport interface CoreApproveConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n spender: Address;\n}\n\nexport interface CoreBalanceOfConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n owner?: Address;\n}\n\nexport interface CoreTransferConfig {\n amount?: IntegerStringInput;\n}\n\nexport interface CoreEmitEvent1Config {\n signature: string;\n}\n\nexport interface CoreEmitEvent2Config {\n signature: string;\n}\n\nexport interface CoreEmitEvent3Config {\n signature: string;\n}\n\nexport interface CoreEmitEvent4Config {\n signature: string;\n}\n\n/**\n * a string at most 65536 character(s) long\n */\nexport type MaxLength65536 = string;\n\nexport interface CoreCallConfig {\n target: Address;\n functionSignature: string;\n callType?: 'Call' | 'ValueCall';\n args?: (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )[]\n )[]\n )[]\n )[]\n )[]\n )[];\n approvals?: (\n | {\n spender: Address;\n }\n | {\n from: 'sender';\n }\n )[];\n}\n\nexport interface CoreStaticCallConfig {\n target: Address;\n functionSignature: string;\n args?: (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )[]\n )[]\n )[]\n )[]\n )[]\n )[];\n}\n\nexport interface CoreRawCallConfig {\n target: Address;\n calldata: string;\n callType?: 'Call' | 'StaticCall' | 'ValueCall' | 'DelegateCall';\n resultType?: string;\n}\n\nexport interface CoreInvokeConfig {\n target: Address;\n functionSignature: string;\n callType?: 'Call' | 'ValueCall';\n args?: (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )\n | (\n | MaxLength65536\n | number\n | boolean\n | {\n $ref: string;\n }\n )[]\n )[]\n )[]\n )[]\n )[]\n )[];\n}\n\nexport interface CoreAsResourceConfig {\n resource:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n}\n\nexport interface AaveBorrowConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n pool: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n asset: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n variableDebtToken: string;\n amount: IntegerStringInput;\n referralId?: number;\n}\n\nexport type AaveRepayConfig =\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n pool: string;\n mode: 'exact';\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n pool: string;\n mode: 'max';\n };\n\nexport interface AaveRepayWithATokensConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n pool: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n asset: string;\n}\n\nexport interface AaveClaimRewardsConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n rewardsController: string;\n assets: string[];\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n reward: string;\n amount?: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n to?: string;\n}\n\n/**\n * a number between 0 and 255\n */\nexport type Between0255 = number;\n\nexport interface AaveSetEModeConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n pool: string;\n category: Between0255;\n}\n\nexport interface AaveGetHealthFactorConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n pool: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n user?: string;\n}\n\nexport type MorphoBlueSupplyCollateralConfig =\n | (\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n mode: 'exact';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n mode: 'exact';\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n }\n )\n | (\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n mode: 'all';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n mode: 'all';\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n }\n );\n\nexport type MorphoBlueWithdrawCollateralConfig =\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n amount: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n amount: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n };\n\nexport type MorphoBlueBorrowConfig =\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n amount: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n amount: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n };\n\nexport type MorphoBlueRepayConfig =\n | (\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'exact';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'exact';\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n }\n )\n | (\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'max';\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'max';\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n }\n );\n\nexport type MorphoBlueSupplyConfig =\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n };\n\nexport type MorphoBlueWithdrawConfig =\n | (\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'exact';\n amount: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'exact';\n amount: IntegerStringInput;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n }\n )\n | (\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'max';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n mode: 'max';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n onBehalfOf?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n receiver?: string;\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n }\n );\n\nexport type MorphoBlueGetPositionConfig =\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n user?: string;\n /**\n * a string matching the pattern ^0x[0-9a-fA-F]{64}$\n */\n marketId: string;\n }\n | {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n morpho?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n user?: string;\n marketParams: {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n loanToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n collateralToken: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n oracle: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n irm: string;\n lltv: string;\n };\n };\n\nexport interface LifiFlashloanRepayConfig {\n leg: string;\n fee?: string;\n}\n\nexport type ContinuationAssertReadyConfig =\n | {\n kind: 'erc20BalanceGte';\n chainId: Positive;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n owner: Address;\n minAmount: string;\n }\n | {\n kind: 'nativeBalanceGte';\n chainId: Positive;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n owner: Address;\n minAmount: string;\n }\n | {\n kind: 'call';\n chainId: Positive;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n to: string;\n /**\n * Hex bytes: 0x followed by an even number of hex characters\n */\n calldata: string;\n comparator: 'gte' | 'eq' | 'lte';\n value: string;\n };\n\nexport interface LifiZapConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n}\n\nexport interface LifiZapAsyncConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n}\n\nexport interface ParaswapBuyConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n exactAmountOut: string;\n srcDecimals: NonNegative;\n destDecimals: NonNegative;\n maxSlippageBps?: Between010000;\n partner?: string;\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n partnerAddress?: string;\n /**\n * Integrator fee in basis points; non-negative integer string capped at 9000.\n */\n partnerFeeBps?: string;\n}\n\nexport interface CorePeekConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n target: Address;\n functionSignature: string;\n args?: string[];\n}\n\n/**\n * a number between 0 and 3318\n */\nexport type Between03318 = number;\n/**\n * a number between 0 and 5000\n */\nexport type Between05000 = number;\n\nexport interface FlySwapConfig {\n resourceOut:\n | {\n kind: 'native';\n chainId: Positive;\n }\n | {\n kind: 'erc20';\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n token: Address;\n chainId: Positive;\n };\n inputVarianceBps?: Between03318;\n maxSlippageBps?: Between05000;\n}\n\nexport interface SlippageGuardConfig {\n port: string;\n bps: Between010000;\n}\n\nexport interface CoreNumericInvariantGuardConfig {\n port: string;\n op: 'gte' | 'gt' | 'lte' | 'lt' | 'eq' | 'neq';\n threshold: IntegerStringInput;\n}\n\nexport interface BalanceOfMaterialiserConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n owner: Address;\n}\n\nexport type DirectDepositMaterialiserConfig =\n | {\n amount: IntegerStringInput;\n allowNonExact?: false;\n }\n | {\n amount: IntegerStringInput;\n allowNonExact: true;\n }\n | {\n allowNonExact: true;\n simAmount?: string;\n };\n\nexport interface CallMaterialiserConfig {\n /**\n * EVM address: 0x followed by 40 hex characters\n */\n target: Address;\n calldata: string;\n}\n\nexport interface FlashloanMaterialiserConfig {\n providerKind: 'aave-v3' | 'erc3156' | 'balancer-v2' | 'morpho-blue';\n amount: IntegerStringInput;\n}\n\nexport interface Erc20BalancePreconditionConfig {\n wallet: Address;\n token: Address;\n balance: IntegerStringInput;\n}\n\nexport interface NativeBalancePreconditionConfig {\n wallet: Address;\n balance: IntegerStringInput;\n}\n\nexport interface Erc20AllowancePreconditionConfig {\n owner: Address;\n spender: Address;\n token: Address;\n allowance: IntegerStringInput;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}