@lifi/composer-sdk 0.4.1 → 0.5.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 (92) hide show
  1. package/README.md +6 -3
  2. package/dist/authoring/FlowBuilderCore.cjs +1 -5
  3. package/dist/authoring/FlowBuilderCore.cjs.map +1 -1
  4. package/dist/authoring/FlowBuilderCore.d.cts +9 -7
  5. package/dist/authoring/FlowBuilderCore.d.ts +9 -7
  6. package/dist/authoring/FlowBuilderCore.js +2 -6
  7. package/dist/authoring/FlowBuilderCore.js.map +1 -1
  8. package/dist/authoring/handles.cjs +5 -2
  9. package/dist/authoring/handles.cjs.map +1 -1
  10. package/dist/authoring/handles.d.cts +25 -6
  11. package/dist/authoring/handles.d.ts +25 -6
  12. package/dist/authoring/handles.js +3 -1
  13. package/dist/authoring/handles.js.map +1 -1
  14. package/dist/authoring/raw.cjs +3 -0
  15. package/dist/authoring/raw.cjs.map +1 -1
  16. package/dist/authoring/raw.d.cts +33 -3
  17. package/dist/authoring/raw.d.ts +33 -3
  18. package/dist/authoring/raw.js +2 -0
  19. package/dist/authoring/raw.js.map +1 -1
  20. package/dist/authoring/signatureArgs.cjs.map +1 -1
  21. package/dist/authoring/signatureArgs.d.cts +16 -12
  22. package/dist/authoring/signatureArgs.d.ts +16 -12
  23. package/dist/authoring/signatureArgs.js.map +1 -1
  24. package/dist/client.cjs +70 -36
  25. package/dist/client.cjs.map +1 -1
  26. package/dist/client.d.cts +33 -4
  27. package/dist/client.d.ts +33 -4
  28. package/dist/client.js +70 -36
  29. package/dist/client.js.map +1 -1
  30. package/dist/discovery.cjs.map +1 -1
  31. package/dist/discovery.d.cts +18 -2
  32. package/dist/discovery.d.ts +18 -2
  33. package/dist/generated/config.generated.cjs.map +1 -1
  34. package/dist/generated/config.generated.d.cts +21 -1
  35. package/dist/generated/config.generated.d.ts +21 -1
  36. package/dist/generated/operations.generated.cjs +6 -0
  37. package/dist/generated/operations.generated.cjs.map +1 -1
  38. package/dist/generated/operations.generated.d.cts +18 -2
  39. package/dist/generated/operations.generated.d.ts +18 -2
  40. package/dist/generated/operations.generated.js +6 -0
  41. package/dist/generated/operations.generated.js.map +1 -1
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.d.cts +6 -6
  44. package/dist/index.d.ts +6 -6
  45. package/dist/index.js.map +1 -1
  46. package/dist/{raw-IxCF_bSS.d.ts → raw-BvRghN3r.d.ts} +3 -2
  47. package/dist/{raw-Dj_2rBSQ.d.cts → raw-s1rer8X3.d.cts} +3 -2
  48. package/dist/raw.cjs +2 -0
  49. package/dist/raw.cjs.map +1 -1
  50. package/dist/raw.d.cts +1 -1
  51. package/dist/raw.d.ts +1 -1
  52. package/dist/raw.js +2 -1
  53. package/dist/raw.js.map +1 -1
  54. package/dist/run/inputs.cjs +14 -15
  55. package/dist/run/inputs.cjs.map +1 -1
  56. package/dist/run/inputs.d.cts +8 -0
  57. package/dist/run/inputs.d.ts +8 -0
  58. package/dist/run/inputs.js +14 -15
  59. package/dist/run/inputs.js.map +1 -1
  60. package/dist/run/simulate.cjs +5 -0
  61. package/dist/run/simulate.cjs.map +1 -1
  62. package/dist/run/simulate.d.cts +5 -2
  63. package/dist/run/simulate.d.ts +5 -2
  64. package/dist/run/simulate.js +5 -0
  65. package/dist/run/simulate.js.map +1 -1
  66. package/dist/sdk.cjs +2 -0
  67. package/dist/sdk.cjs.map +1 -1
  68. package/dist/sdk.d.cts +28 -1
  69. package/dist/sdk.d.ts +28 -1
  70. package/dist/sdk.js +2 -0
  71. package/dist/sdk.js.map +1 -1
  72. package/dist/types.cjs.map +1 -1
  73. package/dist/types.d.cts +18 -2
  74. package/dist/types.d.ts +18 -2
  75. package/package.json +3 -10
  76. package/src/authoring/FlowBuilderCore.ts +13 -15
  77. package/src/authoring/handles.ts +41 -5
  78. package/src/authoring/raw.ts +36 -2
  79. package/src/authoring/signatureArgs.ts +17 -13
  80. package/src/client.ts +133 -39
  81. package/src/discovery.ts +18 -1
  82. package/src/examples/flySwap.ts +167 -0
  83. package/src/examples/run.ts +29 -4
  84. package/src/examples/supportedChains.ts +122 -0
  85. package/src/generated/config.generated.ts +24 -0
  86. package/src/generated/operations.generated.ts +26 -0
  87. package/src/index.ts +10 -1
  88. package/src/raw.ts +1 -1
  89. package/src/run/inputs.ts +30 -11
  90. package/src/run/simulate.ts +14 -2
  91. package/src/sdk.ts +30 -0
  92. package/src/types.ts +20 -1
package/dist/client.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ComposeManifest, ComposeCompileRequest, ComposeCompileResult, ComposeRouteRequest, SimulateRequest, SimulateResult } from '@lifi/compose-spec';
2
- import { GetZapPacksOptions, ZapPackOverview } from './discovery.js';
2
+ import { ChainSummary, GetZapPacksOptions, ZapPackOverview } from './discovery.js';
3
3
 
4
4
  /**
5
5
  * Configuration for creating a low-level Compose API client.
@@ -29,6 +29,28 @@ interface ComposeClient {
29
29
  * @throws {@link ComposeError} on network, validation, or server errors.
30
30
  */
31
31
  readonly getManifest: () => Promise<ComposeManifest>;
