UNPKG

@lifi/composer-sdk

Version:

Public Composer SDK for building and submitting flows

206 lines (193 loc) 8.76 kB
/** * Example harness — builds a request and sends it to a live compose backend. * * Usage: * COMPOSER_BASE_URL=https://composer.li.quest yarn example <name> * * Pass LIFI_API_KEY to authenticate: * LIFI_API_KEY=your-key COMPOSER_BASE_URL=https://composer.li.quest yarn example <name> * * Available examples: * aave-repay — repay an Aave v3 WETH debt by supplying WETH * aave-repay-atoken — repay an Aave v3 USDC debt by burning proxy aTokens * aave-claim — claim AAVE rewards and forward to a recipient * approve-deposit — approve vault allowance then deposit USDC * consolidate — consolidate ERC-20 balances to USDC * consolidate-eth — consolidate ERC-20 balances to native ETH * deposit-proxy — deposit tokens already on the proxy into Aave * dust-sweep — split USDC 80/20 and sweep leftover dust * swap — swap WETH to USDC via LI.FI * swap-fee — swap WETH to USDC with a 50 bps integrator fee * split-zap — split USDC 60/40 and zap into Aave + Morpho vaults * split-arithmetic — split USDC 70/30 with arithmetic assertions * zap — zap USDC into Aave lending position * swap-zap — swap WETH to USDC then zap into Aave * swap-check — swap WETH to USDC with balance check * swap-recipient — swap WETH + DAI to USDC and send to recipient * swap-validate — swap WETH to USDC with output validation bounds * swap-allow-revert — swap WETH to USDC with allow-revert policy * raw-call — query a contract with raw calldata + arithmetic * read-state — read on-chain state via peek, staticCall, balanceOf * redeem — redeem ERC-4626 vault shares via core.call * claim — claim rewards from a contract (resource-free call) * wrap-eth — wrap native ETH into WETH via ValueCall * transfer — transfer full token balance to a recipient * partial-transfer — transfer a specific amount, keeping the remainder * untyped-ref — mix untypedOp with typed handles via raw.ref */ import type { ComposeCompileRequest } from '@lifi/compose-spec'; import { createComposeSdk } from '../sdk.js'; import { buildAaveClaimRewards } from './aaveClaimRewards.js'; import { buildAaveRepay } from './aaveRepay.js'; import { buildAaveRepayWithATokens } from './aaveRepayWithATokens.js'; import { buildApproveAndDeposit } from './approveAndDeposit.js'; import { buildClaimRewards, buildRedeemFromVault, buildWrapEth, } from './callContract.js'; import { API_KEY, BASE_URL, OWNER, PROXY, RECIPIENT } from './config.js'; import { buildConsolidateToEth } from './consolidateToEth.js'; import { buildConsolidateStablesToUsdc } from './consolidateToUsdc.js'; import { buildDepositFromProxy } from './depositFromProxy.js'; import { buildDustSweepExample } from './dustSweep.js'; import { buildLifiSwapExample } from './lifiSwap.js'; import { buildLifiZapExample } from './lifiZap.js'; import { buildRawCallWithArithmetic } from './rawCallWithArithmetic.js'; import { buildReadContractState } from './readContractState.js'; import { buildSplitAndZapExample } from './splitAndZap.js'; import { buildSplitWithArithmetic } from './splitWithArithmetic.js'; import { buildSwapAndZapExample } from './swapAndZap.js'; import { buildSwapToRecipient } from './swapToRecipient.js'; import { buildSwapWithAllowRevertExample } from './swapWithAllowRevert.js'; import { buildSwapWithBalanceCheck } from './swapWithBalanceCheck.js'; import { buildSwapWithFeeExample } from './swapWithFee.js'; import { buildSwapWithOutputValidation } from './swapWithOutputValidation.js'; import { buildPartialTransfer, buildTransferTokens } from './transferTokens.js'; import { buildUntypedOpWithTypedRef } from './untypedOpWithTypedRef.js'; const EXAMPLES: Record<string, () => ComposeCompileRequest> = { 'aave-repay': () => buildAaveRepay({ owner: OWNER, amount: '500000000000000000' }).request, 'aave-repay-atoken': () => buildAaveRepayWithATokens({ owner: OWNER, proxyAddress: PROXY, expectedATokenBalance: '1000000000', }).request, 'aave-claim': () => buildAaveClaimRewards({ owner: OWNER, recipient: RECIPIENT }).request, 'approve-deposit': () => buildApproveAndDeposit({ owner: OWNER, amount: '1000000000' }).request, consolidate: () => buildConsolidateStablesToUsdc({ owner: OWNER, usdtAmount: '1000000000', daiAmount: '1000000000000000000000', fraxAmount: '1000000000000000000000', lusdAmount: '1000000000000000000000', }).request, 'consolidate-eth': () => buildConsolidateToEth({ owner: OWNER, wethAmount: '1000000000000000000', usdcAmount: '1000000000', usdtAmount: '1000000000', daiAmount: '1000000000000000000000', }).request, 'deposit-proxy': () => buildDepositFromProxy({ owner: OWNER, proxyAddress: PROXY, expectedAmount: '1000000000', }).request, 'dust-sweep': () => buildDustSweepExample().request, swap: () => buildLifiSwapExample().request, 'swap-fee': () => buildSwapWithFeeExample().request, 'split-zap': () => buildSplitAndZapExample().request, 'split-arithmetic': () => buildSplitWithArithmetic({ owner: OWNER, amount: '1000000000' }).request, zap: () => buildLifiZapExample().request, 'swap-zap': () => buildSwapAndZapExample().request, 'swap-check': () => buildSwapWithBalanceCheck({ owner: OWNER, amount: '1000000000000000000' }) .request, 'swap-recipient': () => buildSwapToRecipient({ owner: OWNER, recipient: RECIPIENT, wethAmount: '1000000000000000000', daiAmount: '500000000000000000000', }).request, 'swap-validate': () => buildSwapWithOutputValidation({ owner: OWNER, amount: '1000000000000000000', expectedOut: '3000000000', }).request, 'swap-allow-revert': () => buildSwapWithAllowRevertExample().request, 'raw-call': () => buildRawCallWithArithmetic({ owner: OWNER }).request, 'read-state': () => buildReadContractState({ owner: OWNER }).request, redeem: () => buildRedeemFromVault({ owner: OWNER, amount: '1000000000000000000' }) .request, claim: () => buildClaimRewards({ owner: OWNER }).request, 'wrap-eth': () => buildWrapEth({ owner: OWNER, amount: '1000000000000000000' }).request, transfer: () => buildTransferTokens({ owner: OWNER, recipient: RECIPIENT, amount: '1000000000', }).request, 'partial-transfer': () => buildPartialTransfer({ owner: OWNER, recipient: RECIPIENT, amount: '1000000000', }).request, 'untyped-ref': () => buildUntypedOpWithTypedRef({ owner: OWNER }).request, }; const run = async () => { const args = process.argv.slice(2); const useStaged = args.includes('--staged'); const name = args.find((arg) => arg !== '--staged'); // Staged examples live under examples/staged/ and reference not-yet-prod // definitions, so they are deliberately excluded from this production file's // type-check. With --staged, pull their registry in via a NON-LITERAL dynamic // import (kept `any` to tsc, so the staged files are not dragged into the // production program). Requires the SDK to have been regenerated with // `yarn generate --staged` first, so the staged ops/materialisers exist at // runtime; run `yarn generate` afterwards to restore the production surface. let examples: Record<string, () => ComposeCompileRequest> = EXAMPLES; if (useStaged) { const stagedModule = (await import( `${import.meta.dirname}/staged/registry.js` )) as { STAGED_EXAMPLES: Record<string, () => ComposeCompileRequest> }; examples = { ...EXAMPLES, ...stagedModule.STAGED_EXAMPLES }; } const builder = name ? examples[name] : undefined; if (!builder) { const valid = Object.keys(examples).join(', '); console.error( `Error: ${ name ? `unknown example "${name}"` : 'no example specified' }\n` + `Valid examples: ${valid}\n` + `Usage: COMPOSER_BASE_URL=https://composer.li.quest yarn example [--staged] <name>`, ); process.exit(1); } console.log(`Running example: ${name}`); const request = builder(); const sdk = createComposeSdk({ baseUrl: BASE_URL, apiKey: API_KEY }); console.log('--- Request ---'); console.log(JSON.stringify(request, null, 2)); console.log(`\n--- Compiling against ${BASE_URL} ---`); const result = await sdk.client.compile(request); console.log('\n--- Result ---'); console.log(JSON.stringify(result, null, 2)); }; run().catch((err: unknown) => { console.error(err); process.exit(1); });