@lifi/composer-sdk 0.0.1-alpha
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.
- package/LICENSE +201 -0
- package/README.md +220 -0
- package/dist/authoring/FlowBuilderCore.cjs +115 -0
- package/dist/authoring/FlowBuilderCore.cjs.map +1 -0
- package/dist/authoring/FlowBuilderCore.d.cts +114 -0
- package/dist/authoring/FlowBuilderCore.d.ts +114 -0
- package/dist/authoring/FlowBuilderCore.js +91 -0
- package/dist/authoring/FlowBuilderCore.js.map +1 -0
- package/dist/authoring/handles.cjs +43 -0
- package/dist/authoring/handles.cjs.map +1 -0
- package/dist/authoring/handles.d.cts +61 -0
- package/dist/authoring/handles.d.ts +61 -0
- package/dist/authoring/handles.js +17 -0
- package/dist/authoring/handles.js.map +1 -0
- package/dist/authoring/raw.cjs +41 -0
- package/dist/authoring/raw.cjs.map +1 -0
- package/dist/authoring/raw.d.cts +47 -0
- package/dist/authoring/raw.d.ts +47 -0
- package/dist/authoring/raw.js +16 -0
- package/dist/authoring/raw.js.map +1 -0
- package/dist/authoring/signatureArgs.cjs +114 -0
- package/dist/authoring/signatureArgs.cjs.map +1 -0
- package/dist/authoring/signatureArgs.d.cts +146 -0
- package/dist/authoring/signatureArgs.d.ts +146 -0
- package/dist/authoring/signatureArgs.js +87 -0
- package/dist/authoring/signatureArgs.js.map +1 -0
- package/dist/client.cjs +140 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +67 -0
- package/dist/client.d.ts +67 -0
- package/dist/client.js +116 -0
- package/dist/client.js.map +1 -0
- package/dist/discovery.cjs +17 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +56 -0
- package/dist/discovery.d.ts +56 -0
- package/dist/discovery.js +1 -0
- package/dist/discovery.js.map +1 -0
- package/dist/errors.cjs +91 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +77 -0
- package/dist/errors.d.ts +77 -0
- package/dist/errors.js +65 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/config.generated.cjs +17 -0
- package/dist/generated/config.generated.cjs.map +1 -0
- package/dist/generated/config.generated.d.cts +144 -0
- package/dist/generated/config.generated.d.ts +144 -0
- package/dist/generated/config.generated.js +1 -0
- package/dist/generated/config.generated.js.map +1 -0
- package/dist/generated/guards.generated.cjs +32 -0
- package/dist/generated/guards.generated.cjs.map +1 -0
- package/dist/generated/guards.generated.d.cts +4 -0
- package/dist/generated/guards.generated.d.ts +4 -0
- package/dist/generated/guards.generated.js +8 -0
- package/dist/generated/guards.generated.js.map +1 -0
- package/dist/generated/materialisers.generated.cjs +44 -0
- package/dist/generated/materialisers.generated.cjs.map +1 -0
- package/dist/generated/materialisers.generated.d.cts +4 -0
- package/dist/generated/materialisers.generated.d.ts +4 -0
- package/dist/generated/materialisers.generated.js +18 -0
- package/dist/generated/materialisers.generated.js.map +1 -0
- package/dist/generated/operations.generated.cjs +110 -0
- package/dist/generated/operations.generated.cjs.map +1 -0
- package/dist/generated/operations.generated.d.cts +337 -0
- package/dist/generated/operations.generated.d.ts +337 -0
- package/dist/generated/operations.generated.js +89 -0
- package/dist/generated/operations.generated.js.map +1 -0
- package/dist/generated/preconditions.generated.cjs +44 -0
- package/dist/generated/preconditions.generated.cjs.map +1 -0
- package/dist/generated/preconditions.generated.d.cts +4 -0
- package/dist/generated/preconditions.generated.d.ts +4 -0
- package/dist/generated/preconditions.generated.js +18 -0
- package/dist/generated/preconditions.generated.js.map +1 -0
- package/dist/guards.generated-DKKDKREA.d.ts +14 -0
- package/dist/guards.generated-hrQ1KPNv.d.cts +14 -0
- package/dist/index.cjs +76 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +99 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/materialisers.generated-BsA1uDW8.d.ts +24 -0
- package/dist/materialisers.generated-nMxTAaVi.d.cts +24 -0
- package/dist/preconditions.generated-DblS13Wq.d.cts +24 -0
- package/dist/preconditions.generated-U7YpVh30.d.ts +24 -0
- package/dist/raw-Dj_2rBSQ.d.cts +19 -0
- package/dist/raw-IxCF_bSS.d.ts +19 -0
- package/dist/raw.cjs +34 -0
- package/dist/raw.cjs.map +1 -0
- package/dist/raw.d.cts +4 -0
- package/dist/raw.d.ts +4 -0
- package/dist/raw.js +8 -0
- package/dist/raw.js.map +1 -0
- package/dist/resources-BKlFxjo8.d.cts +56 -0
- package/dist/resources-CYis1_DS.d.ts +56 -0
- package/dist/resources.cjs +39 -0
- package/dist/resources.cjs.map +1 -0
- package/dist/resources.d.cts +3 -0
- package/dist/resources.d.ts +3 -0
- package/dist/resources.js +14 -0
- package/dist/resources.js.map +1 -0
- package/dist/run/inputs.cjs +51 -0
- package/dist/run/inputs.cjs.map +1 -0
- package/dist/run/inputs.d.cts +91 -0
- package/dist/run/inputs.d.ts +91 -0
- package/dist/run/inputs.js +26 -0
- package/dist/run/inputs.js.map +1 -0
- package/dist/sdk.cjs +60 -0
- package/dist/sdk.cjs.map +1 -0
- package/dist/sdk.d.cts +112 -0
- package/dist/sdk.d.ts +112 -0
- package/dist/sdk.js +40 -0
- package/dist/sdk.js.map +1 -0
- package/dist/types.cjs +17 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +74 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +81 -0
- package/src/authoring/FlowBuilderCore.ts +270 -0
- package/src/authoring/handles.ts +81 -0
- package/src/authoring/raw.ts +60 -0
- package/src/authoring/signatureArgs.ts +249 -0
- package/src/client.ts +230 -0
- package/src/discovery.ts +51 -0
- package/src/errors.ts +150 -0
- package/src/examples/approveAndDeposit.ts +84 -0
- package/src/examples/callContract.ts +199 -0
- package/src/examples/config.ts +9 -0
- package/src/examples/consolidateToEth.ts +94 -0
- package/src/examples/consolidateToUsdc.ts +95 -0
- package/src/examples/depositFromProxy.ts +87 -0
- package/src/examples/dustSweep.ts +66 -0
- package/src/examples/lifiSwap.ts +56 -0
- package/src/examples/lifiZap.ts +60 -0
- package/src/examples/rawCallWithArithmetic.ts +78 -0
- package/src/examples/readContractState.ts +77 -0
- package/src/examples/run.ts +168 -0
- package/src/examples/splitAndZap.ts +73 -0
- package/src/examples/splitWithArithmetic.ts +93 -0
- package/src/examples/swapAndZap.ts +72 -0
- package/src/examples/swapToRecipient.ts +109 -0
- package/src/examples/swapWithAllowRevert.ts +119 -0
- package/src/examples/swapWithBalanceCheck.ts +73 -0
- package/src/examples/swapWithOutputValidation.ts +125 -0
- package/src/examples/transferTokens.ts +123 -0
- package/src/examples/untypedOpWithTypedRef.ts +77 -0
- package/src/generated/config.generated.ts +174 -0
- package/src/generated/guards.generated.ts +14 -0
- package/src/generated/materialisers.generated.ts +44 -0
- package/src/generated/operations.generated.ts +568 -0
- package/src/generated/preconditions.generated.ts +43 -0
- package/src/index.ts +149 -0
- package/src/raw.ts +10 -0
- package/src/resources.ts +61 -0
- package/src/run/inputs.ts +117 -0
- package/src/sdk.ts +173 -0
- package/src/types.ts +101 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Resource, SolType, Ref, AppliedGuard, Flow } from '@lifi/compose-spec';
|
|
2
|
+
import { TypedRef, InputSchema, InputDecl, TypedGuard, OutputKind } from '../types.js';
|
|
3
|
+
import { InputHandle, OutputHandle, ResourceInputHandle } from './handles.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Arguments for calling an operation node in a flow.
|
|
7
|
+
*/
|
|
8
|
+
interface CallArgs {
|
|
9
|
+
/** Maps parameter names to input/output handles or raw `$ref` pointers. */
|
|
10
|
+
readonly bind: Record<string, AnyBindable>;
|
|
11
|
+
/** Optional operation-specific configuration. */
|
|
12
|
+
readonly config?: object;
|
|
13
|
+
/** Optional guards (e.g. slippage checks) applied to this operation's outputs. */
|
|
14
|
+
readonly guards?: readonly TypedGuard[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Any value that can be bound to an operation parameter: an input handle,
|
|
18
|
+
* an output handle from a previous operation, or a typed `$ref` pointer.
|
|
19
|
+
*
|
|
20
|
+
* Use `raw.ref<T>()` to create a typed ref from a raw path string.
|
|
21
|
+
*/
|
|
22
|
+
type AnyBindable = InputHandle | OutputHandle | TypedRef;
|
|
23
|
+
/**
|
|
24
|
+
* Provides references to runtime context values available inside a flow.
|
|
25
|
+
* Access via `builder.context`.
|
|
26
|
+
*/
|
|
27
|
+
interface ContextAccessor {
|
|
28
|
+
/** A `$ref` pointing to the transaction sender (signer) address. */
|
|
29
|
+
readonly sender: TypedRef<'address'>;
|
|
30
|
+
/** A `$ref` pointing to the on-chain execution (proxy) address. */
|
|
31
|
+
readonly executionAddress: TypedRef<'address'>;
|
|
32
|
+
}
|
|
33
|
+
type InputHandleOf<D extends InputDecl> = D extends Resource ? ResourceInputHandle : D extends SolType ? InputHandle<D> : InputHandle;
|
|
34
|
+
/**
|
|
35
|
+
* A mapped type that converts an input schema into typed handles.
|
|
36
|
+
* Resource inputs produce {@link ResourceInputHandle}; scalar inputs produce {@link InputHandle}.
|
|
37
|
+
*
|
|
38
|
+
* @typeParam T - The flow's input schema.
|
|
39
|
+
*/
|
|
40
|
+
type InputHandles<T extends InputSchema> = {
|
|
41
|
+
readonly [K in keyof T]: InputHandleOf<T[K]>;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Options for creating a new flow builder.
|
|
45
|
+
*
|
|
46
|
+
* @typeParam T - The flow's input schema.
|
|
47
|
+
*/
|
|
48
|
+
interface FlowOptions<T extends InputSchema> {
|
|
49
|
+
/** Optional human-readable name for the flow. Defaults to a random UUID. */
|
|
50
|
+
readonly name?: string;
|
|
51
|
+
/** Input declarations mapping names to resource or scalar types. */
|
|
52
|
+
readonly inputs: T;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A Flow document branded with its input schema for type-safe request building.
|
|
56
|
+
*
|
|
57
|
+
* The `__inputs` field is a phantom type — it exists only at compile time for
|
|
58
|
+
* TypeScript inference and is never present at runtime.
|
|
59
|
+
*/
|
|
60
|
+
type TypedFlow<T extends InputSchema = InputSchema> = Flow & {
|
|
61
|
+
readonly __inputs?: T;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Core flow builder interface providing low-level access to flow construction.
|
|
65
|
+
*
|
|
66
|
+
* For most use cases, prefer the {@link FlowBuilder} type returned by `sdk.flow()`
|
|
67
|
+
* which adds generated operation methods and a `compile` method.
|
|
68
|
+
*
|
|
69
|
+
* @typeParam T - The flow's input schema.
|
|
70
|
+
*/
|
|
71
|
+
interface FlowBuilderCore<T extends InputSchema = InputSchema> {
|
|
72
|
+
/** Runtime context references (sender address, execution address). */
|
|
73
|
+
readonly context: ContextAccessor;
|
|
74
|
+
/** Typed handles for each declared flow input, used to bind inputs to operations. */
|
|
75
|
+
readonly inputs: InputHandles<T>;
|
|
76
|
+
/**
|
|
77
|
+
* Appends an untyped operation node to the flow. This is an escape hatch
|
|
78
|
+
* for operations not yet covered by the generated methods.
|
|
79
|
+
*
|
|
80
|
+
* Use `raw.ref<T>()` to reference this node's outputs in subsequent typed
|
|
81
|
+
* operations.
|
|
82
|
+
*
|
|
83
|
+
* @param id - Unique node identifier within the flow.
|
|
84
|
+
* @param op - The operation name (e.g. `"custom.vaultQuery"`).
|
|
85
|
+
* @param args - Bind map, config, and optional guards for the node.
|
|
86
|
+
* @throws Error if a node with the same `id` already exists in the flow.
|
|
87
|
+
*/
|
|
88
|
+
readonly untypedOp: (id: string, op: string, args: {
|
|
89
|
+
readonly bind: Record<string, Ref>;
|
|
90
|
+
readonly config: Record<string, unknown>;
|
|
91
|
+
readonly guards?: readonly AppliedGuard[];
|
|
92
|
+
}) => void;
|
|
93
|
+
/** Serialises the builder state into a {@link TypedFlow} document. */
|
|
94
|
+
readonly build: () => TypedFlow<T>;
|
|
95
|
+
}
|
|
96
|
+
/** Maps output port names to their output kind for compile-time and runtime validation. */
|
|
97
|
+
type OutputSpec = Record<string, OutputKind>;
|
|
98
|
+
/** Internal interface exposed to bindGeneratedOps — not part of the public API. */
|
|
99
|
+
interface FlowBuilderInternal<T extends InputSchema = InputSchema> extends FlowBuilderCore<T> {
|
|
100
|
+
readonly call: <O extends OutputSpec>(nodeId: string, op: string, args: CallArgs, outputs: O) => {
|
|
101
|
+
readonly [K in keyof O & string]: OutputHandle<O[K]>;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Creates a new flow builder targeting the given chain.
|
|
106
|
+
*
|
|
107
|
+
* @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).
|
|
108
|
+
* @param options - Flow configuration including input declarations.
|
|
109
|
+
* @returns A {@link FlowBuilderInternal} instance.
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
declare const createFlowBuilderCore: <T extends InputSchema>(chainId: number, options: FlowOptions<T>) => FlowBuilderInternal<T>;
|
|
113
|
+
|
|
114
|
+
export { type AnyBindable, type CallArgs, type ContextAccessor, type FlowBuilderCore, type FlowBuilderInternal, type FlowOptions, type InputHandles, type OutputSpec, type TypedFlow, createFlowBuilderCore };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { handleToRef } from "./handles.js";
|
|
2
|
+
import { ref } from "./raw.js";
|
|
3
|
+
const toRef = (bindable) => {
|
|
4
|
+
if ("_tag" in bindable) return handleToRef(bindable);
|
|
5
|
+
return bindable;
|
|
6
|
+
};
|
|
7
|
+
const isResource = (decl) => typeof decl === "object" && decl !== null && "kind" in decl;
|
|
8
|
+
const createFlowBuilderCore = (chainId, options) => {
|
|
9
|
+
const id = options.name ?? crypto.randomUUID();
|
|
10
|
+
const flowInputs = [];
|
|
11
|
+
const nodes = [];
|
|
12
|
+
const nodeIds = /* @__PURE__ */ new Set();
|
|
13
|
+
const inputHandles = {};
|
|
14
|
+
for (const [name, decl] of Object.entries(options.inputs)) {
|
|
15
|
+
if (isResource(decl)) {
|
|
16
|
+
if (decl.chainId !== chainId) {
|
|
17
|
+
throw new Error(
|
|
18
|
+
`Input "${name}" has chainId ${decl.chainId} but flow targets chain ${chainId}`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
flowInputs.push({ name, resource: decl });
|
|
22
|
+
inputHandles[name] = { _tag: "input", inputName: name, resource: decl };
|
|
23
|
+
} else {
|
|
24
|
+
flowInputs.push({ name, type: decl });
|
|
25
|
+
inputHandles[name] = { _tag: "input", inputName: name };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const call = (nodeId, op, args, outputs) => {
|
|
29
|
+
if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: "${nodeId}"`);
|
|
30
|
+
nodeIds.add(nodeId);
|
|
31
|
+
const bind = {};
|
|
32
|
+
for (const [key, val] of Object.entries(args.bind)) {
|
|
33
|
+
bind[key] = toRef(val);
|
|
34
|
+
}
|
|
35
|
+
const node = {
|
|
36
|
+
id: nodeId,
|
|
37
|
+
op,
|
|
38
|
+
bind,
|
|
39
|
+
config: args.config ?? {},
|
|
40
|
+
...args.guards && args.guards.length > 0 && { guards: args.guards }
|
|
41
|
+
};
|
|
42
|
+
nodes.push(node);
|
|
43
|
+
return new Proxy({}, {
|
|
44
|
+
get: (_target, prop) => {
|
|
45
|
+
if (typeof prop !== "string" || prop === "then") return void 0;
|
|
46
|
+
if (!(prop in outputs)) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Op "${op}" has no output port "${prop}". Valid ports: ${Object.keys(
|
|
49
|
+
outputs
|
|
50
|
+
).join(", ")}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
return { _tag: "output", nodeId, portName: prop };
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const untypedOp = (nodeId, op, args) => {
|
|
58
|
+
if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: "${nodeId}"`);
|
|
59
|
+
nodeIds.add(nodeId);
|
|
60
|
+
const node = {
|
|
61
|
+
id: nodeId,
|
|
62
|
+
op,
|
|
63
|
+
bind: args.bind,
|
|
64
|
+
config: args.config,
|
|
65
|
+
...args.guards && args.guards.length > 0 && { guards: args.guards }
|
|
66
|
+
};
|
|
67
|
+
nodes.push(node);
|
|
68
|
+
};
|
|
69
|
+
const build = () => ({
|
|
70
|
+
version: 1,
|
|
71
|
+
id,
|
|
72
|
+
chainId,
|
|
73
|
+
inputs: [...flowInputs],
|
|
74
|
+
nodes: [...nodes]
|
|
75
|
+
});
|
|
76
|
+
const context = {
|
|
77
|
+
sender: ref("context.sender"),
|
|
78
|
+
executionAddress: ref("context.executionAddress")
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
context,
|
|
82
|
+
inputs: inputHandles,
|
|
83
|
+
call,
|
|
84
|
+
untypedOp,
|
|
85
|
+
build
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
export {
|
|
89
|
+
createFlowBuilderCore
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=FlowBuilderCore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/authoring/FlowBuilderCore.ts"],"sourcesContent":["import type {\n AppliedGuard,\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 TypedRef,\n} from '../types.js';\n\nimport type {\n InputHandle,\n OutputHandle,\n ResourceInputHandle,\n} from './handles.js';\nimport { handleToRef } 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,\n * an output handle from a previous operation, or a typed `$ref` pointer.\n *\n * Use `raw.ref<T>()` to create a typed ref from a raw path string.\n */\nexport type AnyBindable = InputHandle | OutputHandle | TypedRef;\n\nconst toRef = (bindable: AnyBindable): Ref => {\n if ('_tag' in bindable) return handleToRef(bindable);\n return bindable;\n};\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, Ref>;\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, Ref> = {};\n for (const [key, val] of Object.entries(args.bind)) {\n bind[key] = toRef(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, Ref>;\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":"AAuBA,SAAS,mBAAmB;AAC5B,SAAS,WAAW;AAsBpB,MAAM,QAAQ,CAAC,aAA+B;AAC5C,MAAI,UAAU,SAAU,QAAO,YAAY,QAAQ;AACnD,SAAO;AACT;AAwGA,MAAM,aAAa,CAAC,SAClB,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU;AAUlD,MAAM,wBAAwB,CACnC,SACA,YAC2B;AAC3B,QAAM,KAAK,QAAQ,QAAQ,OAAO,WAAW;AAC7C,QAAM,aAA0B,CAAC;AACjC,QAAM,QAAgB,CAAC;AACvB,QAAM,UAAU,oBAAI,IAAY;AAEhC,QAAM,eAAe,CAAC;AACtB,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,QAAQ,MAAM,GAAG;AACzD,QAAI,WAAW,IAAI,GAAG;AACpB,UAAI,KAAK,YAAY,SAAS;AAC5B,cAAM,IAAI;AAAA,UACR,UAAU,IAAI,iBAAiB,KAAK,OAAO,2BAA2B,OAAO;AAAA,QAC/E;AAAA,MACF;AACA,iBAAW,KAAK,EAAE,MAAM,UAAU,KAAK,CAAC;AACxC,mBAAa,IAAI,IAAI,EAAE,MAAM,SAAS,WAAW,MAAM,UAAU,KAAK;AAAA,IACxE,OAAO;AACL,iBAAW,KAAK,EAAE,MAAM,MAAM,KAAK,CAAC;AACpC,mBAAa,IAAI,IAAI,EAAE,MAAM,SAAS,WAAW,KAAK;AAAA,IACxD;AAAA,EACF;AAEA,QAAM,OAAO,CACX,QACA,IACA,MACA,YAC6D;AAC7D,QAAI,QAAQ,IAAI,MAAM,EAAG,OAAM,IAAI,MAAM,uBAAuB,MAAM,GAAG;AACzE,YAAQ,IAAI,MAAM;AAElB,UAAM,OAA4B,CAAC;AACnC,eAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,KAAK,IAAI,GAAG;AAClD,WAAK,GAAG,IAAI,MAAM,GAAG;AAAA,IACvB;AAEA,UAAM,OAAa;AAAA,MACjB,IAAI;AAAA,MACJ;AAAA,MACA;AAAA,MACA,QAAS,KAAK,UAAU,CAAC;AAAA,MACzB,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;AAAA,IACrE;AACA,UAAM,KAAK,IAAI;AAGf,WAAO,IAAI,MAAM,CAAC,GAAa;AAAA,MAC7B,KAAK,CAAC,SAAS,SAAmC;AAChD,YAAI,OAAO,SAAS,YAAY,SAAS,OAAQ,QAAO;AACxD,YAAI,EAAE,QAAQ,UAAU;AACtB,gBAAM,IAAI;AAAA,YACR,OAAO,EAAE,yBAAyB,IAAI,mBAAmB,OAAO;AAAA,cAC9D;AAAA,YACF,EAAE,KAAK,IAAI,CAAC;AAAA,UACd;AAAA,QACF;AACA,eAAO,EAAE,MAAM,UAAU,QAAQ,UAAU,KAAK;AAAA,MAClD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,CAChB,QACA,IACA,SAKS;AACT,QAAI,QAAQ,IAAI,MAAM,EAAG,OAAM,IAAI,MAAM,uBAAuB,MAAM,GAAG;AACzE,YAAQ,IAAI,MAAM;AAClB,UAAM,OAAa;AAAA,MACjB,IAAI;AAAA,MACJ;AAAA,MACA,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,GAAI,KAAK,UAAU,KAAK,OAAO,SAAS,KAAK,EAAE,QAAQ,KAAK,OAAO;AAAA,IACrE;AACA,UAAM,KAAK,IAAI;AAAA,EACjB;AAEA,QAAM,QAAQ,OAAqB;AAAA,IACjC,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,QAAQ,CAAC,GAAG,UAAU;AAAA,IACtB,OAAO,CAAC,GAAG,KAAK;AAAA,EAClB;AAEA,QAAM,UAA2B;AAAA,IAC/B,QAAQ,IAAe,gBAAgB;AAAA,IACvC,kBAAkB,IAAe,0BAA0B;AAAA,EAC7D;AAEA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var handles_exports = {};
|
|
20
|
+
__export(handles_exports, {
|
|
21
|
+
handleToRef: () => handleToRef,
|
|
22
|
+
isInputHandle: () => isInputHandle,
|
|
23
|
+
isOutputHandle: () => isOutputHandle
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(handles_exports);
|
|
26
|
+
const isInputHandle = (h) => h._tag === "input";
|
|
27
|
+
const isOutputHandle = (h) => h._tag === "output";
|
|
28
|
+
const handleToRef = (h) => {
|
|
29
|
+
if (h._tag === "input") {
|
|
30
|
+
if (!h.inputName) throw new Error("InputHandle has empty inputName");
|
|
31
|
+
return { $ref: `input.${h.inputName}` };
|
|
32
|
+
}
|
|
33
|
+
if (!h.nodeId) throw new Error("OutputHandle has empty nodeId");
|
|
34
|
+
if (!h.portName) throw new Error("OutputHandle has empty portName");
|
|
35
|
+
return { $ref: `${h.nodeId}.${h.portName}` };
|
|
36
|
+
};
|
|
37
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
38
|
+
0 && (module.exports = {
|
|
39
|
+
handleToRef,
|
|
40
|
+
isInputHandle,
|
|
41
|
+
isOutputHandle
|
|
42
|
+
});
|
|
43
|
+
//# sourceMappingURL=handles.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/authoring/handles.ts"],"sourcesContent":["import type { Resource } from '@lifi/compose-spec';\n\nimport type { OutputKind, 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, also accept `'resource'`-tagged\n * handles when T is `'uint256'` (resources are uint256 amounts).\n */\ntype ResourceAssignable<T extends OutputKind> = T extends 'uint256'\n ? T | 'resource'\n : T;\n\n/**\n * The set of values accepted by a typed bind slot.\n * - `OutputHandle<T>` / `InputHandle<T>` (same type)\n * - For `'uint256'` slots, also `'resource'`-tagged handles\n * - `TypedRef<T>` (typed context refs, subject to `ResourceAssignable`)\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 Bindable<T extends OutputKind> =\n | OutputHandle<ResourceAssignable<T>>\n | InputHandle<ResourceAssignable<T>>\n | TypedRef<ResourceAssignable<T>>;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuCO,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;","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Resource } from '@lifi/compose-spec';
|
|
2
|
+
import { OutputKind, TypedRef } from '../types.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A handle referencing a flow input declared in the flow's input schema.
|
|
6
|
+
* The phantom `__outputKind` field carries the type parameter through
|
|
7
|
+
* TypeScript's structural type system without affecting runtime shape.
|
|
8
|
+
*/
|
|
9
|
+
interface InputHandle<T extends OutputKind = OutputKind> {
|
|
10
|
+
readonly _tag: 'input';
|
|
11
|
+
readonly inputName: string;
|
|
12
|
+
readonly __outputKind?: T;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* An input handle for a resource (token) input, carrying the resource
|
|
16
|
+
* declaration alongside the reference.
|
|
17
|
+
*/
|
|
18
|
+
interface ResourceInputHandle extends InputHandle<'resource'> {
|
|
19
|
+
readonly resource: Resource;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A handle referencing an output port of a previously declared operation node.
|
|
23
|
+
* The phantom `__outputKind` field carries the type parameter through
|
|
24
|
+
* TypeScript's structural type system without affecting runtime shape.
|
|
25
|
+
*/
|
|
26
|
+
interface OutputHandle<T extends OutputKind = OutputKind> {
|
|
27
|
+
readonly _tag: 'output';
|
|
28
|
+
readonly nodeId: string;
|
|
29
|
+
readonly portName: string;
|
|
30
|
+
readonly __outputKind?: T;
|
|
31
|
+
}
|
|
32
|
+
/** Discriminated union of all handle types that can be bound to operation arguments. */
|
|
33
|
+
type AnyHandle = InputHandle | OutputHandle;
|
|
34
|
+
/** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */
|
|
35
|
+
declare const isInputHandle: (h: AnyHandle) => h is InputHandle;
|
|
36
|
+
/** Type guard that narrows an {@link AnyHandle} to an {@link OutputHandle}. */
|
|
37
|
+
declare const isOutputHandle: (h: AnyHandle) => h is OutputHandle;
|
|
38
|
+
/**
|
|
39
|
+
* Converts a handle to a JSON `$ref` pointer used in the flow document.
|
|
40
|
+
* Input handles become `"input.<name>"`; output handles become `"<nodeId>.<port>"`.
|
|
41
|
+
*/
|
|
42
|
+
declare const handleToRef: (h: AnyHandle) => {
|
|
43
|
+
$ref: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* For a bind slot expecting type T, also accept `'resource'`-tagged
|
|
47
|
+
* handles when T is `'uint256'` (resources are uint256 amounts).
|
|
48
|
+
*/
|
|
49
|
+
type ResourceAssignable<T extends OutputKind> = T extends 'uint256' ? T | 'resource' : T;
|
|
50
|
+
/**
|
|
51
|
+
* The set of values accepted by a typed bind slot.
|
|
52
|
+
* - `OutputHandle<T>` / `InputHandle<T>` (same type)
|
|
53
|
+
* - For `'uint256'` slots, also `'resource'`-tagged handles
|
|
54
|
+
* - `TypedRef<T>` (typed context refs, subject to `ResourceAssignable`)
|
|
55
|
+
*
|
|
56
|
+
* Plain `{ $ref: '...' }` objects are **not** accepted — use `raw.ref<T>()`
|
|
57
|
+
* to create a typed ref when you need to reference a raw path.
|
|
58
|
+
*/
|
|
59
|
+
type Bindable<T extends OutputKind> = OutputHandle<ResourceAssignable<T>> | InputHandle<ResourceAssignable<T>> | TypedRef<ResourceAssignable<T>>;
|
|
60
|
+
|
|
61
|
+
export { type AnyHandle, type Bindable, type InputHandle, type OutputHandle, type ResourceInputHandle, handleToRef, isInputHandle, isOutputHandle };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Resource } from '@lifi/compose-spec';
|
|
2
|
+
import { OutputKind, TypedRef } from '../types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A handle referencing a flow input declared in the flow's input schema.
|
|
6
|
+
* The phantom `__outputKind` field carries the type parameter through
|
|
7
|
+
* TypeScript's structural type system without affecting runtime shape.
|
|
8
|
+
*/
|
|
9
|
+
interface InputHandle<T extends OutputKind = OutputKind> {
|
|
10
|
+
readonly _tag: 'input';
|
|
11
|
+
readonly inputName: string;
|
|
12
|
+
readonly __outputKind?: T;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* An input handle for a resource (token) input, carrying the resource
|
|
16
|
+
* declaration alongside the reference.
|
|
17
|
+
*/
|
|
18
|
+
interface ResourceInputHandle extends InputHandle<'resource'> {
|
|
19
|
+
readonly resource: Resource;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A handle referencing an output port of a previously declared operation node.
|
|
23
|
+
* The phantom `__outputKind` field carries the type parameter through
|
|
24
|
+
* TypeScript's structural type system without affecting runtime shape.
|
|
25
|
+
*/
|
|
26
|
+
interface OutputHandle<T extends OutputKind = OutputKind> {
|
|
27
|
+
readonly _tag: 'output';
|
|
28
|
+
readonly nodeId: string;
|
|
29
|
+
readonly portName: string;
|
|
30
|
+
readonly __outputKind?: T;
|
|
31
|
+
}
|
|
32
|
+
/** Discriminated union of all handle types that can be bound to operation arguments. */
|
|
33
|
+
type AnyHandle = InputHandle | OutputHandle;
|
|
34
|
+
/** Type guard that narrows an {@link AnyHandle} to an {@link InputHandle}. */
|
|
35
|
+
declare const isInputHandle: (h: AnyHandle) => h is InputHandle;
|
|
36
|
+
/** Type guard that narrows an {@link AnyHandle} to an {@link OutputHandle}. */
|
|
37
|
+
declare const isOutputHandle: (h: AnyHandle) => h is OutputHandle;
|
|
38
|
+
/**
|
|
39
|
+
* Converts a handle to a JSON `$ref` pointer used in the flow document.
|
|
40
|
+
* Input handles become `"input.<name>"`; output handles become `"<nodeId>.<port>"`.
|
|
41
|
+
*/
|
|
42
|
+
declare const handleToRef: (h: AnyHandle) => {
|
|
43
|
+
$ref: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* For a bind slot expecting type T, also accept `'resource'`-tagged
|
|
47
|
+
* handles when T is `'uint256'` (resources are uint256 amounts).
|
|
48
|
+
*/
|
|
49
|
+
type ResourceAssignable<T extends OutputKind> = T extends 'uint256' ? T | 'resource' : T;
|
|
50
|
+
/**
|
|
51
|
+
* The set of values accepted by a typed bind slot.
|
|
52
|
+
* - `OutputHandle<T>` / `InputHandle<T>` (same type)
|
|
53
|
+
* - For `'uint256'` slots, also `'resource'`-tagged handles
|
|
54
|
+
* - `TypedRef<T>` (typed context refs, subject to `ResourceAssignable`)
|
|
55
|
+
*
|
|
56
|
+
* Plain `{ $ref: '...' }` objects are **not** accepted — use `raw.ref<T>()`
|
|
57
|
+
* to create a typed ref when you need to reference a raw path.
|
|
58
|
+
*/
|
|
59
|
+
type Bindable<T extends OutputKind> = OutputHandle<ResourceAssignable<T>> | InputHandle<ResourceAssignable<T>> | TypedRef<ResourceAssignable<T>>;
|
|
60
|
+
|
|
61
|
+
export { type AnyHandle, type Bindable, type InputHandle, type OutputHandle, type ResourceInputHandle, handleToRef, isInputHandle, isOutputHandle };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const isInputHandle = (h) => h._tag === "input";
|
|
2
|
+
const isOutputHandle = (h) => h._tag === "output";
|
|
3
|
+
const handleToRef = (h) => {
|
|
4
|
+
if (h._tag === "input") {
|
|
5
|
+
if (!h.inputName) throw new Error("InputHandle has empty inputName");
|
|
6
|
+
return { $ref: `input.${h.inputName}` };
|
|
7
|
+
}
|
|
8
|
+
if (!h.nodeId) throw new Error("OutputHandle has empty nodeId");
|
|
9
|
+
if (!h.portName) throw new Error("OutputHandle has empty portName");
|
|
10
|
+
return { $ref: `${h.nodeId}.${h.portName}` };
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
handleToRef,
|
|
14
|
+
isInputHandle,
|
|
15
|
+
isOutputHandle
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=handles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/authoring/handles.ts"],"sourcesContent":["import type { Resource } from '@lifi/compose-spec';\n\nimport type { OutputKind, 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, also accept `'resource'`-tagged\n * handles when T is `'uint256'` (resources are uint256 amounts).\n */\ntype ResourceAssignable<T extends OutputKind> = T extends 'uint256'\n ? T | 'resource'\n : T;\n\n/**\n * The set of values accepted by a typed bind slot.\n * - `OutputHandle<T>` / `InputHandle<T>` (same type)\n * - For `'uint256'` slots, also `'resource'`-tagged handles\n * - `TypedRef<T>` (typed context refs, subject to `ResourceAssignable`)\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 Bindable<T extends OutputKind> =\n | OutputHandle<ResourceAssignable<T>>\n | InputHandle<ResourceAssignable<T>>\n | TypedRef<ResourceAssignable<T>>;\n"],"mappings":"AAuCO,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;","names":[]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var raw_exports = {};
|
|
20
|
+
__export(raw_exports, {
|
|
21
|
+
rawGuard: () => rawGuard,
|
|
22
|
+
ref: () => ref
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(raw_exports);
|
|
25
|
+
const ref = (path) => ({ $ref: path });
|
|
26
|
+
const rawGuard = (kind, config = {}) => {
|
|
27
|
+
if ("kind" in config) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`rawGuard: 'kind' must not appear in config (got "${String(
|
|
30
|
+
config.kind
|
|
31
|
+
)}"). Pass it as the first argument instead.`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return { ...config, kind };
|
|
35
|
+
};
|
|
36
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
37
|
+
0 && (module.exports = {
|
|
38
|
+
rawGuard,
|
|
39
|
+
ref
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=raw.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/authoring/raw.ts"],"sourcesContent":["import type { AppliedGuard } from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedRef } from '../types.js';\n\n/**\n * Creates a typed `$ref` pointer for use in bind slots.\n *\n * This is an **escape hatch** for referencing values that the typed builder\n * API doesn't cover — for example, outputs of an `untypedOp` node or custom\n * context paths. The caller is responsible for choosing the correct type\n * parameter; no runtime validation occurs.\n *\n * Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`\n * whenever possible. Use `ref` only when you need to construct a `$ref` path\n * manually and want it accepted by a `Bindable<T>` slot.\n *\n * @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).\n * @param path - The `$ref` path (e.g. `\"context.sender\"`, `\"myNode.result\"`).\n * @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // Reference an untypedOp output in a typed operation:\n * builder.untypedOp('custom', 'some.op', {\n * bind: { x: { $ref: 'input.token' } },\n * config: {},\n * });\n * builder.core.add('sum', {\n * bind: {\n * a: raw.ref<'uint256'>('custom.result'),\n * b: someTypedHandle,\n * },\n * });\n * ```\n */\nexport const ref = <T extends OutputKind>(path: string): TypedRef<T> =>\n ({ $ref: path }) as TypedRef<T>;\n\n/**\n * Creates a raw guard object for use in the `guards` array of an operation call.\n *\n * @param kind - The guard type (e.g. `\"slippage\"`).\n * @param config - Guard-specific configuration (e.g. `{ toleranceBps: 300 }`).\n * @returns An {@link AppliedGuard} object.\n */\nexport const rawGuard = (\n kind: string,\n config: Record<string, unknown> = {},\n): AppliedGuard => {\n if ('kind' in config) {\n throw new Error(\n `rawGuard: 'kind' must not appear in config (got \"${String(\n config.kind,\n )}\"). Pass it as the first argument instead.`,\n );\n }\n return { ...config, kind };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqCO,MAAM,MAAM,CAAuB,UACvC,EAAE,MAAM,KAAK;AAST,MAAM,WAAW,CACtB,MACA,SAAkC,CAAC,MAClB;AACjB,MAAI,UAAU,QAAQ;AACpB,UAAM,IAAI;AAAA,MACR,oDAAoD;AAAA,QAClD,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,EAAE,GAAG,QAAQ,KAAK;AAC3B;","names":[]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AppliedGuard } from '@lifi/compose-spec';
|
|
2
|
+
import { OutputKind, TypedRef } from '../types.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a typed `$ref` pointer for use in bind slots.
|
|
6
|
+
*
|
|
7
|
+
* This is an **escape hatch** for referencing values that the typed builder
|
|
8
|
+
* API doesn't cover — for example, outputs of an `untypedOp` node or custom
|
|
9
|
+
* context paths. The caller is responsible for choosing the correct type
|
|
10
|
+
* parameter; no runtime validation occurs.
|
|
11
|
+
*
|
|
12
|
+
* Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`
|
|
13
|
+
* whenever possible. Use `ref` only when you need to construct a `$ref` path
|
|
14
|
+
* manually and want it accepted by a `Bindable<T>` slot.
|
|
15
|
+
*
|
|
16
|
+
* @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).
|
|
17
|
+
* @param path - The `$ref` path (e.g. `"context.sender"`, `"myNode.result"`).
|
|
18
|
+
* @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { raw } from '@lifi/composer-sdk';
|
|
23
|
+
*
|
|
24
|
+
* // Reference an untypedOp output in a typed operation:
|
|
25
|
+
* builder.untypedOp('custom', 'some.op', {
|
|
26
|
+
* bind: { x: { $ref: 'input.token' } },
|
|
27
|
+
* config: {},
|
|
28
|
+
* });
|
|
29
|
+
* builder.core.add('sum', {
|
|
30
|
+
* bind: {
|
|
31
|
+
* a: raw.ref<'uint256'>('custom.result'),
|
|
32
|
+
* b: someTypedHandle,
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare const ref: <T extends OutputKind>(path: string) => TypedRef<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a raw guard object for use in the `guards` array of an operation call.
|
|
40
|
+
*
|
|
41
|
+
* @param kind - The guard type (e.g. `"slippage"`).
|
|
42
|
+
* @param config - Guard-specific configuration (e.g. `{ toleranceBps: 300 }`).
|
|
43
|
+
* @returns An {@link AppliedGuard} object.
|
|
44
|
+
*/
|
|
45
|
+
declare const rawGuard: (kind: string, config?: Record<string, unknown>) => AppliedGuard;
|
|
46
|
+
|
|
47
|
+
export { rawGuard, ref };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AppliedGuard } from '@lifi/compose-spec';
|
|
2
|
+
import { OutputKind, TypedRef } from '../types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a typed `$ref` pointer for use in bind slots.
|
|
6
|
+
*
|
|
7
|
+
* This is an **escape hatch** for referencing values that the typed builder
|
|
8
|
+
* API doesn't cover — for example, outputs of an `untypedOp` node or custom
|
|
9
|
+
* context paths. The caller is responsible for choosing the correct type
|
|
10
|
+
* parameter; no runtime validation occurs.
|
|
11
|
+
*
|
|
12
|
+
* Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`
|
|
13
|
+
* whenever possible. Use `ref` only when you need to construct a `$ref` path
|
|
14
|
+
* manually and want it accepted by a `Bindable<T>` slot.
|
|
15
|
+
*
|
|
16
|
+
* @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).
|
|
17
|
+
* @param path - The `$ref` path (e.g. `"context.sender"`, `"myNode.result"`).
|
|
18
|
+
* @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* import { raw } from '@lifi/composer-sdk';
|
|
23
|
+
*
|
|
24
|
+
* // Reference an untypedOp output in a typed operation:
|
|
25
|
+
* builder.untypedOp('custom', 'some.op', {
|
|
26
|
+
* bind: { x: { $ref: 'input.token' } },
|
|
27
|
+
* config: {},
|
|
28
|
+
* });
|
|
29
|
+
* builder.core.add('sum', {
|
|
30
|
+
* bind: {
|
|
31
|
+
* a: raw.ref<'uint256'>('custom.result'),
|
|
32
|
+
* b: someTypedHandle,
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare const ref: <T extends OutputKind>(path: string) => TypedRef<T>;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a raw guard object for use in the `guards` array of an operation call.
|
|
40
|
+
*
|
|
41
|
+
* @param kind - The guard type (e.g. `"slippage"`).
|
|
42
|
+
* @param config - Guard-specific configuration (e.g. `{ toleranceBps: 300 }`).
|
|
43
|
+
* @returns An {@link AppliedGuard} object.
|
|
44
|
+
*/
|
|
45
|
+
declare const rawGuard: (kind: string, config?: Record<string, unknown>) => AppliedGuard;
|
|
46
|
+
|
|
47
|
+
export { rawGuard, ref };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const ref = (path) => ({ $ref: path });
|
|
2
|
+
const rawGuard = (kind, config = {}) => {
|
|
3
|
+
if ("kind" in config) {
|
|
4
|
+
throw new Error(
|
|
5
|
+
`rawGuard: 'kind' must not appear in config (got "${String(
|
|
6
|
+
config.kind
|
|
7
|
+
)}"). Pass it as the first argument instead.`
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
return { ...config, kind };
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
rawGuard,
|
|
14
|
+
ref
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=raw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/authoring/raw.ts"],"sourcesContent":["import type { AppliedGuard } from '@lifi/compose-spec';\n\nimport type { OutputKind, TypedRef } from '../types.js';\n\n/**\n * Creates a typed `$ref` pointer for use in bind slots.\n *\n * This is an **escape hatch** for referencing values that the typed builder\n * API doesn't cover — for example, outputs of an `untypedOp` node or custom\n * context paths. The caller is responsible for choosing the correct type\n * parameter; no runtime validation occurs.\n *\n * Prefer typed handles (`OutputHandle`, `InputHandle`) and `builder.context`\n * whenever possible. Use `ref` only when you need to construct a `$ref` path\n * manually and want it accepted by a `Bindable<T>` slot.\n *\n * @typeParam T - The output kind this ref represents (e.g. `'address'`, `'uint256'`, `'resource'`).\n * @param path - The `$ref` path (e.g. `\"context.sender\"`, `\"myNode.result\"`).\n * @returns A {@link TypedRef} accepted by `Bindable<T>` slots matching `T`.\n *\n * @example\n * ```ts\n * import { raw } from '@lifi/composer-sdk';\n *\n * // Reference an untypedOp output in a typed operation:\n * builder.untypedOp('custom', 'some.op', {\n * bind: { x: { $ref: 'input.token' } },\n * config: {},\n * });\n * builder.core.add('sum', {\n * bind: {\n * a: raw.ref<'uint256'>('custom.result'),\n * b: someTypedHandle,\n * },\n * });\n * ```\n */\nexport const ref = <T extends OutputKind>(path: string): TypedRef<T> =>\n ({ $ref: path }) as TypedRef<T>;\n\n/**\n * Creates a raw guard object for use in the `guards` array of an operation call.\n *\n * @param kind - The guard type (e.g. `\"slippage\"`).\n * @param config - Guard-specific configuration (e.g. `{ toleranceBps: 300 }`).\n * @returns An {@link AppliedGuard} object.\n */\nexport const rawGuard = (\n kind: string,\n config: Record<string, unknown> = {},\n): AppliedGuard => {\n if ('kind' in config) {\n throw new Error(\n `rawGuard: 'kind' must not appear in config (got \"${String(\n config.kind,\n )}\"). Pass it as the first argument instead.`,\n );\n }\n return { ...config, kind };\n};\n"],"mappings":"AAqCO,MAAM,MAAM,CAAuB,UACvC,EAAE,MAAM,KAAK;AAST,MAAM,WAAW,CACtB,MACA,SAAkC,CAAC,MAClB;AACjB,MAAI,UAAU,QAAQ;AACpB,UAAM,IAAI;AAAA,MACR,oDAAoD;AAAA,QAClD,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,EAAE,GAAG,QAAQ,KAAK;AAC3B;","names":[]}
|