32
+ /**
33
+ * Fetches the chains the Compose API supports, ascending by `chainId`.
34
+ *
35
+ * A chain is listed once the server confirms the VM contract is deployed on
36
+ * it — the same condition {@link compile}, {@link route} and
37
+ * {@link simulate} validate against. A chain absent from this list is
38
+ * rejected outright by those endpoints.
39
+ *
40
+ * The converse does not hold: a listed chain can still have no routing edge
41
+ * for a given token pair, which {@link route} reports as `no_route_error`.
42
+ * Use {@link getZapPacks} to enumerate the pairs that do route.
43
+ *
44
+ * Each entry carries a display `name` alongside its `chainId`. The name is a
45
+ * deployment-maintained label — render it, but key on `chainId`.
46
+ *
47
+ * The list tracks the server's chain registry, which refreshes periodically.
48
+ * Results are not cached by the SDK; callers should cache as appropriate.
49
+ *
50
+ * @returns The supported chains, ascending by `chainId`.
51
+ * @throws {@link ComposeError} on network or server errors.
52
+ */
53
+ readonly getChains: () => Promise<readonly ChainSummary[]>;
32
54
  /**
33
55
  * Submits a compile request and returns the result.
34
56
  *
@@ -47,9 +69,9 @@ interface ComposeClient {
47
69
  * `POST /compose/route`.
48
70
  *
49
71
  * A convenience path that skips flow authoring: the server builds a one-node
50
- * `lifi.zap` flow with a `directDeposit` input from the `fromToken` /
51
- * `toToken` pair and runs it through the same pipeline as {@link compile}.
52
- * The response is therefore the same discriminated result — HTTP 206 under
72
+ * zap flow with a `directDeposit` input from the `fromToken` / `toToken`
73
+ * pair and runs it through the same pipeline as {@link compile}. The
74
+ * response is therefore the same discriminated result — HTTP 206 under
53
75
  * `simulationPolicy: 'allow-revert'` yields `status: 'partial'` rather than
54
76
  * throwing, exactly as it does for {@link compile}.
55
77
  *
@@ -60,6 +82,13 @@ interface ComposeClient {
60
82
  * author richer flows later, so the single-step limit is the current state of
61
83
  * the server, not the shape of this contract.
62
84
  *
85
+ * Only synchronous edges are considered unless the request sets
86
+ * `allowAsyncRoutes: true`, so by default every produced resource comes back
87
+ * `availability: 'now'` and a pair reachable only after settlement is a
88
+ * `no_route_error`. Opting in adds the `lifi.zapAsync` fallback, which still
89
+ * loses to a synchronous edge when the pair has one; read
90
+ * `producedResources[*].availability` to see which representation you got.
91
+ *
63
92
  * Use {@link compile} for what the server does not author for you: several
64
93
  * chained operations, splits, explicit preconditions, or per-op guards.
65
94
  *
package/dist/client.js CHANGED
@@ -3,9 +3,52 @@ import {
3
3
  parseCompilePartialEnvelope,
4
4
  parseSimulateResult
5
5
  } from "./responseSchemas.js";
6
- const SDK_VERSION = true ? "0.4.1" : "dev";
6
+ const SDK_VERSION = true ? "0.5.0" : "dev";
7
7
  const bigintReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
8
8
  const isNonNullObject = (v) => typeof v === "object" && v !== null;
9
+ const INTEGER_STRING = /^\d+$/;
10
+ const decodeAmount = (value, key, field, url) => {
11
+ if (typeof value !== "string" || !INTEGER_STRING.test(value)) {
12
+ throw new ComposeError(
13
+ "UNKNOWN_ERROR",
14
+ `Malformed compose response: producedResources.${key}.simulated.${field} is ${value === void 0 ? "absent" : "not an integer string"}`,
15
+ { url }
16
+ );
17
+ }
18
+ return BigInt(value);
19
+ };
20
+ const decodeSimulatedAmounts = (data, url) => {
21
+ if (!isNonNullObject(data)) return;
22
+ const resources = data.producedResources;
23
+ if (!isNonNullObject(resources)) return;
24
+ for (const key of Object.keys(resources)) {
25
+ const resource = resources[key];
26
+ if (!isNonNullObject(resource)) continue;
27
+ const simulated = resource.simulated;
28
+ if (simulated === void 0) continue;
29
+ if (!isNonNullObject(simulated)) {
30
+ throw new ComposeError(
31
+ "UNKNOWN_ERROR",
32
+ `Malformed compose response: producedResources.${key}.simulated is not an object`,
33
+ { url }
34
+ );
35
+ }
36
+ simulated.amountOut = decodeAmount(
37
+ simulated.amountOut,
38
+ key,
39
+ "amountOut",
40
+ url
41
+ );
42
+ if (simulated.amountOutMin !== void 0) {
43
+ simulated.amountOutMin = decodeAmount(
44
+ simulated.amountOutMin,
45
+ key,
46
+ "amountOutMin",
47
+ url
48
+ );
49
+ }
50
+ }
51
+ };
9
52
  const parseBody = async (res, url) => {
10
53
  const body = await res.json().catch((_) => null);
11
54
  if (!isNonNullObject(body) || !("data" in body)) {
@@ -17,6 +60,7 @@ const parseBody = async (res, url) => {
17
60
  };
18
61
  const parseCompileSuccessBody = async (res, url) => {
19
62
  const data = await parseBody(res, url);
63
+ decodeSimulatedAmounts(data, url);
20
64
  return { ...data, status: "success" };
21
65
  };
22
66
  const parsePartialBody = async (res, url) => {
@@ -30,6 +74,7 @@ const parsePartialBody = async (res, url) => {
30
74
  );
31
75
  }
32
76
  const data = envelope.data;
77
+ decodeSimulatedAmounts(data, url);
33
78
  return { ...data, status: "partial", error: envelope.error };
34
79
  };
35
80
  const parseSimulateBody = async (res, url) => {
@@ -65,6 +110,23 @@ const postCompile = async ({ fetchFn, baseHeaders }, url, request) => {
65
110
  }
66
111
  return await parseCompileSuccessBody(res, url);
67
112
  };
113
+ const getJson = async ({ fetchFn, baseHeaders }, url) => {
114
+ let res;
115
+ try {
116
+ res = await fetchFn(url, {
117
+ method: "GET",
118
+ headers: { ...baseHeaders }
119
+ });
120
+ } catch (err) {
121
+ const message = err instanceof Error ? err.message : String(err);
122
+ throw new ComposeError("NETWORK_ERROR", message, { cause: err });
123
+ }
124
+ if (!res.ok) {
125
+ const body = await res.text();
126
+ throw errorFromHttpResponse(res.status, body, url);
127
+ }
128
+ return await parseBody(res, url);
129
+ };
68
130
  const createComposeClient = (options) => {
69
131
  if (!options.baseUrl || !/^https?:\/\//i.test(options.baseUrl)) {
70
132
  throw new ComposeError(
@@ -87,24 +149,8 @@ const createComposeClient = (options) => {
87
149
  "x-lifi-api-key": trimmedApiKey
88
150
  };
89
151
  const transport = { fetchFn, baseHeaders };
90
- const getManifest = async () => {
91
- const url = `${base}/compose/manifest`;
92
- let res;
93
- try {
94
- res = await fetchFn(url, {
95
- method: "GET",
96
- headers: { ...baseHeaders }
97
- });
98
- } catch (err) {
99
- const message = err instanceof Error ? err.message : String(err);
100
- throw new ComposeError("NETWORK_ERROR", message, { cause: err });
101
- }
102
- if (!res.ok) {
103
- const body = await res.text();
104
- throw errorFromHttpResponse(res.status, body, url);
105
- }
106
- return await parseBody(res, url);
107
- };
152
+ const getManifest = async () => getJson(transport, `${base}/compose/manifest`);
153
+ const getChains = async () => getJson(transport, `${base}/chains`);
108
154
  const compile = async (request) => postCompile(transport, `${base}/compose`, request);
109
155
  const route = async (request) => postCompile(transport, `${base}/compose/route`, request);
110
156
  const getZapPacks = async (options2) => {
@@ -115,22 +161,10 @@ const createComposeClient = (options) => {
115
161
  params.set("protocols", list);
116
162
  }
117
163
  const qs = params.toString();
118
- const url = `${base}/compose/zap-packs${qs ? `?${qs}` : ""}`;
119
- let res;
120
- try {
121
- res = await fetchFn(url, {
122
- method: "GET",
123
- headers: { ...baseHeaders }
124
- });
125
- } catch (err) {
126
- const message = err instanceof Error ? err.message : String(err);
127
- throw new ComposeError("NETWORK_ERROR", message, { cause: err });
128
- }
129
- if (!res.ok) {
130
- const body = await res.text();
131
- throw errorFromHttpResponse(res.status, body, url);
132
- }
133
- return await parseBody(res, url);
164
+ return getJson(
165
+ transport,
166
+ `${base}/compose/zap-packs${qs ? `?${qs}` : ""}`
167
+ );
134
168
  };
135
169
  const simulate = async (request) => {
136
170
  const url = `${base}/simulate`;
@@ -151,7 +185,7 @@ const createComposeClient = (options) => {
151
185
  const body = await res.text();
152
186
  throw errorFromHttpResponse(res.status, body, url);
153
187
  };
154
- return { getManifest, compile, route, getZapPacks, simulate };
188
+ return { getManifest, getChains, compile, route, getZapPacks, simulate };
155
189
  };
156
190
  export {
157
191
  createComposeClient
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type {\n ComposeCompilePartialData,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeManifest,\n ComposeRouteRequest,\n SimulateRequest,\n SimulateResult,\n} from '@lifi/compose-spec';\n\nimport type { GetZapPacksOptions, ZapPackOverview } from './discovery.js';\nimport { ComposeError, errorFromHttpResponse } from './errors.js';\nimport {\n parseCompilePartialEnvelope,\n parseSimulateResult,\n} from './responseSchemas.js';\n\n// __SDK_VERSION__ is a compile-time constant injected by tsup (via `define` in tsup.config.ts)\n// and by vitest (via `define` in vitest.config.ts). Both read the version from package.json\n// at build/test time and replace this identifier with the literal string value.\n// It is sent as the `x-lifi-composer-sdk` request header so the server can identify the caller.\n// Falls back to 'dev' when running via tsx without tsup substitution (e.g. the example harness).\ndeclare const __SDK_VERSION__: string;\n\nconst SDK_VERSION: string =\n typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : 'dev';\n\n/**\n * Configuration for creating a low-level Compose API client.\n */\nexport interface ComposeClientOptions {\n /** Base URL of the Compose API. */\n readonly baseUrl: string;\n /** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch;\n /** LI.FI API key, sent as the `x-lifi-api-key` header on every request. Required — the Compose API rejects unauthenticated requests. */\n readonly apiKey: string;\n}\n\n/**\n * Low-level HTTP client for the Compose API.\n *\n * Handles request serialization, SDK version headers, and error mapping.\n * Prefer using {@link ComposeSdk} for the full builder experience. Use this\n * directly when you need to decouple request building from submission — e.g.\n * build via `sdk.request()` then submit via `client.compile()` with custom\n * retry logic or request inspection.\n */\nexport interface ComposeClient {\n /**\n * Fetches the server's operation manifest describing all supported operations,\n * guards, materialisers, and preconditions.\n * @returns The manifest document.\n * @throws {@link ComposeError} on network, validation, or server errors.\n */\n readonly getManifest: () => Promise<ComposeManifest>;\n /**\n * Submits a compile request and returns the result.\n *\n * When the caller passes `simulationPolicy: 'allow-revert'` and the transaction\n * reverts in simulation, the server responds with HTTP 206 and the SDK returns a\n * partial result (`status: 'partial'`) instead of throwing. The partial result\n * includes the transaction (without `gasLimit`) and revert diagnostics.\n *\n * @param request - The full compile request including flow and run inputs.\n * @returns A discriminated result: `status: 'success'` or `status: 'partial'`.\n * @throws {@link ComposeError} on network, validation, or server errors.\n */\n readonly compile: (\n request: ComposeCompileRequest,\n ) => Promise<ComposeCompileResult>;\n /**\n * Compiles a token pair into a submit-ready transaction via\n * `POST /compose/route`.\n *\n * A convenience path that skips flow authoring: the server builds a one-node\n * `lifi.zap` flow with a `directDeposit` input from the `fromToken` /\n * `toToken` pair and runs it through the same pipeline as {@link compile}.\n * The response is therefore the same discriminated result — HTTP 206 under\n * `simulationPolicy: 'allow-revert'` yields `status: 'partial'` rather than\n * throwing, exactly as it does for {@link compile}.\n *\n * As of today that flow is a single zap step: one edge of the backend's\n * routing catalog (a position entry or exit, a wrap or unwrap, a mint or\n * burn). Enumerate the pairs it covers with {@link getZapPacks}; a pair with\n * no edge is rejected with `kind: 'no_route_error'`. The endpoint is meant to\n * author richer flows later, so the single-step limit is the current state of\n * the server, not the shape of this contract.\n *\n * Use {@link compile} for what the server does not author for you: several\n * chained operations, splits, explicit preconditions, or per-op guards.\n *\n * `bigint` amounts in `amount` are serialised to decimal strings\n * automatically.\n *\n * @param request - The from/to token pair, amount, signer, and route options.\n * @returns A discriminated result: `status: 'success'` or `status: 'partial'`.\n * @throws {@link ComposeError} on network, validation, or server errors —\n * including `NOT_FOUND` (HTTP 404) when no catalog edge covers the pair.\n */\n readonly route: (\n request: ComposeRouteRequest,\n ) => Promise<ComposeCompileResult>;\n /**\n * Fetches the available routing edges grouped by protocol.\n *\n * The edge catalog is dynamic — it reflects the current state of the\n * backend's routing snapshot (protocols, chains, token blacklists).\n * Results are not cached by the SDK; callers should cache as appropriate.\n *\n * @param options - Optional filter to restrict results to specific protocols.\n * @returns An array of {@link ZapPackOverview} objects, one per protocol.\n * @throws {@link ComposeError} on network or server errors (503 when the\n * routing catalog is not yet initialized).\n */\n readonly getZapPacks: (\n options?: GetZapPacksOptions,\n ) => Promise<readonly ZapPackOverview[]>;\n /**\n * Simulates a raw, pre-encoded transaction against `POST /simulate` and\n * reports how the watched balances change and how much inner-call gas it\n * burns.\n *\n * The result is a discriminated union on `status`:\n * - `'ok'` — the simulation ran successfully; `deltas`/`gasUsed` are populated.\n * - `'revert'` — the simulation ran but the transaction reverted on-chain. A\n * revert is a *successful simulation*, not a transport error, so it is\n * returned (HTTP 200) rather than thrown — mirroring how {@link compile}\n * returns `status: 'partial'` on a simulated revert.\n * - `'error'` — the request was well-formed but the simulation could not be\n * set up or run (HTTP 422); `message` is intentionally generic.\n *\n * `bigint` amounts in the request (`value`, requirement `balance`/`allowance`)\n * are serialised to decimal strings automatically.\n *\n * @param request - The raw transaction plus funding `requirements` and the\n * `trackedBalances` to watch.\n * @returns A {@link SimulateResult} (`ok` / `revert` / `error`).\n * @throws {@link ComposeError} on network failures, HTTP 400 (malformed\n * input), 401/403 (auth), 404, 429, and 5xx.\n */\n readonly simulate: (request: SimulateRequest) => Promise<SimulateResult>;\n}\n\nconst bigintReplacer = (_key: string, value: unknown): unknown =>\n typeof value === 'bigint' ? value.toString() : value;\n\nconst isNonNullObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null;\n\nconst parseBody = async <T>(res: Response, url: string): Promise<T> => {\n const body = await res.json().catch((_) => null);\n if (!isNonNullObject(body) || !('data' in body)) {\n throw new ComposeError('UNKNOWN_ERROR', 'Unexpected response format', {\n url,\n });\n }\n return body.data as T;\n};\n\nconst parseCompileSuccessBody = async (\n res: Response,\n url: string,\n): Promise<ComposeCompileResult> => {\n const data = await parseBody<ComposeCompileSuccessData>(res, url);\n return { ...data, status: 'success' as const };\n};\n\nconst parsePartialBody = async (\n res: Response,\n url: string,\n): Promise<ComposeCompileResult> => {\n const body = await res.json().catch((_) => null);\n const envelope = parseCompilePartialEnvelope(body);\n if (envelope === null) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n 'Unexpected partial response format',\n { url },\n );\n }\n // `data` is validated as an object by the schema; compose-spec owns its full\n // shape as a hand-authored type, so we narrow it here rather than re-declaring\n // that type as a schema. `error` is fully validated — no cast needed.\n const data = envelope.data as unknown as ComposeCompilePartialData;\n return { ...data, status: 'partial' as const, error: envelope.error };\n};\n\n// `/simulate` is un-enveloped: the discriminated body (`{ status, ... }`) is at\n// the top level, NOT wrapped in `{ data }` like `/compose`. So this reads the\n// body directly and validates it against the simulate union rather than reusing\n// `parseBody`.\nconst parseSimulateBody = async (\n res: Response,\n url: string,\n): Promise<SimulateResult> => {\n const body = await res.json().catch((_) => null);\n const result = parseSimulateResult(body);\n if (result === null) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n 'Unexpected simulate response format',\n { url },\n );\n }\n return result;\n};\n// `POST /compose` and `POST /compose/route` differ only in path and request\n// shape: both return the enveloped success data on 200 and the partial\n// envelope on 206, so they share one transport.\ntype ComposeTransport = {\n readonly fetchFn: typeof fetch;\n readonly baseHeaders: Record<string, string>;\n};\n\nconst postCompile = async (\n { fetchFn, baseHeaders }: ComposeTransport,\n url: string,\n request: ComposeCompileRequest | ComposeRouteRequest,\n): Promise<ComposeCompileResult> => {\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'POST',\n headers: { ...baseHeaders, 'Content-Type': 'application/json' },\n body: JSON.stringify(request, bigintReplacer),\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n if (res.status === 206) {\n return await parsePartialBody(res, url);\n }\n if (!res.ok) {\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n }\n return await parseCompileSuccessBody(res, url);\n};\n\n/**\n * Creates a low-level Compose API client.\n *\n * @param options - Client configuration including the API base URL.\n * @returns A {@link ComposeClient} instance.\n */\nexport const createComposeClient = (\n options: ComposeClientOptions,\n): ComposeClient => {\n if (!options.baseUrl || !/^https?:\\/\\//i.test(options.baseUrl)) {\n throw new ComposeError(\n 'VALIDATION_ERROR',\n `Invalid baseUrl: expected an HTTP(S) URL, got \"${options.baseUrl}\"`,\n );\n }\n const trimmedApiKey = options.apiKey?.trim() || undefined;\n if (!trimmedApiKey) {\n throw new ComposeError(\n 'VALIDATION_ERROR',\n 'apiKey is required: pass a LI.FI API key to createComposeSdk().',\n );\n }\n const fetchFn = options.fetch ?? globalThis.fetch;\n const base = options.baseUrl.replace(/\\/$/, '');\n\n const baseHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'x-lifi-composer-sdk': SDK_VERSION,\n 'x-lifi-api-key': trimmedApiKey,\n };\n const transport: ComposeTransport = { fetchFn, baseHeaders };\n\n const getManifest = async (): Promise<ComposeManifest> => {\n const url = `${base}/compose/manifest`;\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'GET',\n headers: { ...baseHeaders },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n if (!res.ok) {\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n }\n return await parseBody<ComposeManifest>(res, url);\n };\n\n const compile = async (\n request: ComposeCompileRequest,\n ): Promise<ComposeCompileResult> =>\n postCompile(transport, `${base}/compose`, request);\n\n const route = async (\n request: ComposeRouteRequest,\n ): Promise<ComposeCompileResult> =>\n postCompile(transport, `${base}/compose/route`, request);\n\n const getZapPacks = async (\n options?: GetZapPacksOptions,\n ): Promise<readonly ZapPackOverview[]> => {\n const params = new URLSearchParams();\n if (options?.protocols !== undefined) {\n // Backend expects a single comma-separated value, not repeated keys.\n const raw = options.protocols;\n const list = typeof raw === 'string' ? raw : raw.join(',');\n params.set('protocols', list);\n }\n const qs = params.toString();\n const url = `${base}/compose/zap-packs${qs ? `?${qs}` : ''}`;\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'GET',\n headers: { ...baseHeaders },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n if (!res.ok) {\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n }\n return await parseBody<readonly ZapPackOverview[]>(res, url);\n };\n\n const simulate = async (\n request: SimulateRequest,\n ): Promise<SimulateResult> => {\n const url = `${base}/simulate`;\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'POST',\n headers: { ...baseHeaders, 'Content-Type': 'application/json' },\n body: JSON.stringify(request, bigintReplacer),\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n // Only 200 (carries `ok`/`revert`) and 422 (carries the `error` member of\n // the union) have a discriminated body. 422 is deliberately intercepted\n // here (not thrown as VALIDATION_ERROR) so callers get one exhaustive\n // `switch (result.status)`. Every other status is a transport error and is\n // thrown — including HTTP 400 (malformed input, no `status` body) and any\n // unexpected 2xx.\n if (res.status === 200 || res.status === 422) {\n return await parseSimulateBody(res, url);\n }\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n };\n\n return { getManifest, compile, route, getZapPacks, simulate };\n};\n"],"mappings":"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","names":["options"]}
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type {\n ComposeCompilePartialData,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeManifest,\n ComposeRouteRequest,\n SimulateRequest,\n SimulateResult,\n} from '@lifi/compose-spec';\n\nimport type {\n ChainSummary,\n GetZapPacksOptions,\n ZapPackOverview,\n} from './discovery.js';\nimport { ComposeError, errorFromHttpResponse } from './errors.js';\nimport {\n parseCompilePartialEnvelope,\n parseSimulateResult,\n} from './responseSchemas.js';\n\n// __SDK_VERSION__ is a compile-time constant injected by tsup (via `define` in tsup.config.ts)\n// and by vitest (via `define` in vitest.config.ts). Both read the version from package.json\n// at build/test time and replace this identifier with the literal string value.\n// It is sent as the `x-lifi-composer-sdk` request header so the server can identify the caller.\n// Falls back to 'dev' when running via tsx without tsup substitution (e.g. the example harness).\ndeclare const __SDK_VERSION__: string;\n\nconst SDK_VERSION: string =\n typeof __SDK_VERSION__ !== 'undefined' ? __SDK_VERSION__ : 'dev';\n\n/**\n * Configuration for creating a low-level Compose API client.\n */\nexport interface ComposeClientOptions {\n /** Base URL of the Compose API. */\n readonly baseUrl: string;\n /** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch;\n /** LI.FI API key, sent as the `x-lifi-api-key` header on every request. Required — the Compose API rejects unauthenticated requests. */\n readonly apiKey: string;\n}\n\n/**\n * Low-level HTTP client for the Compose API.\n *\n * Handles request serialization, SDK version headers, and error mapping.\n * Prefer using {@link ComposeSdk} for the full builder experience. Use this\n * directly when you need to decouple request building from submission — e.g.\n * build via `sdk.request()` then submit via `client.compile()` with custom\n * retry logic or request inspection.\n */\nexport interface ComposeClient {\n /**\n * Fetches the server's operation manifest describing all supported operations,\n * guards, materialisers, and preconditions.\n * @returns The manifest document.\n * @throws {@link ComposeError} on network, validation, or server errors.\n */\n readonly getManifest: () => Promise<ComposeManifest>;\n /**\n * Fetches the chains the Compose API supports, ascending by `chainId`.\n *\n * A chain is listed once the server confirms the VM contract is deployed on\n * it — the same condition {@link compile}, {@link route} and\n * {@link simulate} validate against. A chain absent from this list is\n * rejected outright by those endpoints.\n *\n * The converse does not hold: a listed chain can still have no routing edge\n * for a given token pair, which {@link route} reports as `no_route_error`.\n * Use {@link getZapPacks} to enumerate the pairs that do route.\n *\n * Each entry carries a display `name` alongside its `chainId`. The name is a\n * deployment-maintained label — render it, but key on `chainId`.\n *\n * The list tracks the server's chain registry, which refreshes periodically.\n * Results are not cached by the SDK; callers should cache as appropriate.\n *\n * @returns The supported chains, ascending by `chainId`.\n * @throws {@link ComposeError} on network or server errors.\n */\n readonly getChains: () => Promise<readonly ChainSummary[]>;\n /**\n * Submits a compile request and returns the result.\n *\n * When the caller passes `simulationPolicy: 'allow-revert'` and the transaction\n * reverts in simulation, the server responds with HTTP 206 and the SDK returns a\n * partial result (`status: 'partial'`) instead of throwing. The partial result\n * includes the transaction (without `gasLimit`) and revert diagnostics.\n *\n * @param request - The full compile request including flow and run inputs.\n * @returns A discriminated result: `status: 'success'` or `status: 'partial'`.\n * @throws {@link ComposeError} on network, validation, or server errors.\n */\n readonly compile: (\n request: ComposeCompileRequest,\n ) => Promise<ComposeCompileResult>;\n /**\n * Compiles a token pair into a submit-ready transaction via\n * `POST /compose/route`.\n *\n * A convenience path that skips flow authoring: the server builds a one-node\n * zap flow with a `directDeposit` input from the `fromToken` / `toToken`\n * pair and runs it through the same pipeline as {@link compile}. The\n * response is therefore the same discriminated result — HTTP 206 under\n * `simulationPolicy: 'allow-revert'` yields `status: 'partial'` rather than\n * throwing, exactly as it does for {@link compile}.\n *\n * As of today that flow is a single zap step: one edge of the backend's\n * routing catalog (a position entry or exit, a wrap or unwrap, a mint or\n * burn). Enumerate the pairs it covers with {@link getZapPacks}; a pair with\n * no edge is rejected with `kind: 'no_route_error'`. The endpoint is meant to\n * author richer flows later, so the single-step limit is the current state of\n * the server, not the shape of this contract.\n *\n * Only synchronous edges are considered unless the request sets\n * `allowAsyncRoutes: true`, so by default every produced resource comes back\n * `availability: 'now'` and a pair reachable only after settlement is a\n * `no_route_error`. Opting in adds the `lifi.zapAsync` fallback, which still\n * loses to a synchronous edge when the pair has one; read\n * `producedResources[*].availability` to see which representation you got.\n *\n * Use {@link compile} for what the server does not author for you: several\n * chained operations, splits, explicit preconditions, or per-op guards.\n *\n * `bigint` amounts in `amount` are serialised to decimal strings\n * automatically.\n *\n * @param request - The from/to token pair, amount, signer, and route options.\n * @returns A discriminated result: `status: 'success'` or `status: 'partial'`.\n * @throws {@link ComposeError} on network, validation, or server errors —\n * including `NOT_FOUND` (HTTP 404) when no catalog edge covers the pair.\n */\n readonly route: (\n request: ComposeRouteRequest,\n ) => Promise<ComposeCompileResult>;\n /**\n * Fetches the available routing edges grouped by protocol.\n *\n * The edge catalog is dynamic — it reflects the current state of the\n * backend's routing snapshot (protocols, chains, token blacklists).\n * Results are not cached by the SDK; callers should cache as appropriate.\n *\n * @param options - Optional filter to restrict results to specific protocols.\n * @returns An array of {@link ZapPackOverview} objects, one per protocol.\n * @throws {@link ComposeError} on network or server errors (503 when the\n * routing catalog is not yet initialized).\n */\n readonly getZapPacks: (\n options?: GetZapPacksOptions,\n ) => Promise<readonly ZapPackOverview[]>;\n /**\n * Simulates a raw, pre-encoded transaction against `POST /simulate` and\n * reports how the watched balances change and how much inner-call gas it\n * burns.\n *\n * The result is a discriminated union on `status`:\n * - `'ok'` — the simulation ran successfully; `deltas`/`gasUsed` are populated.\n * - `'revert'` — the simulation ran but the transaction reverted on-chain. A\n * revert is a *successful simulation*, not a transport error, so it is\n * returned (HTTP 200) rather than thrown — mirroring how {@link compile}\n * returns `status: 'partial'` on a simulated revert.\n * - `'error'` — the request was well-formed but the simulation could not be\n * set up or run (HTTP 422); `message` is intentionally generic.\n *\n * `bigint` amounts in the request (`value`, requirement `balance`/`allowance`)\n * are serialised to decimal strings automatically.\n *\n * @param request - The raw transaction plus funding `requirements` and the\n * `trackedBalances` to watch.\n * @returns A {@link SimulateResult} (`ok` / `revert` / `error`).\n * @throws {@link ComposeError} on network failures, HTTP 400 (malformed\n * input), 401/403 (auth), 404, 429, and 5xx.\n */\n readonly simulate: (request: SimulateRequest) => Promise<SimulateResult>;\n}\n\nconst bigintReplacer = (_key: string, value: unknown): unknown =>\n typeof value === 'bigint' ? value.toString() : value;\n\nconst isNonNullObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null;\n\n// Non-negative decimal integer string, as the server sends token amounts.\nconst INTEGER_STRING = /^\\d+$/;\n\nconst decodeAmount = (\n value: unknown,\n key: string,\n field: 'amountOut' | 'amountOutMin',\n url: string,\n): bigint => {\n if (typeof value !== 'string' || !INTEGER_STRING.test(value)) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n `Malformed compose response: producedResources.${key}.simulated.${field} is ${\n value === undefined ? 'absent' : 'not an integer string'\n }`,\n { url },\n );\n }\n return BigInt(value);\n};\n\n// `simulated.amountOut` / `.amountOutMin` are declared `bigint` on\n// `SimulatedAmounts` (the domain truth: `compose-core` produces real bigints)\n// but arrive as decimal strings on the wire (the backend stringifies them).\n// Decode at this seam so a consumer reading the declared type gets the value\n// the type promises. A resource without `simulated` is left untouched; a\n// `simulated` claiming a missing or non-numeric amount is a contract violation\n// and surfaces as a `ComposeError` rather than `NaN` / `BigInt(undefined)`.\nconst decodeSimulatedAmounts = (data: unknown, url: string): void => {\n if (!isNonNullObject(data)) return;\n const resources = data.producedResources;\n if (!isNonNullObject(resources)) return;\n for (const key of Object.keys(resources)) {\n const resource = resources[key];\n if (!isNonNullObject(resource)) continue;\n const simulated = resource.simulated;\n if (simulated === undefined) continue;\n if (!isNonNullObject(simulated)) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n `Malformed compose response: producedResources.${key}.simulated is not an object`,\n { url },\n );\n }\n simulated.amountOut = decodeAmount(\n simulated.amountOut,\n key,\n 'amountOut',\n url,\n );\n if (simulated.amountOutMin !== undefined) {\n simulated.amountOutMin = decodeAmount(\n simulated.amountOutMin,\n key,\n 'amountOutMin',\n url,\n );\n }\n }\n};\n\nconst parseBody = async <T>(res: Response, url: string): Promise<T> => {\n const body = await res.json().catch((_) => null);\n if (!isNonNullObject(body) || !('data' in body)) {\n throw new ComposeError('UNKNOWN_ERROR', 'Unexpected response format', {\n url,\n });\n }\n return body.data as T;\n};\n\nconst parseCompileSuccessBody = async (\n res: Response,\n url: string,\n): Promise<ComposeCompileResult> => {\n const data = await parseBody<ComposeCompileSuccessData>(res, url);\n decodeSimulatedAmounts(data, url);\n return { ...data, status: 'success' as const };\n};\n\nconst parsePartialBody = async (\n res: Response,\n url: string,\n): Promise<ComposeCompileResult> => {\n const body = await res.json().catch((_) => null);\n const envelope = parseCompilePartialEnvelope(body);\n if (envelope === null) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n 'Unexpected partial response format',\n { url },\n );\n }\n // `data` is validated as an object by the schema; compose-spec owns its full\n // shape as a hand-authored type, so we narrow it here rather than re-declaring\n // that type as a schema. `error` is fully validated — no cast needed.\n const data = envelope.data as unknown as ComposeCompilePartialData;\n decodeSimulatedAmounts(data, url);\n return { ...data, status: 'partial' as const, error: envelope.error };\n};\n\n// `/simulate` is un-enveloped: the discriminated body (`{ status, ... }`) is at\n// the top level, NOT wrapped in `{ data }` like `/compose`. So this reads the\n// body directly and validates it against the simulate union rather than reusing\n// `parseBody`.\nconst parseSimulateBody = async (\n res: Response,\n url: string,\n): Promise<SimulateResult> => {\n const body = await res.json().catch((_) => null);\n const result = parseSimulateResult(body);\n if (result === null) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n 'Unexpected simulate response format',\n { url },\n );\n }\n return result;\n};\n// `POST /compose` and `POST /compose/route` differ only in path and request\n// shape: both return the enveloped success data on 200 and the partial\n// envelope on 206, so they share one transport.\ntype ComposeTransport = {\n readonly fetchFn: typeof fetch;\n readonly baseHeaders: Record<string, string>;\n};\n\nconst postCompile = async (\n { fetchFn, baseHeaders }: ComposeTransport,\n url: string,\n request: ComposeCompileRequest | ComposeRouteRequest,\n): Promise<ComposeCompileResult> => {\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'POST',\n headers: { ...baseHeaders, 'Content-Type': 'application/json' },\n body: JSON.stringify(request, bigintReplacer),\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n if (res.status === 206) {\n return await parsePartialBody(res, url);\n }\n if (!res.ok) {\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n }\n return await parseCompileSuccessBody(res, url);\n};\n\n// Every enveloped GET on this API behaves identically: no body, no query\n// semantics of its own, `{ data }` on success, an error envelope otherwise.\nconst getJson = async <T>(\n { fetchFn, baseHeaders }: ComposeTransport,\n url: string,\n): Promise<T> => {\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'GET',\n headers: { ...baseHeaders },\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n if (!res.ok) {\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n }\n return await parseBody<T>(res, url);\n};\n\n/**\n * Creates a low-level Compose API client.\n *\n * @param options - Client configuration including the API base URL.\n * @returns A {@link ComposeClient} instance.\n */\nexport const createComposeClient = (\n options: ComposeClientOptions,\n): ComposeClient => {\n if (!options.baseUrl || !/^https?:\\/\\//i.test(options.baseUrl)) {\n throw new ComposeError(\n 'VALIDATION_ERROR',\n `Invalid baseUrl: expected an HTTP(S) URL, got \"${options.baseUrl}\"`,\n );\n }\n const trimmedApiKey = options.apiKey?.trim() || undefined;\n if (!trimmedApiKey) {\n throw new ComposeError(\n 'VALIDATION_ERROR',\n 'apiKey is required: pass a LI.FI API key to createComposeSdk().',\n );\n }\n const fetchFn = options.fetch ?? globalThis.fetch;\n const base = options.baseUrl.replace(/\\/$/, '');\n\n const baseHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'x-lifi-composer-sdk': SDK_VERSION,\n 'x-lifi-api-key': trimmedApiKey,\n };\n const transport: ComposeTransport = { fetchFn, baseHeaders };\n\n const getManifest = async (): Promise<ComposeManifest> =>\n getJson<ComposeManifest>(transport, `${base}/compose/manifest`);\n\n const getChains = async (): Promise<readonly ChainSummary[]> =>\n getJson<readonly ChainSummary[]>(transport, `${base}/chains`);\n\n const compile = async (\n request: ComposeCompileRequest,\n ): Promise<ComposeCompileResult> =>\n postCompile(transport, `${base}/compose`, request);\n\n const route = async (\n request: ComposeRouteRequest,\n ): Promise<ComposeCompileResult> =>\n postCompile(transport, `${base}/compose/route`, request);\n\n const getZapPacks = async (\n options?: GetZapPacksOptions,\n ): Promise<readonly ZapPackOverview[]> => {\n const params = new URLSearchParams();\n if (options?.protocols !== undefined) {\n // Backend expects a single comma-separated value, not repeated keys.\n const raw = options.protocols;\n const list = typeof raw === 'string' ? raw : raw.join(',');\n params.set('protocols', list);\n }\n const qs = params.toString();\n return getJson<readonly ZapPackOverview[]>(\n transport,\n `${base}/compose/zap-packs${qs ? `?${qs}` : ''}`,\n );\n };\n\n const simulate = async (\n request: SimulateRequest,\n ): Promise<SimulateResult> => {\n const url = `${base}/simulate`;\n let res: Response;\n try {\n res = await fetchFn(url, {\n method: 'POST',\n headers: { ...baseHeaders, 'Content-Type': 'application/json' },\n body: JSON.stringify(request, bigintReplacer),\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new ComposeError('NETWORK_ERROR', message, { cause: err });\n }\n // Only 200 (carries `ok`/`revert`) and 422 (carries the `error` member of\n // the union) have a discriminated body. 422 is deliberately intercepted\n // here (not thrown as VALIDATION_ERROR) so callers get one exhaustive\n // `switch (result.status)`. Every other status is a transport error and is\n // thrown — including HTTP 400 (malformed input, no `status` body) and any\n // unexpected 2xx.\n if (res.status === 200 || res.status === 422) {\n return await parseSimulateBody(res, url);\n }\n const body = await res.text();\n throw errorFromHttpResponse(res.status, body, url);\n };\n\n return { getManifest, getChains, compile, route, getZapPacks, simulate };\n};\n"],"mappings":"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","names":["options"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/discovery.ts"],"sourcesContent":["/**\n * Types for the Compose discovery API (`GET /compose/zap-packs`).\n *\n * These are SDK-facing presentation types — not part of the core compile\n * contract in compose-spec. The backend response is the source of truth;\n * the SDK provides typed access.\n *\n * The `type` field on edges is a plain `string` rather than a strict union\n * so the SDK remains forward-compatible when the backend introduces new\n * edge types. Known values at time of writing:\n * `\"enter-position\"`, `\"exit-position\"`, `\"wrap\"`, `\"unwrap\"`, `\"mint\"`, `\"burn\"`.\n */\n\n/**\n * A single routing edge representing a supported token-to-token path\n * through a DeFi protocol.\n */\nexport interface ZapPackEdge {\n /** Edge type (e.g. `\"enter-position\"`, `\"exit-position\"`, `\"wrap\"`). */\n readonly type: string;\n /** Input token. */\n readonly in: { readonly address: string; readonly chainId: number };\n /** Output token. */\n readonly out: { readonly address: string; readonly chainId: number };\n /** Minimum input amount accepted (stringified integer), if constrained. */\n readonly inAmountMin?: string;\n /** Maximum input amount accepted (stringified integer), if constrained. */\n readonly inAmountMax?: string;\n /**\n * Recipient binding obligation. `\"required\"` means the zap must bind its\n * `recipient` input. The output is externally owned, terminal, and unswept.\n * The loose string type preserves forward compatibility with new values.\n */\n readonly recipient?: string;\n /**\n * Output availability. `\"future\"` means the output becomes available only\n * after the initiating transaction settles; route via `lifi.zapAsync` with\n * a bound recipient. Absent means the output is available synchronously.\n * The loose string type preserves forward compatibility with new values.\n */\n readonly availability?: string;\n}\n\n/**\n * All routing edges for a single protocol.\n */\nexport interface ZapPackOverview {\n /** Protocol identifier (e.g. `\"aave\"`, `\"morpho\"`). */\n readonly protocol: string;\n /** Available routing edges for this protocol. */\n readonly edges: readonly ZapPackEdge[];\n}\n\n/**\n * Options for {@link ComposeClient.getZapPacks}.\n */\nexport interface GetZapPacksOptions {\n /**\n * Filter to specific protocols. Pass a single string or an array.\n * Only edges belonging to the listed protocols are returned.\n * Omit to fetch all available protocols.\n */\n readonly protocols?: string | readonly string[];\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../src/discovery.ts"],"sourcesContent":["/**\n * Types for the Compose discovery API (`GET /compose/zap-packs`, `GET /chains`).\n *\n * These are SDK-facing presentation types — not part of the core compile\n * contract in compose-spec. The backend response is the source of truth;\n * the SDK provides typed access.\n *\n * The `type` field on edges is a plain `string` rather than a strict union\n * so the SDK remains forward-compatible when the backend introduces new\n * edge types. Known values at time of writing:\n * `\"enter-position\"`, `\"exit-position\"`, `\"wrap\"`, `\"unwrap\"`, `\"mint\"`, `\"burn\"`.\n */\n\n/**\n * A chain the Compose deployment supports.\n */\nexport interface ChainSummary {\n /** EVM chain ID. The stable identifier — key on this. */\n readonly chainId: number;\n /**\n * Human-readable label, suitable for display in a chain selector.\n *\n * Maintained by the deployment rather than derived from canonical chain\n * branding, so it can differ from a chain's marketed name and can change\n * without notice. Never treat it as an identifier, and never match on it.\n * A chain the deployment has no configured label for reports `Chain <id>`.\n */\n readonly name: string;\n}\n\n/**\n * A single routing edge representing a supported token-to-token path\n * through a DeFi protocol.\n */\nexport interface ZapPackEdge {\n /** Edge type (e.g. `\"enter-position\"`, `\"exit-position\"`, `\"wrap\"`). */\n readonly type: string;\n /** Input token. */\n readonly in: { readonly address: string; readonly chainId: number };\n /** Output token. */\n readonly out: { readonly address: string; readonly chainId: number };\n /** Minimum input amount accepted (stringified integer), if constrained. */\n readonly inAmountMin?: string;\n /** Maximum input amount accepted (stringified integer), if constrained. */\n readonly inAmountMax?: string;\n /**\n * Recipient binding obligation. `\"required\"` means the zap must bind its\n * `recipient` input. The output is externally owned, terminal, and unswept.\n * The loose string type preserves forward compatibility with new values.\n */\n readonly recipient?: string;\n /**\n * Output availability. `\"future\"` means the output becomes available only\n * after the initiating transaction settles; route via `lifi.zapAsync` with\n * a bound recipient. Absent means the output is available synchronously.\n * The loose string type preserves forward compatibility with new values.\n */\n readonly availability?: string;\n}\n\n/**\n * All routing edges for a single protocol.\n */\nexport interface ZapPackOverview {\n /** Protocol identifier (e.g. `\"aave\"`, `\"morpho\"`). */\n readonly protocol: string;\n /** Available routing edges for this protocol. */\n readonly edges: readonly ZapPackEdge[];\n}\n\n/**\n * Options for {@link ComposeClient.getZapPacks}.\n */\nexport interface GetZapPacksOptions {\n /**\n * Filter to specific protocols. Pass a single string or an array.\n * Only edges belonging to the listed protocols are returned.\n * Omit to fetch all available protocols.\n */\n readonly protocols?: string | readonly string[];\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Types for the Compose discovery API (`GET /compose/zap-packs`).
2
+ * Types for the Compose discovery API (`GET /compose/zap-packs`, `GET /chains`).
3
3
  *
