@lifi/composer-sdk 0.2.0-staging.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +103 -2
  2. package/dist/client.cjs +46 -8
  3. package/dist/client.cjs.map +1 -1
  4. package/dist/client.d.cts +27 -3
  5. package/dist/client.d.ts +27 -3
  6. package/dist/client.js +49 -8
  7. package/dist/client.js.map +1 -1
  8. package/dist/errors.cjs +4 -1
  9. package/dist/errors.cjs.map +1 -1
  10. package/dist/errors.js +6 -1
  11. package/dist/errors.js.map +1 -1
  12. package/dist/generated/config.generated.cjs.map +1 -1
  13. package/dist/generated/config.generated.d.cts +80 -20
  14. package/dist/generated/config.generated.d.ts +80 -20
  15. package/dist/generated/materialisers.generated.cjs +2 -8
  16. package/dist/generated/materialisers.generated.cjs.map +1 -1
  17. package/dist/generated/materialisers.generated.d.cts +1 -1
  18. package/dist/generated/materialisers.generated.d.ts +1 -1
  19. package/dist/generated/materialisers.generated.js +1 -6
  20. package/dist/generated/materialisers.generated.js.map +1 -1
  21. package/dist/generated/operations.generated.cjs +1 -30
  22. package/dist/generated/operations.generated.cjs.map +1 -1
  23. package/dist/generated/operations.generated.d.cts +2 -94
  24. package/dist/generated/operations.generated.d.ts +2 -94
  25. package/dist/generated/operations.generated.js +1 -30
  26. package/dist/generated/operations.generated.js.map +1 -1
  27. package/dist/index.cjs +8 -0
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +4 -3
  30. package/dist/index.d.ts +4 -3
  31. package/dist/index.js +8 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/{materialisers.generated-BfWJ-g7t.d.ts → materialisers.generated-BMkBQgWZ.d.ts} +3 -8
  34. package/dist/{materialisers.generated-DaJRwiRe.d.cts → materialisers.generated-BWq5oePO.d.cts} +3 -8
  35. package/dist/responseSchemas.cjs +110 -0
  36. package/dist/responseSchemas.cjs.map +1 -0
  37. package/dist/responseSchemas.d.cts +36 -0
  38. package/dist/responseSchemas.d.ts +36 -0
  39. package/dist/responseSchemas.js +74 -0
  40. package/dist/responseSchemas.js.map +1 -0
  41. package/dist/run/simulate.cjs +41 -0
  42. package/dist/run/simulate.cjs.map +1 -0
  43. package/dist/run/simulate.d.cts +59 -0
  44. package/dist/run/simulate.d.ts +59 -0
  45. package/dist/run/simulate.js +17 -0
  46. package/dist/run/simulate.js.map +1 -0
  47. package/dist/sdk.cjs +6 -1
  48. package/dist/sdk.cjs.map +1 -1
  49. package/dist/sdk.d.cts +18 -6
  50. package/dist/sdk.d.ts +18 -6
  51. package/dist/sdk.js +6 -1
  52. package/dist/sdk.js.map +1 -1
  53. package/package.json +8 -6
  54. package/src/client.ts +96 -16
  55. package/src/errors.ts +8 -10
  56. package/src/examples/aaveClaimRewards.ts +2 -2
  57. package/src/examples/aaveRepay.ts +2 -2
  58. package/src/examples/aaveRepayWithATokens.ts +2 -2
  59. package/src/examples/aaveSetEMode.ts +2 -2
  60. package/src/examples/approveAndDeposit.ts +2 -2
  61. package/src/examples/callContract.ts +4 -4
  62. package/src/examples/config.ts +4 -1
  63. package/src/examples/consolidateToEth.ts +2 -2
  64. package/src/examples/consolidateToUsdc.ts +2 -2
  65. package/src/examples/depositFromProxy.ts +2 -2
  66. package/src/examples/dustSweep.ts +2 -2
  67. package/src/examples/emitCustomEvent.ts +2 -2
  68. package/src/examples/invariantChecks.ts +2 -2
  69. package/src/examples/lifiSwap.ts +2 -2
  70. package/src/examples/lifiZap.ts +2 -2
  71. package/src/examples/rawCallWithArithmetic.ts +2 -2
  72. package/src/examples/readContractState.ts +2 -2
  73. package/src/examples/simulateCompiledSwap.ts +76 -0
  74. package/src/examples/simulateRawTransaction.ts +39 -0
  75. package/src/examples/splitAndZap.ts +2 -2
  76. package/src/examples/splitWithArithmetic.ts +2 -2
  77. package/src/examples/swapAndZap.ts +2 -2
  78. package/src/examples/swapToRecipient.ts +2 -2
  79. package/src/examples/swapWithAllowRevert.ts +3 -3
  80. package/src/examples/swapWithBalanceCheck.ts +2 -2
  81. package/src/examples/swapWithFee.ts +2 -2
  82. package/src/examples/swapWithOutputValidation.ts +2 -2
  83. package/src/examples/transferTokens.ts +3 -3
  84. package/src/examples/untypedOpWithTypedRef.ts +2 -2
  85. package/src/generated/config.generated.ts +221 -20
  86. package/src/generated/materialisers.generated.ts +0 -12
  87. package/src/generated/operations.generated.ts +0 -177
  88. package/src/index.ts +25 -0
  89. package/src/responseSchemas.ts +143 -0
  90. package/src/run/simulate.ts +78 -0
  91. package/src/sdk.ts +25 -6
  92. package/src/examples/staged/aaveBorrow.ts +0 -128
  93. package/src/examples/staged/aaveDebtRebalanceExactOut.ts +0 -301
  94. package/src/examples/staged/aaveHealthFactorExplode.ts +0 -70
  95. package/src/examples/staged/aaveToMorphoDebtMigration.ts +0 -200
  96. package/src/examples/staged/aaveToMorphoDebtMigrationWithSwap.ts +0 -231
  97. package/src/examples/staged/aaveToMorphoDebtMigrationWithSwapExactOut.ts +0 -307
  98. package/src/examples/staged/flashloanRepay.ts +0 -142
  99. package/src/examples/staged/morphoBlueBorrow.ts +0 -93
  100. package/src/examples/staged/morphoBlueRepay.ts +0 -132
  101. package/src/examples/staged/registry.ts +0 -80
