@lifi/composer-sdk 0.0.1-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +220 -0
- package/dist/authoring/FlowBuilderCore.cjs +115 -0
- package/dist/authoring/FlowBuilderCore.cjs.map +1 -0
- package/dist/authoring/FlowBuilderCore.d.cts +114 -0
- package/dist/authoring/FlowBuilderCore.d.ts +114 -0
- package/dist/authoring/FlowBuilderCore.js +91 -0
- package/dist/authoring/FlowBuilderCore.js.map +1 -0
- package/dist/authoring/handles.cjs +43 -0
- package/dist/authoring/handles.cjs.map +1 -0
- package/dist/authoring/handles.d.cts +61 -0
- package/dist/authoring/handles.d.ts +61 -0
- package/dist/authoring/handles.js +17 -0
- package/dist/authoring/handles.js.map +1 -0
- package/dist/authoring/raw.cjs +41 -0
- package/dist/authoring/raw.cjs.map +1 -0
- package/dist/authoring/raw.d.cts +47 -0
- package/dist/authoring/raw.d.ts +47 -0
- package/dist/authoring/raw.js +16 -0
- package/dist/authoring/raw.js.map +1 -0
- package/dist/authoring/signatureArgs.cjs +114 -0
- package/dist/authoring/signatureArgs.cjs.map +1 -0
- package/dist/authoring/signatureArgs.d.cts +146 -0
- package/dist/authoring/signatureArgs.d.ts +146 -0
- package/dist/authoring/signatureArgs.js +87 -0
- package/dist/authoring/signatureArgs.js.map +1 -0
- package/dist/client.cjs +140 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +67 -0
- package/dist/client.d.ts +67 -0
- package/dist/client.js +116 -0
- package/dist/client.js.map +1 -0
- package/dist/discovery.cjs +17 -0
- package/dist/discovery.cjs.map +1 -0
- package/dist/discovery.d.cts +56 -0
- package/dist/discovery.d.ts +56 -0
- package/dist/discovery.js +1 -0
- package/dist/discovery.js.map +1 -0
- package/dist/errors.cjs +91 -0
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +77 -0
- package/dist/errors.d.ts +77 -0
- package/dist/errors.js +65 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/config.generated.cjs +17 -0
- package/dist/generated/config.generated.cjs.map +1 -0
- package/dist/generated/config.generated.d.cts +144 -0
- package/dist/generated/config.generated.d.ts +144 -0
- package/dist/generated/config.generated.js +1 -0
- package/dist/generated/config.generated.js.map +1 -0
- package/dist/generated/guards.generated.cjs +32 -0
- package/dist/generated/guards.generated.cjs.map +1 -0
- package/dist/generated/guards.generated.d.cts +4 -0
- package/dist/generated/guards.generated.d.ts +4 -0
- package/dist/generated/guards.generated.js +8 -0
- package/dist/generated/guards.generated.js.map +1 -0
- package/dist/generated/materialisers.generated.cjs +44 -0
- package/dist/generated/materialisers.generated.cjs.map +1 -0
- package/dist/generated/materialisers.generated.d.cts +4 -0
- package/dist/generated/materialisers.generated.d.ts +4 -0
- package/dist/generated/materialisers.generated.js +18 -0
- package/dist/generated/materialisers.generated.js.map +1 -0
- package/dist/generated/operations.generated.cjs +110 -0
- package/dist/generated/operations.generated.cjs.map +1 -0
- package/dist/generated/operations.generated.d.cts +337 -0
- package/dist/generated/operations.generated.d.ts +337 -0
- package/dist/generated/operations.generated.js +89 -0
- package/dist/generated/operations.generated.js.map +1 -0
- package/dist/generated/preconditions.generated.cjs +44 -0
- package/dist/generated/preconditions.generated.cjs.map +1 -0
- package/dist/generated/preconditions.generated.d.cts +4 -0
- package/dist/generated/preconditions.generated.d.ts +4 -0
- package/dist/generated/preconditions.generated.js +18 -0
- package/dist/generated/preconditions.generated.js.map +1 -0
- package/dist/guards.generated-DKKDKREA.d.ts +14 -0
- package/dist/guards.generated-hrQ1KPNv.d.cts +14 -0
- package/dist/index.cjs +76 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +99 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/materialisers.generated-BsA1uDW8.d.ts +24 -0
- package/dist/materialisers.generated-nMxTAaVi.d.cts +24 -0
- package/dist/preconditions.generated-DblS13Wq.d.cts +24 -0
- package/dist/preconditions.generated-U7YpVh30.d.ts +24 -0
- package/dist/raw-Dj_2rBSQ.d.cts +19 -0
- package/dist/raw-IxCF_bSS.d.ts +19 -0
- package/dist/raw.cjs +34 -0
- package/dist/raw.cjs.map +1 -0
- package/dist/raw.d.cts +4 -0
- package/dist/raw.d.ts +4 -0
- package/dist/raw.js +8 -0
- package/dist/raw.js.map +1 -0
- package/dist/resources-BKlFxjo8.d.cts +56 -0
- package/dist/resources-CYis1_DS.d.ts +56 -0
- package/dist/resources.cjs +39 -0
- package/dist/resources.cjs.map +1 -0
- package/dist/resources.d.cts +3 -0
- package/dist/resources.d.ts +3 -0
- package/dist/resources.js +14 -0
- package/dist/resources.js.map +1 -0
- package/dist/run/inputs.cjs +51 -0
- package/dist/run/inputs.cjs.map +1 -0
- package/dist/run/inputs.d.cts +91 -0
- package/dist/run/inputs.d.ts +91 -0
- package/dist/run/inputs.js +26 -0
- package/dist/run/inputs.js.map +1 -0
- package/dist/sdk.cjs +60 -0
- package/dist/sdk.cjs.map +1 -0
- package/dist/sdk.d.cts +112 -0
- package/dist/sdk.d.ts +112 -0
- package/dist/sdk.js +40 -0
- package/dist/sdk.js.map +1 -0
- package/dist/types.cjs +17 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +74 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/package.json +81 -0
- package/src/authoring/FlowBuilderCore.ts +270 -0
- package/src/authoring/handles.ts +81 -0
- package/src/authoring/raw.ts +60 -0
- package/src/authoring/signatureArgs.ts +249 -0
- package/src/client.ts +230 -0
- package/src/discovery.ts +51 -0
- package/src/errors.ts +150 -0
- package/src/examples/approveAndDeposit.ts +84 -0
- package/src/examples/callContract.ts +199 -0
- package/src/examples/config.ts +9 -0
- package/src/examples/consolidateToEth.ts +94 -0
- package/src/examples/consolidateToUsdc.ts +95 -0
- package/src/examples/depositFromProxy.ts +87 -0
- package/src/examples/dustSweep.ts +66 -0
- package/src/examples/lifiSwap.ts +56 -0
- package/src/examples/lifiZap.ts +60 -0
- package/src/examples/rawCallWithArithmetic.ts +78 -0
- package/src/examples/readContractState.ts +77 -0
- package/src/examples/run.ts +168 -0
- package/src/examples/splitAndZap.ts +73 -0
- package/src/examples/splitWithArithmetic.ts +93 -0
- package/src/examples/swapAndZap.ts +72 -0
- package/src/examples/swapToRecipient.ts +109 -0
- package/src/examples/swapWithAllowRevert.ts +119 -0
- package/src/examples/swapWithBalanceCheck.ts +73 -0
- package/src/examples/swapWithOutputValidation.ts +125 -0
- package/src/examples/transferTokens.ts +123 -0
- package/src/examples/untypedOpWithTypedRef.ts +77 -0
- package/src/generated/config.generated.ts +174 -0
- package/src/generated/guards.generated.ts +14 -0
- package/src/generated/materialisers.generated.ts +44 -0
- package/src/generated/operations.generated.ts +568 -0
- package/src/generated/preconditions.generated.ts +43 -0
- package/src/index.ts +149 -0
- package/src/raw.ts +10 -0
- package/src/resources.ts +61 -0
- package/src/run/inputs.ts +117 -0
- package/src/sdk.ts +173 -0
- package/src/types.ts +101 -0
package/dist/client.cjs
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
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 client_exports = {};
|
|
20
|
+
__export(client_exports, {
|
|
21
|
+
createComposeClient: () => createComposeClient
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(client_exports);
|
|
24
|
+
var import_errors = require("./errors.js");
|
|
25
|
+
const SDK_VERSION = true ? "0.0.1-alpha" : "dev";
|
|
26
|
+
const bigintReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
|
|
27
|
+
const isNonNullObject = (v) => typeof v === "object" && v !== null;
|
|
28
|
+
const parseBody = async (res, url) => {
|
|
29
|
+
const body = await res.json().catch((_) => null);
|
|
30
|
+
if (!isNonNullObject(body) || !("data" in body)) {
|
|
31
|
+
throw new import_errors.ComposeError("UNKNOWN_ERROR", "Unexpected response format", {
|
|
32
|
+
url
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
return body.data;
|
|
36
|
+
};
|
|
37
|
+
const parseCompileSuccessBody = async (res, url) => {
|
|
38
|
+
const data = await parseBody(res, url);
|
|
39
|
+
return { ...data, status: "success" };
|
|
40
|
+
};
|
|
41
|
+
const parsePartialBody = async (res, url) => {
|
|
42
|
+
const body = await res.json().catch((_) => null);
|
|
43
|
+
if (!isNonNullObject(body) || !("data" in body) || !isNonNullObject(body.data) || !("error" in body) || !isNonNullObject(body.error)) {
|
|
44
|
+
throw new import_errors.ComposeError(
|
|
45
|
+
"UNKNOWN_ERROR",
|
|
46
|
+
"Unexpected partial response format",
|
|
47
|
+
{ url }
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const data = body.data;
|
|
51
|
+
const error = body.error;
|
|
52
|
+
return { ...data, status: "partial", error };
|
|
53
|
+
};
|
|
54
|
+
const createComposeClient = (options) => {
|
|
55
|
+
if (!options.baseUrl || !/^https?:\/\//i.test(options.baseUrl)) {
|
|
56
|
+
throw new import_errors.ComposeError(
|
|
57
|
+
"VALIDATION_ERROR",
|
|
58
|
+
`Invalid baseUrl: expected an HTTP(S) URL, got "${options.baseUrl}"`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
62
|
+
const base = options.baseUrl.replace(/\/$/, "");
|
|
63
|
+
const trimmedApiKey = options.apiKey?.trim() || void 0;
|
|
64
|
+
const baseHeaders = {
|
|
65
|
+
Accept: "application/json",
|
|
66
|
+
"x-lifi-composer-sdk": SDK_VERSION,
|
|
67
|
+
...trimmedApiKey ? { "x-lifi-api-key": trimmedApiKey } : {}
|
|
68
|
+
};
|
|
69
|
+
const getManifest = async () => {
|
|
70
|
+
const url = `${base}/compose/manifest`;
|
|
71
|
+
let res;
|
|
72
|
+
try {
|
|
73
|
+
res = await fetchFn(url, {
|
|
74
|
+
method: "GET",
|
|
75
|
+
headers: { ...baseHeaders }
|
|
76
|
+
});
|
|
77
|
+
} catch (err) {
|
|
78
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
79
|
+
throw new import_errors.ComposeError("NETWORK_ERROR", message, { cause: err });
|
|
80
|
+
}
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
const body = await res.text();
|
|
83
|
+
throw (0, import_errors.errorFromHttpResponse)(res.status, body, url);
|
|
84
|
+
}
|
|
85
|
+
return await parseBody(res, url);
|
|
86
|
+
};
|
|
87
|
+
const compile = async (request) => {
|
|
88
|
+
const url = `${base}/compose`;
|
|
89
|
+
let res;
|
|
90
|
+
try {
|
|
91
|
+
res = await fetchFn(url, {
|
|
92
|
+
method: "POST",
|
|
93
|
+
headers: { ...baseHeaders, "Content-Type": "application/json" },
|
|
94
|
+
body: JSON.stringify(request, bigintReplacer)
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
98
|
+
throw new import_errors.ComposeError("NETWORK_ERROR", message, { cause: err });
|
|
99
|
+
}
|
|
100
|
+
if (res.status === 206) {
|
|
101
|
+
return await parsePartialBody(res, url);
|
|
102
|
+
}
|
|
103
|
+
if (!res.ok) {
|
|
104
|
+
const body = await res.text();
|
|
105
|
+
throw (0, import_errors.errorFromHttpResponse)(res.status, body, url);
|
|
106
|
+
}
|
|
107
|
+
return await parseCompileSuccessBody(res, url);
|
|
108
|
+
};
|
|
109
|
+
const getZapPacks = async (options2) => {
|
|
110
|
+
const params = new URLSearchParams();
|
|
111
|
+
if (options2?.protocols != null) {
|
|
112
|
+
const raw = options2.protocols;
|
|
113
|
+
const list = typeof raw === "string" ? raw : raw.join(",");
|
|
114
|
+
params.set("protocols", list);
|
|
115
|
+
}
|
|
116
|
+
const qs = params.toString();
|
|
117
|
+
const url = `${base}/compose/zap-packs${qs ? `?${qs}` : ""}`;
|
|
118
|
+
let res;
|
|
119
|
+
try {
|
|
120
|
+
res = await fetchFn(url, {
|
|
121
|
+
method: "GET",
|
|
122
|
+
headers: { ...baseHeaders }
|
|
123
|
+
});
|
|
124
|
+
} catch (err) {
|
|
125
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
126
|
+
throw new import_errors.ComposeError("NETWORK_ERROR", message, { cause: err });
|
|
127
|
+
}
|
|
128
|
+
if (!res.ok) {
|
|
129
|
+
const body = await res.text();
|
|
130
|
+
throw (0, import_errors.errorFromHttpResponse)(res.status, body, url);
|
|
131
|
+
}
|
|
132
|
+
return await parseBody(res, url);
|
|
133
|
+
};
|
|
134
|
+
return { getManifest, compile, getZapPacks };
|
|
135
|
+
};
|
|
136
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
137
|
+
0 && (module.exports = {
|
|
138
|
+
createComposeClient
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type {\n ComposeCompilePartialData,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeManifest,\n} from '@lifi/compose-spec';\n\nimport type { GetZapPacksOptions, ZapPackOverview } from './discovery.js';\nimport { ComposeError, errorFromHttpResponse } from './errors.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 /** Optional LI.FI API key. When set, sent as the `x-lifi-api-key` header on every request. */\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 * 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\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 if (\n !isNonNullObject(body) ||\n !('data' in body) ||\n !isNonNullObject(body.data) ||\n !('error' in body) ||\n !isNonNullObject(body.error)\n ) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n 'Unexpected partial response format',\n { url },\n );\n }\n const data = body.data as unknown as ComposeCompilePartialData;\n const error = body.error as unknown as { kind: string; message: string };\n return { ...data, status: 'partial' as const, error };\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 fetchFn = options.fetch ?? globalThis.fetch;\n const base = options.baseUrl.replace(/\\/$/, '');\n\n const trimmedApiKey = options.apiKey?.trim() || undefined;\n\n const baseHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'x-lifi-composer-sdk': SDK_VERSION,\n ...(trimmedApiKey ? { 'x-lifi-api-key': trimmedApiKey } : {}),\n };\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 const url = `${base}/compose`;\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 const getZapPacks = async (\n options?: GetZapPacksOptions,\n ): Promise<readonly ZapPackOverview[]> => {\n const params = new URLSearchParams();\n if (options?.protocols != null) {\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 return { getManifest, compile, getZapPacks };\n};\n"],"mappings":"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","names":["options"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ComposeManifest, ComposeCompileRequest, ComposeCompileResult } from '@lifi/compose-spec';
|
|
2
|
+
import { GetZapPacksOptions, ZapPackOverview } from './discovery.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for creating a low-level Compose API client.
|
|
6
|
+
*/
|
|
7
|
+
interface ComposeClientOptions {
|
|
8
|
+
/** Base URL of the Compose API. */
|
|
9
|
+
readonly baseUrl: string;
|
|
10
|
+
/** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */
|
|
11
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
12
|
+
/** Optional LI.FI API key. When set, sent as the `x-lifi-api-key` header on every request. */
|
|
13
|
+
readonly apiKey?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Low-level HTTP client for the Compose API.
|
|
17
|
+
*
|
|
18
|
+
* Handles request serialization, SDK version headers, and error mapping.
|
|
19
|
+
* Prefer using {@link ComposeSdk} for the full builder experience. Use this
|
|
20
|
+
* directly when you need to decouple request building from submission — e.g.
|
|
21
|
+
* build via `sdk.request()` then submit via `client.compile()` with custom
|
|
22
|
+
* retry logic or request inspection.
|
|
23
|
+
*/
|
|
24
|
+
interface ComposeClient {
|
|
25
|
+
/**
|
|
26
|
+
* Fetches the server's operation manifest describing all supported operations,
|
|
27
|
+
* guards, materialisers, and preconditions.
|
|
28
|
+
* @returns The manifest document.
|
|
29
|
+
* @throws {@link ComposeError} on network, validation, or server errors.
|
|
30
|
+
*/
|
|
31
|
+
readonly getManifest: () => Promise<ComposeManifest>;
|
|
32
|
+
/**
|
|
33
|
+
* Submits a compile request and returns the result.
|
|
34
|
+
*
|
|
35
|
+
* When the caller passes `simulationPolicy: 'allow-revert'` and the transaction
|
|
36
|
+
* reverts in simulation, the server responds with HTTP 206 and the SDK returns a
|
|
37
|
+
* partial result (`status: 'partial'`) instead of throwing. The partial result
|
|
38
|
+
* includes the transaction (without `gasLimit`) and revert diagnostics.
|
|
39
|
+
*
|
|
40
|
+
* @param request - The full compile request including flow and run inputs.
|
|
41
|
+
* @returns A discriminated result: `status: 'success'` or `status: 'partial'`.
|
|
42
|
+
* @throws {@link ComposeError} on network, validation, or server errors.
|
|
43
|
+
*/
|
|
44
|
+
readonly compile: (request: ComposeCompileRequest) => Promise<ComposeCompileResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Fetches the available routing edges grouped by protocol.
|
|
47
|
+
*
|
|
48
|
+
* The edge catalog is dynamic — it reflects the current state of the
|
|
49
|
+
* backend's routing snapshot (protocols, chains, token blacklists).
|
|
50
|
+
* Results are not cached by the SDK; callers should cache as appropriate.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Optional filter to restrict results to specific protocols.
|
|
53
|
+
* @returns An array of {@link ZapPackOverview} objects, one per protocol.
|
|
54
|
+
* @throws {@link ComposeError} on network or server errors (503 when the
|
|
55
|
+
* routing catalog is not yet initialized).
|
|
56
|
+
*/
|
|
57
|
+
readonly getZapPacks: (options?: GetZapPacksOptions) => Promise<readonly ZapPackOverview[]>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Creates a low-level Compose API client.
|
|
61
|
+
*
|
|
62
|
+
* @param options - Client configuration including the API base URL.
|
|
63
|
+
* @returns A {@link ComposeClient} instance.
|
|
64
|
+
*/
|
|
65
|
+
declare const createComposeClient: (options: ComposeClientOptions) => ComposeClient;
|
|
66
|
+
|
|
67
|
+
export { type ComposeClient, type ComposeClientOptions, createComposeClient };
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { ComposeManifest, ComposeCompileRequest, ComposeCompileResult } from '@lifi/compose-spec';
|
|
2
|
+
import { GetZapPacksOptions, ZapPackOverview } from './discovery.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for creating a low-level Compose API client.
|
|
6
|
+
*/
|
|
7
|
+
interface ComposeClientOptions {
|
|
8
|
+
/** Base URL of the Compose API. */
|
|
9
|
+
readonly baseUrl: string;
|
|
10
|
+
/** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */
|
|
11
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
12
|
+
/** Optional LI.FI API key. When set, sent as the `x-lifi-api-key` header on every request. */
|
|
13
|
+
readonly apiKey?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Low-level HTTP client for the Compose API.
|
|
17
|
+
*
|
|
18
|
+
* Handles request serialization, SDK version headers, and error mapping.
|
|
19
|
+
* Prefer using {@link ComposeSdk} for the full builder experience. Use this
|
|
20
|
+
* directly when you need to decouple request building from submission — e.g.
|
|
21
|
+
* build via `sdk.request()` then submit via `client.compile()` with custom
|
|
22
|
+
* retry logic or request inspection.
|
|
23
|
+
*/
|
|
24
|
+
interface ComposeClient {
|
|
25
|
+
/**
|
|
26
|
+
* Fetches the server's operation manifest describing all supported operations,
|
|
27
|
+
* guards, materialisers, and preconditions.
|
|
28
|
+
* @returns The manifest document.
|
|
29
|
+
* @throws {@link ComposeError} on network, validation, or server errors.
|
|
30
|
+
*/
|
|
31
|
+
readonly getManifest: () => Promise<ComposeManifest>;
|
|
32
|
+
/**
|
|
33
|
+
* Submits a compile request and returns the result.
|
|
34
|
+
*
|
|
35
|
+
* When the caller passes `simulationPolicy: 'allow-revert'` and the transaction
|
|
36
|
+
* reverts in simulation, the server responds with HTTP 206 and the SDK returns a
|
|
37
|
+
* partial result (`status: 'partial'`) instead of throwing. The partial result
|
|
38
|
+
* includes the transaction (without `gasLimit`) and revert diagnostics.
|
|
39
|
+
*
|
|
40
|
+
* @param request - The full compile request including flow and run inputs.
|
|
41
|
+
* @returns A discriminated result: `status: 'success'` or `status: 'partial'`.
|
|
42
|
+
* @throws {@link ComposeError} on network, validation, or server errors.
|
|
43
|
+
*/
|
|
44
|
+
readonly compile: (request: ComposeCompileRequest) => Promise<ComposeCompileResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Fetches the available routing edges grouped by protocol.
|
|
47
|
+
*
|
|
48
|
+
* The edge catalog is dynamic — it reflects the current state of the
|
|
49
|
+
* backend's routing snapshot (protocols, chains, token blacklists).
|
|
50
|
+
* Results are not cached by the SDK; callers should cache as appropriate.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Optional filter to restrict results to specific protocols.
|
|
53
|
+
* @returns An array of {@link ZapPackOverview} objects, one per protocol.
|
|
54
|
+
* @throws {@link ComposeError} on network or server errors (503 when the
|
|
55
|
+
* routing catalog is not yet initialized).
|
|
56
|
+
*/
|
|
57
|
+
readonly getZapPacks: (options?: GetZapPacksOptions) => Promise<readonly ZapPackOverview[]>;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Creates a low-level Compose API client.
|
|
61
|
+
*
|
|
62
|
+
* @param options - Client configuration including the API base URL.
|
|
63
|
+
* @returns A {@link ComposeClient} instance.
|
|
64
|
+
*/
|
|
65
|
+
declare const createComposeClient: (options: ComposeClientOptions) => ComposeClient;
|
|
66
|
+
|
|
67
|
+
export { type ComposeClient, type ComposeClientOptions, createComposeClient };
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ComposeError, errorFromHttpResponse } from "./errors.js";
|
|
2
|
+
const SDK_VERSION = true ? "0.0.1-alpha" : "dev";
|
|
3
|
+
const bigintReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
|
|
4
|
+
const isNonNullObject = (v) => typeof v === "object" && v !== null;
|
|
5
|
+
const parseBody = async (res, url) => {
|
|
6
|
+
const body = await res.json().catch((_) => null);
|
|
7
|
+
if (!isNonNullObject(body) || !("data" in body)) {
|
|
8
|
+
throw new ComposeError("UNKNOWN_ERROR", "Unexpected response format", {
|
|
9
|
+
url
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return body.data;
|
|
13
|
+
};
|
|
14
|
+
const parseCompileSuccessBody = async (res, url) => {
|
|
15
|
+
const data = await parseBody(res, url);
|
|
16
|
+
return { ...data, status: "success" };
|
|
17
|
+
};
|
|
18
|
+
const parsePartialBody = async (res, url) => {
|
|
19
|
+
const body = await res.json().catch((_) => null);
|
|
20
|
+
if (!isNonNullObject(body) || !("data" in body) || !isNonNullObject(body.data) || !("error" in body) || !isNonNullObject(body.error)) {
|
|
21
|
+
throw new ComposeError(
|
|
22
|
+
"UNKNOWN_ERROR",
|
|
23
|
+
"Unexpected partial response format",
|
|
24
|
+
{ url }
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const data = body.data;
|
|
28
|
+
const error = body.error;
|
|
29
|
+
return { ...data, status: "partial", error };
|
|
30
|
+
};
|
|
31
|
+
const createComposeClient = (options) => {
|
|
32
|
+
if (!options.baseUrl || !/^https?:\/\//i.test(options.baseUrl)) {
|
|
33
|
+
throw new ComposeError(
|
|
34
|
+
"VALIDATION_ERROR",
|
|
35
|
+
`Invalid baseUrl: expected an HTTP(S) URL, got "${options.baseUrl}"`
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
39
|
+
const base = options.baseUrl.replace(/\/$/, "");
|
|
40
|
+
const trimmedApiKey = options.apiKey?.trim() || void 0;
|
|
41
|
+
const baseHeaders = {
|
|
42
|
+
Accept: "application/json",
|
|
43
|
+
"x-lifi-composer-sdk": SDK_VERSION,
|
|
44
|
+
...trimmedApiKey ? { "x-lifi-api-key": trimmedApiKey } : {}
|
|
45
|
+
};
|
|
46
|
+
const getManifest = async () => {
|
|
47
|
+
const url = `${base}/compose/manifest`;
|
|
48
|
+
let res;
|
|
49
|
+
try {
|
|
50
|
+
res = await fetchFn(url, {
|
|
51
|
+
method: "GET",
|
|
52
|
+
headers: { ...baseHeaders }
|
|
53
|
+
});
|
|
54
|
+
} catch (err) {
|
|
55
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
56
|
+
throw new ComposeError("NETWORK_ERROR", message, { cause: err });
|
|
57
|
+
}
|
|
58
|
+
if (!res.ok) {
|
|
59
|
+
const body = await res.text();
|
|
60
|
+
throw errorFromHttpResponse(res.status, body, url);
|
|
61
|
+
}
|
|
62
|
+
return await parseBody(res, url);
|
|
63
|
+
};
|
|
64
|
+
const compile = async (request) => {
|
|
65
|
+
const url = `${base}/compose`;
|
|
66
|
+
let res;
|
|
67
|
+
try {
|
|
68
|
+
res = await fetchFn(url, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: { ...baseHeaders, "Content-Type": "application/json" },
|
|
71
|
+
body: JSON.stringify(request, bigintReplacer)
|
|
72
|
+
});
|
|
73
|
+
} catch (err) {
|
|
74
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
75
|
+
throw new ComposeError("NETWORK_ERROR", message, { cause: err });
|
|
76
|
+
}
|
|
77
|
+
if (res.status === 206) {
|
|
78
|
+
return await parsePartialBody(res, url);
|
|
79
|
+
}
|
|
80
|
+
if (!res.ok) {
|
|
81
|
+
const body = await res.text();
|
|
82
|
+
throw errorFromHttpResponse(res.status, body, url);
|
|
83
|
+
}
|
|
84
|
+
return await parseCompileSuccessBody(res, url);
|
|
85
|
+
};
|
|
86
|
+
const getZapPacks = async (options2) => {
|
|
87
|
+
const params = new URLSearchParams();
|
|
88
|
+
if (options2?.protocols != null) {
|
|
89
|
+
const raw = options2.protocols;
|
|
90
|
+
const list = typeof raw === "string" ? raw : raw.join(",");
|
|
91
|
+
params.set("protocols", list);
|
|
92
|
+
}
|
|
93
|
+
const qs = params.toString();
|
|
94
|
+
const url = `${base}/compose/zap-packs${qs ? `?${qs}` : ""}`;
|
|
95
|
+
let res;
|
|
96
|
+
try {
|
|
97
|
+
res = await fetchFn(url, {
|
|
98
|
+
method: "GET",
|
|
99
|
+
headers: { ...baseHeaders }
|
|
100
|
+
});
|
|
101
|
+
} catch (err) {
|
|
102
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
103
|
+
throw new ComposeError("NETWORK_ERROR", message, { cause: err });
|
|
104
|
+
}
|
|
105
|
+
if (!res.ok) {
|
|
106
|
+
const body = await res.text();
|
|
107
|
+
throw errorFromHttpResponse(res.status, body, url);
|
|
108
|
+
}
|
|
109
|
+
return await parseBody(res, url);
|
|
110
|
+
};
|
|
111
|
+
return { getManifest, compile, getZapPacks };
|
|
112
|
+
};
|
|
113
|
+
export {
|
|
114
|
+
createComposeClient
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type {\n ComposeCompilePartialData,\n ComposeCompileRequest,\n ComposeCompileResult,\n ComposeCompileSuccessData,\n ComposeManifest,\n} from '@lifi/compose-spec';\n\nimport type { GetZapPacksOptions, ZapPackOverview } from './discovery.js';\nimport { ComposeError, errorFromHttpResponse } from './errors.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 /** Optional LI.FI API key. When set, sent as the `x-lifi-api-key` header on every request. */\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 * 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\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 if (\n !isNonNullObject(body) ||\n !('data' in body) ||\n !isNonNullObject(body.data) ||\n !('error' in body) ||\n !isNonNullObject(body.error)\n ) {\n throw new ComposeError(\n 'UNKNOWN_ERROR',\n 'Unexpected partial response format',\n { url },\n );\n }\n const data = body.data as unknown as ComposeCompilePartialData;\n const error = body.error as unknown as { kind: string; message: string };\n return { ...data, status: 'partial' as const, error };\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 fetchFn = options.fetch ?? globalThis.fetch;\n const base = options.baseUrl.replace(/\\/$/, '');\n\n const trimmedApiKey = options.apiKey?.trim() || undefined;\n\n const baseHeaders: Record<string, string> = {\n Accept: 'application/json',\n 'x-lifi-composer-sdk': SDK_VERSION,\n ...(trimmedApiKey ? { 'x-lifi-api-key': trimmedApiKey } : {}),\n };\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 const url = `${base}/compose`;\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 const getZapPacks = async (\n options?: GetZapPacksOptions,\n ): Promise<readonly ZapPackOverview[]> => {\n const params = new URLSearchParams();\n if (options?.protocols != null) {\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 return { getManifest, compile, getZapPacks };\n};\n"],"mappings":"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","names":["options"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
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 __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var discovery_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(discovery_exports);
|
|
17
|
+
//# sourceMappingURL=discovery.cjs.map
|
|
@@ -0,0 +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\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":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Compose discovery API (`GET /compose/zap-packs`).
|
|
3
|
+
*
|
|
4
|
+
* These are SDK-facing presentation types — not part of the core compile
|
|
5
|
+
* contract in compose-spec. The backend response is the source of truth;
|
|
6
|
+
* the SDK provides typed access.
|
|
7
|
+
*
|
|
8
|
+
* The `type` field on edges is a plain `string` rather than a strict union
|
|
9
|
+
* so the SDK remains forward-compatible when the backend introduces new
|
|
10
|
+
* edge types. Known values at time of writing:
|
|
11
|
+
* `"enter-position"`, `"exit-position"`, `"wrap"`, `"unwrap"`, `"mint"`, `"burn"`.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* A single routing edge representing a supported token-to-token path
|
|
15
|
+
* through a DeFi protocol.
|
|
16
|
+
*/
|
|
17
|
+
interface ZapPackEdge {
|
|
18
|
+
/** Edge type (e.g. `"enter-position"`, `"exit-position"`, `"wrap"`). */
|
|
19
|
+
readonly type: string;
|
|
20
|
+
/** Input token. */
|
|
21
|
+
readonly in: {
|
|
22
|
+
readonly address: string;
|
|
23
|
+
readonly chainId: number;
|
|
24
|
+
};
|
|
25
|
+
/** Output token. */
|
|
26
|
+
readonly out: {
|
|
27
|
+
readonly address: string;
|
|
28
|
+
readonly chainId: number;
|
|
29
|
+
};
|
|
30
|
+
/** Minimum input amount accepted (stringified integer), if constrained. */
|
|
31
|
+
readonly inAmountMin?: string;
|
|
32
|
+
/** Maximum input amount accepted (stringified integer), if constrained. */
|
|
33
|
+
readonly inAmountMax?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* All routing edges for a single protocol.
|
|
37
|
+
*/
|
|
38
|
+
interface ZapPackOverview {
|
|
39
|
+
/** Protocol identifier (e.g. `"aave"`, `"morpho"`). */
|
|
40
|
+
readonly protocol: string;
|
|
41
|
+
/** Available routing edges for this protocol. */
|
|
42
|
+
readonly edges: readonly ZapPackEdge[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Options for {@link ComposeClient.getZapPacks}.
|
|
46
|
+
*/
|
|
47
|
+
interface GetZapPacksOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Filter to specific protocols. Pass a single string or an array.
|
|
50
|
+
* Only edges belonging to the listed protocols are returned.
|
|
51
|
+
* Omit to fetch all available protocols.
|
|
52
|
+
*/
|
|
53
|
+
readonly protocols?: string | readonly string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type { GetZapPacksOptions, ZapPackEdge, ZapPackOverview };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Compose discovery API (`GET /compose/zap-packs`).
|
|
3
|
+
*
|
|
4
|
+
* These are SDK-facing presentation types — not part of the core compile
|
|
5
|
+
* contract in compose-spec. The backend response is the source of truth;
|
|
6
|
+
* the SDK provides typed access.
|
|
7
|
+
*
|
|
8
|
+
* The `type` field on edges is a plain `string` rather than a strict union
|
|
9
|
+
* so the SDK remains forward-compatible when the backend introduces new
|
|
10
|
+
* edge types. Known values at time of writing:
|
|
11
|
+
* `"enter-position"`, `"exit-position"`, `"wrap"`, `"unwrap"`, `"mint"`, `"burn"`.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* A single routing edge representing a supported token-to-token path
|
|
15
|
+
* through a DeFi protocol.
|
|
16
|
+
*/
|
|
17
|
+
interface ZapPackEdge {
|
|
18
|
+
/** Edge type (e.g. `"enter-position"`, `"exit-position"`, `"wrap"`). */
|
|
19
|
+
readonly type: string;
|
|
20
|
+
/** Input token. */
|
|
21
|
+
readonly in: {
|
|
22
|
+
readonly address: string;
|
|
23
|
+
readonly chainId: number;
|
|
24
|
+
};
|
|
25
|
+
/** Output token. */
|
|
26
|
+
readonly out: {
|
|
27
|
+
readonly address: string;
|
|
28
|
+
readonly chainId: number;
|
|
29
|
+
};
|
|
30
|
+
/** Minimum input amount accepted (stringified integer), if constrained. */
|
|
31
|
+
readonly inAmountMin?: string;
|
|
32
|
+
/** Maximum input amount accepted (stringified integer), if constrained. */
|
|
33
|
+
readonly inAmountMax?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* All routing edges for a single protocol.
|
|
37
|
+
*/
|
|
38
|
+
interface ZapPackOverview {
|
|
39
|
+
/** Protocol identifier (e.g. `"aave"`, `"morpho"`). */
|
|
40
|
+
readonly protocol: string;
|
|
41
|
+
/** Available routing edges for this protocol. */
|
|
42
|
+
readonly edges: readonly ZapPackEdge[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Options for {@link ComposeClient.getZapPacks}.
|
|
46
|
+
*/
|
|
47
|
+
interface GetZapPacksOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Filter to specific protocols. Pass a single string or an array.
|
|
50
|
+
* Only edges belonging to the listed protocols are returned.
|
|
51
|
+
* Omit to fetch all available protocols.
|
|
52
|
+
*/
|
|
53
|
+
readonly protocols?: string | readonly string[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type { GetZapPacksOptions, ZapPackEdge, ZapPackOverview };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|