4
4
  * These are SDK-facing presentation types — not part of the core compile
5
5
  * contract in compose-spec. The backend response is the source of truth;
@@ -10,6 +10,22 @@
10
10
  * edge types. Known values at time of writing:
11
11
  * `"enter-position"`, `"exit-position"`, `"wrap"`, `"unwrap"`, `"mint"`, `"burn"`.
12
12
  */
13
+ /**
14
+ * A chain the Compose deployment supports.
15
+ */
16
+ interface ChainSummary {
17
+ /** EVM chain ID. The stable identifier — key on this. */
18
+ readonly chainId: number;
19
+ /**
20
+ * Human-readable label, suitable for display in a chain selector.
21
+ *
22
+ * Maintained by the deployment rather than derived from canonical chain
23
+ * branding, so it can differ from a chain's marketed name and can change
24
+ * without notice. Never treat it as an identifier, and never match on it.
25
+ * A chain the deployment has no configured label for reports `Chain <id>`.
26
+ */
27
+ readonly name: string;
28
+ }
13
29
  /**
14
30
  * A single routing edge representing a supported token-to-token path
15
31
  * through a DeFi protocol.
@@ -66,4 +82,4 @@ interface GetZapPacksOptions {
66
82
  readonly protocols?: string | readonly string[];
67
83
  }
68
84
 
69
- export type { GetZapPacksOptions, ZapPackEdge, ZapPackOverview };
85
+ export type { ChainSummary, GetZapPacksOptions, ZapPackEdge, ZapPackOverview };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Types for the Compose discovery API (`GET /compose/zap-packs`).
2
+ * Types for the Compose discovery API (`GET /compose/zap-packs`, `GET /chains`).
3
3
  *
4
4
  * These are SDK-facing presentation types — not part of the core compile
5
5
  * contract in compose-spec. The backend response is the source of truth;
@@ -10,6 +10,22 @@
10
10
  * edge types. Known values at time of writing:
11
11
  * `"enter-position"`, `"exit-position"`, `"wrap"`, `"unwrap"`, `"mint"`, `"burn"`.
12
12
  */
