@lifi/composer-sdk 0.6.0 → 0.6.2
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/README.md +21 -10
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +7 -7
- package/dist/client.d.ts +7 -7
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/errors.cjs +20 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +18 -1
- package/dist/errors.d.ts +18 -1
- package/dist/errors.js +20 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/reachability.cjs +123 -0
- package/dist/reachability.cjs.map +1 -0
- package/dist/reachability.d.cts +71 -0
- package/dist/reachability.d.ts +71 -0
- package/dist/reachability.js +99 -0
- package/dist/reachability.js.map +1 -0
- package/dist/responseSchemas.cjs +5 -1
- package/dist/responseSchemas.cjs.map +1 -1
- package/dist/responseSchemas.d.cts +4 -0
- package/dist/responseSchemas.d.ts +4 -0
- package/dist/responseSchemas.js +5 -1
- package/dist/responseSchemas.js.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +7 -7
- package/src/errors.ts +22 -1
- package/src/index.ts +7 -0
- package/src/reachability.ts +203 -0
- package/src/responseSchemas.ts +11 -1
package/dist/errors.d.ts
CHANGED
|
@@ -56,8 +56,23 @@ declare class ComposeError extends Error {
|
|
|
56
56
|
readonly url?: string;
|
|
57
57
|
/** Server-provided error kind for finer-grained classification. */
|
|
58
58
|
readonly kind?: ComposeErrorKind | ComposeRouteErrorKind;
|
|
59
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Where a validation error points: the node id for a rejection of an
|
|
61
|
+
* authored node, or a JSON-pointer path for a rejection of the request shape.
|
|
62
|
+
*/
|
|
60
63
|
readonly path?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The input port of {@link ComposeError.path}'s node whose binding caused the
|
|
66
|
+
* error. Set when the rejection is about what a port binds rather than about
|
|
67
|
+
* the node's config.
|
|
68
|
+
*/
|
|
69
|
+
readonly port?: string;
|
|
70
|
+
/**
|
|
71
|
+
* The one edit that clears the error, written for whoever authored the flow.
|
|
72
|
+
* Set on `continuation.settle` authoring rejections; may be absent on other
|
|
73
|
+
* `validation_error`s.
|
|
74
|
+
*/
|
|
75
|
+
readonly fix?: string;
|
|
61
76
|
/**
|
|
62
77
|
* Simulation revert diagnostics attached to `simulation_revert` errors.
|
|
63
78
|
* Contains the raw error bytes and decoded error candidates when the
|
|
@@ -85,6 +100,8 @@ declare class ComposeError extends Error {
|
|
|
85
100
|
cause?: unknown;
|
|
86
101
|
kind?: ComposeErrorKind | ComposeRouteErrorKind;
|
|
87
102
|
path?: string;
|
|
103
|
+
port?: string;
|
|
104
|
+
fix?: string;
|
|
88
105
|
details?: SimulationRevert;
|
|
89
106
|
failedOps?: readonly FailedPreparedOp[];
|
|
90
107
|
succeededOps?: readonly string[];
|
package/dist/errors.js
CHANGED
|
@@ -12,8 +12,23 @@ class ComposeError extends Error {
|
|
|
12
12
|
url;
|
|
13
13
|
/** Server-provided error kind for finer-grained classification. */
|
|
14
14
|
kind;
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Where a validation error points: the node id for a rejection of an
|
|
17
|
+
* authored node, or a JSON-pointer path for a rejection of the request shape.
|
|
18
|
+
*/
|
|
16
19
|
path;
|
|
20
|
+
/**
|
|
21
|
+
* The input port of {@link ComposeError.path}'s node whose binding caused the
|
|
22
|
+
* error. Set when the rejection is about what a port binds rather than about
|
|
23
|
+
* the node's config.
|
|
24
|
+
*/
|
|
25
|
+
port;
|
|
26
|
+
/**
|
|
27
|
+
* The one edit that clears the error, written for whoever authored the flow.
|
|
28
|
+
* Set on `continuation.settle` authoring rejections; may be absent on other
|
|
29
|
+
* `validation_error`s.
|
|
30
|
+
*/
|
|
31
|
+
fix;
|
|
17
32
|
/**
|
|
18
33
|
* Simulation revert diagnostics attached to `simulation_revert` errors.
|
|
19
34
|
* Contains the raw error bytes and decoded error candidates when the
|
|
@@ -42,6 +57,8 @@ class ComposeError extends Error {
|
|
|
42
57
|
this.url = options?.url;
|
|
43
58
|
this.kind = options?.kind;
|
|
44
59
|
this.path = options?.path;
|
|
60
|
+
this.port = options?.port;
|
|
61
|
+
this.fix = options?.fix;
|
|
45
62
|
this.details = options?.details;
|
|
46
63
|
this.failedOps = options?.failedOps;
|
|
47
64
|
this.succeededOps = options?.succeededOps;
|
|
@@ -95,6 +112,8 @@ const errorFromHttpResponse = (status, body, url) => {
|
|
|
95
112
|
url,
|
|
96
113
|
kind: serverError?.kind,
|
|
97
114
|
path: serverError?.path,
|
|
115
|
+
port: serverError?.port,
|
|
116
|
+
fix: serverError?.fix,
|
|
98
117
|
details: serverError?.details,
|
|
99
118
|
// The wire schema types `kind` as a bare string; the server only ever
|
|
100
119
|
// reports generic kinds for individual ops.
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type {\n ComposeErrorKind,\n ComposeRouteErrorKind,\n FailedPreparedOp,\n GenericComposeErrorKind,\n SimulationRevert,\n} from '@lifi/compose-spec';\nimport z from 'zod';\n\nimport {\n parseServerErrorBody,\n type ServerErrorBody,\n} from './responseSchemas.js';\n\n/**\n * Machine-readable error codes returned by the SDK.\n *\n * - `NETWORK_ERROR` — The HTTP request failed (DNS, timeout, connection refused).\n * - `VALIDATION_ERROR` — The server rejected the request (HTTP 400/422).\n * - `UNAUTHENTICATED` — The request lacks valid authentication credentials (HTTP 401).\n * - `FORBIDDEN` — The server understood the request but refuses to authorise it (HTTP 403).\n * - `SERVER_ERROR` — The server returned a 5xx status.\n * - `RATE_LIMITED` — The server returned HTTP 429.\n * - `NOT_FOUND` — The requested resource does not exist (HTTP 404).\n * - `UNKNOWN_ERROR` — An unexpected error that doesn't fit other categories.\n */\nexport type ComposeErrorCode =\n | 'NETWORK_ERROR'\n | 'VALIDATION_ERROR'\n | 'UNAUTHENTICATED'\n | 'FORBIDDEN'\n | 'SERVER_ERROR'\n | 'RATE_LIMITED'\n | 'NOT_FOUND'\n | 'UNKNOWN_ERROR';\n\n/** Version details returned when the backend rejects an outdated SDK. */\nexport interface ComposeSdkOutdated {\n readonly sdkVersion: string;\n readonly serverVersion: string;\n readonly minimumSdkVersion: string;\n}\n\n/**\n * Version details attached when the SDK is ahead of the backend it reached.\n * Raised by the backend's version gate, or by the SDK itself when the\n * `x-lifi-composer-version` response header names an older contract than the\n * one this SDK was built against.\n */\nexport interface ComposeServerOutdated {\n readonly sdkVersion: string;\n readonly serverVersion: string;\n}\n\n/**\n * Error class for all failures originating from the Compose SDK or API.\n *\n * Includes structured metadata beyond the error message to support\n * programmatic error handling.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposeError(e) && e.code === 'VALIDATION_ERROR') {\n * console.error('Invalid request:', e.message, e.path);\n * }\n * }\n * ```\n */\nexport class ComposeError extends Error {\n override readonly name = 'ComposeError';\n /** Machine-readable error category. */\n readonly code: ComposeErrorCode;\n /** HTTP status code, when the error originated from an HTTP response. */\n readonly status?: number;\n /** The request URL that produced the error. */\n readonly url?: string;\n /** Server-provided error kind for finer-grained classification. */\n readonly kind?: ComposeErrorKind | ComposeRouteErrorKind;\n /** JSON-pointer path to the field that caused a validation error. */\n readonly path?: string;\n /**\n * Simulation revert diagnostics attached to `simulation_revert` errors.\n * Contains the raw error bytes and decoded error candidates when the\n * backend can parse the revert reason.\n */\n readonly details?: SimulationRevert;\n /**\n * The prepared ops that failed, attached to `preparation_error` errors.\n * Each entry carries the `callId` of the failing node so callers can drop\n * the unroutable legs and resubmit a smaller flow.\n */\n readonly failedOps?: readonly FailedPreparedOp[];\n /**\n * The `callId`s of the prepared ops that succeeded, attached to\n * `preparation_error` errors alongside {@link ComposeError.failedOps}.\n */\n readonly succeededOps?: readonly string[];\n /** Version details attached only to `sdk_outdated` errors. */\n readonly sdkOutdated?: ComposeSdkOutdated;\n /** Version details attached only to `server_outdated` errors. */\n readonly serverOutdated?: ComposeServerOutdated;\n\n constructor(\n code: ComposeErrorCode,\n message: string,\n options?: {\n status?: number;\n url?: string;\n cause?: unknown;\n kind?: ComposeErrorKind | ComposeRouteErrorKind;\n path?: string;\n details?: SimulationRevert;\n failedOps?: readonly FailedPreparedOp[];\n succeededOps?: readonly string[];\n sdkOutdated?: ComposeSdkOutdated;\n serverOutdated?: ComposeServerOutdated;\n },\n ) {\n super(message, { cause: options?.cause });\n this.code = code;\n this.status = options?.status;\n this.url = options?.url;\n this.kind = options?.kind;\n this.path = options?.path;\n this.details = options?.details;\n this.failedOps = options?.failedOps;\n this.succeededOps = options?.succeededOps;\n this.sdkOutdated = options?.sdkOutdated;\n this.serverOutdated = options?.serverOutdated;\n }\n}\n\n/**\n * The per-op preparation diagnostics carried by `preparation_error` responses,\n * with both arrays known to be present. Produced by narrowing with\n * {@link isComposePreparationError}.\n */\nexport interface ComposePreparationOps {\n readonly failedOps: readonly FailedPreparedOp[];\n readonly succeededOps: readonly string[];\n}\n\n/**\n * Type guard that narrows an unknown error to {@link ComposeError}.\n * @param e - The value to check.\n * @returns `true` if `e` is an instance of `ComposeError`.\n */\nexport const isComposeError = (e: unknown): e is ComposeError =>\n e instanceof ComposeError ||\n (e instanceof Error && e.name === 'ComposeError' && 'code' in e);\n\n/**\n * Type guard for `preparation_error` failures (HTTP 422): a mixed basket where\n * some prepared ops failed and others succeeded. Narrows both\n * {@link ComposeError.failedOps} and {@link ComposeError.succeededOps} to\n * present, so callers can read them without a cast or a truthiness check.\n *\n * @param e - The value to check.\n * @returns `true` if `e` is a `ComposeError` carrying per-op preparation diagnostics.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposePreparationError(e)) {\n * console.error('Failed ops:', e.failedOps);\n * console.error('Succeeded ops:', e.succeededOps);\n * }\n * }\n * ```\n */\nexport const isComposePreparationError = (\n e: unknown,\n): e is ComposeError & ComposePreparationOps =>\n isComposeError(e) &&\n e.kind === 'preparation_error' &&\n Array.isArray(e.failedOps) &&\n Array.isArray(e.succeededOps);\n\n// `isComposeError` accepts a structurally-similar error by name, so an error\n// raised by a *second* copy of this package in the dependency tree reaches the\n// guard below without its `sdkOutdated` field being type-guaranteed. Parse it.\nconst sdkOutdatedSchema = z.object({\n sdkVersion: z.string(),\n serverVersion: z.string(),\n minimumSdkVersion: z.string(),\n});\n\n/**\n * Narrows an outdated-SDK rejection to its required version details.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposeSdkOutdatedError(e)) {\n * console.error(`Upgrade to at least ${e.sdkOutdated.minimumSdkVersion}`);\n * return;\n * }\n * throw e;\n * }\n * ```\n */\nexport const isComposeSdkOutdatedError = (\n e: unknown,\n): e is ComposeError & { readonly sdkOutdated: ComposeSdkOutdated } =>\n isComposeError(e) &&\n e.kind === 'sdk_outdated' &&\n sdkOutdatedSchema.safeParse(e.sdkOutdated).success;\n\nconst serverOutdatedSchema = z.object({\n sdkVersion: z.string(),\n serverVersion: z.string(),\n});\n\n/**\n * Narrows a server-behind-SDK rejection to its required version details.\n *\n * This is the deploy-window error: the SDK on npm is ahead of the backend that\n * answered. Pin the SDK to the server's `major.minor`, or wait for the rollout.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposeServerOutdatedError(e)) {\n * console.error(`Server serves ${e.serverOutdated.serverVersion}`);\n * return;\n * }\n * throw e;\n * }\n * ```\n */\nexport const isComposeServerOutdatedError = (\n e: unknown,\n): e is ComposeError & { readonly serverOutdated: ComposeServerOutdated } =>\n isComposeError(e) &&\n e.kind === 'server_outdated' &&\n serverOutdatedSchema.safeParse(e.serverOutdated).success;\n\nconst STATUS_TO_CODE: ReadonlyMap<number, ComposeErrorCode> = new Map<\n number,\n ComposeErrorCode\n>([\n [400, 'VALIDATION_ERROR'],\n [401, 'UNAUTHENTICATED'],\n [403, 'FORBIDDEN'],\n [404, 'NOT_FOUND'],\n [422, 'VALIDATION_ERROR'],\n [429, 'RATE_LIMITED'],\n]);\n\nconst tryParseErrorBody = (body: string): ServerErrorBody | null => {\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch {\n return null;\n }\n return parseServerErrorBody(json);\n};\n\n/**\n * Extracts the version triple an `sdk_outdated` or `server_outdated` envelope\n * carries. The slots reuse the same schemas the type guards narrow with. Zod\n * strips keys the schema does not declare, so the parsed value is exactly the\n * triple; a partial payload fails the parse and yields `undefined` rather than\n * a half-populated object.\n */\nconst readVersionSlots = (serverError: ServerErrorBody['error']) => ({\n sdkOutdated:\n serverError?.kind === 'sdk_outdated'\n ? sdkOutdatedSchema.safeParse(serverError).data\n : undefined,\n serverOutdated:\n serverError?.kind === 'server_outdated'\n ? serverOutdatedSchema.safeParse(serverError).data\n : undefined,\n});\n\n/**\n * Constructs a {@link ComposeError} from an HTTP error response, extracting\n * structured error details from the response body when available.\n *\n * @param status - The HTTP status code.\n * @param body - The raw response body text.\n * @param url - The request URL that produced the error.\n * @returns A `ComposeError` with the appropriate error code and metadata.\n */\nexport const errorFromHttpResponse = (\n status: number,\n body: string,\n url: string,\n): ComposeError => {\n const parsed = tryParseErrorBody(body);\n const serverError = parsed?.error;\n const { sdkOutdated, serverOutdated } = readVersionSlots(serverError);\n\n return new ComposeError(\n STATUS_TO_CODE.get(status) ??\n (status >= 500 ? 'SERVER_ERROR' : 'UNKNOWN_ERROR'),\n (serverError?.message ?? body) || `HTTP ${status}`,\n {\n status,\n url,\n kind: serverError?.kind as\n ComposeErrorKind | ComposeRouteErrorKind | undefined,\n path: serverError?.path,\n details: serverError?.details,\n // The wire schema types `kind` as a bare string; the server only ever\n // reports generic kinds for individual ops.\n failedOps: serverError?.failedOps?.map((op) => ({\n ...op,\n kind: op.kind as GenericComposeErrorKind,\n })),\n succeededOps: serverError?.succeededOps,\n sdkOutdated,\n serverOutdated,\n },\n );\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type {\n ComposeErrorKind,\n ComposeRouteErrorKind,\n FailedPreparedOp,\n GenericComposeErrorKind,\n SimulationRevert,\n} from '@lifi/compose-spec';\nimport z from 'zod';\n\nimport {\n parseServerErrorBody,\n type ServerErrorBody,\n} from './responseSchemas.js';\n\n/**\n * Machine-readable error codes returned by the SDK.\n *\n * - `NETWORK_ERROR` — The HTTP request failed (DNS, timeout, connection refused).\n * - `VALIDATION_ERROR` — The server rejected the request (HTTP 400/422).\n * - `UNAUTHENTICATED` — The request lacks valid authentication credentials (HTTP 401).\n * - `FORBIDDEN` — The server understood the request but refuses to authorise it (HTTP 403).\n * - `SERVER_ERROR` — The server returned a 5xx status.\n * - `RATE_LIMITED` — The server returned HTTP 429.\n * - `NOT_FOUND` — The requested resource does not exist (HTTP 404).\n * - `UNKNOWN_ERROR` — An unexpected error that doesn't fit other categories.\n */\nexport type ComposeErrorCode =\n | 'NETWORK_ERROR'\n | 'VALIDATION_ERROR'\n | 'UNAUTHENTICATED'\n | 'FORBIDDEN'\n | 'SERVER_ERROR'\n | 'RATE_LIMITED'\n | 'NOT_FOUND'\n | 'UNKNOWN_ERROR';\n\n/** Version details returned when the backend rejects an outdated SDK. */\nexport interface ComposeSdkOutdated {\n readonly sdkVersion: string;\n readonly serverVersion: string;\n readonly minimumSdkVersion: string;\n}\n\n/**\n * Version details attached when the SDK is ahead of the backend it reached.\n * Raised by the backend's version gate, or by the SDK itself when the\n * `x-lifi-composer-version` response header names an older contract than the\n * one this SDK was built against.\n */\nexport interface ComposeServerOutdated {\n readonly sdkVersion: string;\n readonly serverVersion: string;\n}\n\n/**\n * Error class for all failures originating from the Compose SDK or API.\n *\n * Includes structured metadata beyond the error message to support\n * programmatic error handling.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposeError(e) && e.code === 'VALIDATION_ERROR') {\n * console.error('Invalid request:', e.message, e.path);\n * }\n * }\n * ```\n */\nexport class ComposeError extends Error {\n override readonly name = 'ComposeError';\n /** Machine-readable error category. */\n readonly code: ComposeErrorCode;\n /** HTTP status code, when the error originated from an HTTP response. */\n readonly status?: number;\n /** The request URL that produced the error. */\n readonly url?: string;\n /** Server-provided error kind for finer-grained classification. */\n readonly kind?: ComposeErrorKind | ComposeRouteErrorKind;\n /**\n * Where a validation error points: the node id for a rejection of an\n * authored node, or a JSON-pointer path for a rejection of the request shape.\n */\n readonly path?: string;\n /**\n * The input port of {@link ComposeError.path}'s node whose binding caused the\n * error. Set when the rejection is about what a port binds rather than about\n * the node's config.\n */\n readonly port?: string;\n /**\n * The one edit that clears the error, written for whoever authored the flow.\n * Set on `continuation.settle` authoring rejections; may be absent on other\n * `validation_error`s.\n */\n readonly fix?: string;\n /**\n * Simulation revert diagnostics attached to `simulation_revert` errors.\n * Contains the raw error bytes and decoded error candidates when the\n * backend can parse the revert reason.\n */\n readonly details?: SimulationRevert;\n /**\n * The prepared ops that failed, attached to `preparation_error` errors.\n * Each entry carries the `callId` of the failing node so callers can drop\n * the unroutable legs and resubmit a smaller flow.\n */\n readonly failedOps?: readonly FailedPreparedOp[];\n /**\n * The `callId`s of the prepared ops that succeeded, attached to\n * `preparation_error` errors alongside {@link ComposeError.failedOps}.\n */\n readonly succeededOps?: readonly string[];\n /** Version details attached only to `sdk_outdated` errors. */\n readonly sdkOutdated?: ComposeSdkOutdated;\n /** Version details attached only to `server_outdated` errors. */\n readonly serverOutdated?: ComposeServerOutdated;\n\n constructor(\n code: ComposeErrorCode,\n message: string,\n options?: {\n status?: number;\n url?: string;\n cause?: unknown;\n kind?: ComposeErrorKind | ComposeRouteErrorKind;\n path?: string;\n port?: string;\n fix?: string;\n details?: SimulationRevert;\n failedOps?: readonly FailedPreparedOp[];\n succeededOps?: readonly string[];\n sdkOutdated?: ComposeSdkOutdated;\n serverOutdated?: ComposeServerOutdated;\n },\n ) {\n super(message, { cause: options?.cause });\n this.code = code;\n this.status = options?.status;\n this.url = options?.url;\n this.kind = options?.kind;\n this.path = options?.path;\n this.port = options?.port;\n this.fix = options?.fix;\n this.details = options?.details;\n this.failedOps = options?.failedOps;\n this.succeededOps = options?.succeededOps;\n this.sdkOutdated = options?.sdkOutdated;\n this.serverOutdated = options?.serverOutdated;\n }\n}\n\n/**\n * The per-op preparation diagnostics carried by `preparation_error` responses,\n * with both arrays known to be present. Produced by narrowing with\n * {@link isComposePreparationError}.\n */\nexport interface ComposePreparationOps {\n readonly failedOps: readonly FailedPreparedOp[];\n readonly succeededOps: readonly string[];\n}\n\n/**\n * Type guard that narrows an unknown error to {@link ComposeError}.\n * @param e - The value to check.\n * @returns `true` if `e` is an instance of `ComposeError`.\n */\nexport const isComposeError = (e: unknown): e is ComposeError =>\n e instanceof ComposeError ||\n (e instanceof Error && e.name === 'ComposeError' && 'code' in e);\n\n/**\n * Type guard for `preparation_error` failures (HTTP 422): a mixed basket where\n * some prepared ops failed and others succeeded. Narrows both\n * {@link ComposeError.failedOps} and {@link ComposeError.succeededOps} to\n * present, so callers can read them without a cast or a truthiness check.\n *\n * @param e - The value to check.\n * @returns `true` if `e` is a `ComposeError` carrying per-op preparation diagnostics.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposePreparationError(e)) {\n * console.error('Failed ops:', e.failedOps);\n * console.error('Succeeded ops:', e.succeededOps);\n * }\n * }\n * ```\n */\nexport const isComposePreparationError = (\n e: unknown,\n): e is ComposeError & ComposePreparationOps =>\n isComposeError(e) &&\n e.kind === 'preparation_error' &&\n Array.isArray(e.failedOps) &&\n Array.isArray(e.succeededOps);\n\n// `isComposeError` accepts a structurally-similar error by name, so an error\n// raised by a *second* copy of this package in the dependency tree reaches the\n// guard below without its `sdkOutdated` field being type-guaranteed. Parse it.\nconst sdkOutdatedSchema = z.object({\n sdkVersion: z.string(),\n serverVersion: z.string(),\n minimumSdkVersion: z.string(),\n});\n\n/**\n * Narrows an outdated-SDK rejection to its required version details.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposeSdkOutdatedError(e)) {\n * console.error(`Upgrade to at least ${e.sdkOutdated.minimumSdkVersion}`);\n * return;\n * }\n * throw e;\n * }\n * ```\n */\nexport const isComposeSdkOutdatedError = (\n e: unknown,\n): e is ComposeError & { readonly sdkOutdated: ComposeSdkOutdated } =>\n isComposeError(e) &&\n e.kind === 'sdk_outdated' &&\n sdkOutdatedSchema.safeParse(e.sdkOutdated).success;\n\nconst serverOutdatedSchema = z.object({\n sdkVersion: z.string(),\n serverVersion: z.string(),\n});\n\n/**\n * Narrows a server-behind-SDK rejection to its required version details.\n *\n * This is the deploy-window error: the SDK on npm is ahead of the backend that\n * answered. Pin the SDK to the server's `major.minor`, or wait for the rollout.\n *\n * @example\n * ```ts\n * try {\n * await builder.compile(run);\n * } catch (e) {\n * if (isComposeServerOutdatedError(e)) {\n * console.error(`Server serves ${e.serverOutdated.serverVersion}`);\n * return;\n * }\n * throw e;\n * }\n * ```\n */\nexport const isComposeServerOutdatedError = (\n e: unknown,\n): e is ComposeError & { readonly serverOutdated: ComposeServerOutdated } =>\n isComposeError(e) &&\n e.kind === 'server_outdated' &&\n serverOutdatedSchema.safeParse(e.serverOutdated).success;\n\nconst STATUS_TO_CODE: ReadonlyMap<number, ComposeErrorCode> = new Map<\n number,\n ComposeErrorCode\n>([\n [400, 'VALIDATION_ERROR'],\n [401, 'UNAUTHENTICATED'],\n [403, 'FORBIDDEN'],\n [404, 'NOT_FOUND'],\n [422, 'VALIDATION_ERROR'],\n [429, 'RATE_LIMITED'],\n]);\n\nconst tryParseErrorBody = (body: string): ServerErrorBody | null => {\n let json: unknown;\n try {\n json = JSON.parse(body);\n } catch {\n return null;\n }\n return parseServerErrorBody(json);\n};\n\n/**\n * Extracts the version triple an `sdk_outdated` or `server_outdated` envelope\n * carries. The slots reuse the same schemas the type guards narrow with. Zod\n * strips keys the schema does not declare, so the parsed value is exactly the\n * triple; a partial payload fails the parse and yields `undefined` rather than\n * a half-populated object.\n */\nconst readVersionSlots = (serverError: ServerErrorBody['error']) => ({\n sdkOutdated:\n serverError?.kind === 'sdk_outdated'\n ? sdkOutdatedSchema.safeParse(serverError).data\n : undefined,\n serverOutdated:\n serverError?.kind === 'server_outdated'\n ? serverOutdatedSchema.safeParse(serverError).data\n : undefined,\n});\n\n/**\n * Constructs a {@link ComposeError} from an HTTP error response, extracting\n * structured error details from the response body when available.\n *\n * @param status - The HTTP status code.\n * @param body - The raw response body text.\n * @param url - The request URL that produced the error.\n * @returns A `ComposeError` with the appropriate error code and metadata.\n */\nexport const errorFromHttpResponse = (\n status: number,\n body: string,\n url: string,\n): ComposeError => {\n const parsed = tryParseErrorBody(body);\n const serverError = parsed?.error;\n const { sdkOutdated, serverOutdated } = readVersionSlots(serverError);\n\n return new ComposeError(\n STATUS_TO_CODE.get(status) ??\n (status >= 500 ? 'SERVER_ERROR' : 'UNKNOWN_ERROR'),\n (serverError?.message ?? body) || `HTTP ${status}`,\n {\n status,\n url,\n kind: serverError?.kind as\n ComposeErrorKind | ComposeRouteErrorKind | undefined,\n path: serverError?.path,\n port: serverError?.port,\n fix: serverError?.fix,\n details: serverError?.details,\n // The wire schema types `kind` as a bare string; the server only ever\n // reports generic kinds for individual ops.\n failedOps: serverError?.failedOps?.map((op) => ({\n ...op,\n kind: op.kind as GenericComposeErrorKind,\n })),\n succeededOps: serverError?.succeededOps,\n sdkOutdated,\n serverOutdated,\n },\n );\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ var index_exports = {};
|
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
SIMULATE_MAX_REQUIREMENTS: () => import_compose_spec.SIMULATE_MAX_REQUIREMENTS,
|
|
33
33
|
SIMULATE_MAX_TRACKED_BALANCES: () => import_compose_spec.SIMULATE_MAX_TRACKED_BALANCES,
|
|
34
|
+
buildReachability: () => import_reachability.buildReachability,
|
|
34
35
|
buildSimulateRequest: () => import_simulate.buildSimulateRequest,
|
|
35
36
|
createComposeSdk: () => import_sdk.createComposeSdk,
|
|
36
37
|
guards: () => guards,
|
|
@@ -50,6 +51,7 @@ __export(index_exports, {
|
|
|
50
51
|
terminalOutputs: () => import_outputs.terminalOutputs
|
|
51
52
|
});
|
|
52
53
|
module.exports = __toCommonJS(index_exports);
|
|
54
|
+
var import_reachability = require("./reachability.js");
|
|
53
55
|
var import_compose_spec = require("@lifi/compose-spec");
|
|
54
56
|
var import_errors = require("./errors.js");
|
|
55
57
|
var import_handles = require("./authoring/handles.js");
|
|
@@ -75,6 +77,7 @@ const raw = rawMod;
|
|
|
75
77
|
0 && (module.exports = {
|
|
76
78
|
SIMULATE_MAX_REQUIREMENTS,
|
|
77
79
|
SIMULATE_MAX_TRACKED_BALANCES,
|
|
80
|
+
buildReachability,
|
|
78
81
|
buildSimulateRequest,
|
|
79
82
|
createComposeSdk,
|
|
80
83
|
guards,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@lifi/composer-sdk` — TypeScript SDK for building and compiling\n * Compose flows into executable EVM calldata.\n *\n * Start by creating an SDK instance with {@link createComposeSdk}, then use\n * {@link ComposeSdk.flow} to build flows and compile them.\n *\n * @packageDocumentation\n */\n\nexport type {\n AbiTypeToOutputKind,\n Address,\n InputDecl,\n InputSchema,\n InputSpecOf,\n IntegerString,\n IntegerStringInput,\n OutputKind,\n TypedGuard,\n TypedRef,\n TypedLiteral,\n} from './types.js';\n\nexport type {\n ChainSummary,\n GetZapPacksOptions,\n ZapPackEdge,\n ZapPackOverview,\n} from './discovery.js';\nexport type {\n ComposeError,\n ComposeErrorCode,\n ComposeSdkOutdated,\n ComposeServerOutdated,\n ComposePreparationOps,\n} from './errors.js';\nexport type {\n AppliedGuard,\n ApprovalEntry,\n Call,\n ComposeCompilePartialData,\n ComposeAction,\n ComposeFill,\n ComposeFee,\n ComposeUserProgramSimulation,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeErrorKind,\n ComposeRouteRequest,\n ComposeTransactionRequest,\n FailedPreparedOp,\n Flow,\n InputSpec,\n MaterialiserConfigOf,\n MaterialiserInput,\n OutputAmount,\n Amount,\n ConsumedOutput,\n Delivery,\n Estimate,\n EstimateBasis,\n Minimum,\n MinimumBasis,\n Output,\n Outputs,\n TerminalOutput,\n Precondition,\n PreconditionConfigOf,\n PriceImpact,\n Ref,\n Resource,\n RouteAmount,\n RouteAmountAll,\n RouteAmountExact,\n SimulationPolicy,\n SimulationRevert,\n SolType,\n SweepTo,\n SimulateRequest,\n SimulateResult,\n SimulateOkResult,\n SimulateRevertResult,\n SimulateRevertDecodeResult,\n SimulateSetupErrorResult,\n SimulateBalanceEntry,\n TrackedBalance,\n SlotFinderRequirement,\n Erc20BalanceRequirement,\n NativeBalanceRequirement,\n Erc20AllowanceRequirement,\n ContinuationIntent,\n ContinuationOutcome,\n Check,\n CheckComparator,\n Phase1ArtifactWire,\n ContinuationPlanWire,\n} from '@lifi/compose-spec';\nexport {\n SIMULATE_MAX_TRACKED_BALANCES,\n SIMULATE_MAX_REQUIREMENTS,\n} from '@lifi/compose-spec';\nexport {\n isComposeError,\n isComposePreparationError,\n isComposeSdkOutdatedError,\n isComposeServerOutdatedError,\n} from './errors.js';\n\nexport type {\n Bindable,\n RefBindable,\n AnyRefBindable,\n InputHandle,\n ResourceInputHandle,\n OutputHandle,\n AnyHandle,\n} from './authoring/handles.js';\nexport { isInputHandle, isOutputHandle } from './authoring/handles.js';\nexport { ref } from './authoring/raw.js';\n\nexport type { AnyBindable } from './authoring/FlowBuilderCore.js';\nexport type { TypedFlow, FlowOptions } from './authoring/FlowBuilderCore.js';\n\nexport type { ComposeRunInput } from './run/inputs.js';\nexport { materialiser } from './run/inputs.js';\n\nexport { buildSimulateRequest } from './run/simulate.js';\nexport type { BuildSimulateRequestInput } from './run/simulate.js';\n\nexport { terminalOutputs } from './outputs.js';\n\nexport { createComposeSdk } from './sdk.js';\nexport type { ComposeSdk, ComposeSdkOptions, FlowBuilder } from './sdk.js';\n\nimport * as guardsMod from './generated/guards.generated.js';\nimport * as materialisersMod from './generated/materialisers.generated.js';\nimport * as preconditionsMod from './generated/preconditions.generated.js';\nimport * as rawMod from './raw.js';\nimport * as resourcesMod from './resources.js';\nimport * as routeAmountMod from './routeAmount.js';\n\n/**\n * Guard factories for protecting operation outputs (e.g. slippage tolerance).\n * Pass guards to an operation's `guards` array.\n *\n * @example\n * ```ts\n * builder.lifi.swap('swap1', {\n * bind: { amountIn: builder.inputs.token },\n * config: { resourceOut: resources.native(1) },\n * guards: [guards.slippage({ port: 'amountOut', bps: 300 })],\n * });\n * ```\n */\nexport const guards: typeof guardsMod = guardsMod;\n/**\n * Materialiser factories that tell the runtime how to resolve token input\n * amounts on-chain (e.g. read a wallet balance, accept a direct deposit).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * signer: '0x...',\n * });\n * ```\n */\nexport const materialisers: typeof materialisersMod = materialisersMod;\n/**\n * Precondition factories for asserting on-chain state before a flow executes\n * (e.g. minimum token balances, ERC-20 allowances).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * preconditions: [\n * preconditions.erc20Balance({ wallet: '0x...', token: '0x...', balance: 1000n }),\n * ],\n * signer: '0x...',\n * });\n * ```\n */\nexport const preconditions: typeof preconditionsMod = preconditionsMod;\n/**\n * Resource declaration helpers for defining token inputs in a flow schema.\n * Use {@link resources.erc20} for ERC-20 tokens and {@link resources.native}\n * for the chain's native coin (ETH, MATIC, etc.).\n *\n * @example\n * ```ts\n * const builder = sdk.flow(1, {\n * inputs: {\n * usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1),\n * eth: resources.native(1),\n * },\n * });\n * ```\n */\nexport const resources: typeof resourcesMod = resourcesMod;\n/**\n * Amount constructors for {@link ComposeSdk.route}. Use\n * {@link routeAmount.exact} to spend a fixed amount of the `fromToken`, and\n * {@link routeAmount.all} to spend the signer's whole balance.\n *\n * @example\n * ```ts\n * // USDC into the Aave v3 aEthUSDC position — one routing-catalog edge.\n * const result = await sdk.route({\n * chainId: 1,\n * fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n * toToken: '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c',\n * amount: routeAmount.exact(1_000_000n),\n * signer: '0xYourAddress...',\n * });\n * ```\n */\nexport const routeAmount: typeof routeAmountMod = routeAmountMod;\nexport * from './generated/config.generated.js';\n\n/**\n * Low-level escape hatch for constructing flow nodes, guards, and materialiser\n * inputs without the typed builder API. Prefer the generated operation methods\n * on {@link FlowBuilder} and the typed `guards`/`materialisers` namespaces\n * for most use cases.\n */\nexport const raw: typeof rawMod = rawMod;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@lifi/composer-sdk` — TypeScript SDK for building and compiling\n * Compose flows into executable EVM calldata.\n *\n * Start by creating an SDK instance with {@link createComposeSdk}, then use\n * {@link ComposeSdk.flow} to build flows and compile them.\n *\n * @packageDocumentation\n */\n\nexport type {\n AbiTypeToOutputKind,\n Address,\n InputDecl,\n InputSchema,\n InputSpecOf,\n IntegerString,\n IntegerStringInput,\n OutputKind,\n TypedGuard,\n TypedRef,\n TypedLiteral,\n} from './types.js';\n\nexport type {\n ChainSummary,\n GetZapPacksOptions,\n ZapPackEdge,\n ZapPackOverview,\n} from './discovery.js';\nexport type {\n Reachability,\n ReachabilityOptions,\n RoutablePair,\n TokenRef,\n} from './reachability.js';\nexport { buildReachability } from './reachability.js';\nexport type {\n ComposeError,\n ComposeErrorCode,\n ComposeSdkOutdated,\n ComposeServerOutdated,\n ComposePreparationOps,\n} from './errors.js';\nexport type {\n AppliedGuard,\n ApprovalEntry,\n Call,\n ComposeCompilePartialData,\n ComposeAction,\n ComposeFill,\n ComposeFee,\n ComposeUserProgramSimulation,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeErrorKind,\n ComposeRouteRequest,\n ComposeTransactionRequest,\n FailedPreparedOp,\n Flow,\n InputSpec,\n MaterialiserConfigOf,\n MaterialiserInput,\n OutputAmount,\n Amount,\n ConsumedOutput,\n Delivery,\n Estimate,\n EstimateBasis,\n Minimum,\n MinimumBasis,\n Output,\n Outputs,\n TerminalOutput,\n Precondition,\n PreconditionConfigOf,\n PriceImpact,\n Ref,\n Resource,\n RouteAmount,\n RouteAmountAll,\n RouteAmountExact,\n SimulationPolicy,\n SimulationRevert,\n SolType,\n SweepTo,\n SimulateRequest,\n SimulateResult,\n SimulateOkResult,\n SimulateRevertResult,\n SimulateRevertDecodeResult,\n SimulateSetupErrorResult,\n SimulateBalanceEntry,\n TrackedBalance,\n SlotFinderRequirement,\n Erc20BalanceRequirement,\n NativeBalanceRequirement,\n Erc20AllowanceRequirement,\n ContinuationIntent,\n ContinuationOutcome,\n Check,\n CheckComparator,\n Phase1ArtifactWire,\n ContinuationPlanWire,\n} from '@lifi/compose-spec';\nexport {\n SIMULATE_MAX_TRACKED_BALANCES,\n SIMULATE_MAX_REQUIREMENTS,\n} from '@lifi/compose-spec';\nexport {\n isComposeError,\n isComposePreparationError,\n isComposeSdkOutdatedError,\n isComposeServerOutdatedError,\n} from './errors.js';\n\nexport type {\n Bindable,\n RefBindable,\n AnyRefBindable,\n InputHandle,\n ResourceInputHandle,\n OutputHandle,\n AnyHandle,\n} from './authoring/handles.js';\nexport { isInputHandle, isOutputHandle } from './authoring/handles.js';\nexport { ref } from './authoring/raw.js';\n\nexport type { AnyBindable } from './authoring/FlowBuilderCore.js';\nexport type { TypedFlow, FlowOptions } from './authoring/FlowBuilderCore.js';\n\nexport type { ComposeRunInput } from './run/inputs.js';\nexport { materialiser } from './run/inputs.js';\n\nexport { buildSimulateRequest } from './run/simulate.js';\nexport type { BuildSimulateRequestInput } from './run/simulate.js';\n\nexport { terminalOutputs } from './outputs.js';\n\nexport { createComposeSdk } from './sdk.js';\nexport type { ComposeSdk, ComposeSdkOptions, FlowBuilder } from './sdk.js';\n\nimport * as guardsMod from './generated/guards.generated.js';\nimport * as materialisersMod from './generated/materialisers.generated.js';\nimport * as preconditionsMod from './generated/preconditions.generated.js';\nimport * as rawMod from './raw.js';\nimport * as resourcesMod from './resources.js';\nimport * as routeAmountMod from './routeAmount.js';\n\n/**\n * Guard factories for protecting operation outputs (e.g. slippage tolerance).\n * Pass guards to an operation's `guards` array.\n *\n * @example\n * ```ts\n * builder.lifi.swap('swap1', {\n * bind: { amountIn: builder.inputs.token },\n * config: { resourceOut: resources.native(1) },\n * guards: [guards.slippage({ port: 'amountOut', bps: 300 })],\n * });\n * ```\n */\nexport const guards: typeof guardsMod = guardsMod;\n/**\n * Materialiser factories that tell the runtime how to resolve token input\n * amounts on-chain (e.g. read a wallet balance, accept a direct deposit).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * signer: '0x...',\n * });\n * ```\n */\nexport const materialisers: typeof materialisersMod = materialisersMod;\n/**\n * Precondition factories for asserting on-chain state before a flow executes\n * (e.g. minimum token balances, ERC-20 allowances).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * preconditions: [\n * preconditions.erc20Balance({ wallet: '0x...', token: '0x...', balance: 1000n }),\n * ],\n * signer: '0x...',\n * });\n * ```\n */\nexport const preconditions: typeof preconditionsMod = preconditionsMod;\n/**\n * Resource declaration helpers for defining token inputs in a flow schema.\n * Use {@link resources.erc20} for ERC-20 tokens and {@link resources.native}\n * for the chain's native coin (ETH, MATIC, etc.).\n *\n * @example\n * ```ts\n * const builder = sdk.flow(1, {\n * inputs: {\n * usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1),\n * eth: resources.native(1),\n * },\n * });\n * ```\n */\nexport const resources: typeof resourcesMod = resourcesMod;\n/**\n * Amount constructors for {@link ComposeSdk.route}. Use\n * {@link routeAmount.exact} to spend a fixed amount of the `fromToken`, and\n * {@link routeAmount.all} to spend the signer's whole balance.\n *\n * @example\n * ```ts\n * // USDC into the Aave v3 aEthUSDC position — one routing-catalog edge.\n * const result = await sdk.route({\n * chainId: 1,\n * fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n * toToken: '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c',\n * amount: routeAmount.exact(1_000_000n),\n * signer: '0xYourAddress...',\n * });\n * ```\n */\nexport const routeAmount: typeof routeAmountMod = routeAmountMod;\nexport * from './generated/config.generated.js';\n\n/**\n * Low-level escape hatch for constructing flow nodes, guards, and materialiser\n * inputs without the typed builder API. Prefer the generated operation methods\n * on {@link FlowBuilder} and the typed `guards`/`materialisers` namespaces\n * for most use cases.\n */\nexport const raw: typeof rawMod = rawMod;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoCA,0BAAkC;AAsElC,0BAGO;AACP,oBAKO;AAWP,qBAA8C;AAC9C,iBAAoB;AAMpB,oBAA6B;AAE7B,sBAAqC;AAGrC,qBAAgC;AAEhC,iBAAiC;AAGjC,gBAA2B;AAC3B,uBAAkC;AAClC,uBAAkC;AAClC,aAAwB;AACxB,mBAA8B;AAC9B,qBAAgC;AA+EhC,0BAAc,4CAnOd;AAmKO,MAAM,SAA2B;AAajC,MAAM,gBAAyC;AAgB/C,MAAM,gBAAyC;AAgB/C,MAAM,YAAiC;AAkBvC,MAAM,cAAqC;AAS3C,MAAM,MAAqB;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { AbiTypeToOutputKind, Address, InputDecl, InputSchema, InputSpecOf, IntegerString, IntegerStringInput, OutputKind, TypedGuard, TypedLiteral, TypedRef } from './types.cjs';
|
|
2
2
|
export { ChainSummary, GetZapPacksOptions, ZapPackEdge, ZapPackOverview } from './discovery.cjs';
|
|
3
|
+
export { Reachability, ReachabilityOptions, RoutablePair, TokenRef, buildReachability } from './reachability.cjs';
|
|
3
4
|
export { ComposeError, ComposeErrorCode, ComposePreparationOps, ComposeSdkOutdated, ComposeServerOutdated, isComposeError, isComposePreparationError, isComposeSdkOutdatedError, isComposeServerOutdatedError } from './errors.cjs';
|
|
4
5
|
export { Amount, AppliedGuard, ApprovalEntry, Call, Check, CheckComparator, ComposeAction, ComposeCompilePartialData, ComposeCompileRequest, ComposeCompileResult, ComposeCompileSuccessData, ComposeErrorKind, ComposeFee, ComposeFill, ComposeRouteRequest, ComposeTransactionRequest, ComposeUserProgramSimulation, ConsumedOutput, ContinuationIntent, ContinuationOutcome, ContinuationPlanWire, Delivery, Erc20AllowanceRequirement, Erc20BalanceRequirement, Estimate, EstimateBasis, FailedPreparedOp, Flow, InputSpec, MaterialiserConfigOf, MaterialiserInput, Minimum, MinimumBasis, NativeBalanceRequirement, Output, OutputAmount, Outputs, Phase1ArtifactWire, Precondition, PreconditionConfigOf, PriceImpact, Ref, Resource, RouteAmount, RouteAmountAll, RouteAmountExact, SIMULATE_MAX_REQUIREMENTS, SIMULATE_MAX_TRACKED_BALANCES, SimulateBalanceEntry, SimulateOkResult, SimulateRequest, SimulateResult, SimulateRevertDecodeResult, SimulateRevertResult, SimulateSetupErrorResult, SimulationPolicy, SimulationRevert, SlotFinderRequirement, SolType, SweepTo, TerminalOutput, TrackedBalance } from '@lifi/compose-spec';
|
|
5
6
|
export { AnyHandle, AnyRefBindable, Bindable, InputHandle, OutputHandle, RefBindable, ResourceInputHandle, isInputHandle, isOutputHandle } from './authoring/handles.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { AbiTypeToOutputKind, Address, InputDecl, InputSchema, InputSpecOf, IntegerString, IntegerStringInput, OutputKind, TypedGuard, TypedLiteral, TypedRef } from './types.js';
|
|
2
2
|
export { ChainSummary, GetZapPacksOptions, ZapPackEdge, ZapPackOverview } from './discovery.js';
|
|
3
|
+
export { Reachability, ReachabilityOptions, RoutablePair, TokenRef, buildReachability } from './reachability.js';
|
|
3
4
|
export { ComposeError, ComposeErrorCode, ComposePreparationOps, ComposeSdkOutdated, ComposeServerOutdated, isComposeError, isComposePreparationError, isComposeSdkOutdatedError, isComposeServerOutdatedError } from './errors.js';
|
|
4
5
|
export { Amount, AppliedGuard, ApprovalEntry, Call, Check, CheckComparator, ComposeAction, ComposeCompilePartialData, ComposeCompileRequest, ComposeCompileResult, ComposeCompileSuccessData, ComposeErrorKind, ComposeFee, ComposeFill, ComposeRouteRequest, ComposeTransactionRequest, ComposeUserProgramSimulation, ConsumedOutput, ContinuationIntent, ContinuationOutcome, ContinuationPlanWire, Delivery, Erc20AllowanceRequirement, Erc20BalanceRequirement, Estimate, EstimateBasis, FailedPreparedOp, Flow, InputSpec, MaterialiserConfigOf, MaterialiserInput, Minimum, MinimumBasis, NativeBalanceRequirement, Output, OutputAmount, Outputs, Phase1ArtifactWire, Precondition, PreconditionConfigOf, PriceImpact, Ref, Resource, RouteAmount, RouteAmountAll, RouteAmountExact, SIMULATE_MAX_REQUIREMENTS, SIMULATE_MAX_TRACKED_BALANCES, SimulateBalanceEntry, SimulateOkResult, SimulateRequest, SimulateResult, SimulateRevertDecodeResult, SimulateRevertResult, SimulateSetupErrorResult, SimulationPolicy, SimulationRevert, SlotFinderRequirement, SolType, SweepTo, TerminalOutput, TrackedBalance } from '@lifi/compose-spec';
|
|
5
6
|
export { AnyHandle, AnyRefBindable, Bindable, InputHandle, OutputHandle, RefBindable, ResourceInputHandle, isInputHandle, isOutputHandle } from './authoring/handles.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { buildReachability } from "./reachability.js";
|
|
1
2
|
import {
|
|
2
3
|
SIMULATE_MAX_TRACKED_BALANCES,
|
|
3
4
|
SIMULATE_MAX_REQUIREMENTS
|
|
@@ -30,6 +31,7 @@ const raw = rawMod;
|
|
|
30
31
|
export {
|
|
31
32
|
SIMULATE_MAX_REQUIREMENTS,
|
|
32
33
|
SIMULATE_MAX_TRACKED_BALANCES,
|
|
34
|
+
buildReachability,
|
|
33
35
|
buildSimulateRequest,
|
|
34
36
|
createComposeSdk,
|
|
35
37
|
guards,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@lifi/composer-sdk` — TypeScript SDK for building and compiling\n * Compose flows into executable EVM calldata.\n *\n * Start by creating an SDK instance with {@link createComposeSdk}, then use\n * {@link ComposeSdk.flow} to build flows and compile them.\n *\n * @packageDocumentation\n */\n\nexport type {\n AbiTypeToOutputKind,\n Address,\n InputDecl,\n InputSchema,\n InputSpecOf,\n IntegerString,\n IntegerStringInput,\n OutputKind,\n TypedGuard,\n TypedRef,\n TypedLiteral,\n} from './types.js';\n\nexport type {\n ChainSummary,\n GetZapPacksOptions,\n ZapPackEdge,\n ZapPackOverview,\n} from './discovery.js';\nexport type {\n ComposeError,\n ComposeErrorCode,\n ComposeSdkOutdated,\n ComposeServerOutdated,\n ComposePreparationOps,\n} from './errors.js';\nexport type {\n AppliedGuard,\n ApprovalEntry,\n Call,\n ComposeCompilePartialData,\n ComposeAction,\n ComposeFill,\n ComposeFee,\n ComposeUserProgramSimulation,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeErrorKind,\n ComposeRouteRequest,\n ComposeTransactionRequest,\n FailedPreparedOp,\n Flow,\n InputSpec,\n MaterialiserConfigOf,\n MaterialiserInput,\n OutputAmount,\n Amount,\n ConsumedOutput,\n Delivery,\n Estimate,\n EstimateBasis,\n Minimum,\n MinimumBasis,\n Output,\n Outputs,\n TerminalOutput,\n Precondition,\n PreconditionConfigOf,\n PriceImpact,\n Ref,\n Resource,\n RouteAmount,\n RouteAmountAll,\n RouteAmountExact,\n SimulationPolicy,\n SimulationRevert,\n SolType,\n SweepTo,\n SimulateRequest,\n SimulateResult,\n SimulateOkResult,\n SimulateRevertResult,\n SimulateRevertDecodeResult,\n SimulateSetupErrorResult,\n SimulateBalanceEntry,\n TrackedBalance,\n SlotFinderRequirement,\n Erc20BalanceRequirement,\n NativeBalanceRequirement,\n Erc20AllowanceRequirement,\n ContinuationIntent,\n ContinuationOutcome,\n Check,\n CheckComparator,\n Phase1ArtifactWire,\n ContinuationPlanWire,\n} from '@lifi/compose-spec';\nexport {\n SIMULATE_MAX_TRACKED_BALANCES,\n SIMULATE_MAX_REQUIREMENTS,\n} from '@lifi/compose-spec';\nexport {\n isComposeError,\n isComposePreparationError,\n isComposeSdkOutdatedError,\n isComposeServerOutdatedError,\n} from './errors.js';\n\nexport type {\n Bindable,\n RefBindable,\n AnyRefBindable,\n InputHandle,\n ResourceInputHandle,\n OutputHandle,\n AnyHandle,\n} from './authoring/handles.js';\nexport { isInputHandle, isOutputHandle } from './authoring/handles.js';\nexport { ref } from './authoring/raw.js';\n\nexport type { AnyBindable } from './authoring/FlowBuilderCore.js';\nexport type { TypedFlow, FlowOptions } from './authoring/FlowBuilderCore.js';\n\nexport type { ComposeRunInput } from './run/inputs.js';\nexport { materialiser } from './run/inputs.js';\n\nexport { buildSimulateRequest } from './run/simulate.js';\nexport type { BuildSimulateRequestInput } from './run/simulate.js';\n\nexport { terminalOutputs } from './outputs.js';\n\nexport { createComposeSdk } from './sdk.js';\nexport type { ComposeSdk, ComposeSdkOptions, FlowBuilder } from './sdk.js';\n\nimport * as guardsMod from './generated/guards.generated.js';\nimport * as materialisersMod from './generated/materialisers.generated.js';\nimport * as preconditionsMod from './generated/preconditions.generated.js';\nimport * as rawMod from './raw.js';\nimport * as resourcesMod from './resources.js';\nimport * as routeAmountMod from './routeAmount.js';\n\n/**\n * Guard factories for protecting operation outputs (e.g. slippage tolerance).\n * Pass guards to an operation's `guards` array.\n *\n * @example\n * ```ts\n * builder.lifi.swap('swap1', {\n * bind: { amountIn: builder.inputs.token },\n * config: { resourceOut: resources.native(1) },\n * guards: [guards.slippage({ port: 'amountOut', bps: 300 })],\n * });\n * ```\n */\nexport const guards: typeof guardsMod = guardsMod;\n/**\n * Materialiser factories that tell the runtime how to resolve token input\n * amounts on-chain (e.g. read a wallet balance, accept a direct deposit).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * signer: '0x...',\n * });\n * ```\n */\nexport const materialisers: typeof materialisersMod = materialisersMod;\n/**\n * Precondition factories for asserting on-chain state before a flow executes\n * (e.g. minimum token balances, ERC-20 allowances).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * preconditions: [\n * preconditions.erc20Balance({ wallet: '0x...', token: '0x...', balance: 1000n }),\n * ],\n * signer: '0x...',\n * });\n * ```\n */\nexport const preconditions: typeof preconditionsMod = preconditionsMod;\n/**\n * Resource declaration helpers for defining token inputs in a flow schema.\n * Use {@link resources.erc20} for ERC-20 tokens and {@link resources.native}\n * for the chain's native coin (ETH, MATIC, etc.).\n *\n * @example\n * ```ts\n * const builder = sdk.flow(1, {\n * inputs: {\n * usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1),\n * eth: resources.native(1),\n * },\n * });\n * ```\n */\nexport const resources: typeof resourcesMod = resourcesMod;\n/**\n * Amount constructors for {@link ComposeSdk.route}. Use\n * {@link routeAmount.exact} to spend a fixed amount of the `fromToken`, and\n * {@link routeAmount.all} to spend the signer's whole balance.\n *\n * @example\n * ```ts\n * // USDC into the Aave v3 aEthUSDC position — one routing-catalog edge.\n * const result = await sdk.route({\n * chainId: 1,\n * fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n * toToken: '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c',\n * amount: routeAmount.exact(1_000_000n),\n * signer: '0xYourAddress...',\n * });\n * ```\n */\nexport const routeAmount: typeof routeAmountMod = routeAmountMod;\nexport * from './generated/config.generated.js';\n\n/**\n * Low-level escape hatch for constructing flow nodes, guards, and materialiser\n * inputs without the typed builder API. Prefer the generated operation methods\n * on {@link FlowBuilder} and the typed `guards`/`materialisers` namespaces\n * for most use cases.\n */\nexport const raw: typeof rawMod = rawMod;\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * `@lifi/composer-sdk` — TypeScript SDK for building and compiling\n * Compose flows into executable EVM calldata.\n *\n * Start by creating an SDK instance with {@link createComposeSdk}, then use\n * {@link ComposeSdk.flow} to build flows and compile them.\n *\n * @packageDocumentation\n */\n\nexport type {\n AbiTypeToOutputKind,\n Address,\n InputDecl,\n InputSchema,\n InputSpecOf,\n IntegerString,\n IntegerStringInput,\n OutputKind,\n TypedGuard,\n TypedRef,\n TypedLiteral,\n} from './types.js';\n\nexport type {\n ChainSummary,\n GetZapPacksOptions,\n ZapPackEdge,\n ZapPackOverview,\n} from './discovery.js';\nexport type {\n Reachability,\n ReachabilityOptions,\n RoutablePair,\n TokenRef,\n} from './reachability.js';\nexport { buildReachability } from './reachability.js';\nexport type {\n ComposeError,\n ComposeErrorCode,\n ComposeSdkOutdated,\n ComposeServerOutdated,\n ComposePreparationOps,\n} from './errors.js';\nexport type {\n AppliedGuard,\n ApprovalEntry,\n Call,\n ComposeCompilePartialData,\n ComposeAction,\n ComposeFill,\n ComposeFee,\n ComposeUserProgramSimulation,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeErrorKind,\n ComposeRouteRequest,\n ComposeTransactionRequest,\n FailedPreparedOp,\n Flow,\n InputSpec,\n MaterialiserConfigOf,\n MaterialiserInput,\n OutputAmount,\n Amount,\n ConsumedOutput,\n Delivery,\n Estimate,\n EstimateBasis,\n Minimum,\n MinimumBasis,\n Output,\n Outputs,\n TerminalOutput,\n Precondition,\n PreconditionConfigOf,\n PriceImpact,\n Ref,\n Resource,\n RouteAmount,\n RouteAmountAll,\n RouteAmountExact,\n SimulationPolicy,\n SimulationRevert,\n SolType,\n SweepTo,\n SimulateRequest,\n SimulateResult,\n SimulateOkResult,\n SimulateRevertResult,\n SimulateRevertDecodeResult,\n SimulateSetupErrorResult,\n SimulateBalanceEntry,\n TrackedBalance,\n SlotFinderRequirement,\n Erc20BalanceRequirement,\n NativeBalanceRequirement,\n Erc20AllowanceRequirement,\n ContinuationIntent,\n ContinuationOutcome,\n Check,\n CheckComparator,\n Phase1ArtifactWire,\n ContinuationPlanWire,\n} from '@lifi/compose-spec';\nexport {\n SIMULATE_MAX_TRACKED_BALANCES,\n SIMULATE_MAX_REQUIREMENTS,\n} from '@lifi/compose-spec';\nexport {\n isComposeError,\n isComposePreparationError,\n isComposeSdkOutdatedError,\n isComposeServerOutdatedError,\n} from './errors.js';\n\nexport type {\n Bindable,\n RefBindable,\n AnyRefBindable,\n InputHandle,\n ResourceInputHandle,\n OutputHandle,\n AnyHandle,\n} from './authoring/handles.js';\nexport { isInputHandle, isOutputHandle } from './authoring/handles.js';\nexport { ref } from './authoring/raw.js';\n\nexport type { AnyBindable } from './authoring/FlowBuilderCore.js';\nexport type { TypedFlow, FlowOptions } from './authoring/FlowBuilderCore.js';\n\nexport type { ComposeRunInput } from './run/inputs.js';\nexport { materialiser } from './run/inputs.js';\n\nexport { buildSimulateRequest } from './run/simulate.js';\nexport type { BuildSimulateRequestInput } from './run/simulate.js';\n\nexport { terminalOutputs } from './outputs.js';\n\nexport { createComposeSdk } from './sdk.js';\nexport type { ComposeSdk, ComposeSdkOptions, FlowBuilder } from './sdk.js';\n\nimport * as guardsMod from './generated/guards.generated.js';\nimport * as materialisersMod from './generated/materialisers.generated.js';\nimport * as preconditionsMod from './generated/preconditions.generated.js';\nimport * as rawMod from './raw.js';\nimport * as resourcesMod from './resources.js';\nimport * as routeAmountMod from './routeAmount.js';\n\n/**\n * Guard factories for protecting operation outputs (e.g. slippage tolerance).\n * Pass guards to an operation's `guards` array.\n *\n * @example\n * ```ts\n * builder.lifi.swap('swap1', {\n * bind: { amountIn: builder.inputs.token },\n * config: { resourceOut: resources.native(1) },\n * guards: [guards.slippage({ port: 'amountOut', bps: 300 })],\n * });\n * ```\n */\nexport const guards: typeof guardsMod = guardsMod;\n/**\n * Materialiser factories that tell the runtime how to resolve token input\n * amounts on-chain (e.g. read a wallet balance, accept a direct deposit).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * signer: '0x...',\n * });\n * ```\n */\nexport const materialisers: typeof materialisersMod = materialisersMod;\n/**\n * Precondition factories for asserting on-chain state before a flow executes\n * (e.g. minimum token balances, ERC-20 allowances).\n *\n * @example\n * ```ts\n * await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * preconditions: [\n * preconditions.erc20Balance({ wallet: '0x...', token: '0x...', balance: 1000n }),\n * ],\n * signer: '0x...',\n * });\n * ```\n */\nexport const preconditions: typeof preconditionsMod = preconditionsMod;\n/**\n * Resource declaration helpers for defining token inputs in a flow schema.\n * Use {@link resources.erc20} for ERC-20 tokens and {@link resources.native}\n * for the chain's native coin (ETH, MATIC, etc.).\n *\n * @example\n * ```ts\n * const builder = sdk.flow(1, {\n * inputs: {\n * usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1),\n * eth: resources.native(1),\n * },\n * });\n * ```\n */\nexport const resources: typeof resourcesMod = resourcesMod;\n/**\n * Amount constructors for {@link ComposeSdk.route}. Use\n * {@link routeAmount.exact} to spend a fixed amount of the `fromToken`, and\n * {@link routeAmount.all} to spend the signer's whole balance.\n *\n * @example\n * ```ts\n * // USDC into the Aave v3 aEthUSDC position — one routing-catalog edge.\n * const result = await sdk.route({\n * chainId: 1,\n * fromToken: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n * toToken: '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c',\n * amount: routeAmount.exact(1_000_000n),\n * signer: '0xYourAddress...',\n * });\n * ```\n */\nexport const routeAmount: typeof routeAmountMod = routeAmountMod;\nexport * from './generated/config.generated.js';\n\n/**\n * Low-level escape hatch for constructing flow nodes, guards, and materialiser\n * inputs without the typed builder API. Prefer the generated operation methods\n * on {@link FlowBuilder} and the typed `guards`/`materialisers` namespaces\n * for most use cases.\n */\nexport const raw: typeof rawMod = rawMod;\n"],"mappings":"AAoCA,SAAS,yBAAyB;AAsElC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAWP,SAAS,eAAe,sBAAsB;AAC9C,SAAS,WAAW;AAMpB,SAAS,oBAAoB;AAE7B,SAAS,4BAA4B;AAGrC,SAAS,uBAAuB;AAEhC,SAAS,wBAAwB;AAGjC,YAAY,eAAe;AAC3B,YAAY,sBAAsB;AAClC,YAAY,sBAAsB;AAClC,YAAY,YAAY;AACxB,YAAY,kBAAkB;AAC9B,YAAY,oBAAoB;AAezB,MAAM,SAA2B;AAajC,MAAM,gBAAyC;AAgB/C,MAAM,gBAAyC;AAgB/C,MAAM,YAAiC;AAkBvC,MAAM,cAAqC;AAClD,cAAc;AAQP,MAAM,MAAqB;","names":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
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 reachability_exports = {};
|
|
20
|
+
__export(reachability_exports, {
|
|
21
|
+
buildReachability: () => buildReachability
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(reachability_exports);
|
|
24
|
+
const DEFAULT_MAX_HOPS = 2;
|
|
25
|
+
const tokenKey = (token) => `${token.chainId}:${token.address.toLowerCase()}`;
|
|
26
|
+
const isSync = (edge) => edge.availability === void 0;
|
|
27
|
+
const isProxyHeld = (edge) => isSync(edge) && edge.recipient !== "required";
|
|
28
|
+
const visitEdge = ({
|
|
29
|
+
edge,
|
|
30
|
+
from,
|
|
31
|
+
depth,
|
|
32
|
+
sourceKey,
|
|
33
|
+
isTerminal,
|
|
34
|
+
found,
|
|
35
|
+
expanded
|
|
36
|
+
}) => {
|
|
37
|
+
const key = tokenKey(edge.out);
|
|
38
|
+
if (key === sourceKey) return void 0;
|
|
39
|
+
if (isTerminal(edge) && !found.has(key)) {
|
|
40
|
+
found.set(key, { in: from, out: edge.out, hops: depth });
|
|
41
|
+
}
|
|
42
|
+
if (!isProxyHeld(edge) || expanded.has(key)) return void 0;
|
|
43
|
+
expanded.add(key);
|
|
44
|
+
return edge.out;
|
|
45
|
+
};
|
|
46
|
+
const closureFrom = ({
|
|
47
|
+
byIn,
|
|
48
|
+
from,
|
|
49
|
+
maxHops,
|
|
50
|
+
isTerminal
|
|
51
|
+
}) => {
|
|
52
|
+
const sourceKey = tokenKey(from);
|
|
53
|
+
const found = /* @__PURE__ */ new Map();
|
|
54
|
+
const expanded = /* @__PURE__ */ new Set([sourceKey]);
|
|
55
|
+
let frontier = [from];
|
|
56
|
+
for (let depth = 1; depth <= maxHops && frontier.length > 0; depth++) {
|
|
57
|
+
const next = [];
|
|
58
|
+
for (const node of frontier) {
|
|
59
|
+
for (const edge of byIn.get(tokenKey(node)) ?? []) {
|
|
60
|
+
const out = visitEdge({
|
|
61
|
+
edge,
|
|
62
|
+
from,
|
|
63
|
+
depth,
|
|
64
|
+
sourceKey,
|
|
65
|
+
isTerminal,
|
|
66
|
+
found,
|
|
67
|
+
expanded
|
|
68
|
+
});
|
|
69
|
+
if (out) next.push(out);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
frontier = next;
|
|
73
|
+
}
|
|
74
|
+
return found;
|
|
75
|
+
};
|
|
76
|
+
const indexByIn = (packs) => {
|
|
77
|
+
const byIn = /* @__PURE__ */ new Map();
|
|
78
|
+
for (const pack of packs) {
|
|
79
|
+
for (const edge of pack.edges) {
|
|
80
|
+
const key = tokenKey(edge.in);
|
|
81
|
+
const list = byIn.get(key);
|
|
82
|
+
if (list) list.push(edge);
|
|
83
|
+
else byIn.set(key, [edge]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return byIn;
|
|
87
|
+
};
|
|
88
|
+
const buildReachability = (packs, options = {}) => {
|
|
89
|
+
const maxHops = options.maxHops ?? DEFAULT_MAX_HOPS;
|
|
90
|
+
const allowAsync = options.allowAsyncRoutes ?? false;
|
|
91
|
+
const isTerminal = (edge) => isSync(edge) || allowAsync && edge.availability === "future";
|
|
92
|
+
const byIn = indexByIn(packs);
|
|
93
|
+
const memo = /* @__PURE__ */ new Map();
|
|
94
|
+
const closure = (from) => {
|
|
95
|
+
const key = tokenKey(from);
|
|
96
|
+
const cached = memo.get(key);
|
|
97
|
+
if (cached) return cached;
|
|
98
|
+
const computed = closureFrom({ byIn, from, maxHops, isTerminal });
|
|
99
|
+
memo.set(key, computed);
|
|
100
|
+
return computed;
|
|
101
|
+
};
|
|
102
|
+
return {
|
|
103
|
+
maxHops,
|
|
104
|
+
canRoute: (from, to) => closure(from).has(tokenKey(to)),
|
|
105
|
+
routableFrom: (from) => [...closure(from).values()],
|
|
106
|
+
pairs: () => {
|
|
107
|
+
const sources = /* @__PURE__ */ new Map();
|
|
108
|
+
for (const pack of packs) {
|
|
109
|
+
for (const edge of pack.edges) sources.set(tokenKey(edge.in), edge.in);
|
|
110
|
+
}
|
|
111
|
+
const all = [];
|
|
112
|
+
for (const source of sources.values()) {
|
|
113
|
+
all.push(...closure(source).values());
|
|
114
|
+
}
|
|
115
|
+
return all;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
120
|
+
0 && (module.exports = {
|
|
121
|
+
buildReachability
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=reachability.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/reachability.ts"],"sourcesContent":["/**\n * Client-side reachability over the zap-pack catalog.\n *\n * `GET /compose/zap-packs` lists single routing edges. `POST /compose/route`\n * chains up to the server's hop budget of them, so the set of routable pairs\n * is the closure of the catalog, not the catalog itself. This module computes\n * that closure locally with the planner's admissibility rule, so an integrator\n * can offer every pair `route` connects without a request per pair.\n *\n * The rule, mirrored from the server's route search:\n *\n * - every edge except the last must leave its output in the proxy for the\n * next edge to consume: no `availability`, no `recipient: 'required'`\n * - the last edge must be synchronous, or `availability: 'future'` when the\n * caller opts into `allowAsyncRoutes`\n * - a route never visits the same token twice\n *\n * Amount bounds (`inAmountMin` / `inAmountMax`) on an intermediate edge\n * cannot be checked without an amount, so a pair reported here is routable\n * structurally, exactly as a listed edge is. Routes that open with a\n * `lifi.swap` are not enumerable and are not reported. The server also\n * drops blacklisted tokens as intermediates, which is server-side config\n * this module cannot see, so a reported pair may still answer\n * `no_route_error`.\n */\n\nimport type { ZapPackEdge, ZapPackOverview } from './discovery.js';\n\n/** A token identified by address and chain. */\nexport interface TokenRef {\n readonly address: string;\n readonly chainId: number;\n}\n\n/** A from/to pair `POST /compose/route` can connect through the catalog. */\nexport interface RoutablePair {\n readonly in: TokenRef;\n readonly out: TokenRef;\n /** Catalog edges on the shortest admissible route; `1` is a listed edge. */\n readonly hops: number;\n}\n\nexport interface ReachabilityOptions {\n /**\n * Hop budget. The server's `no_route_error` reports its effective value in\n * `details.maxHops`; the deployment default is 2.\n */\n readonly maxHops?: number;\n /**\n * Admit a route whose last edge has `availability: 'future'`. Mirrors the\n * `allowAsyncRoutes` request option; such a pair is a `no_route_error`\n * without it.\n */\n readonly allowAsyncRoutes?: boolean;\n}\n\nexport interface Reachability {\n readonly maxHops: number;\n /** Whether `route` can connect `from` to `to` through the catalog. */\n readonly canRoute: (from: TokenRef, to: TokenRef) => boolean;\n /** Every pair starting at `from`, shortest routes first. */\n readonly routableFrom: (from: TokenRef) => readonly RoutablePair[];\n /** Every routable pair in the catalog. */\n readonly pairs: () => readonly RoutablePair[];\n}\n\nconst DEFAULT_MAX_HOPS = 2;\n\nconst tokenKey = (token: TokenRef): string =>\n `${token.chainId}:${token.address.toLowerCase()}`;\n\nconst isSync = (edge: ZapPackEdge): boolean => edge.availability === undefined;\n\n// The output stays in the proxy, so a following edge can consume it.\nconst isProxyHeld = (edge: ZapPackEdge): boolean =>\n isSync(edge) && edge.recipient !== 'required';\n\n// One edge out of a frontier token. Records the pair it completes, and returns\n// its output when a further hop may consume it (proxy-held) and no shorter\n// path already expanded that token.\nconst visitEdge = ({\n edge,\n from,\n depth,\n sourceKey,\n isTerminal,\n found,\n expanded,\n}: {\n readonly edge: ZapPackEdge;\n readonly from: TokenRef;\n readonly depth: number;\n readonly sourceKey: string;\n readonly isTerminal: (edge: ZapPackEdge) => boolean;\n readonly found: Map<string, RoutablePair>;\n readonly expanded: Set<string>;\n}): TokenRef | undefined => {\n const key = tokenKey(edge.out);\n if (key === sourceKey) return undefined;\n if (isTerminal(edge) && !found.has(key)) {\n found.set(key, { in: from, out: edge.out, hops: depth });\n }\n if (!isProxyHeld(edge) || expanded.has(key)) return undefined;\n expanded.add(key);\n return edge.out;\n};\n\n// Every pair reachable from one token within `maxHops`, breadth-first so the\n// recorded hop count is the shortest one.\nconst closureFrom = ({\n byIn,\n from,\n maxHops,\n isTerminal,\n}: {\n readonly byIn: ReadonlyMap<string, readonly ZapPackEdge[]>;\n readonly from: TokenRef;\n readonly maxHops: number;\n readonly isTerminal: (edge: ZapPackEdge) => boolean;\n}): Map<string, RoutablePair> => {\n const sourceKey = tokenKey(from);\n const found = new Map<string, RoutablePair>();\n const expanded = new Set<string>([sourceKey]);\n let frontier: readonly TokenRef[] = [from];\n for (let depth = 1; depth <= maxHops && frontier.length > 0; depth++) {\n const next: TokenRef[] = [];\n for (const node of frontier) {\n for (const edge of byIn.get(tokenKey(node)) ?? []) {\n const out = visitEdge({\n edge,\n from,\n depth,\n sourceKey,\n isTerminal,\n found,\n expanded,\n });\n if (out) next.push(out);\n }\n }\n frontier = next;\n }\n return found;\n};\n\nconst indexByIn = (\n packs: readonly ZapPackOverview[],\n): Map<string, ZapPackEdge[]> => {\n const byIn = new Map<string, ZapPackEdge[]>();\n for (const pack of packs) {\n for (const edge of pack.edges) {\n const key = tokenKey(edge.in);\n const list = byIn.get(key);\n if (list) list.push(edge);\n else byIn.set(key, [edge]);\n }\n }\n return byIn;\n};\n\n/**\n * Builds a reachability index over the packs returned by\n * {@link ComposeClient.getZapPacks}. Per-source closures are computed on\n * first use and memoised, so `canRoute` on a handful of pairs stays cheap\n * while `pairs()` enumerates everything.\n */\nexport const buildReachability = (\n packs: readonly ZapPackOverview[],\n options: ReachabilityOptions = {},\n): Reachability => {\n const maxHops = options.maxHops ?? DEFAULT_MAX_HOPS;\n const allowAsync = options.allowAsyncRoutes ?? false;\n const isTerminal = (edge: ZapPackEdge): boolean =>\n isSync(edge) || (allowAsync && edge.availability === 'future');\n\n const byIn = indexByIn(packs);\n const memo = new Map<string, Map<string, RoutablePair>>();\n const closure = (from: TokenRef): Map<string, RoutablePair> => {\n const key = tokenKey(from);\n const cached = memo.get(key);\n if (cached) return cached;\n const computed = closureFrom({ byIn, from, maxHops, isTerminal });\n memo.set(key, computed);\n return computed;\n };\n\n return {\n maxHops,\n canRoute: (from, to) => closure(from).has(tokenKey(to)),\n routableFrom: (from) => [...closure(from).values()],\n pairs: () => {\n const sources = new Map<string, TokenRef>();\n for (const pack of packs) {\n for (const edge of pack.edges) sources.set(tokenKey(edge.in), edge.in);\n }\n const all: RoutablePair[] = [];\n for (const source of sources.values()) {\n all.push(...closure(source).values());\n }\n return all;\n },\n };\n};\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ZapPackOverview } from './discovery.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Client-side reachability over the zap-pack catalog.
|
|
5
|
+
*
|
|
6
|
+
* `GET /compose/zap-packs` lists single routing edges. `POST /compose/route`
|
|
7
|
+
* chains up to the server's hop budget of them, so the set of routable pairs
|
|
8
|
+
* is the closure of the catalog, not the catalog itself. This module computes
|
|
9
|
+
* that closure locally with the planner's admissibility rule, so an integrator
|
|
10
|
+
* can offer every pair `route` connects without a request per pair.
|
|
11
|
+
*
|
|
12
|
+
* The rule, mirrored from the server's route search:
|
|
13
|
+
*
|
|
14
|
+
* - every edge except the last must leave its output in the proxy for the
|
|
15
|
+
* next edge to consume: no `availability`, no `recipient: 'required'`
|
|
16
|
+
* - the last edge must be synchronous, or `availability: 'future'` when the
|
|
17
|
+
* caller opts into `allowAsyncRoutes`
|
|
18
|
+
* - a route never visits the same token twice
|
|
19
|
+
*
|
|
20
|
+
* Amount bounds (`inAmountMin` / `inAmountMax`) on an intermediate edge
|
|
21
|
+
* cannot be checked without an amount, so a pair reported here is routable
|
|
22
|
+
* structurally, exactly as a listed edge is. Routes that open with a
|
|
23
|
+
* `lifi.swap` are not enumerable and are not reported. The server also
|
|
24
|
+
* drops blacklisted tokens as intermediates, which is server-side config
|
|
25
|
+
* this module cannot see, so a reported pair may still answer
|
|
26
|
+
* `no_route_error`.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** A token identified by address and chain. */
|
|
30
|
+
interface TokenRef {
|
|
31
|
+
readonly address: string;
|
|
32
|
+
readonly chainId: number;
|
|
33
|
+
}
|
|
34
|
+
/** A from/to pair `POST /compose/route` can connect through the catalog. */
|
|
35
|
+
interface RoutablePair {
|
|
36
|
+
readonly in: TokenRef;
|
|
37
|
+
readonly out: TokenRef;
|
|
38
|
+
/** Catalog edges on the shortest admissible route; `1` is a listed edge. */
|
|
39
|
+
readonly hops: number;
|
|
40
|
+
}
|
|
41
|
+
interface ReachabilityOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Hop budget. The server's `no_route_error` reports its effective value in
|
|
44
|
+
* `details.maxHops`; the deployment default is 2.
|
|
45
|
+
*/
|
|
46
|
+
readonly maxHops?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Admit a route whose last edge has `availability: 'future'`. Mirrors the
|
|
49
|
+
* `allowAsyncRoutes` request option; such a pair is a `no_route_error`
|
|
50
|
+
* without it.
|
|
51
|
+
*/
|
|
52
|
+
readonly allowAsyncRoutes?: boolean;
|
|
53
|
+
}
|
|
54
|
+
interface Reachability {
|
|
55
|
+
readonly maxHops: number;
|
|
56
|
+
/** Whether `route` can connect `from` to `to` through the catalog. */
|
|
57
|
+
readonly canRoute: (from: TokenRef, to: TokenRef) => boolean;
|
|
58
|
+
/** Every pair starting at `from`, shortest routes first. */
|
|
59
|
+
readonly routableFrom: (from: TokenRef) => readonly RoutablePair[];
|
|
60
|
+
/** Every routable pair in the catalog. */
|
|
61
|
+
readonly pairs: () => readonly RoutablePair[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Builds a reachability index over the packs returned by
|
|
65
|
+
* {@link ComposeClient.getZapPacks}. Per-source closures are computed on
|
|
66
|
+
* first use and memoised, so `canRoute` on a handful of pairs stays cheap
|
|
67
|
+
* while `pairs()` enumerates everything.
|
|
68
|
+
*/
|
|
69
|
+
declare const buildReachability: (packs: readonly ZapPackOverview[], options?: ReachabilityOptions) => Reachability;
|
|
70
|
+
|
|
71
|
+
export { type Reachability, type ReachabilityOptions, type RoutablePair, type TokenRef, buildReachability };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ZapPackOverview } from './discovery.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Client-side reachability over the zap-pack catalog.
|
|
5
|
+
*
|
|
6
|
+
* `GET /compose/zap-packs` lists single routing edges. `POST /compose/route`
|
|
7
|
+
* chains up to the server's hop budget of them, so the set of routable pairs
|
|
8
|
+
* is the closure of the catalog, not the catalog itself. This module computes
|
|
9
|
+
* that closure locally with the planner's admissibility rule, so an integrator
|
|
10
|
+
* can offer every pair `route` connects without a request per pair.
|
|
11
|
+
*
|
|
12
|
+
* The rule, mirrored from the server's route search:
|
|
13
|
+
*
|
|
14
|
+
* - every edge except the last must leave its output in the proxy for the
|
|
15
|
+
* next edge to consume: no `availability`, no `recipient: 'required'`
|
|
16
|
+
* - the last edge must be synchronous, or `availability: 'future'` when the
|
|
17
|
+
* caller opts into `allowAsyncRoutes`
|
|
18
|
+
* - a route never visits the same token twice
|
|
19
|
+
*
|
|
20
|
+
* Amount bounds (`inAmountMin` / `inAmountMax`) on an intermediate edge
|
|
21
|
+
* cannot be checked without an amount, so a pair reported here is routable
|
|
22
|
+
* structurally, exactly as a listed edge is. Routes that open with a
|
|
23
|
+
* `lifi.swap` are not enumerable and are not reported. The server also
|
|
24
|
+
* drops blacklisted tokens as intermediates, which is server-side config
|
|
25
|
+
* this module cannot see, so a reported pair may still answer
|
|
26
|
+
* `no_route_error`.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
/** A token identified by address and chain. */
|
|
30
|
+
interface TokenRef {
|
|
31
|
+
readonly address: string;
|
|
32
|
+
readonly chainId: number;
|
|
33
|
+
}
|
|
34
|
+
/** A from/to pair `POST /compose/route` can connect through the catalog. */
|
|
35
|
+
interface RoutablePair {
|
|
36
|
+
readonly in: TokenRef;
|
|
37
|
+
readonly out: TokenRef;
|
|
38
|
+
/** Catalog edges on the shortest admissible route; `1` is a listed edge. */
|
|
39
|
+
readonly hops: number;
|
|
40
|
+
}
|
|
41
|
+
interface ReachabilityOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Hop budget. The server's `no_route_error` reports its effective value in
|
|
44
|
+
* `details.maxHops`; the deployment default is 2.
|
|
45
|
+
*/
|
|
46
|
+
readonly maxHops?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Admit a route whose last edge has `availability: 'future'`. Mirrors the
|
|
49
|
+
* `allowAsyncRoutes` request option; such a pair is a `no_route_error`
|
|
50
|
+
* without it.
|
|
51
|
+
*/
|
|
52
|
+
readonly allowAsyncRoutes?: boolean;
|
|
53
|
+
}
|
|
54
|
+
interface Reachability {
|
|
55
|
+
readonly maxHops: number;
|
|
56
|
+
/** Whether `route` can connect `from` to `to` through the catalog. */
|
|
57
|
+
readonly canRoute: (from: TokenRef, to: TokenRef) => boolean;
|
|
58
|
+
/** Every pair starting at `from`, shortest routes first. */
|
|
59
|
+
readonly routableFrom: (from: TokenRef) => readonly RoutablePair[];
|
|
60
|
+
/** Every routable pair in the catalog. */
|
|
61
|
+
readonly pairs: () => readonly RoutablePair[];
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Builds a reachability index over the packs returned by
|
|
65
|
+
* {@link ComposeClient.getZapPacks}. Per-source closures are computed on
|
|
66
|
+
* first use and memoised, so `canRoute` on a handful of pairs stays cheap
|
|
67
|
+
* while `pairs()` enumerates everything.
|
|
68
|
+
*/
|
|
69
|
+
declare const buildReachability: (packs: readonly ZapPackOverview[], options?: ReachabilityOptions) => Reachability;
|
|
70
|
+
|
|
71
|
+
export { type Reachability, type ReachabilityOptions, type RoutablePair, type TokenRef, buildReachability };
|