package/dist/sdk.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ComposeCompileResult, ComposeCompileRequest } from '@lifi/compose-spec';
1
+ import { ComposeCompileResult, ComposeCompileRequest, SimulateRequest, SimulateResult } from '@lifi/compose-spec';
2
2
  import { FlowOptions, FlowBuilderCore, TypedFlow } from './authoring/FlowBuilderCore.js';
3
3
  import { ComposeClient } from './client.js';
4
4
  import { GeneratedOps } from './generated/operations.generated.js';
@@ -46,8 +46,8 @@ interface ComposeSdkOptions {
46
46
  readonly baseUrl: string;
47
47
  /** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */
48
48
  readonly fetch?: typeof globalThis.fetch;
49
- /** Optional LI.FI API key for authenticated access. Sent as the `x-lifi-api-key` header on every request. */
50
- readonly apiKey?: string;
49
+ /** LI.FI API key, sent as the `x-lifi-api-key` header on every request. Required — the Compose API rejects unauthenticated requests. */
50
+ readonly apiKey: string;
51
51
  }
52
52
  /**
53
53
  * The top-level Compose SDK interface.
@@ -59,7 +59,7 @@ interface ComposeSdkOptions {
59
59
  * ```ts
60
60
  * import { createComposeSdk, resources, materialisers } from '@lifi/composer-sdk';
61
61
  *
62
- * const sdk = createComposeSdk({ baseUrl: 'https://li.quest' });
62
+ * const sdk = createComposeSdk({ baseUrl: 'https://li.quest', apiKey: 'YOUR_API_KEY' });
63
63
  *
64
64
  * const builder = sdk.flow(1, {
65
65
  * inputs: { usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1) },
@@ -95,16 +95,28 @@ interface ComposeSdk {
95
95
  * @returns A {@link ComposeCompileRequest} ready to send to the Compose API.
96
96
  */
97
97
  readonly request: <T extends InputSchema>(flow: TypedFlow<T>, run: ComposeRunInput<T>) => ComposeCompileRequest;
98
+ /**
99
+ * Simulates a raw, pre-encoded transaction. Thin pass-through to
100
+ * {@link ComposeClient.simulate}; see it for the `ok` / `revert` / `error`
101
+ * result discrimination and error behaviour. Pair with `buildSimulateRequest`
102
+ * to assemble the request from a compile result.
103
+ *
104
+ * @param request - The raw transaction plus funding `requirements` and
105
+ * `trackedBalances`.
106
+ * @returns A {@link SimulateResult} (`ok` / `revert` / `error`).
107
+ * @throws {@link ComposeError} on network, validation, or server errors.
108
+ */
109
+ readonly simulate: (request: SimulateRequest) => Promise<SimulateResult>;
98
110
  }
99
111
  /**
100
112
  * Creates a new Compose SDK instance.
101
113
  *
102
- * @param options - SDK configuration including the API base URL and optional fetch implementation.
114
+ * @param options - SDK configuration including the API base URL, required API key, and optional fetch implementation.
103
115
  * @returns A {@link ComposeSdk} instance.
104
116
  *
105
117
  * @example
106
118
  * ```ts
107
- * const sdk = createComposeSdk({ baseUrl: 'https://li.quest' });
119
+ * const sdk = createComposeSdk({ baseUrl: 'https://li.quest', apiKey: 'YOUR_API_KEY' });
108
120
  * ```
109
121
  */
110
122
  declare const createComposeSdk: (options: ComposeSdkOptions) => ComposeSdk;
package/dist/sdk.js CHANGED
@@ -33,7 +33,12 @@ const createComposeSdk = (options) => {
33
33
  };
34
34
  return Object.assign(builder, { compile });
35
35
  };
36
- return { client: composeClient, flow, request };
36
+ return {
37
+ client: composeClient,
38
+ flow,
39
+ request,
40
+ simulate: composeClient.simulate
41
+ };
37
42
  };