13
+ /**
14
+ * A chain the Compose deployment supports.
15
+ */
16
+ interface ChainSummary {
17
+ /** EVM chain ID. The stable identifier — key on this. */
18
+ readonly chainId: number;
19
+ /**
20
+ * Human-readable label, suitable for display in a chain selector.
21
+ *
22
+ * Maintained by the deployment rather than derived from canonical chain
23
+ * branding, so it can differ from a chain's marketed name and can change
24
+ * without notice. Never treat it as an identifier, and never match on it.
25
+ * A chain the deployment has no configured label for reports `Chain <id>`.
26
+ */
27
+ readonly name: string;
28
+ }
13
29
  /**
14
30
  * A single routing edge representing a supported token-to-token path
15
31
  * through a DeFi protocol.
@@ -66,4 +82,4 @@ interface GetZapPacksOptions {
66
82
  readonly protocols?: string | readonly string[];
67
83
  }
68
84
 
69
- export type { GetZapPacksOptions, ZapPackEdge, ZapPackOverview };
85
+ export type { ChainSummary, GetZapPacksOptions, ZapPackEdge, ZapPackOverview };
@@ -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\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/**\n * a string starting with \"0x\"\n */\nexport type StartsWith0X = string;\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\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 * 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\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/**\n * a string starting with \"0x\"\n */\nexport type StartsWith0X = string;\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":[]}
@@ -496,6 +496,26 @@ interface CorePeekConfig {
496
496
  functionSignature: string;
497
497
  args?: string[];
498
498
  }
