@lifi/composer-sdk
Version:
Public Composer SDK for building and submitting flows
85 lines (72 loc) • 2.46 kB
text/typescript
import type { ComposeCompileRequest, Flow } from '@lifi/compose-spec';
import { createComposeSdk, materialisers, resources } from '../index.js';
import type { Address } from '../types.js';
import { BASE_URL } from './config.js';
const USDC = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48';
// Example ERC-4626 vault address (Steakhouse USDC on Ethereum mainnet)
const VAULT = '0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB';
export interface ApproveAndDepositInput {
readonly owner: Address;
readonly amount: `${bigint}`;
}
/**
* Approve a vault to spend USDC, deposit into it, and track the resulting
* shares as a resource.
*
* Demonstrates:
* - core.approve to grant ERC20 allowance to the vault
* - core.call to invoke the vault's deposit function
* - core.asResource to graduate the raw return value to a tracked resource
*/
export const buildApproveAndDeposit = ({
owner,
amount,
}: ApproveAndDepositInput): {
flow: Flow;
request: ComposeCompileRequest;
} => {
const sdk = createComposeSdk({ baseUrl: BASE_URL });
const builder = sdk.flow(1, {
name: 'approve-and-deposit',
inputs: {
amountIn: resources.erc20(USDC, 1),
},
});
// Approve the vault to spend our USDC.
builder.core.approve('approve-vault', {
bind: { amount: builder.inputs.amountIn },
config: { spender: VAULT },
});
// Call vault.deposit(uint256 assets, address receiver) returns (uint256).
// The input resource (USDC) is consumed by the call.
// The `returns (uint256)` clause gives typed access to `.result` (shares minted).
const depositResult = builder.core.call('deposit', {
resource: builder.inputs.amountIn,
bind: {
assets: builder.inputs.amountIn,
receiver: builder.context.executionAddress,
},
config: {
target: VAULT,
functionSignature:
'function deposit(uint256 assets, address receiver) returns (uint256)',
},
});
// Graduate the raw shares handle to a tracked resource so downstream
// nodes can use it with slippage tracking and linearity checks.
builder.core.asResource('shares', {
bind: { handle: depositResult.result },
config: {
resource: resources.erc20(VAULT, 1),
},
});
const flow = builder.build();
const request = sdk.request(flow, {
signer: owner,
inputs: {
amountIn: materialisers.directDeposit({ amount }),
},
sweepTo: builder.context.sender,
});
return { flow, request };
};