38
43
  export {
39
44
  createComposeSdk
package/dist/sdk.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sdk.ts"],"sourcesContent":["import type {\n ComposeCompileRequest,\n ComposeCompileResult,\n InputSpec,\n} from '@lifi/compose-spec';\n\nimport {\n createFlowBuilderCore,\n type FlowBuilderCore,\n type FlowOptions,\n type TypedFlow,\n} from './authoring/FlowBuilderCore.js';\nimport { type ComposeClient, createComposeClient } from './client.js';\nimport {\n bindGeneratedOps,\n type GeneratedOps,\n} from './generated/operations.generated.js';\nimport { buildRun, type ComposeRunInput } from './run/inputs.js';\nimport type { InputSchema } from './types.js';\n\nexport type { ComposeRunInput };\n\n/**\n * A flow builder augmented with generated operation methods and a `compile` method\n * that submits the flow to the Compose backend for compilation.\n *\n * Created via {@link ComposeSdk.flow}.\n *\n * @typeParam T - The input schema describing the flow's required inputs.\n */\nexport type FlowBuilder<T extends InputSchema = InputSchema> =\n FlowBuilderCore<T> &\n GeneratedOps & {\n /**\n * Builds the flow document from the current builder state and submits it\n * to the Compose API for compilation.\n *\n * @param run - Runtime inputs, preconditions, and signer address.\n * @returns The compiled transaction calldata and metadata.\n * @throws {@link ComposeError} on network, validation, or server errors.\n *\n * @example\n * ```ts\n * const result = await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * signer: '0xYourAddress...',\n * });\n * console.log(result.calldata);\n * ```\n */\n readonly compile: (\n run: ComposeRunInput<T>,\n ) => Promise<ComposeCompileResult>;\n };\n\n/**\n * Configuration for creating a Compose SDK instance.\n */\nexport interface ComposeSdkOptions {\n /** Base URL of the Compose API (e.g. `\"https://li.quest\"`). */\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 for authenticated access. Sent as the `x-lifi-api-key` header on every request. */\n readonly apiKey?: string;\n}\n\n/**\n * The top-level Compose SDK interface.\n *\n * Provides methods to build flows, compile them into executable calldata, and\n * interact with the Compose API directly.\n *\n * @example\n * ```ts\n * import { createComposeSdk, resources, materialisers } from '@lifi/composer-sdk';\n *\n * const sdk = createComposeSdk({ baseUrl: 'https://li.quest' });\n *\n * const builder = sdk.flow(1, {\n * inputs: { usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1) },\n * });\n *\n * builder.lifi.swap('swap1', {\n * bind: { amountIn: builder.inputs.usdc },\n * config: { resourceOut: resources.native(1) },\n * });\n *\n * const result = await builder.compile({\n * inputs: { usdc: materialisers.balanceOf({}) },\n * signer: '0xYourAddress...',\n * });\n * ```\n */\nexport interface ComposeSdk {\n /** Low-level HTTP client for the Compose API. */\n readonly client: ComposeClient;\n /**\n * Creates a new flow builder targeting the given chain.\n * @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).\n * @param options - Flow configuration including input declarations.\n * @returns A {@link FlowBuilder} with generated operation methods and a `compile` method.\n * @throws Error if any resource input's `chainId` doesn't match the flow's `chainId`.\n */\n readonly flow: <T extends InputSchema>(\n chainId: number,\n options: FlowOptions<T>,\n ) => FlowBuilder<T>;\n /**\n * Builds a raw compile request without sending it. Useful for inspecting the\n * request payload or submitting it through a custom transport.\n * @param flow - A built flow document (from `builder.build()`).\n * @param run - Runtime inputs, preconditions, and signer address.\n * @returns A {@link ComposeCompileRequest} ready to send to the Compose API.\n */\n readonly request: <T extends InputSchema>(\n flow: TypedFlow<T>,\n run: ComposeRunInput<T>,\n ) => ComposeCompileRequest;\n}\n\n/**\n * Creates a new Compose SDK instance.\n *\n * @param options - SDK configuration including the API base URL and optional fetch implementation.\n * @returns A {@link ComposeSdk} instance.\n *\n * @example\n * ```ts\n * const sdk = createComposeSdk({ baseUrl: 'https://li.quest' });\n * ```\n */\nexport const createComposeSdk = (options: ComposeSdkOptions): ComposeSdk => {\n const composeClient = createComposeClient(options);\n\n const request = <T extends InputSchema>(\n flowDoc: TypedFlow<T>,\n run: ComposeRunInput<T>,\n ): ComposeCompileRequest => ({\n flow: flowDoc,\n run: buildRun({\n inputs: run.inputs as Record<string, InputSpec>,\n preconditions: run.preconditions,\n signer: run.signer,\n assumptions: run.assumptions as Record<string, bigint> | undefined,\n referrer: run.referrer,\n integratorFeeBps: run.integratorFeeBps,\n maxPriceImpactBps: run.maxPriceImpactBps,\n sweepTo: run.sweepTo,\n simulationPolicy: run.simulationPolicy,\n checkOnChainAllowances: run.checkOnChainAllowances,\n }),\n });\n\n const flow = <T extends InputSchema>(\n chainId: number,\n opts: FlowOptions<T>,\n ): FlowBuilder<T> => {\n const core = createFlowBuilderCore(chainId, opts);\n const builder = Object.assign(core, bindGeneratedOps(core));\n\n const compile = async (\n run: ComposeRunInput<T>,\n ): Promise<ComposeCompileResult> => {\n const flowDoc = builder.build();\n const req = request(flowDoc, run);\n return composeClient.compile(req);\n };\n\n return Object.assign(builder, { compile });\n };\n\n return { client: composeClient, flow, request };\n};\n"],"mappings":"AAMA;AAAA,EACE;AAAA,OAIK;AACP,SAA6B,2BAA2B;AACxD;AAAA,EACE;AAAA,OAEK;AACP,SAAS,gBAAsC;AAmHxC,MAAM,mBAAmB,CAAC,YAA2C;AAC1E,QAAM,gBAAgB,oBAAoB,OAAO;AAEjD,QAAM,UAAU,CACd,SACA,SAC2B;AAAA,IAC3B,MAAM;AAAA,IACN,KAAK,SAAS;AAAA,MACZ,QAAQ,IAAI;AAAA,MACZ,eAAe,IAAI;AAAA,MACnB,QAAQ,IAAI;AAAA,MACZ,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,kBAAkB,IAAI;AAAA,MACtB,mBAAmB,IAAI;AAAA,MACvB,SAAS,IAAI;AAAA,MACb,kBAAkB,IAAI;AAAA,MACtB,wBAAwB,IAAI;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,CACX,SACA,SACmB;AACnB,UAAM,OAAO,sBAAsB,SAAS,IAAI;AAChD,UAAM,UAAU,OAAO,OAAO,MAAM,iBAAiB,IAAI,CAAC;AAE1D,UAAM,UAAU,OACd,QACkC;AAClC,YAAM,UAAU,QAAQ,MAAM;AAC9B,YAAM,MAAM,QAAQ,SAAS,GAAG;AAChC,aAAO,cAAc,QAAQ,GAAG;AAAA,IAClC;AAEA,WAAO,OAAO,OAAO,SAAS,EAAE,QAAQ,CAAC;AAAA,EAC3C;AAEA,SAAO,EAAE,QAAQ,eAAe,MAAM,QAAQ;AAChD;","names":[]}
1
+ {"version":3,"sources":["../src/sdk.ts"],"sourcesContent":["import type {\n ComposeCompileRequest,\n ComposeCompileResult,\n InputSpec,\n SimulateRequest,\n SimulateResult,\n} from '@lifi/compose-spec';\n\nimport {\n createFlowBuilderCore,\n type FlowBuilderCore,\n type FlowOptions,\n type TypedFlow,\n} from './authoring/FlowBuilderCore.js';\nimport { type ComposeClient, createComposeClient } from './client.js';\nimport {\n bindGeneratedOps,\n type GeneratedOps,\n} from './generated/operations.generated.js';\nimport { buildRun, type ComposeRunInput } from './run/inputs.js';\nimport type { InputSchema } from './types.js';\n\nexport type { ComposeRunInput };\n\n/**\n * A flow builder augmented with generated operation methods and a `compile` method\n * that submits the flow to the Compose backend for compilation.\n *\n * Created via {@link ComposeSdk.flow}.\n *\n * @typeParam T - The input schema describing the flow's required inputs.\n */\nexport type FlowBuilder<T extends InputSchema = InputSchema> =\n FlowBuilderCore<T> &\n GeneratedOps & {\n /**\n * Builds the flow document from the current builder state and submits it\n * to the Compose API for compilation.\n *\n * @param run - Runtime inputs, preconditions, and signer address.\n * @returns The compiled transaction calldata and metadata.\n * @throws {@link ComposeError} on network, validation, or server errors.\n *\n * @example\n * ```ts\n * const result = await builder.compile({\n * inputs: { token: materialisers.balanceOf({}) },\n * signer: '0xYourAddress...',\n * });\n * console.log(result.calldata);\n * ```\n */\n readonly compile: (\n run: ComposeRunInput<T>,\n ) => Promise<ComposeCompileResult>;\n };\n\n/**\n * Configuration for creating a Compose SDK instance.\n */\nexport interface ComposeSdkOptions {\n /** Base URL of the Compose API (e.g. `\"https://li.quest\"`). */\n readonly baseUrl: string;\n /** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */\n readonly fetch?: typeof globalThis.fetch;\n /** LI.FI API key, sent as the `x-lifi-api-key` header on every request. Required — the Compose API rejects unauthenticated requests. */\n readonly apiKey: string;\n}\n\n/**\n * The top-level Compose SDK interface.\n *\n * Provides methods to build flows, compile them into executable calldata, and\n * interact with the Compose API directly.\n *\n * @example\n * ```ts\n * import { createComposeSdk, resources, materialisers } from '@lifi/composer-sdk';\n *\n * const sdk = createComposeSdk({ baseUrl: 'https://li.quest', apiKey: 'YOUR_API_KEY' });\n *\n * const builder = sdk.flow(1, {\n * inputs: { usdc: resources.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 1) },\n * });\n *\n * builder.lifi.swap('swap1', {\n * bind: { amountIn: builder.inputs.usdc },\n * config: { resourceOut: resources.native(1) },\n * });\n *\n * const result = await builder.compile({\n * inputs: { usdc: materialisers.balanceOf({}) },\n * signer: '0xYourAddress...',\n * });\n * ```\n */\nexport interface ComposeSdk {\n /** Low-level HTTP client for the Compose API. */\n readonly client: ComposeClient;\n /**\n * Creates a new flow builder targeting the given chain.\n * @param chainId - The EVM chain ID (e.g. `1` for Ethereum mainnet).\n * @param options - Flow configuration including input declarations.\n * @returns A {@link FlowBuilder} with generated operation methods and a `compile` method.\n * @throws Error if any resource input's `chainId` doesn't match the flow's `chainId`.\n */\n readonly flow: <T extends InputSchema>(\n chainId: number,\n options: FlowOptions<T>,\n ) => FlowBuilder<T>;\n /**\n * Builds a raw compile request without sending it. Useful for inspecting the\n * request payload or submitting it through a custom transport.\n * @param flow - A built flow document (from `builder.build()`).\n * @param run - Runtime inputs, preconditions, and signer address.\n * @returns A {@link ComposeCompileRequest} ready to send to the Compose API.\n */\n readonly request: <T extends InputSchema>(\n flow: TypedFlow<T>,\n run: ComposeRunInput<T>,\n ) => ComposeCompileRequest;\n /**\n * Simulates a raw, pre-encoded transaction. Thin pass-through to\n * {@link ComposeClient.simulate}; see it for the `ok` / `revert` / `error`\n * result discrimination and error behaviour. Pair with `buildSimulateRequest`\n * to assemble the request from a compile result.\n *\n * @param request - The raw transaction plus funding `requirements` and\n * `trackedBalances`.\n * @returns A {@link SimulateResult} (`ok` / `revert` / `error`).\n * @throws {@link ComposeError} on network, validation, or server errors.\n */\n readonly simulate: (request: SimulateRequest) => Promise<SimulateResult>;\n}\n\n/**\n * Creates a new Compose SDK instance.\n *\n * @param options - SDK configuration including the API base URL, required API key, and optional fetch implementation.\n * @returns A {@link ComposeSdk} instance.\n *\n * @example\n * ```ts\n * const sdk = createComposeSdk({ baseUrl: 'https://li.quest', apiKey: 'YOUR_API_KEY' });\n * ```\n */\nexport const createComposeSdk = (options: ComposeSdkOptions): ComposeSdk => {\n const composeClient = createComposeClient(options);\n\n const request = <T extends InputSchema>(\n flowDoc: TypedFlow<T>,\n run: ComposeRunInput<T>,\n ): ComposeCompileRequest => ({\n flow: flowDoc,\n run: buildRun({\n inputs: run.inputs as Record<string, InputSpec>,\n preconditions: run.preconditions,\n signer: run.signer,\n assumptions: run.assumptions as Record<string, bigint> | undefined,\n referrer: run.referrer,\n integratorFeeBps: run.integratorFeeBps,\n maxPriceImpactBps: run.maxPriceImpactBps,\n sweepTo: run.sweepTo,\n simulationPolicy: run.simulationPolicy,\n checkOnChainAllowances: run.checkOnChainAllowances,\n }),\n });\n\n const flow = <T extends InputSchema>(\n chainId: number,\n opts: FlowOptions<T>,\n ): FlowBuilder<T> => {\n const core = createFlowBuilderCore(chainId, opts);\n const builder = Object.assign(core, bindGeneratedOps(core));\n\n const compile = async (\n run: ComposeRunInput<T>,\n ): Promise<ComposeCompileResult> => {\n const flowDoc = builder.build();\n const req = request(flowDoc, run);\n return composeClient.compile(req);\n };\n\n return Object.assign(builder, { compile });\n };\n\n return {\n client: composeClient,\n flow,\n request,\n simulate: composeClient.simulate,\n };\n};\n"],"mappings":"AAQA;AAAA,EACE;AAAA,OAIK;AACP,SAA6B,2BAA2B;AACxD;AAAA,EACE;AAAA,OAEK;AACP,SAAS,gBAAsC;AA+HxC,MAAM,mBAAmB,CAAC,YAA2C;AAC1E,QAAM,gBAAgB,oBAAoB,OAAO;AAEjD,QAAM,UAAU,CACd,SACA,SAC2B;AAAA,IAC3B,MAAM;AAAA,IACN,KAAK,SAAS;AAAA,MACZ,QAAQ,IAAI;AAAA,MACZ,eAAe,IAAI;AAAA,MACnB,QAAQ,IAAI;AAAA,MACZ,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,kBAAkB,IAAI;AAAA,MACtB,mBAAmB,IAAI;AAAA,MACvB,SAAS,IAAI;AAAA,MACb,kBAAkB,IAAI;AAAA,MACtB,wBAAwB,IAAI;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,CACX,SACA,SACmB;AACnB,UAAM,OAAO,sBAAsB,SAAS,IAAI;AAChD,UAAM,UAAU,OAAO,OAAO,MAAM,iBAAiB,IAAI,CAAC;AAE1D,UAAM,UAAU,OACd,QACkC;AAClC,YAAM,UAAU,QAAQ,MAAM;AAC9B,YAAM,MAAM,QAAQ,SAAS,GAAG;AAChC,aAAO,cAAc,QAAQ,GAAG;AAAA,IAClC;AAEA,WAAO,OAAO,OAAO,SAAS,EAAE,QAAQ,CAAC;AAAA,EAC3C;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA,UAAU,cAAc;AAAA,EAC1B;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/composer-sdk",
3
- "version": "0.2.0-staging.5",
3
+ "version": "0.3.0",
4
4
  "description": "Public Composer SDK for building and submitting flows",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -23,7 +23,7 @@
23
23
  "./package.json": "./package.json"
24
24
  },
25
25
  "engines": {
26
- "node": ">=18"
26
+ "node": ">=24"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
@@ -51,11 +51,12 @@
51
51
  "example:staged": "tsx src/examples/run.ts --staged"
52
52
  },
53
53
  "peerDependencies": {
54
- "@lifi/compose-spec": "0.2.0-staging.5"
54
+ "@lifi/compose-spec": "0.3.0"
55
55
  },
56
56
  "dependencies": {
57
57
  "abitype": "^1.2.3",
58
- "effect": "^3.21.0"
58
+ "effect": "^3.21.0",
59
+ "zod": "^4.1.11"
59
60
  },
60
61
  "devDependencies": {
61
62
  "@eslint/compat": "^1.4.0",
@@ -70,7 +71,7 @@
70
71
  "eslint-plugin-require-extensions": "^0.1.3",
71
72
  "json-schema-to-typescript": "^15.0.4",
72
73
  "npm-run-all": "^4.1.5",
73
- "prettier": "^3.0.0",
74
+ "prettier": "^3.9.4",
74
75
  "tsup": "^8.5.1",
75
76
  "tsx": "^4.20.4",
76
77
  "typescript": "^5.9.2",
@@ -84,6 +85,7 @@
84
85
  "!src/**/*.test.ts",
85
86
  "!src/**/*.mock.ts",
86
87
  "!src/**/*.typecheck.ts",
87
- "!dist/**/*.typecheck.*"
88
+ "!dist/**/*.typecheck.*",
89
+ "!src/examples/staged/**"
88
90
  ]
89
91
  }
package/src/client.ts CHANGED
@@ -4,10 +4,16 @@ import type {
4
4
  ComposeCompileResult,
5
5
  ComposeCompileSuccessData,
6
6
  ComposeManifest,
7
+ SimulateRequest,
8
+ SimulateResult,
7
9
  } from '@lifi/compose-spec';
8
10
 
9
11
  import type { GetZapPacksOptions, ZapPackOverview } from './discovery.js';
10
12
  import { ComposeError, errorFromHttpResponse } from './errors.js';
13
+ import {
14
+ parseCompilePartialEnvelope,
15
+ parseSimulateResult,
16
+ } from './responseSchemas.js';
11
17
 
12
18
  // __SDK_VERSION__ is a compile-time constant injected by tsup (via `define` in tsup.config.ts)
13
19
  // and by vitest (via `define` in vitest.config.ts). Both read the version from package.json
@@ -27,8 +33,8 @@ export interface ComposeClientOptions {
27
33
  readonly baseUrl: string;
28
34
  /** Optional custom `fetch` implementation. Defaults to `globalThis.fetch`. */
29
35
  readonly fetch?: typeof globalThis.fetch;
30
- /** Optional LI.FI API key. When set, sent as the `x-lifi-api-key` header on every request. */
31
- readonly apiKey?: string;
36
+ /** LI.FI API key, sent as the `x-lifi-api-key` header on every request. Required — the Compose API rejects unauthenticated requests. */
37
+ readonly apiKey: string;
32
38
  }
33
39
 
34
40
  /**
@@ -78,6 +84,30 @@ export interface ComposeClient {
78
84
  readonly getZapPacks: (
79
85
  options?: GetZapPacksOptions,
80
86
  ) => Promise<readonly ZapPackOverview[]>;
87
+ /**
88
+ * Simulates a raw, pre-encoded transaction against `POST /simulate` and
89
+ * reports how the watched balances change and how much inner-call gas it
90
+ * burns.
91
+ *
92
+ * The result is a discriminated union on `status`:
93
+ * - `'ok'` — the simulation ran successfully; `deltas`/`gasUsed` are populated.
94
+ * - `'revert'` — the simulation ran but the transaction reverted on-chain. A
95
+ * revert is a *successful simulation*, not a transport error, so it is
96
+ * returned (HTTP 200) rather than thrown — mirroring how {@link compile}
97
+ * returns `status: 'partial'` on a simulated revert.
98
+ * - `'error'` — the request was well-formed but the simulation could not be
99
+ * set up or run (HTTP 422); `message` is intentionally generic.
100
+ *
101
+ * `bigint` amounts in the request (`value`, requirement `balance`/`allowance`)
102
+ * are serialised to decimal strings automatically.
103
+ *
104
+ * @param request - The raw transaction plus funding `requirements` and the
105
+ * `trackedBalances` to watch.
106
+ * @returns A {@link SimulateResult} (`ok` / `revert` / `error`).
107
+ * @throws {@link ComposeError} on network failures, HTTP 400 (malformed
108
+ * input), 401/403 (auth), 404, 429, and 5xx.
109
+ */
110
+ readonly simulate: (request: SimulateRequest) => Promise<SimulateResult>;
81
111
  }