499
+ /**
500
+ * a number between 0 and 3318
501
+ */
502
+ type Between03318 = number;
503
+ /**
504
+ * a number between 0 and 5000
505
+ */
506
+ type Between05000 = number;
507
+ interface FlySwapConfig {
508
+ resourceOut: {
509
+ kind: 'native';
510
+ chainId: Positive;
511
+ } | {
512
+ kind: 'erc20';
513
+ token: Address;
514
+ chainId: Positive;
515
+ };
516
+ inputVarianceBps?: Between03318;
517
+ maxSlippageBps?: Between05000;
518
+ }
499
519
  interface SlippageGuardConfig {
500
520
  port: string;
501
521
  bps: Between010000;
@@ -542,4 +562,4 @@ interface Erc20AllowancePreconditionConfig {
542
562
  allowance: IntegerStringInput;
543
563
  }
544
564
 
545
- export type { AaveBorrowConfig, AaveClaimRewardsConfig, AaveGetHealthFactorConfig, AaveRepayConfig, AaveRepayWithATokensConfig, AaveSetEModeConfig, BalanceOfMaterialiserConfig, Between010000, Between0255, CallMaterialiserConfig, ContinuationAssertReadyConfig, CoreApproveConfig, CoreAsResourceConfig, CoreBalanceOfConfig, CoreBpsDownConfig, CoreBpsUpConfig, CoreCallConfig, CoreEmitEvent1Config, CoreEmitEvent2Config, CoreEmitEvent3Config, CoreEmitEvent4Config, CoreInvokeConfig, CoreNumericInvariantGuardConfig, CorePeekConfig, CoreRawCallConfig, CoreSplitConfig, CoreStaticCallConfig, CoreTransferConfig, DirectDepositMaterialiserConfig, Erc20AllowancePreconditionConfig, Erc20BalancePreconditionConfig, FlashloanMaterialiserConfig, InvariantEqConfig, InvariantGtConfig, InvariantGteConfig, InvariantLtConfig, InvariantLteConfig, InvariantNeqConfig, InvariantNumericConfig, InvariantNumericInRangeConfig, LifiFlashloanRepayConfig, LifiSwapConfig, LifiZapAsyncConfig, LifiZapConfig, MaxItems50, MaxLength64, MaxLength65536, MorphoBlueBorrowConfig, MorphoBlueGetPositionConfig, MorphoBlueRepayConfig, MorphoBlueSupplyCollateralConfig, MorphoBlueSupplyConfig, MorphoBlueWithdrawCollateralConfig, MorphoBlueWithdrawConfig, NativeBalancePreconditionConfig, NonNegative, ParaswapBuyConfig, Positive, SlippageGuardConfig, StartsWith0X };
565
+ export type { AaveBorrowConfig, AaveClaimRewardsConfig, AaveGetHealthFactorConfig, AaveRepayConfig, AaveRepayWithATokensConfig, AaveSetEModeConfig, BalanceOfMaterialiserConfig, Between010000, Between0255, Between03318, Between05000, CallMaterialiserConfig, ContinuationAssertReadyConfig, CoreApproveConfig, CoreAsResourceConfig, CoreBalanceOfConfig, CoreBpsDownConfig, CoreBpsUpConfig, CoreCallConfig, CoreEmitEvent1Config, CoreEmitEvent2Config, CoreEmitEvent3Config, CoreEmitEvent4Config, CoreInvokeConfig, CoreNumericInvariantGuardConfig, CorePeekConfig, CoreRawCallConfig, CoreSplitConfig, CoreStaticCallConfig, CoreTransferConfig, DirectDepositMaterialiserConfig, Erc20AllowancePreconditionConfig, Erc20BalancePreconditionConfig, FlashloanMaterialiserConfig, FlySwapConfig, InvariantEqConfig, InvariantGtConfig, InvariantGteConfig, InvariantLtConfig, InvariantLteConfig, InvariantNeqConfig, InvariantNumericConfig, InvariantNumericInRangeConfig, LifiFlashloanRepayConfig, LifiSwapConfig, LifiZapAsyncConfig, LifiZapConfig, MaxItems50, MaxLength64, MaxLength65536, MorphoBlueBorrowConfig, MorphoBlueGetPositionConfig, MorphoBlueRepayConfig, MorphoBlueSupplyCollateralConfig, MorphoBlueSupplyConfig, MorphoBlueWithdrawCollateralConfig, MorphoBlueWithdrawConfig, NativeBalancePreconditionConfig, NonNegative, ParaswapBuyConfig, Positive, SlippageGuardConfig, StartsWith0X };
@@ -496,6 +496,26 @@ interface CorePeekConfig {
496
496
  functionSignature: string;
497
497
  args?: string[];
498
498
  }
499
+ /**
500
+ * a number between 0 and 3318
501
+ */
502
+ type Between03318 = number;
503
+ /**
504
+ * a number between 0 and 5000
505
+ */
506
+ type Between05000 = number;
507
+ interface FlySwapConfig {
508
+ resourceOut: {
509
+ kind: 'native';
510
+ chainId: Positive;
511
+ } | {
512
+ kind: 'erc20';
513
+ token: Address;
514
+ chainId: Positive;
515
+ };
516
+ inputVarianceBps?: Between03318;
517
+ maxSlippageBps?: Between05000;
518
+ }
499
519
  interface SlippageGuardConfig {
500
520
  port: string;
501
521
  bps: Between010000;
@@ -542,4 +562,4 @@ interface Erc20AllowancePreconditionConfig {
542
562
  allowance: IntegerStringInput;
543
563
  }
544
564
 
545
- export type { AaveBorrowConfig, AaveClaimRewardsConfig, AaveGetHealthFactorConfig, AaveRepayConfig, AaveRepayWithATokensConfig, AaveSetEModeConfig, BalanceOfMaterialiserConfig, Between010000, Between0255, CallMaterialiserConfig, ContinuationAssertReadyConfig, CoreApproveConfig, CoreAsResourceConfig, CoreBalanceOfConfig, CoreBpsDownConfig, CoreBpsUpConfig, CoreCallConfig, CoreEmitEvent1Config, CoreEmitEvent2Config, CoreEmitEvent3Config, CoreEmitEvent4Config, CoreInvokeConfig, CoreNumericInvariantGuardConfig, CorePeekConfig, CoreRawCallConfig, CoreSplitConfig, CoreStaticCallConfig, CoreTransferConfig, DirectDepositMaterialiserConfig, Erc20AllowancePreconditionConfig, Erc20BalancePreconditionConfig, FlashloanMaterialiserConfig, InvariantEqConfig, InvariantGtConfig, InvariantGteConfig, InvariantLtConfig, InvariantLteConfig, InvariantNeqConfig, InvariantNumericConfig, InvariantNumericInRangeConfig, LifiFlashloanRepayConfig, LifiSwapConfig, LifiZapAsyncConfig, LifiZapConfig, MaxItems50, MaxLength64, MaxLength65536, MorphoBlueBorrowConfig, MorphoBlueGetPositionConfig, MorphoBlueRepayConfig, MorphoBlueSupplyCollateralConfig, MorphoBlueSupplyConfig, MorphoBlueWithdrawCollateralConfig, MorphoBlueWithdrawConfig, NativeBalancePreconditionConfig, NonNegative, ParaswapBuyConfig, Positive, SlippageGuardConfig, StartsWith0X };
565
+ export type { AaveBorrowConfig, AaveClaimRewardsConfig, AaveGetHealthFactorConfig, AaveRepayConfig, AaveRepayWithATokensConfig, AaveSetEModeConfig, BalanceOfMaterialiserConfig, Between010000, Between0255, Between03318, Between05000, CallMaterialiserConfig, ContinuationAssertReadyConfig, CoreApproveConfig, CoreAsResourceConfig, CoreBalanceOfConfig, CoreBpsDownConfig, CoreBpsUpConfig, CoreCallConfig, CoreEmitEvent1Config, CoreEmitEvent2Config, CoreEmitEvent3Config, CoreEmitEvent4Config, CoreInvokeConfig, CoreNumericInvariantGuardConfig, CorePeekConfig, CoreRawCallConfig, CoreSplitConfig, CoreStaticCallConfig, CoreTransferConfig, DirectDepositMaterialiserConfig, Erc20AllowancePreconditionConfig, Erc20BalancePreconditionConfig, FlashloanMaterialiserConfig, FlySwapConfig, InvariantEqConfig, InvariantGtConfig, InvariantGteConfig, InvariantLtConfig, InvariantLteConfig, InvariantNeqConfig, InvariantNumericConfig, InvariantNumericInRangeConfig, LifiFlashloanRepayConfig, LifiSwapConfig, LifiZapAsyncConfig, LifiZapConfig, MaxItems50, MaxLength64, MaxLength65536, MorphoBlueBorrowConfig, MorphoBlueGetPositionConfig, MorphoBlueRepayConfig, MorphoBlueSupplyCollateralConfig, MorphoBlueSupplyConfig, MorphoBlueWithdrawCollateralConfig, MorphoBlueWithdrawConfig, NativeBalancePreconditionConfig, NonNegative, ParaswapBuyConfig, Positive, SlippageGuardConfig, StartsWith0X };
@@ -199,6 +199,12 @@ const bindGeneratedOps = (builder) => ({
199
199
  amountOut: "resource",
200
200
  unspentIn: "resource"
201
201
  })
202
+ },
203
+ fly: {
204
+ swap: (nodeId, args) => builder.call(nodeId, "fly.swap", args, {
205
+ amountOut: "resource",
206
+ unspentIn: "resource"
207
+ })
202
208
  }
203
209
  });
204
210
  // Annotate the CommonJS export names for ESM import in node: