@lifi/composer-sdk
Version:
Public Composer SDK for building and submitting flows
91 lines • 2.67 kB
JavaScript
import { handleToRef } from "./handles.js";
import { ref } from "./raw.js";
const toRef = (bindable) => {
if ("_tag" in bindable) return handleToRef(bindable);
return bindable;
};
const isResource = (decl) => typeof decl === "object" && decl !== null && "kind" in decl;
const createFlowBuilderCore = (chainId, options) => {
const id = options.name ?? crypto.randomUUID();
const flowInputs = [];
const nodes = [];
const nodeIds = /* @__PURE__ */ new Set();
const inputHandles = {};
for (const [name, decl] of Object.entries(options.inputs)) {
if (isResource(decl)) {
if (decl.chainId !== chainId) {
throw new Error(
`Input "${name}" has chainId ${decl.chainId} but flow targets chain ${chainId}`
);
}
flowInputs.push({ name, resource: decl });
inputHandles[name] = { _tag: "input", inputName: name, resource: decl };
} else {
flowInputs.push({ name, type: decl });
inputHandles[name] = { _tag: "input", inputName: name };
}
}
const call = (nodeId, op, args, outputs) => {
if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: "${nodeId}"`);
nodeIds.add(nodeId);
const bind = {};
for (const [key, val] of Object.entries(args.bind)) {
bind[key] = toRef(val);
}
const node = {
id: nodeId,
op,
bind,
config: args.config ?? {},
...args.guards && args.guards.length > 0 && { guards: args.guards }
};
nodes.push(node);
return new Proxy({}, {
get: (_target, prop) => {
if (typeof prop !== "string" || prop === "then") return void 0;
if (!(prop in outputs)) {
throw new Error(
`Op "${op}" has no output port "${prop}". Valid ports: ${Object.keys(
outputs
).join(", ")}`
);
}
return { _tag: "output", nodeId, portName: prop };
}
});
};
const untypedOp = (nodeId, op, args) => {
if (nodeIds.has(nodeId)) throw new Error(`Duplicate node id: "${nodeId}"`);
nodeIds.add(nodeId);
const node = {
id: nodeId,
op,
bind: args.bind,
config: args.config,
...args.guards && args.guards.length > 0 && { guards: args.guards }
};
nodes.push(node);
};
const build = () => ({
version: 1,
id,
chainId,
inputs: [...flowInputs],
nodes: [...nodes]
});
const context = {
sender: ref("context.sender"),
executionAddress: ref("context.executionAddress")
};
return {
context,
inputs: inputHandles,
call,
untypedOp,
build
};
};
export {
createFlowBuilderCore
};
//# sourceMappingURL=FlowBuilderCore.js.map