82
112
 
83
113
  const bigintReplacer = (_key: string, value: unknown): unknown =>
@@ -109,22 +139,39 @@ const parsePartialBody = async (
109
139
  url: string,
110
140
  ): Promise<ComposeCompileResult> => {
111
141
  const body = await res.json().catch((_) => null);
112
- if (
113
- !isNonNullObject(body) ||
114
- !('data' in body) ||
115
- !isNonNullObject(body.data) ||
116
- !('error' in body) ||
117
- !isNonNullObject(body.error)
118
- ) {
142
+ const envelope = parseCompilePartialEnvelope(body);
143
+ if (envelope === null) {
119
144
  throw new ComposeError(
120
145
  'UNKNOWN_ERROR',
121
146
  'Unexpected partial response format',
122
147
  { url },
123
148
  );
124
149
  }
125
- const data = body.data as unknown as ComposeCompilePartialData;
126
- const error = body.error as unknown as { kind: string; message: string };
127
- return { ...data, status: 'partial' as const, error };
150
+ // `data` is validated as an object by the schema; compose-spec owns its full
151
+ // shape as a hand-authored type, so we narrow it here rather than re-declaring
152
+ // that type as a schema. `error` is fully validated — no cast needed.
153
+ const data = envelope.data as unknown as ComposeCompilePartialData;
154
+ return { ...data, status: 'partial' as const, error: envelope.error };
155
+ };
156
+
157
+ // `/simulate` is un-enveloped: the discriminated body (`{ status, ... }`) is at
158
+ // the top level, NOT wrapped in `{ data }` like `/compose`. So this reads the
159
+ // body directly and validates it against the simulate union rather than reusing
160
+ // `parseBody`.
161
+ const parseSimulateBody = async (
162
+ res: Response,
163
+ url: string,
164
+ ): Promise<SimulateResult> => {
165
+ const body = await res.json().catch((_) => null);
166
+ const result = parseSimulateResult(body);
167
+ if (result === null) {
168
+ throw new ComposeError(
169
+ 'UNKNOWN_ERROR',
170
+ 'Unexpected simulate response format',
171
+ { url },
172
+ );
173
+ }
174
+ return result;
128
175
  };
129
176
 
130
177
  /**
@@ -142,15 +189,20 @@ export const createComposeClient = (
142
189
  `Invalid baseUrl: expected an HTTP(S) URL, got "${options.baseUrl}"`,
143
190
  );
144
191
  }
192
+ const trimmedApiKey = options.apiKey?.trim() || undefined;
193
+ if (!trimmedApiKey) {
194
+ throw new ComposeError(
195
+ 'VALIDATION_ERROR',
196
+ 'apiKey is required: pass a LI.FI API key to createComposeSdk().',
197
+ );
198
+ }
145
199
  const fetchFn = options.fetch ?? globalThis.fetch;
146
200
  const base = options.baseUrl.replace(/\/$/, '');
147
201
 
148
- const trimmedApiKey = options.apiKey?.trim() || undefined;
149
-
150
202
  const baseHeaders: Record<string, string> = {
151
203
  Accept: 'application/json',
152
204
  'x-lifi-composer-sdk': SDK_VERSION,
153
- ...(trimmedApiKey ? { 'x-lifi-api-key': trimmedApiKey } : {}),
205
+ 'x-lifi-api-key': trimmedApiKey,
154
206
  };
155
207
 
156
208
  const getManifest = async (): Promise<ComposeManifest> => {
@@ -226,5 +278,33 @@ export const createComposeClient = (
226
278
  return await parseBody<readonly ZapPackOverview[]>(res, url);
227
279
  };
228
280
 
229
- return { getManifest, compile, getZapPacks };
281
+ const simulate = async (
282
+ request: SimulateRequest,
283
+ ): Promise<SimulateResult> => {
284
+ const url = `${base}/simulate`;
285
+ let res: Response;
286
+ try {
287
+ res = await fetchFn(url, {
288
+ method: 'POST',
289
+ headers: { ...baseHeaders, 'Content-Type': 'application/json' },
290
+ body: JSON.stringify(request, bigintReplacer),
291
+ });
292
+ } catch (err) {
293
+ const message = err instanceof Error ? err.message : String(err);
294
+ throw new ComposeError('NETWORK_ERROR', message, { cause: err });
295
+ }
296
+ // Only 200 (carries `ok`/`revert`) and 422 (carries the `error` member of
297
+ // the union) have a discriminated body. 422 is deliberately intercepted
298
+ // here (not thrown as VALIDATION_ERROR) so callers get one exhaustive
299
+ // `switch (result.status)`. Every other status is a transport error and is
300
+ // thrown — including HTTP 400 (malformed input, no `status` body) and any
301
+ // unexpected 2xx.
302
+ if (res.status === 200 || res.status === 422) {
303
+ return await parseSimulateBody(res, url);
304
+ }
305
+ const body = await res.text();
306
+ throw errorFromHttpResponse(res.status, body, url);
307
+ };
308
+
309
+ return { getManifest, compile, getZapPacks, simulate };
230
310
  };
package/src/errors.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import type { ComposeErrorKind, SimulationRevert } from '@lifi/compose-spec';
2
2
 
3
+ import {
4
+ parseServerErrorBody,
5
+ type ServerErrorBody,
6
+ } from './responseSchemas.js';
7
+
3
8
  /**
4
9
  * Machine-readable error codes returned by the SDK.
5
10
  *
@@ -101,21 +106,14 @@ const STATUS_TO_CODE: ReadonlyMap<number, ComposeErrorCode> = new Map<
101
106
  [429, 'RATE_LIMITED'],
102
107
  ]);
103
108
 
104
- interface ServerErrorBody {
105
- readonly error?: {
106
- readonly kind?: string;
107
- readonly message?: string;
108
- readonly path?: string;
109
- readonly details?: SimulationRevert;
110
- };
111
- }
112
-
113
109
  const tryParseErrorBody = (body: string): ServerErrorBody | null => {
110
+ let json: unknown;
114
111
  try {
115
- return JSON.parse(body) as ServerErrorBody;
112
+ json = JSON.parse(body);
116
113
  } catch {
117
114
  return null;
118
115
  }
116
+ return parseServerErrorBody(json);
119
117
  };
120
118
 
121
119
  /**
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  // Aave v3 incentives contracts on Ethereum mainnet.
9
9
  const REWARDS_CONTROLLER = '0x8164Cc65827dcFe994AB23944CBC90e0aa80bFcb';
@@ -37,7 +37,7 @@ export const buildAaveClaimRewards = ({
37
37
  flow: Flow;
38
38
  request: ComposeCompileRequest;
39
39
  } => {
40
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
40
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
41
41
 
42
42
  const builder = sdk.flow(1, {
43
43
  name: 'aave-claim-rewards',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  // Aave v3 contracts on Ethereum mainnet.
9
9
  const AAVE_V3_POOL = '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2';
@@ -49,7 +49,7 @@ export const buildAaveRepay = ({
49
49
  flow: Flow;
50
50
  request: ComposeCompileRequest;
51
51
  } => {
52
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
52
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
53
53
 
54
54
  const builder = sdk.flow(1, {
55
55
  name: 'aave-repay-weth',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  // Aave v3 contracts on Ethereum mainnet.
9
9
  const AAVE_V3_POOL = '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2';
@@ -39,7 +39,7 @@ export const buildAaveRepayWithATokens = ({
39
39
  flow: Flow;
40
40
  request: ComposeCompileRequest;
41
41
  } => {
42
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
42
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
43
43
 
44
44
  const builder = sdk.flow(1, {
45
45
  name: 'aave-repay-with-atokens',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  // Aave v3 contracts on Ethereum mainnet.
9
9
  const AAVE_V3_POOL = '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2';
@@ -41,7 +41,7 @@ export const buildAaveSetEMode = ({
41
41
  flow: Flow;
42
42
  request: ComposeCompileRequest;
43
43
  } => {
44
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
44
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
45
45
 
46
46
  const builder = sdk.flow(1, {
47
47
  name: 'aave-set-emode',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
9
9
  // Example ERC-4626 vault address (Steakhouse USDC on Ethereum mainnet)
@@ -30,7 +30,7 @@ export const buildApproveAndDeposit = ({
30
30
  flow: Flow;
31
31
  request: ComposeCompileRequest;
32
32
  } => {
33
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
33
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
34
34
 
35
35
  const builder = sdk.flow(1, {
36
36
  name: 'approve-and-deposit',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  // Example ERC-4626 vault address (Steakhouse USDC on Ethereum mainnet)
9
9
  const VAULT = '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB';
@@ -31,7 +31,7 @@ export const buildRedeemFromVault = ({
31
31
  flow: Flow;
32
32
  request: ComposeCompileRequest;
33
33
  } => {
34
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
34
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
35
35
 
36
36
  const builder = sdk.flow(1, {
37
37
  name: 'redeem-from-vault',
@@ -103,7 +103,7 @@ export const buildClaimRewards = ({
103
103
  const REWARDS_CONTRACT = '0x1111111111111111111111111111111111111111';
104
104
  const REWARD_TOKEN = '0x2222222222222222222222222222222222222222';
105
105
 
106
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
106
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
107
107
 
108
108
  const builder = sdk.flow(1, {
109
109
  name: 'claim-rewards',
@@ -154,7 +154,7 @@ export const buildWrapEth = ({
154
154
  flow: Flow;
155
155
  request: ComposeCompileRequest;
156
156
  } => {
157
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
157
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
158
158
 
159
159
  const builder = sdk.flow(1, {
160
160
  name: 'wrap-eth',
@@ -2,7 +2,10 @@
2
2
  // built-in process.env.BASE_URL (set to "/" from the `base` config option).
3
3
  export const BASE_URL: string =
4
4
  process.env['COMPOSER_BASE_URL'] ?? 'https://composer.li.quest';
5
- export const API_KEY: string | undefined = process.env['LIFI_API_KEY'];
5
+ // `apiKey` is required by `createComposeSdk`/`createComposeClient`; fall back to a
6
+ // placeholder so the examples remain runnable (against a backend that accepts it)
7
+ // without every contributor needing a real LI.FI API key set locally.
8
+ export const API_KEY: string = process.env['LIFI_API_KEY'] ?? 'YOUR_API_KEY';
6
9
 
7
10
  export const OWNER = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045';
8
11
  export const RECIPIENT = '0x1234567890abcdef1234567890abcdef12345678';
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  export interface ConsolidateToEthInput {
9
9
  readonly owner: Address;
@@ -38,7 +38,7 @@ export const buildConsolidateToEth = ({
38
38
  flow: Flow;
39
39
  request: ComposeCompileRequest;
40
40
  } => {
41
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
41
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
42
42
  const erc20 = (token: Address) => resources.erc20(token, CHAIN_ID);
43
43
 
44
44
  // Declare the flow with one input per ERC-20 token on Ethereum mainnet.
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  export interface ConsolidateStablesToUsdcInput {
9
9
  readonly owner: Address;
@@ -39,7 +39,7 @@ export const buildConsolidateStablesToUsdc = ({
39
39
  flow: Flow;
40
40
  request: ComposeCompileRequest;
41
41
  } => {
42
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
42
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
43
43
  const erc20 = (token: Address) => resources.erc20(token, CHAIN_ID);
44
44
 
45
45
  // Declare the flow with one input per stablecoin on Ethereum mainnet.
@@ -9,7 +9,7 @@ import {
9
9
  } from '../index.js';
10
10
  import type { Address } from '../types.js';
11
11
 
12
- import { BASE_URL } from './config.js';
12
+ import { API_KEY, BASE_URL } from './config.js';
13
13
 
14
14
  const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
15
15
  // Aave v3 aEthUSDC receipt token on Ethereum mainnet
@@ -45,7 +45,7 @@ export const buildDepositFromProxy = ({
45
45
  flow: Flow;
46
46
  request: ComposeCompileRequest;
47
47
  } => {
48
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
48
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
49
49
 
50
50
  const builder = sdk.flow(1, {
51
51
  name: 'deposit-from-proxy',
@@ -2,7 +2,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
2
2
 
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
 
5
- import { BASE_URL, OWNER } from './config.js';
5
+ import { API_KEY, BASE_URL, OWNER } from './config.js';
6
6
  const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
7
7
  const USDT = '0xdAC17F958D2ee523a2206206994597C13D831ec7';
8
8
 
@@ -23,7 +23,7 @@ export const buildDustSweepExample = (): {
23
23
  flow: Flow;
24
24
  request: ComposeCompileRequest;
25
25
  } => {
26
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
26
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
27
27
 
28
28
  const builder = sdk.flow(1, {
29
29
  name: 'dust-sweep',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  // Example ERC-4626 vault address (Steakhouse USDC on Ethereum mainnet)
9
9
  const VAULT = '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB';
@@ -33,7 +33,7 @@ export const buildEmitCustomEvent = ({
33
33
  flow: Flow;
34
34
  request: ComposeCompileRequest;
35
35
  } => {
36
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
36
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
37
37
 
38
38
  const builder = sdk.flow(1, {
39
39
  name: 'emit-custom-event',
@@ -3,7 +3,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
  import type { Address } from '../types.js';
5
5
 
6
- import { BASE_URL } from './config.js';
6
+ import { API_KEY, BASE_URL } from './config.js';
7
7
 
8
8
  const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
9
9
  const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
@@ -41,7 +41,7 @@ export const buildInvariantChecks = ({
41
41
  flow: Flow;
42
42
  request: ComposeCompileRequest;
43
43
  } => {
44
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
44
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
45
45
 
46
46
  // One WETH resource input plus a scalar spender address.
47
47
  const builder = sdk.flow(1, {
@@ -2,7 +2,7 @@ import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
2
2
 
3
3
  import { createComposeSdk, materialisers, resources } from '../index.js';
4
4
 
5
- import { BASE_URL, OWNER } from './config.js';
5
+ import { API_KEY, BASE_URL, OWNER } from './config.js';
6
6
 
7
7
  const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2';
8
8
  const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
@@ -19,7 +19,7 @@ export const buildLifiSwapExample = (): {
19
19
  flow: Flow;
20
20
  request: ComposeCompileRequest;
21
21
  } => {
22
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
22
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
23
23
 
24
24
  // Declare the flow with a single WETH input on Ethereum mainnet.
25
25
  const builder = sdk.flow(1, {
@@ -7,7 +7,7 @@ import {
7
7
  resources,
8
8
  } from '../index.js';
9
9
 
10
- import { BASE_URL, OWNER } from './config.js';
10
+ import { API_KEY, BASE_URL, OWNER } from './config.js';
11
11
  const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
12
12
  // Aave aEthUSDC receipt token on Ethereum mainnet
13
13
  const A_ETH_USDC = '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c';
@@ -24,7 +24,7 @@ export const buildLifiZapExample = (): {
24
24
  flow: Flow;
25
25
  request: ComposeCompileRequest;
26
26
  } => {
27
- const sdk = createComposeSdk({ baseUrl: BASE_URL });
27
+ const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
28
28
 
29
29
  // Declare the flow with a single USDC input on Ethereum mainnet.
30
30
  const builder = sdk.flow(1, {