@lifi/composer-sdk 0.2.0 → 0.4.0-staging.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -3
- package/dist/client.cjs +9 -3
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +9 -3
- package/dist/client.js.map +1 -1
- package/dist/errors.cjs +26 -3
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +46 -2
- package/dist/errors.d.ts +46 -2
- package/dist/errors.js +24 -2
- package/dist/errors.js.map +1 -1
- package/dist/generated/config.generated.cjs.map +1 -1
- package/dist/generated/config.generated.d.cts +37 -14
- package/dist/generated/config.generated.d.ts +37 -14
- package/dist/generated/materialisers.generated.cjs +8 -2
- package/dist/generated/materialisers.generated.cjs.map +1 -1
- package/dist/generated/materialisers.generated.d.cts +1 -1
- package/dist/generated/materialisers.generated.d.ts +1 -1
- package/dist/generated/materialisers.generated.js +6 -1
- package/dist/generated/materialisers.generated.js.map +1 -1
- package/dist/generated/operations.generated.cjs +39 -1
- package/dist/generated/operations.generated.cjs.map +1 -1
- package/dist/generated/operations.generated.d.cts +111 -2
- package/dist/generated/operations.generated.d.ts +111 -2
- package/dist/generated/operations.generated.js +39 -1
- package/dist/generated/operations.generated.js.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/{materialisers.generated-BMkBQgWZ.d.ts → materialisers.generated-BfWJ-g7t.d.ts} +8 -3
- package/dist/{materialisers.generated-BWq5oePO.d.cts → materialisers.generated-DaJRwiRe.d.cts} +8 -3
- package/dist/responseSchemas.cjs +10 -1
- package/dist/responseSchemas.cjs.map +1 -1
- package/dist/responseSchemas.d.cts +15 -1
- package/dist/responseSchemas.d.ts +15 -1
- package/dist/responseSchemas.js +10 -1
- package/dist/responseSchemas.js.map +1 -1
- package/dist/sdk.cjs.map +1 -1
- package/dist/sdk.d.cts +5 -5
- package/dist/sdk.d.ts +5 -5
- package/dist/sdk.js.map +1 -1
- package/package.json +4 -5
- package/src/client.ts +10 -5
- package/src/errors.ts +67 -1
- package/src/examples/aaveClaimRewards.ts +2 -2
- package/src/examples/aaveRepay.ts +2 -2
- package/src/examples/aaveRepayWithATokens.ts +2 -2
- package/src/examples/aaveSetEMode.ts +2 -2
- package/src/examples/approveAndDeposit.ts +2 -2
- package/src/examples/callContract.ts +4 -4
- package/src/examples/config.ts +4 -1
- package/src/examples/consolidateToEth.ts +2 -2
- package/src/examples/consolidateToUsdc.ts +2 -2
- package/src/examples/depositFromProxy.ts +2 -2
- package/src/examples/dustSweep.ts +2 -2
- package/src/examples/emitCustomEvent.ts +2 -2
- package/src/examples/invariantChecks.ts +2 -2
- package/src/examples/lifiSwap.ts +2 -2
- package/src/examples/lifiZap.ts +2 -2
- package/src/examples/rawCallWithArithmetic.ts +2 -2
- package/src/examples/readContractState.ts +2 -2
- package/src/examples/splitAndZap.ts +2 -2
- package/src/examples/splitWithArithmetic.ts +2 -2
- package/src/examples/staged/aaveBorrow.ts +128 -0
- package/src/examples/staged/aaveDebtRebalanceExactOut.ts +301 -0
- package/src/examples/staged/aaveHealthFactorExplode.ts +70 -0
- package/src/examples/staged/aaveToMorphoDebtMigration.ts +200 -0
- package/src/examples/staged/aaveToMorphoDebtMigrationWithSwap.ts +231 -0
- package/src/examples/staged/aaveToMorphoDebtMigrationWithSwapExactOut.ts +307 -0
- package/src/examples/staged/flashloanRepay.ts +142 -0
- package/src/examples/staged/manualRelayContinuation.ts +161 -0
- package/src/examples/staged/morphoBlueBorrow.ts +93 -0
- package/src/examples/staged/morphoBlueRepay.ts +132 -0
- package/src/examples/staged/registry.ts +89 -0
- package/src/examples/swapAndZap.ts +2 -2
- package/src/examples/swapToRecipient.ts +2 -2
- package/src/examples/swapWithAllowRevert.ts +3 -3
- package/src/examples/swapWithBalanceCheck.ts +2 -2
- package/src/examples/swapWithFee.ts +2 -2
- package/src/examples/swapWithOutputValidation.ts +2 -2
- package/src/examples/transferTokens.ts +3 -3
- package/src/examples/untypedOpWithTypedRef.ts +2 -2
- package/src/generated/config.generated.ts +42 -14
- package/src/generated/materialisers.generated.ts +12 -0
- package/src/generated/operations.generated.ts +214 -0
- package/src/index.ts +13 -2
- package/src/responseSchemas.ts +29 -0
- package/src/sdk.ts +5 -5
package/src/errors.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
ComposeErrorKind,
|
|
3
|
+
FailedPreparedOp,
|
|
4
|
+
GenericComposeErrorKind,
|
|
5
|
+
SimulationRevert,
|
|
6
|
+
} from '@lifi/compose-spec';
|
|
2
7
|
|
|
3
8
|
import {
|
|
4
9
|
parseServerErrorBody,
|
|
@@ -62,6 +67,17 @@ export class ComposeError extends Error {
|
|
|
62
67
|
* backend can parse the revert reason.
|
|
63
68
|
*/
|
|
64
69
|
readonly details?: SimulationRevert;
|
|
70
|
+
/**
|
|
71
|
+
* The prepared ops that failed, attached to `preparation_error` errors.
|
|
72
|
+
* Each entry carries the `callId` of the failing node so callers can drop
|
|
73
|
+
* the unroutable legs and resubmit a smaller flow.
|
|
74
|
+
*/
|
|
75
|
+
readonly failedOps?: readonly FailedPreparedOp[];
|
|
76
|
+
/**
|
|
77
|
+
* The `callId`s of the prepared ops that succeeded, attached to
|
|
78
|
+
* `preparation_error` errors alongside {@link ComposeError.failedOps}.
|
|
79
|
+
*/
|
|
80
|
+
readonly succeededOps?: readonly string[];
|
|
65
81
|
|
|
66
82
|
constructor(
|
|
67
83
|
code: ComposeErrorCode,
|
|
@@ -73,6 +89,8 @@ export class ComposeError extends Error {
|
|
|
73
89
|
kind?: ComposeErrorKind;
|
|
74
90
|
path?: string;
|
|
75
91
|
details?: SimulationRevert;
|
|
92
|
+
failedOps?: readonly FailedPreparedOp[];
|
|
93
|
+
succeededOps?: readonly string[];
|
|
76
94
|
},
|
|
77
95
|
) {
|
|
78
96
|
super(message, { cause: options?.cause });
|
|
@@ -82,9 +100,21 @@ export class ComposeError extends Error {
|
|
|
82
100
|
this.kind = options?.kind;
|
|
83
101
|
this.path = options?.path;
|
|
84
102
|
this.details = options?.details;
|
|
103
|
+
this.failedOps = options?.failedOps;
|
|
104
|
+
this.succeededOps = options?.succeededOps;
|
|
85
105
|
}
|
|
86
106
|
}
|
|
87
107
|
|
|
108
|
+
/**
|
|
109
|
+
* The per-op preparation diagnostics carried by `preparation_error` responses,
|
|
110
|
+
* with both arrays known to be present. Produced by narrowing with
|
|
111
|
+
* {@link isComposePreparationError}.
|
|
112
|
+
*/
|
|
113
|
+
export interface ComposePreparationOps {
|
|
114
|
+
readonly failedOps: readonly FailedPreparedOp[];
|
|
115
|
+
readonly succeededOps: readonly string[];
|
|
116
|
+
}
|
|
117
|
+
|
|
88
118
|
/**
|
|
89
119
|
* Type guard that narrows an unknown error to {@link ComposeError}.
|
|
90
120
|
* @param e - The value to check.
|
|
@@ -94,6 +124,35 @@ export const isComposeError = (e: unknown): e is ComposeError =>
|
|
|
94
124
|
e instanceof ComposeError ||
|
|
95
125
|
(e instanceof Error && e.name === 'ComposeError' && 'code' in e);
|
|
96
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Type guard for `preparation_error` failures (HTTP 422): a mixed basket where
|
|
129
|
+
* some prepared ops failed and others succeeded. Narrows both
|
|
130
|
+
* {@link ComposeError.failedOps} and {@link ComposeError.succeededOps} to
|
|
131
|
+
* present, so callers can read them without a cast or a truthiness check.
|
|
132
|
+
*
|
|
133
|
+
* @param e - The value to check.
|
|
134
|
+
* @returns `true` if `e` is a `ComposeError` carrying per-op preparation diagnostics.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* try {
|
|
139
|
+
* await builder.compile(run);
|
|
140
|
+
* } catch (e) {
|
|
141
|
+
* if (isComposePreparationError(e)) {
|
|
142
|
+
* console.error('Failed ops:', e.failedOps);
|
|
143
|
+
* console.error('Succeeded ops:', e.succeededOps);
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
export const isComposePreparationError = (
|
|
149
|
+
e: unknown,
|
|
150
|
+
): e is ComposeError & ComposePreparationOps =>
|
|
151
|
+
isComposeError(e) &&
|
|
152
|
+
e.kind === 'preparation_error' &&
|
|
153
|
+
Array.isArray(e.failedOps) &&
|
|
154
|
+
Array.isArray(e.succeededOps);
|
|
155
|
+
|
|
97
156
|
const STATUS_TO_CODE: ReadonlyMap<number, ComposeErrorCode> = new Map<
|
|
98
157
|
number,
|
|
99
158
|
ComposeErrorCode
|
|
@@ -143,6 +202,13 @@ export const errorFromHttpResponse = (
|
|
|
143
202
|
kind: serverError?.kind as ComposeErrorKind | undefined,
|
|
144
203
|
path: serverError?.path,
|
|
145
204
|
details: serverError?.details,
|
|
205
|
+
// The wire schema types `kind` as a bare string; the server only ever
|
|
206
|
+
// reports generic kinds for individual ops.
|
|
207
|
+
failedOps: serverError?.failedOps?.map((op) => ({
|
|
208
|
+
...op,
|
|
209
|
+
kind: op.kind as GenericComposeErrorKind,
|
|
210
|
+
})),
|
|
211
|
+
succeededOps: serverError?.succeededOps,
|
|
146
212
|
},
|
|
147
213
|
);
|
|
148
214
|
};
|
|
@@ -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',
|
package/src/examples/config.ts
CHANGED
|
@@ -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
|
-
|
|
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, {
|
package/src/examples/lifiSwap.ts
CHANGED
|
@@ -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, {
|
package/src/examples/lifiZap.ts
CHANGED
|
@@ -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, {
|
|
@@ -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 contract address for a non-standard oracle
|
|
9
9
|
const ORACLE = '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419';
|
|
@@ -27,7 +27,7 @@ export const buildRawCallWithArithmetic = ({
|
|
|
27
27
|
flow: Flow;
|
|
28
28
|
request: ComposeCompileRequest;
|
|
29
29
|
} => {
|
|
30
|
-
const sdk = createComposeSdk({ baseUrl: BASE_URL });
|
|
30
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
31
31
|
|
|
32
32
|
const builder = sdk.flow(1, {
|
|
33
33
|
name: 'raw-call-with-arithmetic',
|
|
@@ -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
|
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
|
|
9
9
|
// Example ERC-4626 vault address (Steakhouse USDC on Ethereum mainnet)
|
|
@@ -28,7 +28,7 @@ export const buildReadContractState = ({
|
|
|
28
28
|
flow: Flow;
|
|
29
29
|
request: ComposeCompileRequest;
|
|
30
30
|
} => {
|
|
31
|
-
const sdk = createComposeSdk({ baseUrl: BASE_URL });
|
|
31
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
32
32
|
|
|
33
33
|
const builder = sdk.flow(1, {
|
|
34
34
|
name: 'read-contract-state',
|
|
@@ -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 v3 aEthUSDC receipt token on Ethereum mainnet
|
|
13
13
|
const A_ETH_USDC = '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c';
|
|
@@ -26,7 +26,7 @@ export const buildSplitAndZapExample = (): {
|
|
|
26
26
|
flow: Flow;
|
|
27
27
|
request: ComposeCompileRequest;
|
|
28
28
|
} => {
|
|
29
|
-
const sdk = createComposeSdk({ baseUrl: BASE_URL });
|
|
29
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
30
30
|
|
|
31
31
|
const builder = sdk.flow(1, {
|
|
32
32
|
name: 'split-usdc-to-two-vaults',
|
|
@@ -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
|
|
|
@@ -29,7 +29,7 @@ export const buildSplitWithArithmetic = ({
|
|
|
29
29
|
flow: Flow;
|
|
30
30
|
request: ComposeCompileRequest;
|
|
31
31
|
} => {
|
|
32
|
-
const sdk = createComposeSdk({ baseUrl: BASE_URL });
|
|
32
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
33
33
|
|
|
34
34
|
const builder = sdk.flow(1, {
|
|
35
35
|
name: 'split-with-arithmetic',
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createComposeSdk,
|
|
5
|
+
guards,
|
|
6
|
+
materialisers,
|
|
7
|
+
resources,
|
|
8
|
+
} from '../../index.js';
|
|
9
|
+
import type { Address } from '../../types.js';
|
|
10
|
+
import { API_KEY, BASE_URL } from '../config.js';
|
|
11
|
+
|
|
12
|
+
// Aave v3 contracts on Ethereum mainnet.
|
|
13
|
+
const AAVE_V3_POOL = '0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2';
|
|
14
|
+
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
|
|
15
|
+
// Aave v3 aEthUSDC receipt token and variable-debt USDC token.
|
|
16
|
+
const A_ETH_USDC = '0x98C23E9d8f34FEFb1B7BD6a91B7FF122F4e16F5c';
|
|
17
|
+
const VDEBT_USDC = '0x72E95b8931767C79bA4EeE721354d6E99a61D004';
|
|
18
|
+
|
|
19
|
+
// 1.05 WAD (1e18) — minimum acceptable Aave health factor after the borrow.
|
|
20
|
+
// The on-chain VM reverts the run if the post-borrow HF drops below this.
|
|
21
|
+
const MIN_HEALTH_FACTOR_WAD = '1050000000000000000';
|
|
22
|
+
|
|
23
|
+
export interface AaveBorrowInput {
|
|
24
|
+
readonly owner: Address;
|
|
25
|
+
readonly recipient: Address;
|
|
26
|
+
/** USDC supplied as collateral so the proxy can borrow (6 dp). */
|
|
27
|
+
readonly collateralAmount: `${bigint}`;
|
|
28
|
+
/** USDC borrowed against the collateral and sent to the recipient (6 dp). */
|
|
29
|
+
readonly borrowAmount: `${bigint}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Supply USDC to Aave v3, borrow USDC against it, and transfer the borrowed
|
|
34
|
+
* funds to a recipient — with an on-chain health-factor guard that reverts
|
|
35
|
+
* if the post-borrow position is too thin.
|
|
36
|
+
*
|
|
37
|
+
* The in-flow supply makes the example self-contained: the borrow is backed
|
|
38
|
+
* by collateral created in the same transaction, so it simulates cleanly
|
|
39
|
+
* for a fresh proxy. Keep `borrowAmount` comfortably below the collateral's
|
|
40
|
+
* borrowing power or the health-factor guard reverts the run.
|
|
41
|
+
*
|
|
42
|
+
* Demonstrates:
|
|
43
|
+
* - `lifi.zap` to supply USDC into Aave (USDC → aEthUSDC routing edge)
|
|
44
|
+
* - `aave.borrow` with no resource input — the borrowed asset materialises
|
|
45
|
+
* as the `borrowed` resource output.
|
|
46
|
+
* - Chaining the borrow output into a `core.transfer` to forward funds.
|
|
47
|
+
* - `aave.getHealthFactor` + `core.numericInvariant` guard asserts that
|
|
48
|
+
* `healthFactor >= MIN_HEALTH_FACTOR_WAD` after the borrow; the run reverts
|
|
49
|
+
* on-chain if the threshold is violated.
|
|
50
|
+
*
|
|
51
|
+
* The supplied aEthUSDC stays on the proxy: it backs the open debt, and
|
|
52
|
+
* Aave rejects aToken transfers that would break the position's health
|
|
53
|
+
* factor, so it cannot be swept while the borrow is outstanding.
|
|
54
|
+
*/
|
|
55
|
+
export const buildAaveBorrow = ({
|
|
56
|
+
owner,
|
|
57
|
+
recipient,
|
|
58
|
+
collateralAmount,
|
|
59
|
+
borrowAmount,
|
|
60
|
+
}: AaveBorrowInput): {
|
|
61
|
+
flow: Flow;
|
|
62
|
+
request: ComposeCompileRequest;
|
|
63
|
+
} => {
|
|
64
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
65
|
+
|
|
66
|
+
const builder = sdk.flow(1, {
|
|
67
|
+
name: 'aave-borrow-usdc',
|
|
68
|
+
inputs: {
|
|
69
|
+
collateralIn: resources.erc20(USDC, 1),
|
|
70
|
+
recipient: 'address',
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Supply USDC as collateral (USDC → aEthUSDC) so the proxy can borrow.
|
|
75
|
+
builder.lifi.zap('supply', {
|
|
76
|
+
bind: { amountIn: builder.inputs.collateralIn },
|
|
77
|
+
config: { resourceOut: resources.erc20(A_ETH_USDC, 1) },
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const borrowOut = builder.aave.borrow('borrow', {
|
|
81
|
+
bind: {},
|
|
82
|
+
config: {
|
|
83
|
+
pool: AAVE_V3_POOL,
|
|
84
|
+
asset: USDC,
|
|
85
|
+
variableDebtToken: VDEBT_USDC,
|
|
86
|
+
amount: borrowAmount,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Read the post-borrow Aave health factor and assert it stays above the
|
|
91
|
+
// minimum threshold. The numericInvariant guard lowers to an on-chain
|
|
92
|
+
// `AssertRawInvariant` IR1 instruction; the run reverts if HF < threshold.
|
|
93
|
+
builder.aave.getHealthFactor('hf', {
|
|
94
|
+
bind: {},
|
|
95
|
+
config: { pool: AAVE_V3_POOL },
|
|
96
|
+
guards: [
|
|
97
|
+
guards.coreNumericInvariant({
|
|
98
|
+
port: 'healthFactor',
|
|
99
|
+
op: 'gte',
|
|
100
|
+
threshold: MIN_HEALTH_FACTOR_WAD,
|
|
101
|
+
}),
|
|
102
|
+
],
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Forward the freshly borrowed USDC to the recipient.
|
|
106
|
+
builder.core.transfer('send-borrowed', {
|
|
107
|
+
bind: {
|
|
108
|
+
amount: borrowOut.borrowed,
|
|
109
|
+
recipient: builder.inputs.recipient,
|
|
110
|
+
},
|
|
111
|
+
config: {},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const flow = builder.build();
|
|
115
|
+
|
|
116
|
+
// No sweepTo: the aEthUSDC collateral must stay on the proxy while the
|
|
117
|
+
// debt is open — Aave blocks aToken transfers that would leave the
|
|
118
|
+
// position undercollateralized.
|
|
119
|
+
const request = sdk.request(flow, {
|
|
120
|
+
signer: owner,
|
|
121
|
+
inputs: {
|
|
122
|
+
collateralIn: materialisers.directDeposit({ amount: collateralAmount }),
|
|
123
|
+
recipient,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
return { flow, request };
|
|
128
|
+
};
|