Files
237-combo/examples/ts/protocolink-batch.ts
2026-02-09 21:51:30 -08:00

136 lines
4.5 KiB
TypeScript

/**
* Protocolink: Complex multi-step batch transactions
*
* This example demonstrates how to build complex multi-step transactions
* using Protocolink, such as:
* - Flash loan
* - Swap
* - Supply
* - Borrow
* - Repay
* All in one transaction!
*/
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 batchComplexTransaction() {
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',
};
console.log('Building complex batch transaction:');
console.log(' 1. Flash loan USDC');
console.log(' 2. Supply USDC to Aave');
console.log(' 3. Borrow USDT from Aave');
console.log(' 4. Swap USDT → USDC');
console.log(' 5. Repay flash loan');
console.log(`Account: ${account}`);
try {
const logics: any[] = [];
const flashLoanAmount = '10000'; // 10,000 USDC
// Step 1: Flash loan logic (using utility flash loan)
console.log('\n1. Adding flash loan logic...');
const flashLoanQuotation = await api.utility.getFlashLoanQuotation(CHAIN_ID, {
loans: [{ token: USDC, amount: flashLoanAmount }],
});
const flashLoanLogic = api.utility.newFlashLoanLogic(flashLoanQuotation);
logics.push(flashLoanLogic);
// Step 2: Supply logic
console.log('2. Adding supply logic...');
const supplyQuotation = await api.protocols.aavev3.getSupplyQuotation(CHAIN_ID, {
input: { token: USDC, amount: flashLoanAmount },
});
const supplyLogic = api.protocols.aavev3.newSupplyLogic(supplyQuotation);
logics.push(supplyLogic);
// Step 3: Borrow logic
console.log('3. Adding borrow logic...');
const borrowAmount = '5000'; // 5,000 USDT
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 logic
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: Flash loan repay logic
console.log('5. Adding flash loan repay logic...');
const flashLoanRepayLogic = api.utility.newFlashLoanRepayLogic({
id: flashLoanLogic.id,
input: swapQuotation.output, // Use swapped USDC to repay
});
logics.push(flashLoanRepayLogic);
// Step 6: Get router data and execute
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✅ Complex batch transaction completed successfully!');
} catch (error) {
console.error('Error executing batch transaction:', error);
throw error;
}
}
// Run if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
batchComplexTransaction().catch(console.error);
}
export { batchComplexTransaction };