@lifi/composer-sdk 0.3.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 +21 -0
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- 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/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 +3 -3
- package/dist/index.d.ts +3 -3
- 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/package.json +3 -4
- package/src/errors.ts +67 -1
- 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/generated/materialisers.generated.ts +12 -0
- package/src/generated/operations.generated.ts +214 -0
- package/src/index.ts +7 -2
- package/src/responseSchemas.ts +29 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type ContinuationIntent,
|
|
5
|
+
type ContinuationOutcome,
|
|
6
|
+
createComposeSdk,
|
|
7
|
+
raw,
|
|
8
|
+
resources,
|
|
9
|
+
} from '../../index.js';
|
|
10
|
+
import type { Address } from '../../types.js';
|
|
11
|
+
import { API_KEY, BASE_URL } from '../config.js';
|
|
12
|
+
|
|
13
|
+
// USDC on Ethereum mainnet (6 decimals). Matches the funding input, the
|
|
14
|
+
// committed outcome token, and the second-leg balance read below.
|
|
15
|
+
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
|
|
16
|
+
|
|
17
|
+
// The self-serve settlement provider's registry name. This literal must match
|
|
18
|
+
// `MANUAL_RELAY_PROVIDER_NAME` in the compose-builtins package
|
|
19
|
+
// (ts/packages/compose-builtins/src/providers/manualRelay/provider.ts); that
|
|
20
|
+
// package is not an SDK dependency, so it is inlined here rather than imported.
|
|
21
|
+
const MANUAL_RELAY_PROVIDER = 'manual-relay';
|
|
22
|
+
|
|
23
|
+
export interface ManualRelayContinuationInput {
|
|
24
|
+
/** The transaction signer for leg 1. */
|
|
25
|
+
readonly owner: Address;
|
|
26
|
+
/** Where the committed outcome is delivered — the user's own custody. */
|
|
27
|
+
readonly recipient: Address;
|
|
28
|
+
/** Funding amount for leg 1, in USDC smallest units (6 decimals). */
|
|
29
|
+
readonly amount: `${bigint}`;
|
|
30
|
+
/** Minimum USDC (smallest units) the outcome commits to delivering. */
|
|
31
|
+
readonly minAmountOut: `${bigint}`;
|
|
32
|
+
/** Unix-epoch milliseconds after which the continuation is no longer valid. */
|
|
33
|
+
readonly expiresAtMs: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Manual-relay (self-serve) deferred settlement — the two-leg continuation model.
|
|
38
|
+
*
|
|
39
|
+
* A `continuation.settle` node splits one intent into two legs. Leg 1 funds the
|
|
40
|
+
* settlement and commits to an outcome; leg 2 is a second flow the caller
|
|
41
|
+
* re-submits later, once the committed proceeds have actually landed. The
|
|
42
|
+
* `manual-relay` provider performs no I/O and funds no escrow — the funds stay
|
|
43
|
+
* in the user's own custody between the legs, and the caller ("relays") the
|
|
44
|
+
* second leg itself. That makes it the simplest provider to author against and
|
|
45
|
+
* the right one for a self-serve integration.
|
|
46
|
+
*
|
|
47
|
+
* Why `untypedOp`:
|
|
48
|
+
* - `continuation.settle` has no generated `builder.*` method: it is a
|
|
49
|
+
* provider-dependent factory op (`createContinuationSettleOp`), registered at
|
|
50
|
+
* server wiring rather than emitted into the static manifest the SDK is
|
|
51
|
+
* generated from, so it never appears on the typed builder surface. It is
|
|
52
|
+
* authored through the `untypedOp` escape hatch: the op id is a plain string
|
|
53
|
+
* and its `bind`/`config` are validated by the backend at compile time rather
|
|
54
|
+
* than by the TypeScript surface.
|
|
55
|
+
* - The funding resource is wired via `bind.input` (a resource ref); the delivery
|
|
56
|
+
* address via `bind.destination` (an address ref), which becomes the produced
|
|
57
|
+
* future resource's owner.
|
|
58
|
+
* - `config` is a `ContinuationIntent`. This example imports `ContinuationIntent`
|
|
59
|
+
* and `ContinuationOutcome` from the SDK's own re-exports (`../../index.js`) to
|
|
60
|
+
* type the config even though the op itself is untyped — the authoring types
|
|
61
|
+
* ship publicly even while the op is staged.
|
|
62
|
+
*
|
|
63
|
+
* The committed terms:
|
|
64
|
+
* - `outcomes` — one or more `{ token, minAmount, destination, chainId }` promises.
|
|
65
|
+
* The manual-relay provider supports exactly one outcome per settle node; model
|
|
66
|
+
* multiple deliveries as multiple `continuation.settle` nodes.
|
|
67
|
+
* - `validity.expiresAtMs` — after this the continuation cannot be settled.
|
|
68
|
+
* - `provider` — the settlement mechanism, selected by name (`manual-relay` here).
|
|
69
|
+
* - `continuationFlow` — the inline second leg. The provider embeds the readiness
|
|
70
|
+
* `check` into it as a pre-execution on-chain assertion before returning it, so a
|
|
71
|
+
* premature re-submission reverts instead of running on stale balances.
|
|
72
|
+
*
|
|
73
|
+
* How to CONSUME the compile response (leg 1):
|
|
74
|
+
* - `continuations` — the list of settle nodes that produced a deferred outcome.
|
|
75
|
+
* - `phase1ByNode.<node>` — what the caller must do to fund leg 1. For manual-relay
|
|
76
|
+
* this is `{ kind: 'none' }`: nothing to sign or fund now, the funds stay in the
|
|
77
|
+
* user's custody. (Other providers may return `kind: 'transaction'` or `signables`.)
|
|
78
|
+
* - `continuationPlans.<node>` — `{ chainId, validity, check, nextFlow }`. Poll the
|
|
79
|
+
* `check` (an `erc20BalanceGte` predicate here) until it passes, then re-submit
|
|
80
|
+
* `nextFlow` verbatim through the normal `/compose` pipeline. `nextFlow` already
|
|
81
|
+
* has the readiness check compiled in as an on-chain assertion, so an early
|
|
82
|
+
* re-submission reverts safely rather than executing on stale state.
|
|
83
|
+
*/
|
|
84
|
+
export const buildManualRelayContinuation = ({
|
|
85
|
+
owner,
|
|
86
|
+
recipient,
|
|
87
|
+
amount,
|
|
88
|
+
minAmountOut,
|
|
89
|
+
expiresAtMs,
|
|
90
|
+
}: ManualRelayContinuationInput): {
|
|
91
|
+
flow: Flow;
|
|
92
|
+
request: ComposeCompileRequest;
|
|
93
|
+
} => {
|
|
94
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
95
|
+
|
|
96
|
+
// The inline second leg. Authored as an ordinary flow via the builder; the
|
|
97
|
+
// provider will prepend the readiness assertion to it before returning it in
|
|
98
|
+
// `continuationPlans`. Here it simply reads the delivered proceeds — a real
|
|
99
|
+
// integration would deposit them into a vault, repay a loan, etc.
|
|
100
|
+
const secondLeg = sdk.flow(1, {
|
|
101
|
+
name: 'manual-relay-continuation-leg2',
|
|
102
|
+
inputs: {},
|
|
103
|
+
});
|
|
104
|
+
secondLeg.core.balanceOf('read-proceeds', {
|
|
105
|
+
bind: {},
|
|
106
|
+
config: { token: USDC, owner: recipient },
|
|
107
|
+
});
|
|
108
|
+
const continuationFlow: Flow = secondLeg.build();
|
|
109
|
+
|
|
110
|
+
// The committed outcome: at least `minAmountOut` USDC delivered to `recipient`
|
|
111
|
+
// on mainnet. `ContinuationOutcome` is the SDK-re-exported authoring type.
|
|
112
|
+
const outcome: ContinuationOutcome = {
|
|
113
|
+
token: USDC,
|
|
114
|
+
minAmount: minAmountOut,
|
|
115
|
+
destination: recipient,
|
|
116
|
+
chainId: 1,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const config: ContinuationIntent = {
|
|
120
|
+
outcomes: [outcome],
|
|
121
|
+
validity: { expiresAtMs },
|
|
122
|
+
provider: MANUAL_RELAY_PROVIDER,
|
|
123
|
+
continuationFlow,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const builder = sdk.flow(1, {
|
|
127
|
+
name: 'manual-relay-continuation-leg1',
|
|
128
|
+
inputs: {
|
|
129
|
+
usdc: resources.erc20(USDC, 1),
|
|
130
|
+
destination: 'address',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// `continuation.settle` has no generated method (it is staged), so it is added
|
|
135
|
+
// via untypedOp. `bind.input` carries the funding resource; `bind.destination`
|
|
136
|
+
// carries the delivery address. Both are plain `$ref` pointers into the flow's
|
|
137
|
+
// declared inputs — untypedOp takes wire-format refs, so `raw.ref` builds them.
|
|
138
|
+
builder.untypedOp('settle', 'continuation.settle', {
|
|
139
|
+
bind: {
|
|
140
|
+
input: raw.ref<'resource'>('input.usdc'),
|
|
141
|
+
destination: raw.ref<'address'>('input.destination'),
|
|
142
|
+
},
|
|
143
|
+
config,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const flow = builder.build();
|
|
147
|
+
|
|
148
|
+
const request = sdk.request(flow, {
|
|
149
|
+
signer: owner,
|
|
150
|
+
inputs: {
|
|
151
|
+
usdc: amount,
|
|
152
|
+
destination: recipient,
|
|
153
|
+
},
|
|
154
|
+
// A deferred settle's output is a future resource with no spot value at
|
|
155
|
+
// simulation time, so the price-impact guard would register it as 100%
|
|
156
|
+
// impact. 0 disables the guard for this deferred-settlement flow.
|
|
157
|
+
maxPriceImpactBps: 0,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
return { flow, request };
|
|
161
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
|
|
2
|
+
|
|
3
|
+
import { createComposeSdk, materialisers, resources } from '../../index.js';
|
|
4
|
+
import type { Address } from '../../types.js';
|
|
5
|
+
import { API_KEY, BASE_URL } from '../config.js';
|
|
6
|
+
|
|
7
|
+
// Morpho Blue WETH/USDC market on Base (chainId 8453).
|
|
8
|
+
// The Morpho singleton address (0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb)
|
|
9
|
+
// is the default `morpho` config field and is read from compose-builtins.
|
|
10
|
+
const ADAPTIVE_CURVE_IRM_BASE = '0x46415998764C29aB2a25CbeA6254146D50D22687';
|
|
11
|
+
const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
|
|
12
|
+
const BASE_WETH = '0x4200000000000000000000000000000000000006';
|
|
13
|
+
const WETH_USDC_ORACLE = '0xFEa2D58cEfCb9fcb597723c6bAE66fFE4193aFE4';
|
|
14
|
+
const WETH_USDC_LLTV = '860000000000000000'; // 0.86e18
|
|
15
|
+
|
|
16
|
+
const WETH_USDC_MARKET = {
|
|
17
|
+
loanToken: BASE_USDC,
|
|
18
|
+
collateralToken: BASE_WETH,
|
|
19
|
+
oracle: WETH_USDC_ORACLE,
|
|
20
|
+
irm: ADAPTIVE_CURVE_IRM_BASE,
|
|
21
|
+
lltv: WETH_USDC_LLTV,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export interface MorphoBlueBorrowInput {
|
|
25
|
+
readonly owner: Address;
|
|
26
|
+
readonly collateralAmount: `${bigint}`;
|
|
27
|
+
readonly borrowAmount: `${bigint}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Open a leveraged-borrow position on the Base Morpho Blue WETH/USDC market.
|
|
32
|
+
*
|
|
33
|
+
* - `morphoBlue.supplyCollateral` debits the proxy's WETH and credits
|
|
34
|
+
* `Morpho.position(WETH_USDC_MARKET_ID, proxy).collateral`. There is no
|
|
35
|
+
* receipt token — collateral is non-transferable accounting state.
|
|
36
|
+
* - `morphoBlue.borrow` mints debt shares against that collateral and
|
|
37
|
+
* transfers USDC to the proxy. The borrowed asset is exposed as the
|
|
38
|
+
* `borrowed` Resource port for downstream nodes.
|
|
39
|
+
* - The flow sweeps the borrowed USDC back to the signer's wallet via
|
|
40
|
+
* `sweepTo` on the request.
|
|
41
|
+
*/
|
|
42
|
+
export const buildMorphoBlueBorrow = ({
|
|
43
|
+
owner,
|
|
44
|
+
collateralAmount,
|
|
45
|
+
borrowAmount,
|
|
46
|
+
}: MorphoBlueBorrowInput): {
|
|
47
|
+
flow: Flow;
|
|
48
|
+
request: ComposeCompileRequest;
|
|
49
|
+
} => {
|
|
50
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
51
|
+
|
|
52
|
+
const builder = sdk.flow(8453, {
|
|
53
|
+
name: 'morpho-blue-borrow-weth-usdc',
|
|
54
|
+
inputs: {
|
|
55
|
+
assetIn: resources.erc20(BASE_WETH, 8453),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
builder.morphoBlue.supplyCollateral('supply-collateral', {
|
|
60
|
+
bind: {
|
|
61
|
+
assetIn: builder.inputs.assetIn,
|
|
62
|
+
},
|
|
63
|
+
config: {
|
|
64
|
+
marketParams: WETH_USDC_MARKET,
|
|
65
|
+
mode: 'exact',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
builder.morphoBlue.borrow('borrow', {
|
|
70
|
+
bind: {},
|
|
71
|
+
config: {
|
|
72
|
+
marketParams: WETH_USDC_MARKET,
|
|
73
|
+
amount: borrowAmount,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const flow = builder.build();
|
|
78
|
+
|
|
79
|
+
const request = sdk.request(flow, {
|
|
80
|
+
signer: owner,
|
|
81
|
+
inputs: {
|
|
82
|
+
assetIn: materialisers.directDeposit({ amount: collateralAmount }),
|
|
83
|
+
},
|
|
84
|
+
// Sweep the borrowed USDC back to the signer.
|
|
85
|
+
sweepTo: builder.context.sender,
|
|
86
|
+
// The WETH collateral becomes unpriced Morpho position state (no receipt
|
|
87
|
+
// token), so the default 500 bps price-impact check reads any safe borrow
|
|
88
|
+
// (LLTV caps at 86%) as a loss. 0 skips the check.
|
|
89
|
+
maxPriceImpactBps: 0,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return { flow, request };
|
|
93
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
|
|
2
|
+
|
|
3
|
+
import { createComposeSdk, materialisers, resources } from '../../index.js';
|
|
4
|
+
import type { Address } from '../../types.js';
|
|
5
|
+
import { API_KEY, BASE_URL } from '../config.js';
|
|
6
|
+
|
|
7
|
+
// Morpho Blue WETH/USDC market on Base (chainId 8453).
|
|
8
|
+
const ADAPTIVE_CURVE_IRM_BASE = '0x46415998764C29aB2a25CbeA6254146D50D22687';
|
|
9
|
+
const BASE_USDC = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
|
|
10
|
+
const BASE_WETH = '0x4200000000000000000000000000000000000006';
|
|
11
|
+
const WETH_USDC_ORACLE = '0xFEa2D58cEfCb9fcb597723c6bAE66fFE4193aFE4';
|
|
12
|
+
const WETH_USDC_LLTV = '860000000000000000';
|
|
13
|
+
|
|
14
|
+
const WETH_USDC_MARKET = {
|
|
15
|
+
loanToken: BASE_USDC,
|
|
16
|
+
collateralToken: BASE_WETH,
|
|
17
|
+
oracle: WETH_USDC_ORACLE,
|
|
18
|
+
irm: ADAPTIVE_CURVE_IRM_BASE,
|
|
19
|
+
lltv: WETH_USDC_LLTV,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface MorphoBlueRepayInput {
|
|
23
|
+
readonly owner: Address;
|
|
24
|
+
/** WETH supplied as collateral for the in-flow borrow (18 dp). */
|
|
25
|
+
readonly collateralAmount: `${bigint}`;
|
|
26
|
+
/** USDC borrowed against the collateral, then repaid by this flow (6 dp). */
|
|
27
|
+
readonly borrowAmount: `${bigint}`;
|
|
28
|
+
/**
|
|
29
|
+
* USDC deposited to repay the debt (6 dp). Must exceed `borrowAmount`:
|
|
30
|
+
* Morpho's share rounding can leave the debt a wei above the borrowed
|
|
31
|
+
* amount, so the `max`-mode repay needs a little headroom. The leftover
|
|
32
|
+
* surfaces on the `residual` port.
|
|
33
|
+
*/
|
|
34
|
+
readonly repayAmount: `${bigint}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Open and close a Morpho Blue WETH/USDC position on Base in one flow —
|
|
39
|
+
* a self-contained supplyCollateral → borrow → repay → withdrawCollateral
|
|
40
|
+
* round trip that creates the debt it retires.
|
|
41
|
+
*
|
|
42
|
+
* Demonstrates:
|
|
43
|
+
* - `morphoBlue.supplyCollateral` to post WETH (collateral is internal
|
|
44
|
+
* position state — no receipt token).
|
|
45
|
+
* - `morphoBlue.borrow` to mint USDC debt against it.
|
|
46
|
+
* - `morphoBlue.repay` with `mode: 'max'`, which reads the proxy's current
|
|
47
|
+
* `borrowShares` on-chain and repays in shares mode to retire the debt to
|
|
48
|
+
* the wei. Unused USDC surfaces on the `residual` Resource port.
|
|
49
|
+
* - `morphoBlue.withdrawCollateral` to pull the freed WETH once the debt
|
|
50
|
+
* is cleared.
|
|
51
|
+
* - `sweepTo` to return the borrowed USDC, the repay residual, and the
|
|
52
|
+
* freed WETH to the signer.
|
|
53
|
+
*/
|
|
54
|
+
export const buildMorphoBlueRepay = ({
|
|
55
|
+
owner,
|
|
56
|
+
collateralAmount,
|
|
57
|
+
borrowAmount,
|
|
58
|
+
repayAmount,
|
|
59
|
+
}: MorphoBlueRepayInput): {
|
|
60
|
+
flow: Flow;
|
|
61
|
+
request: ComposeCompileRequest;
|
|
62
|
+
} => {
|
|
63
|
+
const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY });
|
|
64
|
+
|
|
65
|
+
const builder = sdk.flow(8453, {
|
|
66
|
+
name: 'morpho-blue-repay-usdc-withdraw-weth',
|
|
67
|
+
inputs: {
|
|
68
|
+
collateralIn: resources.erc20(BASE_WETH, 8453),
|
|
69
|
+
repayIn: resources.erc20(BASE_USDC, 8453),
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Post WETH collateral so the proxy can open the debt it will repay.
|
|
74
|
+
builder.morphoBlue.supplyCollateral('supply-collateral', {
|
|
75
|
+
bind: {
|
|
76
|
+
assetIn: builder.inputs.collateralIn,
|
|
77
|
+
},
|
|
78
|
+
config: {
|
|
79
|
+
marketParams: WETH_USDC_MARKET,
|
|
80
|
+
mode: 'exact',
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Borrow USDC against the collateral; the borrowed USDC stays on the
|
|
85
|
+
// proxy as a terminal resource and is swept back to the signer.
|
|
86
|
+
builder.morphoBlue.borrow('borrow', {
|
|
87
|
+
bind: {},
|
|
88
|
+
config: {
|
|
89
|
+
marketParams: WETH_USDC_MARKET,
|
|
90
|
+
amount: borrowAmount,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Retire the just-opened debt from the deposited USDC. mode 'max' reads
|
|
95
|
+
// the live borrowShares and repays in shares mode, clearing the debt to
|
|
96
|
+
// the wei; the unused USDC surfaces on the `residual` port.
|
|
97
|
+
builder.morphoBlue.repay('repay', {
|
|
98
|
+
bind: {
|
|
99
|
+
assetIn: builder.inputs.repayIn,
|
|
100
|
+
onBehalfOf: builder.context.executionAddress,
|
|
101
|
+
},
|
|
102
|
+
config: {
|
|
103
|
+
marketParams: WETH_USDC_MARKET,
|
|
104
|
+
mode: 'max',
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// The debt is cleared, so the full collateral can be withdrawn. The freed
|
|
109
|
+
// WETH lands on the proxy and is swept to the signer.
|
|
110
|
+
builder.morphoBlue.withdrawCollateral('withdraw-collateral', {
|
|
111
|
+
bind: {},
|
|
112
|
+
config: {
|
|
113
|
+
marketParams: WETH_USDC_MARKET,
|
|
114
|
+
amount: collateralAmount,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const flow = builder.build();
|
|
119
|
+
|
|
120
|
+
const request = sdk.request(flow, {
|
|
121
|
+
signer: owner,
|
|
122
|
+
inputs: {
|
|
123
|
+
collateralIn: materialisers.directDeposit({ amount: collateralAmount }),
|
|
124
|
+
repayIn: materialisers.directDeposit({ amount: repayAmount }),
|
|
125
|
+
},
|
|
126
|
+
// Sweep the borrowed USDC, the repay residual, and the freed WETH back
|
|
127
|
+
// to the signer.
|
|
128
|
+
sweepTo: builder.context.sender,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
return { flow, request };
|
|
132
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Registry of staged (not-yet-prod) examples for the live runner. This is data,
|
|
2
|
+
// not a runner: src/examples/run.ts imports it via a non-literal dynamic import
|
|
3
|
+
// when invoked with `--staged`, so this file (which references staged definitions)
|
|
4
|
+
// is never pulled into the production type-check. It IS type-checked under
|
|
5
|
+
// tsconfig.staged.json (see verify:staged).
|
|
6
|
+
//
|
|
7
|
+
// Running these requires the SDK regenerated with `--staged`; the example:staged
|
|
8
|
+
// wrapper does that and restores production afterward.
|
|
9
|
+
import type { ComposeCompileRequest } from '@lifi/compose-spec';
|
|
10
|
+
|
|
11
|
+
import { OWNER, RECIPIENT } from '../config.js';
|
|
12
|
+
|
|
13
|
+
import { buildAaveBorrow } from './aaveBorrow.js';
|
|
14
|
+
import { buildAaveDebtRebalanceExactOut } from './aaveDebtRebalanceExactOut.js';
|
|
15
|
+
import { buildAaveHealthFactorExplode } from './aaveHealthFactorExplode.js';
|
|
16
|
+
import { buildAaveToMorphoDebtMigration } from './aaveToMorphoDebtMigration.js';
|
|
17
|
+
import { buildAaveToMorphoDebtMigrationWithSwap } from './aaveToMorphoDebtMigrationWithSwap.js';
|
|
18
|
+
import { buildAaveToMorphoDebtMigrationWithSwapExactOut } from './aaveToMorphoDebtMigrationWithSwapExactOut.js';
|
|
19
|
+
import { buildTrivialFlashloanRepay } from './flashloanRepay.js';
|
|
20
|
+
import { buildManualRelayContinuation } from './manualRelayContinuation.js';
|
|
21
|
+
import { buildMorphoBlueBorrow } from './morphoBlueBorrow.js';
|
|
22
|
+
import { buildMorphoBlueRepay } from './morphoBlueRepay.js';
|
|
23
|
+
|
|
24
|
+
export const STAGED_EXAMPLES: Record<string, () => ComposeCompileRequest> = {
|
|
25
|
+
'aave-borrow': () =>
|
|
26
|
+
buildAaveBorrow({
|
|
27
|
+
owner: OWNER,
|
|
28
|
+
recipient: RECIPIENT,
|
|
29
|
+
collateralAmount: '1000000000',
|
|
30
|
+
borrowAmount: '500000000',
|
|
31
|
+
}).request,
|
|
32
|
+
'aave-hf-explode': () =>
|
|
33
|
+
buildAaveHealthFactorExplode({ signer: OWNER }).request,
|
|
34
|
+
'morpho-borrow': () =>
|
|
35
|
+
buildMorphoBlueBorrow({
|
|
36
|
+
owner: OWNER,
|
|
37
|
+
collateralAmount: '1000000000000000000',
|
|
38
|
+
borrowAmount: '1200000000',
|
|
39
|
+
}).request,
|
|
40
|
+
'morpho-repay': () =>
|
|
41
|
+
buildMorphoBlueRepay({
|
|
42
|
+
owner: OWNER,
|
|
43
|
+
collateralAmount: '1000000000000000000',
|
|
44
|
+
borrowAmount: '500000000',
|
|
45
|
+
repayAmount: '501000000',
|
|
46
|
+
}).request,
|
|
47
|
+
'debt-rebalance': () =>
|
|
48
|
+
buildAaveDebtRebalanceExactOut({
|
|
49
|
+
owner: OWNER,
|
|
50
|
+
collateralAmount: '1000000000000000000',
|
|
51
|
+
debtAmount: '1000000000',
|
|
52
|
+
newDebtBorrowAmount: '965000000',
|
|
53
|
+
}).request,
|
|
54
|
+
'debt-migration-swap-exact-out': () =>
|
|
55
|
+
buildAaveToMorphoDebtMigrationWithSwapExactOut({
|
|
56
|
+
owner: OWNER,
|
|
57
|
+
collateralAmount: '1000000000000000000',
|
|
58
|
+
debtAmount: '1000000000',
|
|
59
|
+
morphoBorrowAmount: '975000000',
|
|
60
|
+
}).request,
|
|
61
|
+
'flashloan-repay': () =>
|
|
62
|
+
buildTrivialFlashloanRepay({
|
|
63
|
+
owner: OWNER,
|
|
64
|
+
amount: '10000000000',
|
|
65
|
+
fee: '5000000',
|
|
66
|
+
}).request,
|
|
67
|
+
'debt-migration': () =>
|
|
68
|
+
buildAaveToMorphoDebtMigration({
|
|
69
|
+
owner: OWNER,
|
|
70
|
+
collateralAmount: '1000000000000000000',
|
|
71
|
+
debtAmount: '1000000000',
|
|
72
|
+
debtFlashloanFee: '500000',
|
|
73
|
+
}).request,
|
|
74
|
+
'debt-migration-swap': () =>
|
|
75
|
+
buildAaveToMorphoDebtMigrationWithSwap({
|
|
76
|
+
owner: OWNER,
|
|
77
|
+
collateralAmount: '1000000000000000000',
|
|
78
|
+
debtAmount: '1000000000',
|
|
79
|
+
morphoBorrowAmount: '1100000000',
|
|
80
|
+
}).request,
|
|
81
|
+
'manual-relay-continuation': () =>
|
|
82
|
+
buildManualRelayContinuation({
|
|
83
|
+
owner: OWNER,
|
|
84
|
+
recipient: RECIPIENT,
|
|
85
|
+
amount: '1000000',
|
|
86
|
+
minAmountOut: '990000',
|
|
87
|
+
expiresAtMs: 1900000000000,
|
|
88
|
+
}).request,
|
|
89
|
+
};
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
BalanceOfMaterialiserConfig as BalanceOfMaterialiserConfigSchema,
|
|
11
11
|
CallMaterialiserConfig as CallMaterialiserConfigSchema,
|
|
12
12
|
DirectDepositMaterialiserConfig as DirectDepositMaterialiserConfigSchema,
|
|
13
|
+
FlashloanMaterialiserConfig as FlashloanMaterialiserConfigSchema,
|
|
13
14
|
} from './config.generated.js';
|
|
14
15
|
|
|
15
16
|
export type BalanceOfMaterialiserConfig =
|
|
@@ -42,3 +43,14 @@ export const call = (config: CallMaterialiserConfig): MaterialiserInput => ({
|
|
|
42
43
|
kind: 'call',
|
|
43
44
|
...config,
|
|
44
45
|
});
|
|
46
|
+
|
|
47
|
+
export type FlashloanMaterialiserConfig =
|
|
48
|
+
MaterialiserConfigOf<FlashloanMaterialiserConfigSchema>;
|
|
49
|
+
|
|
50
|
+
/** Borrow tokens from a flashloan provider; amount becomes a register populated by the proxy at callback time — accepts: resource */
|
|
51
|
+
export const flashloan = (
|
|
52
|
+
config: FlashloanMaterialiserConfig,
|
|
53
|
+
): MaterialiserInput => ({
|
|
54
|
+
kind: 'flashloan',
|
|
55
|
+
...config,
|
|
56
|
+
});
|