133 lines
4.5 KiB
TypeScript
133 lines
4.5 KiB
TypeScript
/**
|
|
* Cross-Protocol: Complete DeFi strategy example
|
|
*
|
|
* This example demonstrates a complete DeFi strategy using Protocolink:
|
|
* 1. Supply USDC to Aave v3
|
|
* 2. Enable as collateral
|
|
* 3. Borrow USDT from Aave v3
|
|
* 4. Swap USDT → USDC on Uniswap v3
|
|
* 5. Supply swapped USDC back to Aave
|
|
*
|
|
* All in one transaction via Protocolink!
|
|
*/
|
|
|
|
import * as api from '@protocolink/api';
|
|
import * as common from '@protocolink/common';
|
|
import { createWalletRpcClient } from '../../src/utils/chain-config.js';
|
|
import { waitForTransaction } from '../../src/utils/rpc.js';
|
|
|
|
const CHAIN_ID = common.ChainId.mainnet;
|
|
const PRIVATE_KEY = process.env.PRIVATE_KEY as `0x${string}`;
|
|
|
|
async function supplyBorrowSwapStrategy() {
|
|
const walletClient = createWalletRpcClient(CHAIN_ID, PRIVATE_KEY);
|
|
const publicClient = walletClient as any;
|
|
const account = walletClient.account?.address;
|
|
|
|
if (!account) {
|
|
throw new Error('No account available');
|
|
}
|
|
|
|
const USDC: common.Token = {
|
|
chainId: CHAIN_ID,
|
|
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
decimals: 6,
|
|
symbol: 'USDC',
|
|
name: 'USD Coin',
|
|
};
|
|
|
|
const USDT: common.Token = {
|
|
chainId: CHAIN_ID,
|
|
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
decimals: 6,
|
|
symbol: 'USDT',
|
|
name: 'Tether USD',
|
|
};
|
|
|
|
const initialSupply = '5000'; // 5,000 USDC
|
|
const borrowAmount = '2000'; // 2,000 USDT
|
|
|
|
console.log('Complete DeFi strategy:');
|
|
console.log(` 1. Supply ${initialSupply} USDC to Aave`);
|
|
console.log(` 2. Enable as collateral`);
|
|
console.log(` 3. Borrow ${borrowAmount} USDT from Aave`);
|
|
console.log(` 4. Swap USDT → USDC on Uniswap v3`);
|
|
console.log(` 5. Supply swapped USDC back to Aave`);
|
|
console.log(`\nAccount: ${account}`);
|
|
|
|
try {
|
|
const logics: any[] = [];
|
|
|
|
// Step 1: Supply USDC
|
|
console.log('\n1. Adding supply logic...');
|
|
const supplyQuotation1 = await api.protocols.aavev3.getSupplyQuotation(CHAIN_ID, {
|
|
input: { token: USDC, amount: initialSupply },
|
|
});
|
|
const supplyLogic1 = api.protocols.aavev3.newSupplyLogic(supplyQuotation1);
|
|
logics.push(supplyLogic1);
|
|
|
|
// Step 2: Set as collateral (may be automatic, check Aave docs)
|
|
// Note: Some Aave markets automatically enable as collateral
|
|
console.log('2. Collateral enabled automatically in most markets');
|
|
|
|
// Step 3: Borrow USDT
|
|
console.log('3. Adding borrow logic...');
|
|
const borrowQuotation = await api.protocols.aavev3.getBorrowQuotation(CHAIN_ID, {
|
|
output: { token: USDT, amount: borrowAmount },
|
|
});
|
|
const borrowLogic = api.protocols.aavev3.newBorrowLogic(borrowQuotation);
|
|
logics.push(borrowLogic);
|
|
|
|
// Step 4: Swap USDT → USDC
|
|
console.log('4. Adding swap logic...');
|
|
const swapQuotation = await api.protocols.uniswapv3.getSwapTokenQuotation(CHAIN_ID, {
|
|
input: { token: USDT, amount: borrowAmount },
|
|
tokenOut: USDC,
|
|
slippage: 100, // 1% slippage
|
|
});
|
|
const swapLogic = api.protocols.uniswapv3.newSwapTokenLogic(swapQuotation);
|
|
logics.push(swapLogic);
|
|
|
|
// Step 5: Supply swapped USDC
|
|
console.log('5. Adding second supply logic...');
|
|
const supplyQuotation2 = await api.protocols.aavev3.getSupplyQuotation(CHAIN_ID, {
|
|
input: swapQuotation.output, // Use swapped USDC
|
|
});
|
|
const supplyLogic2 = api.protocols.aavev3.newSupplyLogic(supplyQuotation2);
|
|
logics.push(supplyLogic2);
|
|
|
|
// Step 6: Execute all in one transaction
|
|
console.log('\n6. Building router transaction...');
|
|
const routerData = await api.router.getRouterData(CHAIN_ID, {
|
|
account,
|
|
logics,
|
|
});
|
|
|
|
console.log(`Router: ${routerData.router}`);
|
|
console.log(`Estimated gas: ${routerData.estimation.gas}`);
|
|
|
|
console.log('\n7. Executing transaction...');
|
|
const tx = await walletClient.sendTransaction({
|
|
to: routerData.router,
|
|
data: routerData.data,
|
|
value: BigInt(routerData.estimation.value || '0'),
|
|
gas: BigInt(routerData.estimation.gas),
|
|
});
|
|
|
|
await waitForTransaction(publicClient, tx);
|
|
console.log(`Transaction executed: ${tx}`);
|
|
console.log('\n✅ Complete DeFi strategy executed successfully!');
|
|
} catch (error) {
|
|
console.error('Error executing strategy:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Run if executed directly
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
supplyBorrowSwapStrategy().catch(console.error);
|
|
}
|
|
|
|
export { supplyBorrowSwapStrategy };
|
|
|